package park import ( "reflect" "strings" "testing" "github.com/carlosframework/platform/internal/hostclaim" ) func TestInstanceParkPreservesStaging(t *testing.T) { for _, legacy := range []bool{true, false} { name := "incarnation" if legacy { name = "legacy" } t.Run(name, func(t *testing.T) { f := newFixture(t) if legacy { f.ob.Park.Location = "instances/" + f.w.Host } obs, err := hostclaim.Read(t.Context(), f.e.Claims, f.w.Host) if err != nil { t.Fatal(err) } _, err = hostclaim.Update(t.Context(), f.e.Claims, obs, func(c *hostclaim.Claim) error { c.Holder.Location = f.ob.Park.Location c.Op = hostclaim.Op{Kind: hostclaim.KindLanding, ID: "move-1", Phase: "parking", Exec: "target"} c.Obligations = []hostclaim.Obligation{f.ob} return nil }) if err != nil { t.Fatal(err) } source := f.seed() for _, op := range []string{"move-1", f.ob.Park.Incarnation} { p := "moves/" + f.w.Host + "/" + op + "/" for _, key := range []string{"replica/0000/data", "seal.json"} { f.b.Put("data", p+key, []byte("old")) f.b.Put("data", p+key, []byte("sealed")) } f.b.BareDelete("data", p+"replica/0000/data") } child := "instances/" + f.w.Host + "/" + strings.Repeat("b", 64) + "/0000/data" childID := f.b.Put("data", child, []byte("other incarnation")) staging, err := f.b.ListVersions(t.Context(), "data", "moves/") if err != nil { t.Fatal(err) } f.b.FailOn = func(action, key string) error { if action == "list" && !strings.HasPrefix(key, "parked/") && key != f.ob.Park.Location+"/" { t.Errorf("instance park listed %q", key) return ErrUnsafe } return nil } if err := f.e.Run(t.Context(), f.w); err != nil { t.Fatal(err) } f.done(t) m, err := f.e.manifest(t.Context(), f.w, f.ob) if err != nil || m == nil || !reflect.DeepEqual(m.Delete, source) { t.Fatalf("manifest = %+v, error = %v", m, err) } f.b.FailOn = nil after, err := f.b.ListVersions(t.Context(), "data", "moves/") if err != nil || !reflect.DeepEqual(after, staging) { t.Fatalf("staging changed: %+v, error = %v", after, err) } if body, err := f.b.GetVersion(t.Context(), "data", child, childID); err != nil || string(body) != "other incarnation" { t.Fatalf("child incarnation changed: %q, error = %v", body, err) } }) } } func TestInstanceScopeExcludesMovesKeys(t *testing.T) { f := newFixture(t) for _, location := range []string{"instances/" + f.w.Host, f.ob.Park.Location} { for _, op := range []string{"move-1", f.ob.Park.Incarnation} { key := "moves/" + f.w.Host + "/" + op + "/replica/0000/data" if inScope, _ := scopeContains(f.w.Host, location, key); inScope { t.Errorf("%q includes %q", location, key) } } } }