package host import ( "context" "errors" "github.com/carlosframework/platform/internal/hostguard" "github.com/carlosframework/platform/internal/stopevidence" "testing" ) type plan11CompositeKernel struct{ writers, noProcess int } func (*plan11CompositeKernel) VerifyStopped(context.Context, hostguard.FenceTarget, StopInventory, DrainAcknowledgement) (StopKernelEvidence, error) { return StopKernelEvidence{}, nil } func (k *plan11CompositeKernel) VerifyWritersStopped(context.Context, hostguard.FenceTarget, StopInventory, StopPeer, []stopevidence.DescriptorHint) (WritersKernelEvidence, error) { k.writers++ return WritersKernelEvidence{}, nil } func (k *plan11CompositeKernel) VerifyNoProcess(context.Context, hostguard.FenceTarget, StopInventory) (StopKernelEvidence, error) { k.noProcess++ return StopKernelEvidence{}, nil } func TestPlan11IsolatedWrapperPreservesRootObservations(t *testing.T) { f := newLaunchFixture(t, servingOp()) if _, err := f.root.Serve(t.Context(), f.peer, f.req); err != nil { t.Fatal(err) } if err := f.journal.CloseWriters(t.Context(), f.target); err != nil { t.Fatal(err) } inner := &plan11CompositeKernel{} k := claimUnitStopKernel{Inner: inner, Journal: f.journal, Units: f.units} writers, ok := any(k).(stopWritersKernel) if !ok { t.Fatal("isolated wrapper hides writers-stopped observation") } zero, ok := any(k).(stopNoProcessKernel) if !ok { t.Fatal("isolated wrapper hides session-zero observation") } f.units.goneErr = errors.New("unit is active") if _, err := writers.VerifyWritersStopped(t.Context(), f.target, StopInventory{}, f.peer, nil); err == nil || inner.writers != 0 { t.Fatal("active isolated writer passed observation") } target := f.target target.Session = 0 if _, err := zero.VerifyNoProcess(t.Context(), target, StopInventory{}); err == nil || inner.noProcess != 0 { t.Fatal("active isolated unit passed session-zero observation") } f.units.goneErr = nil if _, err := writers.VerifyWritersStopped(t.Context(), f.target, StopInventory{}, f.peer, nil); err != nil || inner.writers != 1 { t.Fatalf("writers forwarding: %v %d", err, inner.writers) } if _, err := zero.VerifyNoProcess(t.Context(), target, StopInventory{}); err != nil || inner.noProcess != 1 { t.Fatalf("session-zero forwarding: %v %d", err, inner.noProcess) } } func TestPlan11WritersWitnessDoesNotShareCachedSlices(t *testing.T) { f := newWritersFixture(t) first, err := f.attempt.StopWriters(t.Context()) if err != nil { t.Fatal(err) } expected := first.DBPaths[0] first.DBPaths[0] = "forged.db" next, err := f.attempt.StopWriters(t.Context()) if err != nil { t.Fatal(err) } if next.DBPaths[0] != expected { t.Fatal("caller changed the cached session witness") } }