105 lines
2.8 KiB
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()
|
|
}
|
|
}
|