package agent_test import ( "os" "path/filepath" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/coder/coder/v2/agent" "github.com/coder/coder/v2/agent/agentcontextconfig" "github.com/coder/coder/v2/agent/agenttest" agentproto "github.com/coder/coder/v2/agent/proto" "github.com/coder/coder/v2/codersdk/agentsdk" "github.com/coder/coder/v2/testutil" ) // TestAgent_ContextStatePushed verifies the agent's // agentcontext.Manager pushes its initial Snapshot to coderd // over the v2.10 PushContextState RPC during a normal boot. func TestAgent_ContextStatePushed(t *testing.T) { t.Parallel() dir := t.TempDir() require.NoError(t, os.WriteFile(filepath.Join(dir, "AGENTS.md"), []byte("test rules"), 0o600)) //nolint:dogsled // setupAgent returns a wide tuple; we only care about the client. _, client, _, _, _ := setupAgent(t, agentsdk.Manifest{Directory: dir}, 0, func(_ *agenttest.Client, opts *agent.Options) { opts.ContextConfig = agentcontextconfig.Config{} }, ) // The first push is the initial empty-workspace snapshot // because the manifest has not been fetched yet. Wait for a // later push that includes the seeded AGENTS.md. var pushes []*agentproto.PushContextStateRequest require.Eventually(t, func() bool { pushes = client.ContextStatePushes() for _, push := range pushes { for _, r := range push.GetResources() { if r.GetInstructionFile() != nil && filepath.Base(r.GetSource()) == "AGENTS.md" { return true } } } return false }, testutil.WaitMedium, testutil.IntervalFast, "expected the seeded AGENTS.md to appear in a snapshot push; got %d pushes", len(pushes)) require.NotEmpty(t, pushes) first := pushes[0] assert.True(t, first.GetInitial(), "first push must carry Initial=true") assert.Equal(t, uint64(1), first.GetSchemaVersion(), "schema_version must be the v1 wire shape") assert.NotEmpty(t, first.GetAggregateHash(), "aggregate_hash must be populated") // Subsequent pushes must not be Initial. for _, p := range pushes[1:] { assert.False(t, p.GetInitial(), "only the first push must be Initial") } }