carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package hostops
2
3import (
4 "context"
5 "errors"
6 "testing"
7
8 "github.com/carlosframework/platform/internal/release"
9)
10
11func TestAppMutationRunnerOwnsTheWholeCall(t *testing.T) {
12 for _, kind := range []string{"joined", "validation", "ambiguous-bucket", "ambiguous-backend", "foreign", "nested"} {
13 t.Run(kind, func(t *testing.T) {
14 ctx := t.Context()
15 w, raw, _ := testWriter(t)
16 seedAdmission(t, raw, "bab", "demo", openAdmission("app"))
17 check, err := NewProductionMutationCheck(raw, w)
18 if err != nil {
19 t.Fatal(err)
20 }
21 data, err := NewMutationBoundary(true, raw, check)
22 if err != nil {
23 t.Fatal(err)
24 }
25 owner := RegistrationOwner{Console: "console", Enrollment: "enrollment", Controller: "controller"}
26 if err = BindMutationRunner(data, w, owner, func(context.Context, string, string) (string, error) { return "app", nil }); err != nil {
27 t.Fatal(err)
28 }
29 if kind == "foreign" {
30 _, err = w.BeginExclusive(ctx, "bab", "demo", "app", AppOperation{ID: "foreign", Kind: OpAppMutation, AppID: "app"}, owner)
31 if err != nil {
32 t.Fatal(err)
33 }
34 }
35 before, _ := ReadAdmission(ctx, raw, "bab", "demo", "app")
36 called := false
37 failure := errors.New("joined callback failure")
38 var saved context.Context
39 err = release.WithAppMutation(ctx, data, "bab", "demo", "test", func(pctx context.Context) error {
40 called = true
41 saved = pctx
42 if err := RequireAppMutation(pctx, raw, "bab", "demo", "app"); err != nil {
43 return err
44 }
45 switch kind {
46 case "validation":
47 return failure
48 case "ambiguous-backend":
49 MarkAppMutationIssued(pctx)
50 return failure
51 case "nested":
52 a, _ := ReadAdmission(pctx, raw, "bab", "demo", "app")
53 return release.WithAppMutation(pctx, data, "bab", "demo", "nested", func(inner context.Context) error {
54 b, _ := ReadAdmission(inner, raw, "bab", "demo", "app")
55 if a.Value.Op.ID != b.Value.Op.ID {
56 t.Fatal("nested call acquired another operation")
57 }
58 _, err := data.Put(inner, "apps/bab/demo/test.json", []byte(`{}`), "")
59 return err
60 })
61 }
62 _, err := data.Put(pctx, "apps/bab/demo/test.json", []byte(`{}`), "")
63 if err != nil {
64 return err
65 }
66 if kind == "ambiguous-bucket" {
67 return failure
68 }
69 return nil
70 })
71 after, _ := ReadAdmission(ctx, raw, "bab", "demo", "app")
72 switch kind {
73 case "foreign":
74 if called || !errors.Is(err, ErrPending) || before.ETag != after.ETag {
75 t.Fatalf("crossed foreign op: called=%v err=%v", called, err)
76 }
77 case "validation":
78 if !errors.Is(err, failure) || after.Value.State != "open" || after.Value.Op != nil {
79 t.Fatalf("unissued failure retained authority: %v %+v", err, after.Value)
80 }
81 case "ambiguous-bucket", "ambiguous-backend":
82 if !errors.Is(err, failure) || after.Value.State != "closed" || after.Value.Op == nil {
83 t.Fatalf("ambiguous effect lost authority: %v %+v", err, after.Value)
84 }
85 default:
86 if err != nil || after.Value.State != "open" || after.Value.Op != nil {
87 t.Fatalf("joined call did not finish: %v %+v", err, after.Value)
88 }
89 }
90 if saved != nil && RequireAppMutation(saved, raw, "bab", "demo", "app") == nil {
91 t.Fatal("callback permit survived settlement")
92 }
93 })
94 }
95}
96
97func TestRunAppMutationRequiresLocalIncarnation(t *testing.T) {
98 for _, local := range []string{"", "old", "app"} {
99 t.Run("local="+local, func(t *testing.T) {
100 w, raw, _ := testWriter(t)
101 seedAdmission(t, raw, "bab", "demo", openAdmission("app"))
102 check, err := NewProductionMutationCheck(raw, w)
103 if err != nil {
104 t.Fatal(err)
105 }
106 data, err := NewMutationBoundary(true, raw, check)
107 if err != nil {
108 t.Fatal(err)
109 }
110 owner := RegistrationOwner{Console: "console", Enrollment: "enrollment", Controller: "controller"}
111 if err = BindMutationRunner(data, w, owner, func(context.Context, string, string) (string, error) { return local, nil }); err != nil {
112 t.Fatal(err)
113 }
114 before, err := ReadAdmission(t.Context(), raw, "bab", "demo", "app")
115 if err != nil {
116 t.Fatal(err)
117 }
118 called := false
119 err = release.WithAppMutation(t.Context(), data, "bab", "demo", "test", func(context.Context) error { called = true; return nil })
120 after, e := ReadAdmission(t.Context(), raw, "bab", "demo", "app")
121 if e != nil {
122 t.Fatal(e)
123 }
124 if local == "app" {
125 if err != nil || !called {
126 t.Fatalf("matching identity refused: %v", err)
127 }
128 } else if err == nil || called || before.ETag != after.ETag {
129 t.Fatalf("local identity %q acquired authority: called=%v err=%v", local, called, err)
130 }
131 })
132 }
133}
134