diff --git a/internal/apply/hold_test.go b/internal/apply/hold_test.go index 73cc417e..4b0a8fde 100644 --- a/internal/apply/hold_test.go +++ b/internal/apply/hold_test.go @@ -283,7 +283,7 @@ func predecessor(t *testing.T) (dir, page string, m *machine) { }} } -func TestAFoundFileOfAnUntakenModuleIsKeptAsItIs(t *testing.T) { +func caseAFoundFileOfAnUntakenModuleIsKeptAsItIs(t *testing.T) { dir, page, m := predecessor(t) report, state := applyAdopted(t, adopted(t, untakenWeb, webResources(page)), store.State{}, m, dir) @@ -318,7 +318,7 @@ func TestAFoundFileOfAnUntakenModuleIsKeptAsItIs(t *testing.T) { } } -func TestAFoundContainerOfAnUntakenModuleIsNotReplaced(t *testing.T) { +func caseAFoundContainerOfAnUntakenModuleIsNotReplaced(t *testing.T) { dir, page, m := predecessor(t) report, state := applyAdopted(t, adopted(t, untakenWeb, webResources(page)), store.State{}, m, dir) @@ -338,7 +338,7 @@ func TestAFoundContainerOfAnUntakenModuleIsNotReplaced(t *testing.T) { } } -func TestWhatIsNotFoundIsCreatedWhenAssigned(t *testing.T) { +func caseWhatIsNotFoundIsCreatedWhenAssigned(t *testing.T) { // Assigning prepares: what the module declares that is not there is made. dir := t.TempDir() page := filepath.Join(dir, "index.html") @@ -355,7 +355,7 @@ func TestWhatIsNotFoundIsCreatedWhenAssigned(t *testing.T) { } } -func TestAFileThisHostWroteIsNotFound(t *testing.T) { +func caseAFileThisHostWroteIsNotFound(t *testing.T) { // Found means present with no record. A record of any origin — carried or declared, this life // of the node or an earlier one — means this host wrote it. for _, origin := range []string{store.OriginCarried, store.OriginDeclared} { @@ -372,7 +372,7 @@ func TestAFileThisHostWroteIsNotFound(t *testing.T) { } } -func TestAContainerAHostMadeIsNotFound(t *testing.T) { +func caseAContainerAHostMadeIsNotFound(t *testing.T) { dir, page, m := predecessor(t) m.containers["hello-web"].spec = "some-spec" report, _ := applyAdopted(t, adopted(t, untakenWeb, webResources(page)), store.State{}, m, dir) @@ -381,7 +381,7 @@ func TestAContainerAHostMadeIsNotFound(t *testing.T) { } } -func TestTheGenesisStoreAdoptedInPlaceIsNotFound(t *testing.T) { +func caseTheGenesisStoreAdoptedInPlaceIsNotFound(t *testing.T) { // ADR 0078: the foundation's store, raised from the bundle and recorded as carried, is adopted // as a module by name. It is the mesh's own and must never read as a predecessor's. dir := t.TempDir() @@ -398,7 +398,7 @@ func TestTheGenesisStoreAdoptedInPlaceIsNotFound(t *testing.T) { } } -func TestTakingAModuleReplacesWhatWasHeldAndTheOriginalSurvives(t *testing.T) { +func caseTakingAModuleReplacesWhatWasHeldAndTheOriginalSurvives(t *testing.T) { dir, page, m := predecessor(t) _, state := applyAdopted(t, adopted(t, untakenWeb, webResources(page)), store.State{}, m, dir) h, _ := state.HeldAt("hello-web.page") @@ -426,7 +426,7 @@ func TestTakingAModuleReplacesWhatWasHeldAndTheOriginalSurvives(t *testing.T) { } } -func TestAHeldFileIsNeverRemovedWhenItsModuleIsUnassigned(t *testing.T) { +func caseAHeldFileIsNeverRemovedWhenItsModuleIsUnassigned(t *testing.T) { dir, page, m := predecessor(t) _, state := applyAdopted(t, adopted(t, untakenWeb, webResources(page)), store.State{}, m, dir) @@ -447,7 +447,7 @@ func TestAHeldFileIsNeverRemovedWhenItsModuleIsUnassigned(t *testing.T) { } } -func TestAHoldNoLongerDeclaredIsLetGoAndFoundAgainIfItsModuleReturns(t *testing.T) { +func caseAHoldNoLongerDeclaredIsLetGoAndFoundAgainIfItsModuleReturns(t *testing.T) { dir, page, m := predecessor(t) _, state := applyAdopted(t, adopted(t, untakenWeb, webResources(page)), store.State{}, m, dir) first, _ := state.HeldAt("hello-web.page") @@ -482,7 +482,7 @@ func TestAHoldNoLongerDeclaredIsLetGoAndFoundAgainIfItsModuleReturns(t *testing. } } -func TestACarriedApplyLetsNoHoldGo(t *testing.T) { +func caseACarriedApplyLetsNoHoldGo(t *testing.T) { dir, page, m := predecessor(t) _, state := applyAdopted(t, adopted(t, untakenWeb, webResources(page)), store.State{}, m, dir) carried := parse(t, `{"declaration":1,"resources":[`+withConf(dir)+`]}`) @@ -496,7 +496,7 @@ func TestACarriedApplyLetsNoHoldGo(t *testing.T) { } } -func TestAHeldFileRewrittenIsReportedAndNotReverted(t *testing.T) { +func caseAHeldFileRewrittenIsReportedAndNotReverted(t *testing.T) { dir, page, m := predecessor(t) d := adopted(t, untakenWeb, webResources(page)) _, state := applyAdopted(t, d, store.State{}, m, dir) @@ -520,7 +520,7 @@ func TestAHeldFileRewrittenIsReportedAndNotReverted(t *testing.T) { } } -func TestAHeldContainerStoppedOrReplacedIsReportedAndNotRestarted(t *testing.T) { +func caseAHeldContainerStoppedOrReplacedIsReportedAndNotRestarted(t *testing.T) { for _, c := range []struct { change func(*machine) want string @@ -547,7 +547,7 @@ func TestAHeldContainerStoppedOrReplacedIsReportedAndNotRestarted(t *testing.T) } } -func TestAHeldFileThatVanishesIsNotCreated(t *testing.T) { +func caseAHeldFileThatVanishesIsNotCreated(t *testing.T) { dir, page, m := predecessor(t) d := adopted(t, untakenWeb, webResources(page)) _, state := applyAdopted(t, d, store.State{}, m, dir) @@ -563,7 +563,7 @@ func TestAHeldFileThatVanishesIsNotCreated(t *testing.T) { } } -func TestAConvergedNodeStillReplacesWhatItFinds(t *testing.T) { +func caseAConvergedNodeStillReplacesWhatItFinds(t *testing.T) { // No adoption, no holds: byte for byte what a converged node did before ADR 0100. dir, page, m := predecessor(t) d := parse(t, `{"declaration":1,"resources":[`+webResources(page)+`]}`) @@ -585,7 +585,7 @@ func TestAConvergedNodeStillReplacesWhatItFinds(t *testing.T) { } } -func TestAFileWrittenOverIsKeptOnceAndOnlyWhenTheHostHasNoRecordOfIt(t *testing.T) { +func caseAFileWrittenOverIsKeptOnceAndOnlyWhenTheHostHasNoRecordOfIt(t *testing.T) { dir := t.TempDir() conf := filepath.Join(dir, "nftables.conf") _ = os.WriteFile(conf, []byte("# the distribution's own\n"), 0o644) @@ -621,7 +621,7 @@ func untaken(ids ...string) string { return `{"taken":[],"untaken":{"hello-web":["` + strings.Join(ids, `","`) + `"]}}` } -func TestAFoundDirectoryOfAnUntakenModuleKeepsItsModeOwnerAndContents(t *testing.T) { +func caseAFoundDirectoryOfAnUntakenModuleKeepsItsModeOwnerAndContents(t *testing.T) { dir := t.TempDir() data := filepath.Join(dir, "data") if err := os.Mkdir(data, 0o700); err != nil { @@ -652,7 +652,7 @@ func TestAFoundDirectoryOfAnUntakenModuleKeepsItsModeOwnerAndContents(t *testing } } -func TestADirectoryMadeInTheSameApplyIsNotFound(t *testing.T) { +func caseADirectoryMadeInTheSameApplyIsNotFound(t *testing.T) { // A file's parent is made as the file is written; what the mesh made is not found. dir := t.TempDir() data := filepath.Join(dir, "data") @@ -671,7 +671,7 @@ func TestADirectoryMadeInTheSameApplyIsNotFound(t *testing.T) { } } -func TestAFoundServiceOfAnUntakenModuleIsNeitherStartedNorEnabledNorRestarted(t *testing.T) { +func caseAFoundServiceOfAnUntakenModuleIsNeitherStartedNorEnabledNorRestarted(t *testing.T) { dir := t.TempDir() conf := filepath.Join(dir, "hello.conf") m := &machine{containers: map[string]*fakeContainer{}, @@ -695,7 +695,7 @@ func TestAFoundServiceOfAnUntakenModuleIsNeitherStartedNorEnabledNorRestarted(t } } -func TestAHeldServiceIsStillReloadedButNeverRestarted(t *testing.T) { +func caseAHeldServiceIsStillReloadedButNeverRestarted(t *testing.T) { // A reload stops nothing (novox/hq ADR 0102); a restart would stop the predecessor's service. dir := t.TempDir() conf := filepath.Join(dir, "daemon.json") @@ -716,7 +716,7 @@ func TestAHeldServiceIsStillReloadedButNeverRestarted(t *testing.T) { } } -func TestAUnitAPackageOnlyShipsIsNotFound(t *testing.T) { +func caseAUnitAPackageOnlyShipsIsNotFound(t *testing.T) { // The adoption bed found this: the private network's wg-quick@mesh0 is an instance of a unit // the tunnel package ships. Nothing had ever run it, yet it was held as a predecessor's, and // the private network never came up. Found is what the machine runs. @@ -738,7 +738,7 @@ func TestAUnitAPackageOnlyShipsIsNotFound(t *testing.T) { } } -func TestAServiceWhoseUnitIsNotThereIsAppliedAsUsual(t *testing.T) { +func caseAServiceWhoseUnitIsNotThereIsAppliedAsUsual(t *testing.T) { // No unit before the apply: nothing of a predecessor's to hold. dir := t.TempDir() m := &machine{containers: map[string]*fakeContainer{}, units: map[string]*fakeUnit{}} @@ -750,7 +750,7 @@ func TestAServiceWhoseUnitIsNotThereIsAppliedAsUsual(t *testing.T) { } } -func TestAContainerThatWouldMountFoundDataIsNotCreated(t *testing.T) { +func caseAContainerThatWouldMountFoundDataIsNotCreated(t *testing.T) { dir := t.TempDir() data := filepath.Join(dir, "predecessor-data") if err := os.Mkdir(data, 0o700); err != nil { @@ -788,7 +788,7 @@ func TestAContainerThatWouldMountFoundDataIsNotCreated(t *testing.T) { } } -func TestAContainerMountingWhatTheMeshMadeIsCreated(t *testing.T) { +func caseAContainerMountingWhatTheMeshMadeIsCreated(t *testing.T) { dir := t.TempDir() data := filepath.Join(dir, "data") m := &machine{containers: map[string]*fakeContainer{}} @@ -801,7 +801,7 @@ func TestAContainerMountingWhatTheMeshMadeIsCreated(t *testing.T) { } } -func TestARunOnceStepInAHeldContainerIsHeld(t *testing.T) { +func caseARunOnceStepInAHeldContainerIsHeld(t *testing.T) { dir, page, m := predecessor(t) step := `{"id":"hello-web.migrate","type":"container","name":"hello-web-migrate","image":"` + pinned + `", "run-once":true,"network":"container:hello-web"}` @@ -818,7 +818,7 @@ func TestARunOnceStepInAHeldContainerIsHeld(t *testing.T) { } } -func TestAnActionInAHeldContainerIsHeldUntilItsModuleIsTaken(t *testing.T) { +func caseAnActionInAHeldContainerIsHeldUntilItsModuleIsTaken(t *testing.T) { // An action cannot arrive over the link today, and a bundle cannot say a node is adopted; the // host holds one anyway, since what it would run in is the predecessor's. dir, page, m := predecessor(t) @@ -850,7 +850,7 @@ func TestAnActionInAHeldContainerIsHeldUntilItsModuleIsTaken(t *testing.T) { const sixtyFourZeros = "0000000000000000000000000000000000000000000000000000000000000000" -func TestAnArchiveOverSomethingFoundIsNotUnpacked(t *testing.T) { +func caseAnArchiveOverSomethingFoundIsNotUnpacked(t *testing.T) { dir := t.TempDir() at := filepath.Join(dir, "site") if err := os.Mkdir(at, 0o750); err != nil { @@ -874,7 +874,7 @@ func TestAnArchiveOverSomethingFoundIsNotUnpacked(t *testing.T) { } } -func TestAProcessWhoseUnitIsFoundIsNotWrittenOverOrRestarted(t *testing.T) { +func caseAProcessWhoseUnitIsFoundIsNotWrittenOverOrRestarted(t *testing.T) { dir := t.TempDir() was := unitDir unitDir = dir @@ -899,7 +899,7 @@ func TestAProcessWhoseUnitIsFoundIsNotWrittenOverOrRestarted(t *testing.T) { } } -func TestAUserFoundOnTheMachineKeepsItsShellAndGroups(t *testing.T) { +func caseAUserFoundOnTheMachineKeepsItsShellAndGroups(t *testing.T) { dir := t.TempDir() m := &machine{containers: map[string]*fakeContainer{}, users: map[string]bool{"hello": true}} report, _ := applyAdopted(t, adopted(t, untaken("hello-web.user"), @@ -915,7 +915,7 @@ func TestAUserFoundOnTheMachineKeepsItsShellAndGroups(t *testing.T) { } } -func TestMountingTheMachinesOwnPlumbingIsNotFoundData(t *testing.T) { +func caseMountingTheMachinesOwnPlumbingIsNotFoundData(t *testing.T) { // The runtime's socket, the kernel's filesystems and the clock are on every machine; a // container mounting them shares nothing a predecessor kept (novox/hq ADR 0103). dir := t.TempDir() @@ -950,7 +950,7 @@ func (u *unreachable) run(_ context.Context, name string, args ...string) (strin return "", nil } -func TestARuntimeThatCannotAnswerNeverLetsTheMeshCreateOverAFoundContainer(t *testing.T) { +func caseARuntimeThatCannotAnswerNeverLetsTheMeshCreateOverAFoundContainer(t *testing.T) { dir := t.TempDir() u := &unreachable{} d := adopted(t, untaken("hello-web.server"), @@ -970,7 +970,7 @@ func TestARuntimeThatCannotAnswerNeverLetsTheMeshCreateOverAFoundContainer(t *te } } -func TestAHeldContainerStaysHeldWhenTheRuntimeCannotAnswer(t *testing.T) { +func caseAHeldContainerStaysHeldWhenTheRuntimeCannotAnswer(t *testing.T) { dir, page, m := predecessor(t) d := adopted(t, untaken("hello-web.page", "hello-web.server"), webResources(page)) _, state := applyAdopted(t, d, store.State{}, m, dir) @@ -988,7 +988,7 @@ func TestAHeldContainerStaysHeldWhenTheRuntimeCannotAnswer(t *testing.T) { } } -func TestAVolumeTheRuntimeCannotBeAskedAboutStopsTheContainer(t *testing.T) { +func caseAVolumeTheRuntimeCannotBeAskedAboutStopsTheContainer(t *testing.T) { dir := t.TempDir() run := func(_ context.Context, name string, args ...string) (string, error) { args = oldShape(name, args) @@ -1014,7 +1014,7 @@ func TestAVolumeTheRuntimeCannotBeAskedAboutStopsTheContainer(t *testing.T) { } } -func TestAUnitSomebodyInstalledIsHeldWhateverStateItIsIn(t *testing.T) { +func caseAUnitSomebodyInstalledIsHeldWhateverStateItIsIn(t *testing.T) { // A predecessor's unit under /etc, deliberately stopped and disabled: starting it would put // back a service somebody took down on purpose (novox/hq ADR 0103). dir := t.TempDir() @@ -1035,7 +1035,7 @@ func TestAUnitSomebodyInstalledIsHeldWhateverStateItIsIn(t *testing.T) { } } -func TestAPackagedUnitTheMachineUsesIsStillHeld(t *testing.T) { +func caseAPackagedUnitTheMachineUsesIsStillHeld(t *testing.T) { // The predecessor's own service from a package, running: not the mesh's to restart. dir := t.TempDir() conf := filepath.Join(dir, "hello.conf") @@ -1054,7 +1054,7 @@ func TestAPackagedUnitTheMachineUsesIsStillHeld(t *testing.T) { } } -func TestASecondOriginalAtTheSamePathIsKeptToo(t *testing.T) { +func caseASecondOriginalAtTheSamePathIsKeptToo(t *testing.T) { // Held, let go when the module was unassigned, rewritten by the predecessor, found again: // both originals are kept, and the report names the one it kept (novox/hq ADR 0100). dir := t.TempDir() @@ -1083,7 +1083,7 @@ func TestASecondOriginalAtTheSamePathIsKeptToo(t *testing.T) { } } -func TestAHoldLetGoAndFoundAgainKeepsBothOriginals(t *testing.T) { +func caseAHoldLetGoAndFoundAgainKeepsBothOriginals(t *testing.T) { dir, page, m := predecessor(t) _, state := applyAdopted(t, adopted(t, untaken("hello-web.page", "hello-web.server"), webResources(page)), store.State{}, m, dir) @@ -1111,7 +1111,7 @@ func TestAHoldLetGoAndFoundAgainKeepsBothOriginals(t *testing.T) { } } -func TestAPathTheMeshOnlySetAccessOnIsStillFound(t *testing.T) { +func caseAPathTheMeshOnlySetAccessOnIsStillFound(t *testing.T) { // An access record says the mesh set permissions on a path it does not own — which is what it // does to somebody else's directory. It is not a record of making it (novox/hq ADR 0103). dir := t.TempDir() @@ -1144,3 +1144,51 @@ func asideShape(args []string) []string { } return args } + +// TestHold runs the cases of this file as subtests of one test (the test budget: one test, a table of cases). +func TestHold(t *testing.T) { + for _, c := range []struct { + name string + run func(*testing.T) + }{ + {"AFoundFileOfAnUntakenModuleIsKeptAsItIs", caseAFoundFileOfAnUntakenModuleIsKeptAsItIs}, + {"AFoundContainerOfAnUntakenModuleIsNotReplaced", caseAFoundContainerOfAnUntakenModuleIsNotReplaced}, + {"WhatIsNotFoundIsCreatedWhenAssigned", caseWhatIsNotFoundIsCreatedWhenAssigned}, + {"AFileThisHostWroteIsNotFound", caseAFileThisHostWroteIsNotFound}, + {"AContainerAHostMadeIsNotFound", caseAContainerAHostMadeIsNotFound}, + {"TheGenesisStoreAdoptedInPlaceIsNotFound", caseTheGenesisStoreAdoptedInPlaceIsNotFound}, + {"TakingAModuleReplacesWhatWasHeldAndTheOriginalSurvives", caseTakingAModuleReplacesWhatWasHeldAndTheOriginalSurvives}, + {"AHeldFileIsNeverRemovedWhenItsModuleIsUnassigned", caseAHeldFileIsNeverRemovedWhenItsModuleIsUnassigned}, + {"AHoldNoLongerDeclaredIsLetGoAndFoundAgainIfItsModuleReturns", caseAHoldNoLongerDeclaredIsLetGoAndFoundAgainIfItsModuleReturns}, + {"ACarriedApplyLetsNoHoldGo", caseACarriedApplyLetsNoHoldGo}, + {"AHeldFileRewrittenIsReportedAndNotReverted", caseAHeldFileRewrittenIsReportedAndNotReverted}, + {"AHeldContainerStoppedOrReplacedIsReportedAndNotRestarted", caseAHeldContainerStoppedOrReplacedIsReportedAndNotRestarted}, + {"AHeldFileThatVanishesIsNotCreated", caseAHeldFileThatVanishesIsNotCreated}, + {"AConvergedNodeStillReplacesWhatItFinds", caseAConvergedNodeStillReplacesWhatItFinds}, + {"AFileWrittenOverIsKeptOnceAndOnlyWhenTheHostHasNoRecordOfIt", caseAFileWrittenOverIsKeptOnceAndOnlyWhenTheHostHasNoRecordOfIt}, + {"AFoundDirectoryOfAnUntakenModuleKeepsItsModeOwnerAndContents", caseAFoundDirectoryOfAnUntakenModuleKeepsItsModeOwnerAndContents}, + {"ADirectoryMadeInTheSameApplyIsNotFound", caseADirectoryMadeInTheSameApplyIsNotFound}, + {"AFoundServiceOfAnUntakenModuleIsNeitherStartedNorEnabledNorRestarted", caseAFoundServiceOfAnUntakenModuleIsNeitherStartedNorEnabledNorRestarted}, + {"AHeldServiceIsStillReloadedButNeverRestarted", caseAHeldServiceIsStillReloadedButNeverRestarted}, + {"AUnitAPackageOnlyShipsIsNotFound", caseAUnitAPackageOnlyShipsIsNotFound}, + {"AServiceWhoseUnitIsNotThereIsAppliedAsUsual", caseAServiceWhoseUnitIsNotThereIsAppliedAsUsual}, + {"AContainerThatWouldMountFoundDataIsNotCreated", caseAContainerThatWouldMountFoundDataIsNotCreated}, + {"AContainerMountingWhatTheMeshMadeIsCreated", caseAContainerMountingWhatTheMeshMadeIsCreated}, + {"ARunOnceStepInAHeldContainerIsHeld", caseARunOnceStepInAHeldContainerIsHeld}, + {"AnActionInAHeldContainerIsHeldUntilItsModuleIsTaken", caseAnActionInAHeldContainerIsHeldUntilItsModuleIsTaken}, + {"AnArchiveOverSomethingFoundIsNotUnpacked", caseAnArchiveOverSomethingFoundIsNotUnpacked}, + {"AProcessWhoseUnitIsFoundIsNotWrittenOverOrRestarted", caseAProcessWhoseUnitIsFoundIsNotWrittenOverOrRestarted}, + {"AUserFoundOnTheMachineKeepsItsShellAndGroups", caseAUserFoundOnTheMachineKeepsItsShellAndGroups}, + {"MountingTheMachinesOwnPlumbingIsNotFoundData", caseMountingTheMachinesOwnPlumbingIsNotFoundData}, + {"ARuntimeThatCannotAnswerNeverLetsTheMeshCreateOverAFoundContainer", caseARuntimeThatCannotAnswerNeverLetsTheMeshCreateOverAFoundContainer}, + {"AHeldContainerStaysHeldWhenTheRuntimeCannotAnswer", caseAHeldContainerStaysHeldWhenTheRuntimeCannotAnswer}, + {"AVolumeTheRuntimeCannotBeAskedAboutStopsTheContainer", caseAVolumeTheRuntimeCannotBeAskedAboutStopsTheContainer}, + {"AUnitSomebodyInstalledIsHeldWhateverStateItIsIn", caseAUnitSomebodyInstalledIsHeldWhateverStateItIsIn}, + {"APackagedUnitTheMachineUsesIsStillHeld", caseAPackagedUnitTheMachineUsesIsStillHeld}, + {"ASecondOriginalAtTheSamePathIsKeptToo", caseASecondOriginalAtTheSamePathIsKeptToo}, + {"AHoldLetGoAndFoundAgainKeepsBothOriginals", caseAHoldLetGoAndFoundAgainKeepsBothOriginals}, + {"APathTheMeshOnlySetAccessOnIsStillFound", caseAPathTheMeshOnlySetAccessOnIsStillFound}, + } { + t.Run(c.name, c.run) + } +}