Skip to content

Commit b6fc735

Browse files
committed
Add integration tests and configurable limits
1 parent 05112eb commit b6fc735

7 files changed

Lines changed: 584 additions & 173 deletions

File tree

.github/workflows/ci.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,17 @@ jobs:
1616
- name: Checkout
1717
uses: actions/checkout@v4
1818

19+
- name: Set up Zig
20+
uses: goto-bus-stop/setup-zig@v2
21+
with:
22+
version: 0.15.2
23+
24+
- name: Build binary
25+
run: zig build
26+
27+
- name: Run unit tests
28+
run: make test-unit
29+
1930
- name: Set up QEMU
2031
uses: docker/setup-qemu-action@v3
2132

AGENT.md renamed to AGENTS.md

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Code Execution HTTP Service
22

33
## Overview
4-
This service accepts source code and optional test/checker data over HTTP, executes the code in an isolated filesystem jail, and returns the execution result. It is designed to be fast, stateless, and container-friendly.
4+
This service accepts source code and optional test/checker data over HTTP, executes the code in a temporary workspace copy, and returns the execution result. It is designed to be fast, stateless, and container-friendly.
55

66
## HTTP API
77

@@ -25,16 +25,19 @@ Response JSON:
2525
### `GET /health`
2626
Returns HTTP 200 when the service is ready.
2727

28+
### `POST /shutdown`
29+
Sets a shutdown flag and returns HTTP 200 when `ALLOW_SHUTDOWN` is enabled.
30+
2831
## Execution Flow
29-
1. Validate request parameters.
30-
2. Create a temporary filesystem jail using an overlay of the current root.
32+
1. Validate request parameters (reject non-identity content-encoding and oversized bodies).
33+
2. Create a temporary directory under `/tmp` and copy the current workspace into it.
3134
3. Write input files into a language-specific working directory:
3235
- `solution_text` → language-specific filename (e.g. `solution.py`, `Solution.java`).
3336
- `checker_text` (if provided) → language-specific checker file.
3437
- `asserts` (if provided) → `asserts.json`.
35-
4. Execute `make test` inside the jail.
38+
4. Execute the test command resolved from `make -n test` via `sh -c` in the temp workspace.
3639
5. Enforce timeout; on expiration, terminate the process group.
37-
6. Capture `stdout` and `stderr` and return them with the exit code.
40+
6. Capture `stdout` and `stderr`; if either stream exceeds 1MB, return an error.
3841

3942
## Files and Layout Expectations
4043
The service runs `make test` in its working directory. That directory is expected to contain language-specific runner logic. The service writes files into a subdirectory:
@@ -63,11 +66,25 @@ Filename mapping and checker requirement:
6366
- `zig`: `solution.zig` + `checker.zig` (checker required)
6467
- `ts`: `solution.js` (no checker)
6568

69+
## Configuration
70+
Environment variables:
71+
- `PORT` (default `4040`): Listener port.
72+
- `ALLOW_SHUTDOWN` (default `false`): Enable the `/shutdown` endpoint when set to `1` or `true`.
73+
- `RUN_CONCURRENCY` (default `10`): Max concurrent `/run` handlers; requests return 429 when busy.
74+
- `RUN_INPUT_MAX` (default `1048576` bytes): Max request body size.
75+
- `RUN_OUTPUT_MAX` (default `1048576` bytes): Max bytes allowed per stream (0 disables the limit).
76+
- `DEBUG` (default `false`): Enable request header logging; empty value enables it too.
77+
78+
## Timeout Rules
79+
`timeout` accepts a string with units: `ms`, `s`, or `m` (defaults to `30s` when omitted).
80+
81+
## Payload Limits
82+
- Request body limit: `RUN_INPUT_MAX` (HTTP 413 on overflow).
83+
- Output limit: `RUN_OUTPUT_MAX` per stream (HTTP 413 when exceeded).
84+
6685
## Isolation and Safety
67-
- The execution occurs in a chrooted directory backed by an overlay filesystem.
68-
- On Linux, it creates new namespaces (filesystem, file descriptors, mount, network) before chrooting.
86+
- The execution occurs in a temporary directory under `/tmp` built by copying the current workspace.
6987
- The service runs commands in a separate process group for reliable termination.
7088

7189
## Runtime Notes
72-
- If the process is PID 1 (container init), it spawns a child and acts as a signal reaper to avoid zombie processes.
73-
- The service is stateless; each request creates a fresh jail and cleans it up after execution.
90+
- The service is stateless; each request creates a fresh temp workspace and cleans it up after execution.

Containerfile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ ARG ALPINE_VERSION=3.23
33
ARG ZIG_URL=
44
ARG PORT=4040
55
ARG RUN_CONCURRENCY=32
6+
ARG RUN_INPUT_MAX=1048576
67
ARG RUN_OUTPUT_MAX=1048576
78
ARG DEBUG=
89
ARG ALLOW_SHUTDOWN=
@@ -50,13 +51,15 @@ FROM alpine:${ALPINE_VERSION}
5051
WORKDIR /app
5152
ARG PORT
5253
ARG RUN_CONCURRENCY
54+
ARG RUN_INPUT_MAX
5355
ARG RUN_OUTPUT_MAX
5456
ARG DEBUG
5557
ARG ALLOW_SHUTDOWN
5658
RUN adduser -S -u 10001 app
5759
COPY --from=builder /build/zig-out/bin/runner-zig /app/codebattle_runner
5860
ENV PORT=$PORT \
5961
RUN_CONCURRENCY=$RUN_CONCURRENCY \
62+
RUN_INPUT_MAX=$RUN_INPUT_MAX \
6063
RUN_OUTPUT_MAX=$RUN_OUTPUT_MAX \
6164
DEBUG=$DEBUG \
6265
ALLOW_SHUTDOWN=$ALLOW_SHUTDOWN

Makefile

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ PLATFORMS ?= linux/amd64,linux/arm64
44
CONTAINER ?= docker
55
TEST_IMAGE ?= runner-zig-test
66

7-
.PHONY: build lint lint-fix test test-container test-integration test-integration-arm test-integration-linux container-build container-push curl-local-health curl-local-test start
7+
.PHONY: build lint lint-fix test test-unit test-integration container-build container-push curl-local-health curl-local-test start
88

99
## Build multi-arch image directly for GHCR
1010
build:
@@ -18,14 +18,13 @@ lint:
1818
lint-fix:
1919
zig fmt src
2020

21-
## Run checker (expects check/checker.zig to exist)
21+
## fake check
2222
test:
23-
zig run check/checker.zig
23+
ls -la
2424

2525
## Run integration tests inside the builder container
26-
test-container:
27-
$(CONTAINER) build --target builder -t $(TEST_IMAGE) .
28-
$(CONTAINER) run --rm $(TEST_IMAGE) zig build test
26+
test-unit:
27+
zig test src/test.zig
2928

3029
## Run integration tests against an already-built container (container + HTTP checks)
3130
test-integration:

src/integration_test.zig

Lines changed: 0 additions & 140 deletions
This file was deleted.

0 commit comments

Comments
 (0)