auth-ui: Use Ory Kratos/Hydra v26.2.0 in E2E tests
Change-Id: I9301ccec0b634fef2a8b64e813ba9cec6c1b0b66
diff --git a/core/auth/ui/e2e/README.md b/core/auth/ui/e2e/README.md
index 5e2a8ac..710061d 100644
--- a/core/auth/ui/e2e/README.md
+++ b/core/auth/ui/e2e/README.md
@@ -7,8 +7,8 @@
The harness accepts no `latest` or system-browser fallback:
- Go **1.22 or newer** (the module directive is exactly `go 1.22`)
-- Kratos **v1.1.0**, SQLite release archive
-- Hydra **v2.2.0**, SQLite release archive
+- Kratos **v26.2.0**, SQLite release archive
+- Hydra **v26.2.0**, SQLite release archive
- `github.com/mxschmitt/playwright-go` **v0.6100.0**
- embedded Playwright CLI **1.61.1**
- managed Chromium revision **1228**, Chromium **149.0.7827.55**
@@ -22,10 +22,12 @@
| Platform | Kratos archive / SHA-256 | Hydra archive / SHA-256 |
|---|---|---|
-| linux/amd64 | `kratos_1.1.0-linux_sqlite_64bit.tar.gz` / `6fb3077252dde7578c3100d2cd4eb52364ca6b3c1b0b76987e6d586e29008cbd` | `hydra_2.2.0-linux_sqlite_64bit.tar.gz` / `0fe0539fa452496ac5d98b558f93eb2dbb4cf43733da0b09f8f2bdb4445fc31e` |
-| linux/arm64 | `kratos_1.1.0-linux_sqlite_arm64.tar.gz` / `fde8a1a1aebd153baff88b1232e0c2a34fdaaafe90b5364f4ea580151e74898e` | `hydra_2.2.0-linux_sqlite_arm64.tar.gz` / `c499ffdaae0f2ab85eff0567214734515b741a393bef89115c16018f4dc0560d` |
-| darwin/amd64 | `kratos_1.1.0-macOS_sqlite_64bit.tar.gz` / `ebdc94f27cb6e6a3087ed756accfb7837465ac8e30af9433b4414101814f7769` | `hydra_2.2.0-macOS_sqlite_64bit.tar.gz` / `3d40ca8e99e2a6d840130928d5e0245212dba0eea9c26a0d7186ebb4382e673d` |
-| darwin/arm64 | `kratos_1.1.0-macOS_sqlite_arm64.tar.gz` / `6681d7b15dd04686d10764750ce3ad69672b3962553223399a3a315ba5370517` | `hydra_2.2.0-macOS_sqlite_arm64.tar.gz` / `89732ad1494c57ea39348f62dc5ef5c48de129cd205b17cb12bb67ad27094bb7` |
+| linux/amd64 | `kratos_26.2.0-linux_sqlite_64bit.tar.gz` / `c80113f2c861b2fbd80290697d1380000111e297716018617423cca7f2e7e668` | `hydra_26.2.0-linux_sqlite_64bit.tar.gz` / `28baf98c6d5da617c905d5ca77826fe863db9f9edab8f72664c69a56bde56b5a` |
+| linux/arm64 | `kratos_26.2.0-linux_sqlite_arm64.tar.gz` / `fd2cedebc4034ad1aef726f64665052c809fb05f86968e9c8a36372d7578e865` | `hydra_26.2.0-linux_sqlite_arm64.tar.gz` / `18e73ac632d2081b76fbceb03130803a63bdb9b8e2ecc3f06f4a6e6820cabe26` |
+| darwin/amd64 | `kratos_26.2.0-macOS_sqlite_64bit.tar.gz` / `0ac76d0ad85fe452e711a2aafe56b49b0f5d1a57200f4464dcb48e7267c94062` | `hydra_26.2.0-macOS_sqlite_64bit.tar.gz` / `ede453fa15c82cfb23e61b138a0b4d9558127a26ebf51eead97d0c58a7eff422` |
+| darwin/arm64 | `kratos_26.2.0-macOS_sqlite_arm64.tar.gz` / `e198d84bde6e4b7c68714cdad00c8800edd88c2311adde8b08ea5469cea263ec` | `hydra_26.2.0-macOS_sqlite_arm64.tar.gz` / `d45f26be758196e66e98dff06a9eaefcd21d719123f74f43a0f1fabcfb71da60` |
+
+The Kratos fixture declares `version: v26.2.0`; executable identity is independently enforced by archive checksum and binary version verification. These in-memory SQLite tests validate auth-ui compatibility, not production database migrations or rollback.
These four Linux/macOS architecture combinations are the supported selection matrix. Windows and every other `GOOS/GOARCH` fail before downloads, builds, or service startup. Selection and compile checks do not constitute a native real-browser result. The complete native online/offline suite and automated artifact-format checks have been exercised on Linux amd64; Linux arm64 and both macOS rows remain pending and must not be described as empirically green.
diff --git a/core/auth/ui/e2e/archive_test.go b/core/auth/ui/e2e/archive_test.go
index c9c9c91..f41866e 100644
--- a/core/auth/ui/e2e/archive_test.go
+++ b/core/auth/ui/e2e/archive_test.go
@@ -82,13 +82,13 @@
}
func TestVersionOutputMatchesExactSemanticVersion(t *testing.T) {
- for _, output := range []string{"Version:\tv1.1.0\n", "Version: 1.1.0\n"} {
- if !versionOutputMatches([]byte(output), "v1.1.0") {
+ for _, output := range []string{"Version:\tv9.8.7\n", "Version: 9.8.7\n"} {
+ if !versionOutputMatches([]byte(output), "v9.8.7") {
t.Errorf("expected match for %q", output)
}
}
- for _, output := range []string{"Version: v11.1.0", "Version: v1.1.01", "commit-v1.1.0-extra"} {
- if versionOutputMatches([]byte(output), "v1.1.0") {
+ for _, output := range []string{"Version: v19.8.7", "Version: v9.8.70", "commit-v9.8.7-extra"} {
+ if versionOutputMatches([]byte(output), "v9.8.7") {
t.Errorf("unexpected match for %q", output)
}
}
diff --git a/core/auth/ui/e2e/artifacts.go b/core/auth/ui/e2e/artifacts.go
index fda096e..5b9a41b 100644
--- a/core/auth/ui/e2e/artifacts.go
+++ b/core/auth/ui/e2e/artifacts.go
@@ -18,8 +18,8 @@
const (
maxOryArchiveDownloadSize int64 = 512 << 20
- kratosVersion = "v1.1.0"
- hydraVersion = "v2.2.0"
+ kratosVersion = "v26.2.0"
+ hydraVersion = "v26.2.0"
playwrightVersion = "v0.6100.0"
playwrightCLIVersion = "1.61.1"
chromiumRevision = "1228"
@@ -41,13 +41,13 @@
}
// Hashes are from the official release checksum manifests:
-// https://github.com/ory/kratos/releases/download/v1.1.0/checksums.txt
-// https://github.com/ory/hydra/releases/download/v2.2.0/checksums.txt
+// https://github.com/ory/kratos/releases/download/v26.2.0/checksums.txt
+// https://github.com/ory/hydra/releases/download/v26.2.0/checksums.txt
var artifactPlatforms = map[string]platformArtifacts{
- "linux/amd64": platform("kratos_1.1.0-linux_sqlite_64bit.tar.gz", "6fb3077252dde7578c3100d2cd4eb52364ca6b3c1b0b76987e6d586e29008cbd", "hydra_2.2.0-linux_sqlite_64bit.tar.gz", "0fe0539fa452496ac5d98b558f93eb2dbb4cf43733da0b09f8f2bdb4445fc31e"),
- "linux/arm64": platform("kratos_1.1.0-linux_sqlite_arm64.tar.gz", "fde8a1a1aebd153baff88b1232e0c2a34fdaaafe90b5364f4ea580151e74898e", "hydra_2.2.0-linux_sqlite_arm64.tar.gz", "c499ffdaae0f2ab85eff0567214734515b741a393bef89115c16018f4dc0560d"),
- "darwin/amd64": platform("kratos_1.1.0-macOS_sqlite_64bit.tar.gz", "ebdc94f27cb6e6a3087ed756accfb7837465ac8e30af9433b4414101814f7769", "hydra_2.2.0-macOS_sqlite_64bit.tar.gz", "3d40ca8e99e2a6d840130928d5e0245212dba0eea9c26a0d7186ebb4382e673d"),
- "darwin/arm64": platform("kratos_1.1.0-macOS_sqlite_arm64.tar.gz", "6681d7b15dd04686d10764750ce3ad69672b3962553223399a3a315ba5370517", "hydra_2.2.0-macOS_sqlite_arm64.tar.gz", "89732ad1494c57ea39348f62dc5ef5c48de129cd205b17cb12bb67ad27094bb7"),
+ "linux/amd64": platform("kratos_26.2.0-linux_sqlite_64bit.tar.gz", "c80113f2c861b2fbd80290697d1380000111e297716018617423cca7f2e7e668", "hydra_26.2.0-linux_sqlite_64bit.tar.gz", "28baf98c6d5da617c905d5ca77826fe863db9f9edab8f72664c69a56bde56b5a"),
+ "linux/arm64": platform("kratos_26.2.0-linux_sqlite_arm64.tar.gz", "fd2cedebc4034ad1aef726f64665052c809fb05f86968e9c8a36372d7578e865", "hydra_26.2.0-linux_sqlite_arm64.tar.gz", "18e73ac632d2081b76fbceb03130803a63bdb9b8e2ecc3f06f4a6e6820cabe26"),
+ "darwin/amd64": platform("kratos_26.2.0-macOS_sqlite_64bit.tar.gz", "0ac76d0ad85fe452e711a2aafe56b49b0f5d1a57200f4464dcb48e7267c94062", "hydra_26.2.0-macOS_sqlite_64bit.tar.gz", "ede453fa15c82cfb23e61b138a0b4d9558127a26ebf51eead97d0c58a7eff422"),
+ "darwin/arm64": platform("kratos_26.2.0-macOS_sqlite_arm64.tar.gz", "e198d84bde6e4b7c68714cdad00c8800edd88c2311adde8b08ea5469cea263ec", "hydra_26.2.0-macOS_sqlite_arm64.tar.gz", "d45f26be758196e66e98dff06a9eaefcd21d719123f74f43a0f1fabcfb71da60"),
}
func platform(kratosArchive, kratosHash, hydraArchive, hydraHash string) platformArtifacts {
diff --git a/core/auth/ui/e2e/artifacts_test.go b/core/auth/ui/e2e/artifacts_test.go
index 89c8d77..088c963 100644
--- a/core/auth/ui/e2e/artifacts_test.go
+++ b/core/auth/ui/e2e/artifacts_test.go
@@ -43,22 +43,37 @@
func TestOfficialArtifactHashes(t *testing.T) {
want := map[string]string{
- "kratos_1.1.0-linux_sqlite_64bit.tar.gz": "6fb3077252dde7578c3100d2cd4eb52364ca6b3c1b0b76987e6d586e29008cbd",
- "kratos_1.1.0-linux_sqlite_arm64.tar.gz": "fde8a1a1aebd153baff88b1232e0c2a34fdaaafe90b5364f4ea580151e74898e",
- "kratos_1.1.0-macOS_sqlite_64bit.tar.gz": "ebdc94f27cb6e6a3087ed756accfb7837465ac8e30af9433b4414101814f7769",
- "kratos_1.1.0-macOS_sqlite_arm64.tar.gz": "6681d7b15dd04686d10764750ce3ad69672b3962553223399a3a315ba5370517",
- "hydra_2.2.0-linux_sqlite_64bit.tar.gz": "0fe0539fa452496ac5d98b558f93eb2dbb4cf43733da0b09f8f2bdb4445fc31e",
- "hydra_2.2.0-linux_sqlite_arm64.tar.gz": "c499ffdaae0f2ab85eff0567214734515b741a393bef89115c16018f4dc0560d",
- "hydra_2.2.0-macOS_sqlite_64bit.tar.gz": "3d40ca8e99e2a6d840130928d5e0245212dba0eea9c26a0d7186ebb4382e673d",
- "hydra_2.2.0-macOS_sqlite_arm64.tar.gz": "89732ad1494c57ea39348f62dc5ef5c48de129cd205b17cb12bb67ad27094bb7",
+ "kratos_26.2.0-linux_sqlite_64bit.tar.gz": "c80113f2c861b2fbd80290697d1380000111e297716018617423cca7f2e7e668",
+ "kratos_26.2.0-linux_sqlite_arm64.tar.gz": "fd2cedebc4034ad1aef726f64665052c809fb05f86968e9c8a36372d7578e865",
+ "kratos_26.2.0-macOS_sqlite_64bit.tar.gz": "0ac76d0ad85fe452e711a2aafe56b49b0f5d1a57200f4464dcb48e7267c94062",
+ "kratos_26.2.0-macOS_sqlite_arm64.tar.gz": "e198d84bde6e4b7c68714cdad00c8800edd88c2311adde8b08ea5469cea263ec",
+ "hydra_26.2.0-linux_sqlite_64bit.tar.gz": "28baf98c6d5da617c905d5ca77826fe863db9f9edab8f72664c69a56bde56b5a",
+ "hydra_26.2.0-linux_sqlite_arm64.tar.gz": "18e73ac632d2081b76fbceb03130803a63bdb9b8e2ecc3f06f4a6e6820cabe26",
+ "hydra_26.2.0-macOS_sqlite_64bit.tar.gz": "ede453fa15c82cfb23e61b138a0b4d9558127a26ebf51eead97d0c58a7eff422",
+ "hydra_26.2.0-macOS_sqlite_arm64.tar.gz": "d45f26be758196e66e98dff06a9eaefcd21d719123f74f43a0f1fabcfb71da60",
}
+ seen := make(map[string]bool, len(want))
for _, platform := range artifactPlatforms {
for _, artifact := range []releaseArtifact{platform.Kratos, platform.Hydra} {
if want[artifact.Archive] != artifact.SHA256 {
t.Errorf("hash for %s=%s", artifact.Archive, artifact.SHA256)
}
+ if artifact.Version != "v26.2.0" {
+ t.Errorf("version for %s=%s", artifact.Archive, artifact.Version)
+ }
+ wantURL := "https://github.com/ory/" + artifact.Service + "/releases/download/v26.2.0/" + artifact.Archive
+ if artifact.URL != wantURL {
+ t.Errorf("URL for %s=%s, want %s", artifact.Archive, artifact.URL, wantURL)
+ }
+ if seen[artifact.Archive] {
+ t.Errorf("duplicate artifact %s", artifact.Archive)
+ }
+ seen[artifact.Archive] = true
}
}
+ if len(seen) != len(want) {
+ t.Errorf("artifact count=%d, want %d", len(seen), len(want))
+ }
}
func TestEnsureArchiveDownloadAndCache(t *testing.T) {
diff --git a/core/auth/ui/e2e/browser_artifacts_test.go b/core/auth/ui/e2e/browser_artifacts_test.go
index 5825dcf..c51766b 100644
--- a/core/auth/ui/e2e/browser_artifacts_test.go
+++ b/core/auth/ui/e2e/browser_artifacts_test.go
@@ -6,7 +6,6 @@
"archive/zip"
"bytes"
"encoding/json"
- "fmt"
"os"
"path/filepath"
"strings"
@@ -36,7 +35,7 @@
t.Fatalf("health check %s: %v", sanitizeFinalURL(endpoint), err)
}
}
- if kratosVersion != "v1.1.0" || hydraVersion != "v2.2.0" || playwrightVersion != "v0.6100.0" {
+ if kratosVersion != "v26.2.0" || hydraVersion != "v26.2.0" || playwrightVersion != "v0.6100.0" {
t.Fatalf("unexpected pinned versions: %s %s %s", kratosVersion, hydraVersion, playwrightVersion)
}
if got := testBrowser.Browser.Version(); got != chromiumVersion {
@@ -55,7 +54,7 @@
t.Fatalf("%s reported a wildcard listener", service)
}
for _, port := range ports {
- if !strings.Contains(string(log), fmt.Sprintf("http server on 127.0.0.1:%d", port)) && !strings.Contains(string(log), fmt.Sprintf("httpd on: 127.0.0.1:%d", port)) {
+ if !listenerLogReportsLoopback(string(log), port) {
t.Fatalf("%s did not report loopback listener port %d", service, port)
}
}
diff --git a/core/auth/ui/e2e/browser_test.go b/core/auth/ui/e2e/browser_test.go
index 3a42eb3..9422096 100644
--- a/core/auth/ui/e2e/browser_test.go
+++ b/core/auth/ui/e2e/browser_test.go
@@ -10,6 +10,98 @@
"time"
)
+func listenerLogReportsLoopback(log string, port int) bool {
+ if strings.Contains(log, "0.0.0.0:") {
+ return false
+ }
+
+ address := fmt.Sprintf("127.0.0.1:%d", port)
+ for _, line := range strings.Split(log, "\n") {
+ if logLineContainsPhrase(line, "http server on "+address) || logLineContainsPhrase(line, "httpd on: "+address) {
+ return true
+ }
+
+ structuredStartup := logLineContainsFieldPhrase(line, `msg="Starting the public httpd"`) ||
+ logLineContainsFieldPhrase(line, `msg="Starting the admin httpd"`) ||
+ logLineContainsFieldPhrase(line, "msg=Starting the public httpd") ||
+ logLineContainsFieldPhrase(line, "msg=Starting the admin httpd")
+ if structuredStartup && logLineHasField(line, "addr", address) {
+ return true
+ }
+ }
+ return false
+}
+
+func logLineContainsPhrase(line, phrase string) bool {
+ for start := 0; start < len(line); {
+ index := strings.Index(line[start:], phrase)
+ if index < 0 {
+ return false
+ }
+ end := start + index + len(phrase)
+ if end == len(line) || line[end] == ' ' || line[end] == '\t' {
+ return true
+ }
+ start += index + 1
+ }
+ return false
+}
+
+func logLineContainsFieldPhrase(line, phrase string) bool {
+ for start := 0; start < len(line); {
+ index := strings.Index(line[start:], phrase)
+ if index < 0 {
+ return false
+ }
+ begin := start + index
+ end := begin + len(phrase)
+ beginBoundary := begin == 0 || line[begin-1] == ' ' || line[begin-1] == '\t'
+ endBoundary := end == len(line) || line[end] == ' ' || line[end] == '\t'
+ if beginBoundary && endBoundary {
+ return true
+ }
+ start = begin + 1
+ }
+ return false
+}
+
+func logLineHasField(line, name, value string) bool {
+ plain, quoted := name+"="+value, name+`="`+value+`"`
+ for _, field := range strings.Fields(line) {
+ if field == plain || field == quoted {
+ return true
+ }
+ }
+ return false
+}
+
+func TestListenerLogReportsLoopback(t *testing.T) {
+ tests := []struct {
+ name string
+ log string
+ want bool
+ }{
+ {name: "legacy Kratos", log: "level=info msg=Running http server on 127.0.0.1:4433", want: true},
+ {name: "legacy Hydra", log: "time=now httpd on: 127.0.0.1:4433", want: true},
+ {name: "structured public quoted", log: `level=info msg="Starting the public httpd" addr="127.0.0.1:4433"`, want: true},
+ {name: "structured admin unquoted", log: "level=info msg=Starting the admin httpd addr=127.0.0.1:4433", want: true},
+ {name: "wrong structured port", log: `level=info msg="Starting the public httpd" addr=127.0.0.1:4434`},
+ {name: "wrong legacy port", log: "level=info httpd on: 127.0.0.1:44330"},
+ {name: "wildcard", log: `level=info msg="Starting the public httpd" addr=0.0.0.0:4433`},
+ {name: "split structured evidence", log: "level=info msg=Starting the public httpd\nlevel=info addr=127.0.0.1:4433"},
+ {name: "unrelated event", log: "level=info msg=Starting metrics addr=127.0.0.1:4433"},
+ {name: "address in unrelated field", log: `level=info msg="Starting the public httpd" target=127.0.0.1:4433`},
+ {name: "message in unrelated field", log: `diagnosticmsg="Starting the public httpd" addr=127.0.0.1:4433`},
+ }
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ if got := listenerLogReportsLoopback(test.log, 4433); got != test.want {
+ t.Fatalf("listenerLogReportsLoopback()=%v, want %v for %q", got, test.want, test.log)
+ }
+ })
+ }
+}
+
func TestLoopbackRoutePolicy(t *testing.T) {
policy := newRoutePolicy([]string{"http://127.0.0.1:10001", "http://127.0.0.1:10002"})
for _, raw := range []string{"http://127.0.0.1:10001/login?flow=secret", "http://127.0.0.1:10002/static/main.css"} {
diff --git a/core/auth/ui/e2e/config_test.go b/core/auth/ui/e2e/config_test.go
index a1cf000..7e74723 100644
--- a/core/auth/ui/e2e/config_test.go
+++ b/core/auth/ui/e2e/config_test.go
@@ -45,7 +45,7 @@
}
}
kratos, _ := os.ReadFile(filepath.Join(first, "kratos.yml"))
- for _, required := range []string{"dsn: memory", "default_schema_id: user", "id: user", "password:\n enabled: true", "hook: session", "leak_sensitive_values: false", "smtp://e2e:e2e@127.0.0.1:11007", "http://127.0.0.1:11005/login", "file://"} {
+ for _, required := range []string{"version: v26.2.0", "dsn: memory", "default_schema_id: user", "id: user", "password:\n enabled: true", "hook: session", "leak_sensitive_values: false", "smtp://e2e:e2e@127.0.0.1:11007", "http://127.0.0.1:11005/login", "file://"} {
if !strings.Contains(string(kratos), required) {
t.Errorf("kratos config missing %q", required)
}
diff --git a/core/auth/ui/e2e/testdata/kratos.yml.tmpl b/core/auth/ui/e2e/testdata/kratos.yml.tmpl
index 820786a..d175b77 100644
--- a/core/auth/ui/e2e/testdata/kratos.yml.tmpl
+++ b/core/auth/ui/e2e/testdata/kratos.yml.tmpl
@@ -1,4 +1,4 @@
-version: v1.1.0
+version: v26.2.0
dsn: memory
serve: