Files
sandbox-runtime/.github/workflows/integration-tests.yml
Dylan Conway 703741b618 test(integration): use async spawn so the in-process proxy can respond; bump bun to 1.3.13 (#243)
* test(integration): use async spawn so the in-process proxy can respond

The integration tests run sandboxed curl commands against the HTTP/SOCKS
proxy that lives in the same process. Driving them with spawnSync blocks
this event loop for the duration of the wrapped command, so the proxy
request handler cannot run — curl is waiting on a server whose JS thread
is parked inside the very spawnSync that is waiting for curl. The suite
only passed because some bun versions happen to let the loop tick during
spawnSync; on linux/x86-64 that has been intermittent (the recent CI
flakes), and on newer bun it stops entirely.

Replace spawnSync with a small async spawnAsync helper that mirrors the
{stdout, stderr, status, signal} return shape. The event loop stays
alive, the proxy responds, and reset() between describes no longer hits
its 5s fallback.

Also bump CI bun to 1.3.13.

* test: move spawnAsync to shared helper, close stdin, convert remaining proxy tests

- Extract spawnAsync into test/helpers/spawn.ts so configurable-proxy-ports
  and update-config tests can share it (both drive curl through an
  in-process proxy and hit the same deadlock on bun >=1.3.2).
- Close child stdin so the child sees EOF immediately, matching spawnSync
  with no `input`. Without this, `su` in the privilege-escalation test
  waits on the open pipe.
- Convert the remaining proxy-hitting spawnSync call sites in those two
  files.
2026-05-05 13:14:19 -07:00

139 lines
4.0 KiB
YAML

name: Tests
on:
push:
branches: ['main']
pull_request:
branches: ['**']
jobs:
integration-tests:
name: Tests (${{ matrix.os }} / ${{ matrix.arch }})
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- arch: x86-64
runner: ubuntu-latest
os: linux
- arch: arm64
runner: ubuntu-24.04-arm
os: linux
- arch: x86-64
runner: macos-15-large
os: macos
- arch: arm64
runner: macos-14
os: macos
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: 1.3.13
- name: Install system dependencies (Linux)
if: matrix.os == 'linux'
run: |
sudo apt-get update
sudo apt-get install -y bubblewrap libseccomp-dev gcc socat ripgrep apparmor-profiles zsh
- name: Enable unprivileged user namespaces (Linux)
if: matrix.os == 'linux'
run: |
# Ubuntu 24.04+ sets kernel.apparmor_restrict_unprivileged_userns=1 which
# allows unshare(CLONE_NEWUSER) but grants the new namespace zero
# capabilities. Disable it so bwrap and apply-seccomp can nest
# namespaces without needing setuid.
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 || true
sudo sysctl -w kernel.unprivileged_userns_clone=1 || true
# Verify bwrap can create namespaces
echo "Testing bwrap namespace creation..."
bwrap --ro-bind / / --unshare-net true && echo "✓ bwrap namespace creation works" || echo "✗ bwrap namespace creation still fails"
- name: Install system dependencies (macOS)
if: matrix.os == 'macos'
run: |
brew install ripgrep zsh
- name: Install Node dependencies
run: npm install
- name: Build seccomp binaries (Linux)
if: matrix.os == 'linux'
run: npm run build:seccomp
- name: Build project
run: npm run build
- name: Run tests
run: npm test
- name: Run Node.js fallback tests
run: node test/utils/which-node-test.mjs
- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: test-results-${{ matrix.os }}-${{ matrix.arch }}
path: |
test-results/
*.log
if-no-files-found: ignore
docker-tests:
name: Tests (docker / ${{ matrix.arch }})
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- arch: x86-64
runner: ubuntu-latest
- arch: arm64
runner: ubuntu-24.04-arm
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Enable unprivileged user namespaces on host
run: |
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 || true
sudo sysctl -w kernel.unprivileged_userns_clone=1 || true
- name: Run srt end-to-end in unprivileged container
run: |
docker run --rm \
--security-opt seccomp=unconfined \
--security-opt apparmor=unconfined \
-v "${{ github.workspace }}:/work" \
-w /work \
-e SRT_E2E_DOCKER=1 \
ubuntu:24.04 \
bash -euo pipefail -c '
apt-get update -qq
apt-get install -y -qq bubblewrap socat ripgrep python3 curl ca-certificates unzip gcc libseccomp-dev
curl -fsSL https://bun.sh/install | bash
export PATH="$HOME/.bun/bin:$PATH"
curl -fsSL https://deb.nodesource.com/setup_18.x | bash -
apt-get install -y -qq nodejs
npm ci
npm run build:seccomp
npm run build
bun test test/docker-weak-sandbox.test.ts
'