Skip to content

Commit 0cedefb

Browse files
koki-developclaude
andcommitted
feat: add arch field to E2E framework and split architecture-dependent tests
Co-Authored-By: Claude <noreply@anthropic.com>
1 parent af93855 commit 0cedefb

13 files changed

Lines changed: 1092 additions & 103 deletions

e2e/CLAUDE.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Each YAML file has a top-level `tests` key containing a list of test cases:
2525
```yaml
2626
tests:
2727
- name: "test case name"
28+
arch: [amd64, arm64]
2829
requests:
2930
- input:
3031
runtime: node
@@ -56,6 +57,19 @@ tests:
5657
error: ""
5758
```
5859
60+
### Architecture Filter
61+
62+
The optional `arch` field restricts a test case to specific CPU architectures. When omitted, the test runs on all architectures. When specified, the test runs only on the listed architectures (matched against Go's `runtime.GOARCH`).
63+
64+
```yaml
65+
tests:
66+
- name: "amd64-only syscall test"
67+
arch: [amd64]
68+
requests:
69+
- input:
70+
# ...
71+
```
72+
5973
### File Types
6074

6175
- `raw` (default): File content is provided inline via the `content` field.

e2e/e2e_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import (
1111
"io/fs"
1212
"net/http"
1313
"regexp"
14+
"runtime"
15+
"slices"
1416
"strings"
1517
"testing"
1618

@@ -85,6 +87,7 @@ type testRequest struct {
8587

8688
type testCase struct {
8789
Name string `yaml:"name"`
90+
Arch []string `yaml:"arch"`
8891
Requests []testRequest `yaml:"requests"`
8992
}
9093

@@ -168,6 +171,9 @@ func TestE2E(t *testing.T) {
168171
for i, tc := range tf.Tests {
169172
t.Run(fmt.Sprintf("%s/%d/%s", testPath, i, tc.Name), func(t *testing.T) {
170173
t.Parallel()
174+
if len(tc.Arch) > 0 && !slices.Contains(tc.Arch, runtime.GOARCH) {
175+
t.Skipf("skipping: test requires arch %v, got %s", tc.Arch, runtime.GOARCH)
176+
}
171177
for ri, req := range tc.Requests {
172178
func() {
173179
files := make([]apiFile, len(req.Input.Files))

e2e/tests/security/filesystem.yml

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ tests:
8787
status: "OK"
8888
signal: null
8989

90-
- name: "/lib64 is read-only or absent"
90+
- name: "/lib64 is read-only"
91+
arch: [amd64]
9192
requests:
9293
- input:
9394
runtime: bash
@@ -101,9 +102,29 @@ tests:
101102
body:
102103
run:
103104
stdout: ""
104-
# Error message differs by architecture: see nsjail.cfg /lib64 comments.
105-
stderr: "/^/code/main\\.sh: line 1: /lib64/test: (Not a directory|Read-only file system)\n$/"
106-
output: "/^/code/main\\.sh: line 1: /lib64/test: (Not a directory|Read-only file system)\n$/"
105+
stderr: "/code/main.sh: line 1: /lib64/test: Read-only file system\n"
106+
output: "/code/main.sh: line 1: /lib64/test: Read-only file system\n"
107+
exit_code: 1
108+
status: "OK"
109+
signal: null
110+
111+
- name: "/lib64 is not accessible"
112+
arch: [arm64]
113+
requests:
114+
- input:
115+
runtime: bash
116+
files:
117+
- name: main.sh
118+
type: raw
119+
content: |
120+
echo x > /lib64/test
121+
output:
122+
status: 200
123+
body:
124+
run:
125+
stdout: ""
126+
stderr: "/code/main.sh: line 1: /lib64/test: Not a directory\n"
127+
output: "/code/main.sh: line 1: /lib64/test: Not a directory\n"
107128
exit_code: 1
108129
status: "OK"
109130
signal: null

e2e/tests/security/memory_execution.yml

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,46 @@ tests:
6868
signal: null
6969

7070
- name: "memfd_create is not blocked by seccomp"
71+
arch: [amd64]
7172
requests:
7273
- input:
7374
runtime: ruby
7475
files:
7576
- name: main.rb
7677
type: raw
7778
content: |
78-
nr = RUBY_PLATFORM.include?('aarch64') ? 279 : 319
7979
begin
80-
fd = syscall(nr, "test", 0)
80+
fd = syscall(319, "test", 0)
81+
if fd >= 0
82+
puts "allowed"
83+
else
84+
puts "error"
85+
end
86+
rescue Errno::ENOSYS
87+
puts "enosys"
88+
end
89+
output:
90+
status: 200
91+
body:
92+
run:
93+
stdout: "allowed\n"
94+
stderr: ""
95+
output: "allowed\n"
96+
exit_code: 0
97+
status: "OK"
98+
signal: null
99+
100+
- name: "memfd_create is not blocked by seccomp"
101+
arch: [arm64]
102+
requests:
103+
- input:
104+
runtime: ruby
105+
files:
106+
- name: main.rb
107+
type: raw
108+
content: |
109+
begin
110+
fd = syscall(279, "test", 0)
81111
if fd >= 0
82112
puts "allowed"
83113
else

e2e/tests/security/seccomp.yml

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,56 @@
11
tests:
22
- name: "ptrace is blocked by seccomp (ruby)"
3+
arch: [amd64]
34
requests:
45
- input:
56
runtime: ruby
67
files:
78
- name: main.rb
89
type: raw
910
content: |
10-
nr = RUBY_PLATFORM.include?('aarch64') ? 117 : 101
11-
syscall(nr)
11+
syscall(101)
12+
output:
13+
status: 200
14+
body:
15+
run:
16+
stdout: ""
17+
stderr: ""
18+
output: ""
19+
exit_code: 159
20+
status: "SIGNAL"
21+
signal: "SIGSYS"
22+
23+
- name: "ptrace is blocked by seccomp (ruby)"
24+
arch: [arm64]
25+
requests:
26+
- input:
27+
runtime: ruby
28+
files:
29+
- name: main.rb
30+
type: raw
31+
content: |
32+
syscall(117)
33+
output:
34+
status: 200
35+
body:
36+
run:
37+
stdout: ""
38+
stderr: ""
39+
output: ""
40+
exit_code: 159
41+
status: "SIGNAL"
42+
signal: "SIGSYS"
43+
44+
- name: "mount is blocked by seccomp (ruby)"
45+
arch: [amd64]
46+
requests:
47+
- input:
48+
runtime: ruby
49+
files:
50+
- name: main.rb
51+
type: raw
52+
content: |
53+
syscall(165)
1254
output:
1355
status: 200
1456
body:
@@ -21,15 +63,15 @@ tests:
2163
signal: "SIGSYS"
2264

2365
- name: "mount is blocked by seccomp (ruby)"
66+
arch: [arm64]
2467
requests:
2568
- input:
2669
runtime: ruby
2770
files:
2871
- name: main.rb
2972
type: raw
3073
content: |
31-
nr = RUBY_PLATFORM.include?('aarch64') ? 40 : 165
32-
syscall(nr)
74+
syscall(40)
3375
output:
3476
status: 200
3577
body:

e2e/tests/security/seccomp_filesystem.yml

Lines changed: 92 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,35 @@
11
tests:
22
- name: "open_by_handle_at (Shocker attack) is blocked by seccomp (ruby)"
3+
arch: [amd64]
34
requests:
45
- input:
56
runtime: ruby
67
files:
78
- name: main.rb
89
type: raw
910
content: |
10-
nr = RUBY_PLATFORM.include?('aarch64') ? 265 : 304
11-
syscall(nr, 0, 0, 0)
11+
syscall(304, 0, 0, 0)
12+
output:
13+
status: 200
14+
body:
15+
run:
16+
stdout: ""
17+
stderr: ""
18+
output: ""
19+
exit_code: 159
20+
status: "SIGNAL"
21+
signal: "SIGSYS"
22+
23+
- name: "open_by_handle_at (Shocker attack) is blocked by seccomp (ruby)"
24+
arch: [arm64]
25+
requests:
26+
- input:
27+
runtime: ruby
28+
files:
29+
- name: main.rb
30+
type: raw
31+
content: |
32+
syscall(265, 0, 0, 0)
1233
output:
1334
status: 200
1435
body:
@@ -161,15 +182,36 @@ tests:
161182
signal: "SIGSYS"
162183

163184
- name: "name_to_handle_at is blocked by seccomp (ruby)"
185+
arch: [amd64]
186+
requests:
187+
- input:
188+
runtime: ruby
189+
files:
190+
- name: main.rb
191+
type: raw
192+
content: |
193+
syscall(303, 0, 0, 0, 0, 0)
194+
output:
195+
status: 200
196+
body:
197+
run:
198+
stdout: ""
199+
stderr: ""
200+
output: ""
201+
exit_code: 159
202+
status: "SIGNAL"
203+
signal: "SIGSYS"
204+
205+
- name: "name_to_handle_at is blocked by seccomp (ruby)"
206+
arch: [arm64]
164207
requests:
165208
- input:
166209
runtime: ruby
167210
files:
168211
- name: main.rb
169212
type: raw
170213
content: |
171-
nr = RUBY_PLATFORM.include?('aarch64') ? 264 : 303
172-
syscall(nr, 0, 0, 0, 0, 0)
214+
syscall(264, 0, 0, 0, 0, 0)
173215
output:
174216
status: 200
175217
body:
@@ -182,15 +224,57 @@ tests:
182224
signal: "SIGSYS"
183225

184226
- name: "fanotify_init is blocked by seccomp (ruby)"
227+
arch: [amd64]
228+
requests:
229+
- input:
230+
runtime: ruby
231+
files:
232+
- name: main.rb
233+
type: raw
234+
content: |
235+
syscall(300, 0, 0)
236+
output:
237+
status: 200
238+
body:
239+
run:
240+
stdout: ""
241+
stderr: ""
242+
output: ""
243+
exit_code: 159
244+
status: "SIGNAL"
245+
signal: "SIGSYS"
246+
247+
- name: "fanotify_init is blocked by seccomp (ruby)"
248+
arch: [arm64]
249+
requests:
250+
- input:
251+
runtime: ruby
252+
files:
253+
- name: main.rb
254+
type: raw
255+
content: |
256+
syscall(262, 0, 0)
257+
output:
258+
status: 200
259+
body:
260+
run:
261+
stdout: ""
262+
stderr: ""
263+
output: ""
264+
exit_code: 159
265+
status: "SIGNAL"
266+
signal: "SIGSYS"
267+
268+
- name: "fanotify_mark is blocked by seccomp (ruby)"
269+
arch: [amd64]
185270
requests:
186271
- input:
187272
runtime: ruby
188273
files:
189274
- name: main.rb
190275
type: raw
191276
content: |
192-
nr = RUBY_PLATFORM.include?('aarch64') ? 262 : 300
193-
syscall(nr, 0, 0)
277+
syscall(301, 0, 0, 0, 0, 0)
194278
output:
195279
status: 200
196280
body:
@@ -203,15 +287,15 @@ tests:
203287
signal: "SIGSYS"
204288

205289
- name: "fanotify_mark is blocked by seccomp (ruby)"
290+
arch: [arm64]
206291
requests:
207292
- input:
208293
runtime: ruby
209294
files:
210295
- name: main.rb
211296
type: raw
212297
content: |
213-
nr = RUBY_PLATFORM.include?('aarch64') ? 263 : 301
214-
syscall(nr, 0, 0, 0, 0, 0)
298+
syscall(263, 0, 0, 0, 0, 0)
215299
output:
216300
status: 200
217301
body:

0 commit comments

Comments
 (0)