diff --git a/cmd/mesh-controller/adopting_test.go b/cmd/mesh-controller/adopting_test.go index 7d2009e8..d10914d1 100644 --- a/cmd/mesh-controller/adopting_test.go +++ b/cmd/mesh-controller/adopting_test.go @@ -248,6 +248,7 @@ func TestConvergingPreviewsThenChangesAndAdoptingKeepsWhatWasTaken(t *testing.T) if _, err := take(ctx, open, "anchor", "hello-web", takeOptions{Yes: true}); err != nil { t.Fatal(err) } + *sent = nil // the take composed the node; what follows is judged from here reportsHolding(t, open, heldFile) preview, err := converge(ctx, open, "anchor", false, "", "") @@ -436,6 +437,7 @@ func TestTheFlipActsOnlyOnThePreviewTheOperatorSaw(t *testing.T) { if _, err := take(ctx, open, "anchor", "hello-web", takeOptions{Yes: true}); err != nil { t.Fatal(err) } + *sent = nil // the take composed the node; what follows is judged from here reportsHolding(t, open, heldFile) preview, err := converge(ctx, open, "anchor", false, "", "") if err != nil { @@ -501,6 +503,7 @@ func TestThePreviewNamesEveryHeldKind(t *testing.T) { if _, err := take(ctx, open, "anchor", "hello-web", takeOptions{Yes: true}); err != nil { t.Fatal(err) } + *sent = nil // the take composed the node; what follows is judged from here since := time.Now() held := []link.Held{heldFile, {ID: "notes.data", Module: "notes", Kind: "directory", Target: "/var/lib/notes", Since: since}, @@ -544,6 +547,7 @@ func TestTheFlipIsRefusedOnAnAccountNamingNothingReachable(t *testing.T) { if _, err := take(ctx, open, "anchor", "hello-web", takeOptions{Yes: true}); err != nil { t.Fatal(err) } + *sent = nil // the take composed the node; what follows is judged from here // Only a loopback listener: nothing off the machine, which is the same silence. reportsReaching(t, open, []link.Reach{ {Protocol: "tcp", Address: "127.0.0.1", Port: 15672, By: "mesh-broker"}, @@ -627,3 +631,31 @@ func TestTheFlipIsRefusedWithTheBusUnreachableSayingItCannotTell(t *testing.T) { t.Fatal("a refused flip sent something") } } + +// **A take composes the node only when it is performed** (issue 1945): a preview, a take that names no digest and a take refused +// for a changed preview compose nothing; the performed take composes the machine once, and says so. +func TestATakeComposesTheNodeOnlyWhenItIsPerformed(t *testing.T) { + open, sent := anAdoptedAnchor(t) + ctx := t.Context() + reportsHolding(t, open, heldContainer, heldFile) + preview, err := take(ctx, open, "anchor", "hello-web", takeOptions{}) + if err != nil { + t.Fatal(err) + } + if _, err := take(ctx, open, "anchor", "hello-web", takeOptions{Yes: true}); err == nil { + t.Fatal("a take of a held module without the preview's digest was performed") + } + if _, err := take(ctx, open, "anchor", "hello-web", takeOptions{Yes: true, Digest: "not-the-digest"}); err == nil { + t.Fatal("a take naming another preview's digest was performed") + } + if len(*sent) != 0 { + t.Fatalf("a preview or a refused take composed %v", *sent) + } + said, err := take(ctx, open, "anchor", "hello-web", takeOptions{Yes: true, Digest: takeDigestIn(t, preview)}) + if err != nil { + t.Fatal(err) + } + if len(*sent) != 1 || (*sent)[0] != "anchor" || !strings.Contains(said, "compositions of anchor are written") { + t.Fatalf("the performed take composed %v and said:\n%s", *sent, said) + } +}