package main import ( "bytes" "context" "errors" "os" "testing" "github.com/carlosframework/platform/internal/release" ) type fix4MigrationReadTrap struct{ release.Store } func (fix4MigrationReadTrap) Get(context.Context, string) ([]byte, string, error) { return nil, "", errors.New("main did not read records during preflight") } func TestPlan9Fix4FlagOffMigrationMatchesMain(t *testing.T) { t.Setenv("CARLOS_HOST_CLAIM", "") for _, family := range []string{"instances", "sidecars"} { for _, body := range []string{`{"record_seq":0}`, "{\"record_seq\":9, \"unknown\": true}\n", `{"record_seq":1,"record_seq":2}`, `{"Record_Seq":1}`, `{"record_seq":null}`, `{"record_seq":18446744073709551615}`} { t.Run(family+"/"+body, func(t *testing.T) { store := release.NewDirStore(t.TempDir()) source := "apps/bab/app/" + family + "/source.json" dest := "apps/cac/app/" + family + "/source.json" if _, err := store.Put(t.Context(), source, []byte(body), ""); err != nil { t.Fatal(err) } if err := validateMigrationRecords(t.Context(), fix4MigrationReadTrap{store}, []copyOp{{from: source, to: dest}}); err != nil { t.Fatalf("flag-off preflight differs from main: %v", err) } if _, err := putMigrationObject(t.Context(), store, dest, []byte(body)); err != nil { t.Fatalf("main's create-only copy refused: %v", err) } raw, _, err := store.Get(t.Context(), dest) if err != nil || !bytes.Equal(raw, []byte(body)) { t.Fatalf("copy changed bytes: %q %v", raw, err) } if _, err := putMigrationObject(t.Context(), store, dest, []byte(`{"different":true}`)); !errors.Is(err, release.ErrCASConflict) { t.Fatalf("copy overwrote existing destination: %v", err) } if _, _, err := store.Get(t.Context(), source); errors.Is(err, os.ErrNotExist) { t.Fatal("copy removed source") } }) } } }