package host import ( "context" "errors" "github.com/carlosframework/platform/internal/rootparticipation" "go/ast" "go/parser" "go/token" "os" "sync" "testing" "github.com/carlosframework/platform/internal/rootstate" ) type plan14ReleaseStore struct { rootstate.Store mu sync.Mutex held bool fail error } func (s *plan14ReleaseStore) Lock(ctx context.Context, name string) (func(), error) { if name != "release.lock" { return nil, os.ErrPermission } if s.fail != nil { return nil, s.fail } s.mu.Lock() s.held = true return func() { s.held = false; s.mu.Unlock() }, nil } func (s *plan14ReleaseStore) Close() error { return nil } func TestPlan14AdoptReleaseLock(t *testing.T) { s := &plan14ReleaseStore{} called := 0 open := func() (rootstate.Store, error) { called++; return s, nil } effects := 0 run := func() error { if !s.held { t.Fatal("effect outside release lock") } effects++ return nil } if err := withRootReleaseStore(context.Background(), open, run); err != nil { t.Fatal(err) } if effects != 1 || called != 1 { t.Fatal(effects, called) } s.fail = os.ErrPermission if err := withRootReleaseStore(context.Background(), open, run); !errors.Is(err, os.ErrPermission) || effects != 1 { t.Fatal("lock failure admitted effects", err, effects) } if err := withRootReleaseStore(context.Background(), open, run); !errors.Is(err, os.ErrPermission) || effects != 1 { t.Fatal("flag-off lock failure admitted effects", err, effects) } s.fail = nil if err := withRootReleaseStore(context.Background(), open, run); err != nil || effects != 2 || called != 4 { t.Fatal(err, effects) } } func TestPlan14AdoptBodyIsUnderRelease(t *testing.T) { f, err := parser.ParseFile(token.NewFileSet(), "agent.go", nil, 0) if err != nil { t.Fatal(err) } var wrapper *ast.FuncDecl for _, d := range f.Decls { if fn, ok := d.(*ast.FuncDecl); ok && fn.Name.Name == "runAdoptWithEnsureSystemUnits" { wrapper = fn } } if wrapper == nil { t.Fatal("missing adoption entrypoint") } calls, protected := 0, 0 ast.Inspect(wrapper, func(n ast.Node) bool { call, ok := n.(*ast.CallExpr) if !ok { return true } id, ok := call.Fun.(*ast.Ident) if !ok { return true } if id.Name == "runAdoptUnderRootRelease" { calls++ } if id.Name == "withClaimRootRelease" && len(call.Args) == 5 { fn, ok := call.Args[3].(*ast.FuncLit) if !ok { t.Fatal("release effect is not the adoption callback") } ast.Inspect(fn.Body, func(n ast.Node) bool { if c, ok := n.(*ast.CallExpr); ok { if id, ok := c.Fun.(*ast.Ident); ok && id.Name == "runAdoptUnderRootRelease" { protected++ } } return true }) } return true }) if calls != 1 || protected != 1 { t.Fatalf("adoption calls=%d; under release=%d", calls, protected) } } func TestPlan14AdoptNoCensusDoesNotOpenRelease(t *testing.T) { effects := 0 for range 2 { err := withClaimReleaseCensus(t.Context(), func() (rootparticipation.Ledger, bool, error) { return rootparticipation.Ledger{}, false, nil }, func() (rootstate.Store, error) { t.Fatal("opened release without census") return nil, os.ErrPermission }, func() error { effects++; return nil }) if err != nil { t.Fatal(err) } } if effects != 2 { t.Fatal(effects) } } func TestPlan14ActivationNoCensusDoesNotExclude(t *testing.T) { err := claimActivationReady(t.Context(), func() (rootparticipation.Ledger, bool, error) { return rootparticipation.Ledger{ExcludeLaunches: func(context.Context, func(context.Context) error) error { t.Fatal("excluded without census") return nil }}, false, nil }) if !errors.Is(err, rootparticipation.ErrUnavailable) { t.Fatal(err) } } func noCensusAdoptSource(open func() (rootstate.Store, error)) adoptRootSource { return adoptRootSource{OpenRelease: open, Census: func() (rootparticipation.Ledger, bool, error) { return rootparticipation.Ledger{}, false, nil }} } func TestPlan14AdoptRetainedCensusBothFlags(t *testing.T) { for _, flag := range []bool{false, true} { store := &plan14ReleaseStore{} called := false err := withClaimRootRelease(t.Context(), flag, func() (rootstate.Store, error) { return store, nil }, func() error { called = true if !store.held { t.Fatal("retained census effect outside release") } return nil }, func() (rootparticipation.Ledger, bool, error) { return rootparticipation.Ledger{}, true, nil }) if err != nil || !called { t.Fatal(err, called) } } }