package console import ( "bytes" "context" "log/slog" "strings" "testing" "time" "github.com/carlosframework/platform/internal/hostactors" "github.com/carlosframework/platform/internal/hostfloor" "github.com/carlosframework/platform/internal/release" ) type plan9CollisionStore struct { release.Store cancel context.CancelFunc reads int } func (s *plan9CollisionStore) Get(ctx context.Context, key string) ([]byte, string, error) { if strings.HasPrefix(key, "status/consoles/") { s.reads++ if s.reads == 3 { s.cancel() } return plan9Report("foreign:2", time.Now()), "etag", nil } return s.Store.Get(ctx, key) } func TestPlan9Fix1RepeatedReportCollisionLogsOnceAtInfo(t *testing.T) { s, d, _ := activationFixture(t) observed, err := d.Read(t.Context()) if err != nil { t.Fatal(err) } observed.Roster.Consoles["console-2"] = hostactors.Console{Enrollment: strings.Repeat("c", 32), InstanceID: "console-2", Namespaces: []string{"platform"}, DeploymentBucket: d.Bucket} raw, err := release.SignRootEnvelope(release.RootSigner(s.cfg.Key), observed.Roster) if err != nil { t.Fatal(err) } if _, err := d.Store.Put(t.Context(), hostactors.Key, raw, observed.ETag); err != nil { t.Fatal(err) } s.cfg.HostConsoleID, s.cfg.ReleasePub = "console-2", d.PublicKey prior := hostRunningImage hostRunningImage = func() (hostfloor.Running, error) { return hostfloor.Running{BootID: "boot"}, nil } t.Cleanup(func() { hostRunningImage = prior }) ctx, cancel := context.WithTimeout(t.Context(), time.Second) defer cancel() spy := &plan9CollisionStore{Store: d.Store, cancel: cancel} s.cfg.Releases = spy var logs bytes.Buffer previousLog := slog.Default() slog.SetDefault(slog.New(slog.NewTextHandler(&logs, nil))) t.Cleanup(func() { slog.SetDefault(previousLog) }) ticks := make(chan time.Time, 2) ticks <- time.Now() ticks <- time.Now() s.runHostReports(ctx, ticks) if spy.reads != 3 { t.Fatalf("report ticks=%d, want 3", spy.reads) } if strings.Count(logs.String(), "collision=") != 1 || !strings.Contains(logs.String(), "level=INFO") { t.Fatalf("collision log: %s", logs.String()) } }