Files
orbit/cmd/orbit-admin/release_test.go

105 lines
2.8 KiB
Go

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()
}
}