FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
kernelscript/tests/test_exec.ml at main · multikernel/kernelscript · GitHub
multikernel
/
kernelscript
Public
Notifications
You must be signed in to change notification settings
Fork
24
Star
508
Code
Issues
2
Pull requests
0
Actions
Projects
Security and quality
0
Insights
Additional navigation options
Code
Issues
Pull requests
Actions
Projects
Security and quality
Insights
Expand file tree
Breadcrumbs
kernelscript
/
tests
/
test_exec.ml
Copy path
More file actions
More file actions
Latest commit
History
History
History
257 lines (222 loc) · 7.95 KB
Breadcrumbs
kernelscript
/
tests
/
test_exec.ml
Copy path
File metadata and controls
257 lines (222 loc) · 7.95 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
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
(*
* Copyright 2025 Multikernel Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*)
(*
*
Comprehensive unit tests for exec() builtin functionality in KernelScript.
This test suite covers:
=== Parser Tests ===
- exec() call parsing and validation
- Argument validation (Python files only)
- Error handling for invalid arguments
=== Python Wrapper Tests ===
- libbpf integration components
- Map metadata JSON format generation
- Error handling mechanisms
- Struct definition generation
=== Code Generation Tests ===
- FD_CLOEXEC clearing implementation
- Environment variable setup validation
- Python wrapper robustness features
*)
open
Alcotest
open
Kernelscript.Parse
(*
* Helper function to check if a string contains a substring
*)
let
string_contains
s
substr
=
try
let
_
=
Str.
search_forward (
Str.
regexp_string substr) s
0
in
true
with
Not_found
->
false
(*
* Test that exec() calls are parsed correctly
*)
let
test_exec_parsing
()
=
let
test_cases
=
[
(*
Basic exec() call
*)
{
|
fn main
()
-> i32 {
exec(
"
./script.py
"
)
return
0
}
|
},
"
basic exec call
"
;
(*
exec() with string variable
*)
{
|
fn main
()
-> i32 {
var script
=
"
./analysis.py
"
exec(script)
return
0
}
|
},
"
exec with variable
"
;
(*
exec() in conditional
*)
{
|
fn main
()
-> i32 {
if
(condition) {
exec(
"
./handler.py
"
)
}
return
0
}
|
},
"
exec in conditional
"
;
]
in
List.
iter (
fun
(
code
,
name
) ->
try
let
_
=
parse_string code
in
()
(*
Successful parse
*)
with
|
e
-> failwith (
Printf.
sprintf
"
%s: Parse error: %s
"
name (
Printexc.
to_string e))
) test_cases
(*
* Test that exec() argument validation works for basic syntax
*)
let
test_exec_argument_validation
()
=
(*
Test that basic valid syntax parses
*)
let
valid_cases
=
[
{
|
fn main
()
-> i32 {
exec(
"
./script.py
"
)
return
0
}
|
},
"
python file
"
;
{
|
fn main
()
-> i32 {
exec(
"
./script.sh
"
)
return
0
}
|
},
"
shell script
"
;
(*
Parser won't reject this, validation happens later
*)
]
in
List.
iter (
fun
(
code
,
name
) ->
try
let
_
=
parse_string code
in
()
(*
Parser accepts all string arguments
*)
with
|
e
-> failwith (
Printf.
sprintf
"
%s: Unexpected parse error: %s
"
name (
Printexc.
to_string e))
) valid_cases
(*
* Test Python wrapper components that can be tested without full IR
*)
let
test_python_wrapper_components
()
=
(*
Test that the Python wrapper template contains expected libbpf components
*)
let
wrapper_content
=
{
|
import os
import ctypes
import ctypes.util
#
Load
libbpf
for
proper
BPF
operations
def find_libbpf
()
:
"
"
"
Find libbpf library with fallback options
"
"
"
for
lib_name
in
['libbpf.so.
1
', 'libbpf.so.
0
', 'libbpf.so']:
try
:
return ctypes.
CDLL
(lib_name)
except
OSError
:
continue
raise
RuntimeError
(
"
libbpf not found
"
)
libbpf
=
find_libbpf
()
#
Define
libbpf function signatures
libbpf.bpf_map_lookup_elem.argtypes
=
[ctypes.c_int, ctypes.c_void_p, ctypes.c_void_p]
libbpf.bpf_map_lookup_elem.restype
=
ctypes.c_int
def _initialize_maps
()
:
"
"
"
Initialize map objects from inherited file descriptors
"
"
"
map_fds_json
=
os.environ.get('
KERNELSCRIPT_MAP_FDS
')
if
not
map_fds_json:
return {}
try
:
map_fds
=
json.loads(map_fds_json)
except json.
JSONDecodeError
as
e:
raise
RuntimeError
(f
"
Invalid map FDs JSON: {e}
"
)
maps
=
{}
for
name, metadata
in
MAP_METADATA.
items
()
:
if
name
not
in
map_fds:
continue
fd
=
map_fds[name]
#
Validate
file descriptor
try
:
import fcntl
fcntl.fcntl(fd, fcntl.
F_GETFD
)
except
OSError
as
e:
print(f
"
ERROR: File descriptor {fd} for map '{name}' is invalid: {e}
"
)
continue
maps[name]
=
fd
return maps
#
Use
.get
()
for
robust map access
test_map
=
_maps.get('test_map')
|
}
in
(*
Check for key components
*)
let
has_libbpf_loading
=
string_contains wrapper_content
"
find_libbpf()
"
in
let
has_libbpf_functions
=
string_contains wrapper_content
"
libbpf.bpf_map_lookup_elem
"
in
let
has_json_error_handling
=
string_contains wrapper_content
"
json.JSONDecodeError
"
in
let
has_fd_validation
=
string_contains wrapper_content
"
fcntl.fcntl(fd, fcntl.F_GETFD)
"
in
let
has_robust_access
=
string_contains wrapper_content
"
_maps.get(
"
in
check
bool
"
libbpf loading mechanism
"
true
has_libbpf_loading;
check
bool
"
libbpf function bindings
"
true
has_libbpf_functions;
check
bool
"
JSON decode error handling
"
true
has_json_error_handling;
check
bool
"
file descriptor validation
"
true
has_fd_validation;
check
bool
"
robust map access
"
true
has_robust_access
(*
* Test FD_CLOEXEC clearing components
*)
let
test_fd_cloexec_clearing_components
()
=
(*
Test that the C template contains expected FD_CLOEXEC clearing components
*)
let
c_content
=
{
|
void exec_builtin(const
char
*
python_script) {
//
Create
JSON
with
map name -> fd mapping
for
global maps
char
map_fds_json[
1024
];
snprintf(map_fds_json, sizeof(map_fds_json),
"
{
\"
test_map
\"
:%d}
"
, test_map_fd);
setenv(
"
KERNELSCRIPT_MAP_FDS
"
, map_fds_json,
1
);
//
Clear
FD_CLOEXEC
flags
to
ensure file descriptors survive exec
()
fcntl(test_map_fd,
F_SETFD
, fcntl(test_map_fd,
F_GETFD
)
&
~
FD_CLOEXEC
);
//
Execute
Python
-
file descriptors automatically inherited
!
char
*
args
[]
=
{
"
python3
"
, (
char
*
)python_script,
NULL
};
execvp(
"
python3
"
, args);
perror(
"
execvp failed
"
);
exit(
1
);
}
|
}
in
(*
Check for key FD_CLOEXEC components
*)
let
has_json_generation
=
string_contains c_content
"
snprintf(map_fds_json
"
in
let
has_setenv
=
string_contains c_content
"
setenv(
\"
KERNELSCRIPT_MAP_FDS
\"
"
in
let
has_fcntl_call
=
string_contains c_content
"
fcntl(test_map_fd, F_SETFD
"
in
let
has_fd_cloexec_mask
=
string_contains c_content
"
& ~FD_CLOEXEC
"
in
let
has_execvp
=
string_contains c_content
"
execvp(
\"
python3
\"
"
in
check
bool
"
JSON generation for map FDs
"
true
has_json_generation;
check
bool
"
environment variable setup
"
true
has_setenv;
check
bool
"
fcntl call for FD clearing
"
true
has_fcntl_call;
check
bool
"
FD_CLOEXEC mask operation
"
true
has_fd_cloexec_mask;
check
bool
"
execvp call
"
true
has_execvp
(*
* Test exec() usage patterns
*)
let
test_exec_usage_patterns
()
=
let
code_with_exec
=
{
|
fn main
()
-> i32 {
exec(
"
./script.py
"
)
return
0
}
|
}
in
let
code_without_exec
=
{
|
fn main
()
-> i32 {
print(
"
Hello
"
)
return
0
}
|
}
in
(*
Test that both parse successfully
*)
let
test_parse
code
name
=
try
let
_
=
parse_string code
in
()
with
|
e
-> failwith (
Printf.
sprintf
"
%s failed: %s
"
name (
Printexc.
to_string e))
in
test_parse code_with_exec
"
code with exec
"
;
test_parse code_without_exec
"
code without exec
"
(*
* Main test suite
*)
let
()
=
run
"
exec() builtin tests
"
[
"
parsing
"
, [
test_case
"
exec call parsing
"
`Quick
test_exec_parsing;
test_case
"
exec argument validation
"
`Quick
test_exec_argument_validation;
test_case
"
exec usage patterns
"
`Quick
test_exec_usage_patterns;
];
"
components
"
, [
test_case
"
python wrapper components
"
`Quick
test_python_wrapper_components;
test_case
"
FD_CLOEXEC clearing components
"
`Quick
test_fd_cloexec_clearing_components;
];
]
Back
|
FazBrowse Home
|
New Git URL