package main import ( "bytes" "encoding/json" "os" "path/filepath" "testing" "git.yuntuo.hk/k2safe/orbit/internal/buildinfo" "git.yuntuo.hk/k2safe/orbit/internal/storage/mysql" ) func TestReleaseManifestIsDatabaseIndependent(t *testing.T) { output, restore := captureStdout(t) err := runRelease([]string{"manifest"}) restore() if err != nil { t.Fatal(err) } var got releaseManifest if err := json.Unmarshal(output.Bytes(), &got); err != nil { t.Fatal(err) } migrations, err := mysql.Migrations() if err != nil || len(migrations) == 0 { t.Fatalf("migrations: %v", err) } if got.ManifestVersion != 1 { t.Fatalf("manifest version=%d", got.ManifestVersion) } if got.Build != buildinfo.Current() { t.Fatalf("build identity=%+v want=%+v", got.Build, buildinfo.Current()) } if got.Schema.CurrentVersion != migrations[len(migrations)-1].Version || got.Schema.MigrationCount != len(migrations) { t.Fatalf("schema summary=%+v migrations=%d", got.Schema, len(migrations)) } if len(got.Schema.Migrations) != len(migrations) { t.Fatalf("manifest migrations=%d want=%d", len(got.Schema.Migrations), len(migrations)) } for i, migration := range migrations { item := got.Schema.Migrations[i] if item.Version != migration.Version || item.Name != migration.Name || item.Checksum != migration.Checksum { t.Fatalf("migration[%d]=%+v want version=%d name=%s checksum=%s", i, item, migration.Version, migration.Name, migration.Checksum) } } } func TestReleaseManifestRejectsUnknownCommand(t *testing.T) { if err := runRelease([]string{"status"}); err == nil { t.Fatal("unknown release command accepted") } } func TestReleaseManifestValidationBindsBinaryIdentity(t *testing.T) { manifest, err := currentReleaseManifest() if err != nil { t.Fatal(err) } path := filepath.Join(t.TempDir(), "release-manifest.json") encoded, err := json.Marshal(manifest) if err != nil { t.Fatal(err) } if err := os.WriteFile(path, encoded, 0600); err != nil { t.Fatal(err) } if err := validateReleaseManifest(path); err != nil { t.Fatalf("matching manifest rejected: %v", err) } manifest.Build.Revision = "different-release" encoded, err = json.Marshal(manifest) if err != nil { t.Fatal(err) } if err := os.WriteFile(path, encoded, 0600); err != nil { t.Fatal(err) } if err := validateReleaseManifest(path); err == nil { t.Fatal("manifest with different revision accepted") } } func captureStdout(t *testing.T) (*bytes.Buffer, func()) { t.Helper() old := os.Stdout read, write, err := os.Pipe() if err != nil { t.Fatal(err) } os.Stdout = write var output bytes.Buffer done := make(chan struct{}) go func() { _, _ = output.ReadFrom(read) close(done) }() return &output, func() { _ = write.Close() os.Stdout = old <-done _ = read.Close() } }