@@ -181,3 +181,130 @@ test-bounded cmd='pnpm test':
181181
182182test-risky-probe * tests :
183183 ./ .agent/ scripts/ run-risky-test-probe.sh " $@"
184+
185+ # Build the exact-workspace image used by every load-test lane. Dockerfile-local
186+ # ignore rules keep generated artifacts and unrelated website sources out of the
187+ # build context.
188+ load-test-image :
189+ docker build --file packages/ load-tests/ Dockerfile --tag agentos-load-tests:local .
190+
191+ # Container-boundary self-test: prove the cgroup envelope, fd ulimit, tmpfs, and
192+ # network isolation match the flags before trusting any survival verdict. Uses
193+ # the exact bounded profile of the limit lane.
194+ load-test-boundary :
195+ #!/usr/bin/env bash
196+ set -euo pipefail
197+ mkdir -p .artifacts/load-tests
198+ container=" agentos-load-boundary-$$ "
199+ trap ' docker rm -f "$container" >/dev/null 2>&1 || true' EXIT INT TERM
200+ timeout --signal=TERM --kill-after=30s 2m docker run --rm \
201+ --name " $container " \
202+ --memory=3g --memory-swap=3g --cpus=2 --pids-limit=256 \
203+ --ulimit nofile=1024:1024 --network=none \
204+ --user " $( id -u) :$( id -g) " \
205+ --security-opt no-new-privileges --cap-drop=ALL \
206+ --tmpfs /tmp:rw,nosuid,nodev,size=512m,mode=1777 \
207+ --volume " $PWD /.artifacts/load-tests:/artifacts" \
208+ agentos-load-tests:local boundary
209+
210+ # Guest process-limit attack beside a sentinel VM. The workload never runs on
211+ # the host; the container has hard memory/CPU/PID/fd/swap/time ceilings.
212+ load-test-limits :
213+ #!/usr/bin/env bash
214+ set -euo pipefail
215+ mkdir -p .artifacts/load-tests
216+ container=" agentos-load-limits-$$ "
217+ trap ' docker rm -f "$container" >/dev/null 2>&1 || true' EXIT INT TERM
218+ timeout --signal=TERM --kill-after=30s 8m docker run --rm \
219+ --name " $container " \
220+ --memory=3g --memory-swap=3g --cpus=2 --pids-limit=256 \
221+ --ulimit nofile=1024:1024 --network=none \
222+ --user " $( id -u) :$( id -g) " \
223+ --security-opt no-new-privileges --cap-drop=ALL \
224+ --tmpfs /tmp:rw,nosuid,nodev,size=512m,mode=1777 \
225+ --volume " $PWD /.artifacts/load-tests:/artifacts" \
226+ --env LOAD_TEST_PROCESS_LIMIT --env LOAD_TEST_PROCESS_ATTEMPTS \
227+ agentos-load-tests:local limits
228+
229+ # High-scale adversarial battery: bounded-but-LARGER cgroup (8 CPU / 8 GiB) so
230+ # the V8 executor pool (= CPU count) is big enough to actually run hundreds of
231+ # concurrent VMs. Still a hard-capped container. Runs the `scale` command.
232+ # Args after the recipe name are passed as the command (default `scale`).
233+ load-test-scale cmd = ' scale':
234+ #!/usr/bin/env bash
235+ set -euo pipefail
236+ mkdir -p .artifacts/load-tests
237+ container=" agentos-load-scale-$$ "
238+ trap ' docker rm -f "$container" >/dev/null 2>&1 || true' EXIT INT TERM
239+ timeout --signal=TERM --kill-after=30s 25m docker run --rm \
240+ --name " $container " \
241+ --user " $( id -u) :$( id -g) " \
242+ --memory=8g --memory-swap=8g --cpus=8 --pids-limit=2048 \
243+ --ulimit nofile=8192:8192 --network=none \
244+ --security-opt no-new-privileges --cap-drop=ALL \
245+ --tmpfs /tmp:rw,nosuid,nodev,size=2g,mode=1777 \
246+ --volume " $PWD /.artifacts/load-tests:/artifacts" \
247+ --env LOAD_TEST_VM_COUNT --env LOAD_TEST_CONCURRENCY --env LOAD_TEST_CYCLES \
248+ --env LOAD_TEST_EXEC_CONCURRENCY --env LOAD_TEST_MATRIX_ONLY \
249+ agentos-load-tests:local " {{ cmd }}"
250+
251+ # Full deterministic adversarial limit matrix (processes, fds, sockets,
252+ # filesystem bytes) beside a sentinel, same bounded cgroup as the limit lane.
253+ load-test-limits-matrix :
254+ #!/usr/bin/env bash
255+ set -euo pipefail
256+ mkdir -p .artifacts/load-tests
257+ container=" agentos-load-matrix-$$ "
258+ trap ' docker rm -f "$container" >/dev/null 2>&1 || true' EXIT INT TERM
259+ timeout --signal=TERM --kill-after=30s 10m docker run --rm \
260+ --name " $container " \
261+ --user " $( id -u) :$( id -g) " \
262+ --memory=3g --memory-swap=3g --cpus=2 --pids-limit=256 \
263+ --ulimit nofile=1024:1024 --network=none \
264+ --security-opt no-new-privileges --cap-drop=ALL \
265+ --tmpfs /tmp:rw,nosuid,nodev,size=512m,mode=1777 \
266+ --volume " $PWD /.artifacts/load-tests:/artifacts" \
267+ agentos-load-tests:local limits-matrix
268+
269+ # Sequential, burst, and steady-replacement VM churn with leak gates. This is
270+ # intentionally more generous than the limit lane but remains a bounded cgroup.
271+ load-test-churn :
272+ #!/usr/bin/env bash
273+ set -euo pipefail
274+ mkdir -p .artifacts/load-tests
275+ container=" agentos-load-churn-$$ "
276+ trap ' docker rm -f "$container" >/dev/null 2>&1 || true' EXIT INT TERM
277+ timeout --signal=TERM --kill-after=30s 20m docker run --rm \
278+ --name " $container " \
279+ --memory=4g --memory-swap=4g --cpus=3 --pids-limit=384 \
280+ --ulimit nofile=2048:2048 --network=none \
281+ --user " $( id -u) :$( id -g) " \
282+ --security-opt no-new-privileges --cap-drop=ALL \
283+ --tmpfs /tmp:rw,nosuid,nodev,size=1g,mode=1777 \
284+ --volume " $PWD /.artifacts/load-tests:/artifacts" \
285+ --env LOAD_TEST_CYCLES --env LOAD_TEST_BATCH --env LOAD_TEST_SETTLE_MS \
286+ --env LOAD_TEST_RSS_SLOPE_BYTES --env LOAD_TEST_RSS_TOTAL_BYTES \
287+ --env LOAD_TEST_PSS_TOTAL_BYTES \
288+ agentos-load-tests:local churn
289+
290+ # The external Compute load generator is also containerized. Unlike the local
291+ # lanes it needs egress to the Rivet APIs, but retains hard resource ceilings.
292+ load-test-compute :
293+ #!/usr/bin/env bash
294+ set -euo pipefail
295+ mkdir -p .artifacts/load-tests
296+ container=" agentos-load-compute-$$ "
297+ trap ' docker rm -f "$container" >/dev/null 2>&1 || true' EXIT INT TERM
298+ timeout --signal=TERM --kill-after=30s 20m docker run --rm \
299+ --name " $container " \
300+ --memory=1g --memory-swap=1g --cpus=1 --pids-limit=128 \
301+ --ulimit nofile=1024:1024 \
302+ --user " $( id -u) :$( id -g) " \
303+ --security-opt no-new-privileges --cap-drop=ALL \
304+ --tmpfs /tmp:rw,nosuid,nodev,size=128m,mode=1777 \
305+ --volume " $PWD /.artifacts/load-tests:/artifacts" \
306+ --env RIVET_ENDPOINT --env RIVET_PUBLIC_ENDPOINT --env RIVET_RUN_URL \
307+ --env COMPUTE_STEPS --env COMPUTE_HOLD_MS --env COMPUTE_SCALE_DOWN_MS \
308+ --env COMPUTE_ACTOR_NAME --env COMPUTE_CREATE_CONCURRENCY \
309+ --env COMPUTE_READY_TIMEOUT_MS --env COMPUTE_CLEANUP_DEADLINE_MS \
310+ agentos-load-tests:local compute-load
0 commit comments