-
-
Notifications
You must be signed in to change notification settings - Fork 156
353 lines (314 loc) · 12.6 KB
/
Copy pathcontainer-tests.yml
File metadata and controls
353 lines (314 loc) · 12.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
name: Container Tests
# Comprehensive automated test suite for the perry/container subsystem.
#
# Test layers (ordered fastest → slowest, by run trigger):
#
# Layer A — Unit + Property tests every PR no runtime needed
# Layer A.1 — Functional (MockBackend) every PR hermetic, all v0.5.372 invariants
# Layer A.2 — Protocol arg snapshots every PR CLI flag emission
# Layer A.3 — Workspace invariants every PR fail-fast on missing workspace.member
# Layer B — FFI bug regressions every PR each surfaced-and-fixed bug pinned
# Layer C — Live-runtime integration PR + main real Docker/podman/apple-container
# Layer D — End-to-end (Perry compile + run) main + tags full TS → … → docker chain
# Layer E — Fuzz nightly libfuzzer; surfaces parser DoS/panics
#
# CI matrix: macOS-14 (apple/container) + ubuntu-24.04 (podman) for layers
# requiring a runtime; ubuntu-only for hermetic tests + fuzz.
on:
push:
branches: [main]
tags: ['v*']
paths:
- 'crates/perry-container-compose/**'
- 'crates/perry-container-e2e/**'
- 'crates/perry-stdlib/src/container/**'
- 'crates/perry-stdlib/tests/container_*'
- 'crates/perry-hir/src/lower.rs'
- 'crates/perry-hir/src/ir.rs'
- 'crates/perry-codegen/src/lower_call.rs'
- 'tests/e2e/**'
- 'types/perry/{container,compose,workloads}/**'
- '.github/workflows/container-tests.yml'
pull_request:
branches: [main]
paths:
- 'crates/perry-container-compose/**'
- 'crates/perry-container-e2e/**'
- 'crates/perry-stdlib/src/container/**'
- 'crates/perry-stdlib/tests/container_*'
- 'crates/perry-hir/src/lower.rs'
- 'crates/perry-hir/src/ir.rs'
- 'crates/perry-codegen/src/lower_call.rs'
- 'tests/e2e/**'
- 'types/perry/{container,compose,workloads}/**'
- '.github/workflows/container-tests.yml'
schedule:
# Nightly fuzz at 03:30 UTC
- cron: '30 3 * * *'
workflow_dispatch:
inputs:
run_e2e:
description: "Run e2e tests (Layer D)"
required: false
default: "false"
type: choice
options: ["true", "false"]
run_fuzz:
description: "Run fuzz tests (Layer E)"
required: false
default: "false"
type: choice
options: ["true", "false"]
concurrency:
group: container-tests-${{ github.ref }}
cancel-in-progress: true
env:
CARGO_TERM_COLOR: always
PERRY_NO_INSTALL_PROMPT: "1"
PERRY_NO_DEFAULT_SIGINT_CLEANUP: "1" # tests own their teardown via ProjectCleanup RAII
jobs:
# ===========================================================================
# Layer A + B: hermetic tests (no runtime). Every PR.
# ===========================================================================
hermetic:
name: Hermetic Tests (Layer A + B)
strategy:
fail-fast: false
matrix:
os: [macos-14, ubuntu-24.04]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v7
- name: Free up disk space (macOS)
if: runner.os == 'macOS'
run: |
sudo rm -rf /Library/Developer/CoreSimulator/Profiles/Runtimes/*Simulator* || true
sudo rm -rf ~/Library/Developer/CoreSimulator/Caches/* || true
df -h / | tail -1
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- uses: ./.github/actions/setup-llvm22
- name: Cache cargo registry
uses: actions/cache@v6
with:
path: |
~/.cargo/registry
~/.cargo/git
key: ${{ runner.os }}-cargo-container-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.os }}-cargo-container-
# ── Layer A.0: lib unit + protocol arg tests ──────────────────────
- name: A.0 — perry-container-compose lib + protocol args
run: |
cargo test -p perry-container-compose --lib
# ── Layer A.1: functional tests with MockBackend ──────────────────
- name: A.1 — Functional tests (MockBackend, hermetic)
run: |
cargo test -p perry-container-compose \
--features test-utils \
--test functional_orchestration \
-- --test-threads=2
# ── Layer A.2: fixture + property tests ───────────────────────────
- name: A.2 — Fixture + property tests
run: |
cargo test -p perry-container-compose \
--test fixtures_tests \
--test round_trip \
-- --test-threads=2
# ── Layer A.3: workspace invariants ───────────────────────────────
- name: A.3 — Workspace invariants
run: |
cargo test -p perry-stdlib \
--features container \
--test container_workspace_invariants
# ── Layer B: FFI bug regressions ──────────────────────────────────
- name: B — FFI bug regressions
run: |
cargo test -p perry-stdlib \
--features container \
--test container_capability_tests \
--test container_extra_tests \
--test container_ffi_tests \
--test container_props \
--test container_verification_tests
# ── Smoke tests on perry-stdlib's container module ────────────────
- name: stdlib container::smoke_tests
run: |
cargo test -p perry-stdlib \
--features container \
--lib container::smoke_tests
# ===========================================================================
# Layer C: Live-runtime integration tests. PR + main.
# ===========================================================================
integration-macos-apple:
name: Layer C — Integration (macOS / apple/container)
runs-on: macos-14
if: github.event_name != 'pull_request' || github.base_ref == 'main'
steps:
- uses: actions/checkout@v7
- name: Free up disk space (macOS)
run: |
sudo rm -rf /Library/Developer/CoreSimulator/Profiles/Runtimes/*Simulator* || true
df -h / | tail -1
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- uses: ./.github/actions/setup-llvm22
- name: Cache cargo registry
uses: actions/cache@v6
with:
path: |
~/.cargo/registry
~/.cargo/git
key: macos-cargo-container-integration-${{ hashFiles('**/Cargo.lock') }}
restore-keys: macos-cargo-container-integration-
- name: Probe apple/container availability
id: backend
run: |
if command -v container &>/dev/null && container --version; then
echo "available=true" >> "$GITHUB_OUTPUT"
else
echo "available=false" >> "$GITHUB_OUTPUT"
echo "::warning::apple/container not available — Layer C skipped"
fi
- name: C — live_runtime_tests against apple/container
if: steps.backend.outputs.available == 'true'
run: |
cargo test -p perry-container-compose \
--features integration-tests \
--test live_runtime_tests \
-- --test-threads=1
env:
PERRY_INTEGRATION_TESTS: "1"
PERRY_CONTAINER_BACKEND: "apple/container"
timeout-minutes: 15
integration-linux-podman:
name: Layer C — Integration (Linux / podman)
runs-on: ubuntu-24.04
if: github.event_name != 'pull_request' || github.base_ref == 'main'
steps:
- uses: actions/checkout@v7
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- uses: ./.github/actions/setup-llvm22
- name: Cache cargo registry
uses: actions/cache@v6
with:
path: |
~/.cargo/registry
~/.cargo/git
key: linux-cargo-container-integration-${{ hashFiles('**/Cargo.lock') }}
restore-keys: linux-cargo-container-integration-
- name: Install podman
run: |
sudo apt-get update -qq
sudo apt-get install -y podman
podman --version
- name: C — live_runtime_tests against podman
run: |
cargo test -p perry-container-compose \
--features integration-tests \
--test live_runtime_tests \
-- --test-threads=1
env:
PERRY_INTEGRATION_TESTS: "1"
PERRY_CONTAINER_BACKEND: "podman"
timeout-minutes: 15
# ===========================================================================
# Layer D: E2E (Perry compile + run). main + tags + manual.
# ===========================================================================
e2e-linux:
name: Layer D — E2E (Linux / docker)
runs-on: ubuntu-24.04
if: |
github.ref == 'refs/heads/main' ||
startsWith(github.ref, 'refs/tags/v') ||
github.event.inputs.run_e2e == 'true'
steps:
- uses: actions/checkout@v7
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- uses: ./.github/actions/setup-llvm22
- name: Cache cargo registry
uses: actions/cache@v6
with:
path: |
~/.cargo/registry
~/.cargo/git
key: linux-cargo-container-e2e-${{ hashFiles('**/Cargo.lock') }}
restore-keys: linux-cargo-container-e2e-
- name: Probe docker
run: docker info --format '{{.ServerVersion}}'
- name: Build Perry CLI (release)
run: |
cargo build --release \
-p perry -p perry-runtime -p perry-stdlib -p perry-runtime-static -p perry-stdlib-static
- name: D — redis smoke
run: |
cargo test -p perry-container-e2e --test e2e_container -- e2e_redis_smoke --test-threads=1
env:
PERRY_E2E_TESTS: "1"
PERRY_CONTAINER_BACKEND: "docker"
timeout-minutes: 10
- name: D — Forgejo full stack [advisory]
# Forgejo pulls ~250 MB; mark advisory so a slow registry
# doesn't block the PR gate.
continue-on-error: true
run: |
cargo test -p perry-container-e2e --test e2e_container -- e2e_forgejo_stack --test-threads=1
env:
PERRY_E2E_TESTS: "1"
PERRY_E2E_FORGEJO: "1"
PERRY_CONTAINER_BACKEND: "docker"
timeout-minutes: 25
- name: Upload e2e binaries (debugging)
if: always()
uses: actions/upload-artifact@v7
with:
name: e2e-bins-linux
path: target/e2e-bin/
if-no-files-found: ignore
# ===========================================================================
# Layer E: Fuzz. Nightly + manual.
# ===========================================================================
fuzz:
name: Layer E — Fuzz (libfuzzer)
runs-on: ubuntu-24.04
if: |
github.event_name == 'schedule' ||
github.event.inputs.run_fuzz == 'true'
strategy:
fail-fast: false
matrix:
target: [compose_yaml_parse, env_interpolation, compose_spec_json_round_trip]
steps:
- uses: actions/checkout@v7
- name: Install nightly Rust + cargo-fuzz
run: |
rustup toolchain install nightly --profile minimal --component rust-src
cargo install cargo-fuzz --locked
- name: Run fuzz target ${{ matrix.target }} for 5 minutes
working-directory: crates/perry-container-compose/fuzz
run: |
cargo +nightly fuzz run ${{ matrix.target }} -- -max_total_time=300
- name: Upload crash artifacts
if: failure()
uses: actions/upload-artifact@v7
with:
name: fuzz-crashes-${{ matrix.target }}
path: crates/perry-container-compose/fuzz/artifacts/${{ matrix.target }}/
# ===========================================================================
# Required-check gate. Hermetic tier MUST pass; live + e2e + fuzz are
# informational so a slow registry / runtime hiccup doesn't block PRs.
# ===========================================================================
container-tests-gate:
name: Container Tests Gate
runs-on: ubuntu-24.04
needs: [hermetic]
if: always()
steps:
- name: Check required jobs
run: |
if [[ "${{ needs.hermetic.result }}" != "success" ]]; then
echo "::error::hermetic tier failed: ${{ needs.hermetic.result }}"
exit 1
fi
echo "✅ Hermetic test tier passed."