(t *testing.T)
| 287 | } |
| 288 | |
| 289 | func TestUnixSocketClientAgentTaskMethods(t *testing.T) { |
| 290 | t.Parallel() |
| 291 | |
| 292 | credentials := agentidentity.Credentials{ |
| 293 | SessionID: "sess-1", |
| 294 | AgentName: "coder", |
| 295 | WorkspaceID: "ws-1", |
| 296 | } |
| 297 | var sawClaim bool |
| 298 | var sawNoWork bool |
| 299 | var sawHeartbeat bool |
| 300 | var sawComplete bool |
| 301 | var sawFail bool |
| 302 | var sawRelease bool |
| 303 | |
| 304 | client := &unixSocketClient{ |
| 305 | socketPath: "/tmp/agh.sock", |
| 306 | httpClient: &http.Client{ |
| 307 | Transport: roundTripperFunc(func(req *http.Request) (*http.Response, error) { |
| 308 | assertAgentRequestHeaders(t, req, credentials) |
| 309 | switch { |
| 310 | case req.Method == http.MethodPost && req.URL.Path == "/api/agent/tasks/claim-next": |
| 311 | var payload contract.AgentTaskClaimNextRequest |
| 312 | if err := json.NewDecoder(req.Body).Decode(&payload); err != nil { |
| 313 | t.Fatalf("json.Decode(claim-next body) error = %v", err) |
| 314 | } |
| 315 | if payload.WorkspaceID == "empty" { |
| 316 | sawNoWork = true |
| 317 | return newHTTPResponse(http.StatusNoContent, ""), nil |
| 318 | } |
| 319 | sawClaim = true |
| 320 | if payload.WorkspaceID != "ws-1" || |
| 321 | payload.PriorityMin != 2 || |
| 322 | payload.LeaseSeconds != 120 || |
| 323 | !payload.Wait || |
| 324 | len(payload.RequiredCapabilities) != 1 || |
| 325 | payload.RequiredCapabilities[0] != "go" { |
| 326 | t.Fatalf("claim-next body = %#v, want parsed request", payload) |
| 327 | } |
| 328 | return newHTTPResponse( |
| 329 | http.StatusOK, |
| 330 | `{"claim":{"task":{"id":"task-1","title":"Run task","status":"in_progress","scope":"workspace","workspace_id":"ws-1"},"run":{"id":"run-1","task_id":"task-1","status":"claimed","attempt":1,"session_id":"sess-1","queued_at":"2026-04-03T12:00:00Z"},"lease":{"task_id":"task-1","run_id":"run-1","status":"claimed","session_id":"sess-1","coordination_channel_id":"builders","claim_token_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"},"coordination_channel":{"id":"builders","channel":"builders","display_name":"Builders","allowed_message_kinds":["status"]}}}`, |
| 331 | ), nil |
| 332 | case req.Method == http.MethodPost && req.URL.Path == "/api/agent/tasks/run-1/heartbeat": |
| 333 | sawHeartbeat = true |
| 334 | var payload contract.AgentTaskHeartbeatRequest |
| 335 | if err := json.NewDecoder(req.Body).Decode(&payload); err != nil { |
| 336 | t.Fatalf("json.Decode(heartbeat body) error = %v", err) |
| 337 | } |
| 338 | if payload.LeaseSeconds != 60 { |
| 339 | t.Fatalf("heartbeat body = %#v, want lease duration only", payload) |
| 340 | } |
| 341 | return agentTaskLeaseHTTPResponse(taskpkg.TaskRunStatusClaimed), nil |
| 342 | case req.Method == http.MethodPost && req.URL.Path == "/api/agent/tasks/run-1/complete": |
| 343 | sawComplete = true |
| 344 | var payload contract.AgentTaskCompleteRequest |
| 345 | if err := json.NewDecoder(req.Body).Decode(&payload); err != nil { |
| 346 | t.Fatalf("json.Decode(complete body) error = %v", err) |
nothing calls this directly
no test coverage detected