slice 10B: signed-op job completion (DELETE clear-job) (hub v0.10.0)
Add DELETE /hosts/{id}/jobs/{job_id} (per-host self-scoped, idempotent) so the
agent clears a job after executing or terminally rejecting it. The hub stores
the operator-signed blobs opaquely (no signing key — cannot forge or open);
the agent verifies + executes. Doc 03 §4/§6/§9 updated (operator-signed path
live; 8C wipe completes; 10B done).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -244,6 +244,33 @@ func TestGetJobs_SelfScopedAndServesBlobs(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// DELETE /hosts/{id}/jobs/{job_id} clears a processed job (slice 10B), self-scoped + idempotent.
|
||||
func TestDeleteJob_SelfScopedAndIdempotent(t *testing.T) {
|
||||
h, st, _ := newTestHandler(t)
|
||||
seedHost(t, st, "h1", "c1", "HKEY1")
|
||||
seedHost(t, st, "h2", "c2", "HKEY2")
|
||||
st.EnqueueSignedJob("h1", "jobA", []byte("blob"))
|
||||
|
||||
// h2 cannot clear h1's job (self-scope).
|
||||
if rr := do(h, http.MethodDelete, "/hosts/h1/jobs/jobA", "HKEY2", ""); rr.Code != http.StatusForbidden {
|
||||
t.Errorf("h2 clearing h1's job = %d, want 403", rr.Code)
|
||||
}
|
||||
if n, _ := st.CountSignedJobs("h1"); n != 1 {
|
||||
t.Errorf("job was removed by an unauthorized delete (depth=%d)", n)
|
||||
}
|
||||
// h1 clears its own job → 200, queue empties.
|
||||
if rr := do(h, http.MethodDelete, "/hosts/h1/jobs/jobA", "HKEY1", ""); rr.Code != http.StatusOK {
|
||||
t.Fatalf("h1 clearing own job = %d, want 200", rr.Code)
|
||||
}
|
||||
if n, _ := st.CountSignedJobs("h1"); n != 0 {
|
||||
t.Errorf("queue depth after delete = %d, want 0", n)
|
||||
}
|
||||
// Idempotent: deleting an absent job is a clean 200.
|
||||
if rr := do(h, http.MethodDelete, "/hosts/h1/jobs/jobA", "HKEY1", ""); rr.Code != http.StatusOK {
|
||||
t.Errorf("idempotent delete = %d, want 200", rr.Code)
|
||||
}
|
||||
}
|
||||
|
||||
// The admin enqueue-job endpoint (global key only) seeds the queue, reflected in has_signed_ops.
|
||||
func TestAdminEnqueueJob_GlobalKeyOnly(t *testing.T) {
|
||||
h, st, _ := newTestHandler(t)
|
||||
|
||||
Reference in New Issue
Block a user