Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions tests/remote-runners-doors.test.mts
Original file line number Diff line number Diff line change
Expand Up @@ -483,12 +483,16 @@ test('an upload refused in the middle of its body is answered, marked: never a r
send(c)
const { m, lease } = await runningLease(c)
/** A PUT whose body is megabytes of `chunk()`, sent as it is read: still on its way when home finds what is wrong with it. */
let pulled = 0
const streamed = (headers: Record<string, string>, chunk: () => Uint8Array, chunks: number) => {
let sent = 0
const body = new ReadableStream<Uint8Array>({
pull(controller) {
if (sent++ >= chunks) controller.close()
else controller.enqueue(chunk())
else {
pulled++
controller.enqueue(chunk())
}
},
})
return fetch(`${m.home}/api/runners/v1/attempts/${lease.attemptId}/files/submission.csv`, {
Expand Down Expand Up @@ -526,9 +530,13 @@ test('an upload refused in the middle of its body is answered, marked: never a r
const { cancelRemote } = await import('../server/src/competitions/remote/release.js')
assert.equal(cancelRemote(queueRow(lease.submissionId)!, 'teacher'), true)
const started = Date.now()
pulled = 0
const late = await streamed({ 'content-encoding': 'gzip', 'x-colloq-sha256': 'c'.repeat(64), 'x-colloq-bytes': '100' }, noise, 1024)
assert.equal(late.status, 409)
assert.ok(Date.now() - started < 1_500, `answered before the sixty-four megabytes were sent (${Date.now() - started} ms)`)
// Counted in chunks, not milliseconds, which a loaded runner stretches: a body home does not read stops at what the
// sockets' buffers hold, a few megabytes, while one it drained would have been sent whole before the answer.
assert.ok(pulled < 512, `answered before the sixty-four megabytes were sent (${pulled} of 1024 chunks, ${Date.now() - started} ms)`)
assert.ok(Date.now() - started < 10_000, `answered at once, not after a timeout (${Date.now() - started} ms)`)
assert.equal(parseRemoteErrorReply(await late.json()).error, 'revoked')
})

Expand Down
4 changes: 4 additions & 0 deletions tests/runner-agent-lifecycle.test.mts
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,8 @@ test('a drain lets a held hidden-test run finish: what it reads stays until it h
return { json: syncReply({ seq: lease.seq, leases, trusted: true, want: { revisions: [{ id: REVISION.id, ref: REVISION.ref, layers: LAYERS, gpu: false }], data, bundles: [] } }), delayMs: leases.length > 0 ? 0 : 20 }
}
const { agent, seam, docker } = agentFor(home)
// The run waits for the read of its /data below: one that ended at once could have its tree removed under the read.
seam.next = 'wait'
// The lease's image is checked once more right before its run (images.ts · verify), before it links the hidden test: held there, where a drain can come.
let verifying = 0
let release!: () => void
Expand All @@ -636,12 +638,14 @@ test('a drain lets a held hidden-test run finish: what it reads stays until it h
await waitFor(() => seam.runs.length === 1, 'the hidden-test run, after the drain')
assert.equal(seam.runs[0]!.sealedInputs, true)
assert.equal(fs.readFileSync(path.join(seam.runs[0]!.dataDir, 'test.csv'), 'utf8'), 'id\n9\n')
seam.release()
await waitFor(() => !fs.existsSync(path.join(layout.leasesDir, `${lease.attemptId}.json`)), 'the run settled')
assert.ok(!home.calls.some((call) => call.path.endsWith(`/attempts/${lease.attemptId}/outcome`) && (call.body as { kind: string }).kind === 'declined'), 'the drain declined a run it was to finish')
// Settled, it reads nothing more: a draining machine keeps none of the hidden test.
await waitFor(() => fs.readdirSync(path.join(competitionsDir, '.sealed')).length === 0, 'the hidden test gone once the run is done')
} finally {
release()
seam.release()
await agent.stop()
await running
await home.close()
Expand Down
Loading