name: memory-limit run-name: "memory_limit enforcement check" on: workflow_dispatch: env: SUITE_FILE: mem.jdg EXAMPLE_DIR: example/mem-limit jobs: build_judge: name: Build judge runs-on: Linux-Runner timeout-minutes: 10 steps: - uses: actions/checkout@v4 - name: Set up Go uses: actions/setup-go@v5 with: go-version: '1.22' - name: Cross-compile judge shell: bash run: | mkdir -p dist CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o dist/judge-linux-amd64 ./cmd/cli CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -o dist/judge-windows-amd64.exe ./cmd/cli - name: Upload judge binaries uses: https://github.com/christopherHX/gitea-upload-artifact@v4 with: name: judge-bin-mem path: dist/ retention-days: 1 check: needs: build_judge name: "${{ matrix.toolchain.system }} / ${{ matrix.toolchain.use_compiler }}" strategy: fail-fast: false matrix: toolchain: - { system: Linux, use_compiler: gcc } - { system: Linux, use_compiler: clang } - { system: Windows, use_compiler: clang } - { system: Windows, use_compiler: msvc } runs-on: ${{ matrix.toolchain.system }}-Runner timeout-minutes: 10 env: CC: ${{ matrix.toolchain.use_compiler }} steps: - name: Checkout judge harness uses: actions/checkout@v4 - name: Set up MSVC environment if: matrix.toolchain.use_compiler == 'msvc' uses: ilammy/msvc-dev-cmd@v1 - name: Download judge binary uses: https://github.com/christopherHX/gitea-download-artifact@v4 with: name: judge-bin-mem path: judge-bin - name: Install judge on PATH shell: bash run: | mkdir -p bin if [ "${{ matrix.toolchain.system }}" = "Windows" ]; then cp judge-bin/judge-windows-amd64.exe bin/judge.exe else cp judge-bin/judge-linux-amd64 bin/judge chmod +x bin/judge fi echo "$PWD/bin" >> "$GITHUB_PATH" - name: Install jq (Linux) if: matrix.toolchain.system == 'Linux' run: sudo apt-get update && sudo apt-get install -y jq - name: Run judge and capture JSON shell: bash working-directory: ${{ env.EXAMPLE_DIR }} run: | # `|| true` — the "exceeds_limit" group is *expected* to have a # failing test, so judge will exit non-zero. judge "$SUITE_FILE" . --json > report.json || true cat report.json - name: Assert enforcement (Linux) if: matrix.toolchain.system == 'Linux' shell: bash working-directory: ${{ env.EXAMPLE_DIR }} run: | set -euo pipefail pass_status=$(jq -r '.groups[] | select(.name=="within_limit") | .tests[] | select(.name=="allocate_16mb") | .status' report.json) fail_status=$(jq -r '.groups[] | select(.name=="exceeds_limit") | .tests[] | select(.name=="allocate_256mb") | .status' report.json) pass_peak=$(jq -r '.groups[] | select(.name=="within_limit") | .tests[] | select(.name=="allocate_16mb") | .peak_memory_kb // 0' report.json) fail_peak=$(jq -r '.groups[] | select(.name=="exceeds_limit") | .tests[] | select(.name=="allocate_256mb") | .peak_memory_kb // 0' report.json) echo "within_limit/allocate_16mb: status=$pass_status peak=${pass_peak} KiB" echo "exceeds_limit/allocate_256mb: status=$fail_status peak=${fail_peak} KiB" rc=0 if [ "$pass_status" != "PASS" ]; then echo "FAIL: within_limit test should PASS, got $pass_status" rc=1 fi if [ "$fail_status" != "MLE" ]; then echo "FAIL: exceeds_limit test should be MLE, got $fail_status" rc=1 fi if [ "${pass_peak:-0}" -le 0 ]; then echo "FAIL: within_limit peak memory not reported (got $pass_peak)" rc=1 fi exit $rc - name: Assert enforcement (Windows) if: matrix.toolchain.system == 'Windows' shell: powershell working-directory: ${{ env.EXAMPLE_DIR }} run: | $ErrorActionPreference = 'Stop' $report = Get-Content report.json -Raw | ConvertFrom-Json $pass = $report.groups | Where-Object { $_.name -eq 'within_limit' } | Select-Object -ExpandProperty tests | Where-Object { $_.name -eq 'allocate_16mb' } $fail = $report.groups | Where-Object { $_.name -eq 'exceeds_limit' } | Select-Object -ExpandProperty tests | Where-Object { $_.name -eq 'allocate_256mb' } $passStatus = $pass.status $failStatus = $fail.status $passPeak = if ($pass.peak_memory_kb) { [int]$pass.peak_memory_kb } else { 0 } $failPeak = if ($fail.peak_memory_kb) { [int]$fail.peak_memory_kb } else { 0 } Write-Host "within_limit/allocate_16mb: status=$passStatus peak=$passPeak KiB" Write-Host "exceeds_limit/allocate_256mb: status=$failStatus peak=$failPeak KiB" $rc = 0 if ($passStatus -ne 'PASS') { Write-Host "FAIL: within_limit test should PASS, got $passStatus" $rc = 1 } if ($failStatus -ne 'MLE') { Write-Host "FAIL: exceeds_limit test should be MLE, got $failStatus" $rc = 1 } if ($passPeak -le 0) { Write-Host "FAIL: within_limit peak memory not reported (got $passPeak)" $rc = 1 } exit $rc