FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
kernelscript/tests/test_void_functions.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_void_functions.ml
Copy path
More file actions
More file actions
Latest commit
History
History
History
414 lines (362 loc) · 14.3 KB
Breadcrumbs
kernelscript
/
tests
/
test_void_functions.ml
Copy path
File metadata and controls
414 lines (362 loc) · 14.3 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
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
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
(*
* 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.
*)
(*
* Unit tests for void function validation
*)
open
Alcotest
open
Kernelscript.Parse
open
Kernelscript.Type_checker
open
Kernelscript.Ir_generator
open
Kernelscript.Ebpf_c_codegen
(*
* Helper to check if string contains substring
*)
let
contains_substr
str
substr
=
try
let
_
=
Str.
search_forward (
Str.
regexp_string substr) str
0
in
true
with
Not_found
->
false
(*
* Test that void functions with naked return statements are accepted
*)
let
test_void_function_naked_return
()
=
let
program_text
=
{
|
@
helper
fn log_message(msg:
u32
) -> void {
print(
"
Message:
"
, msg)
return
}
@
xdp fn test_prog(ctx:
*xdp_md
) -> xdp_action {
log_message(
42
)
return
XDP_PASS
}
fn main
()
-> i32 {
return
0
}
|
}
in
try
let
ast
=
parse_string program_text
in
let
symbol_table
=
Test_utils.Helpers.
create_test_symbol_table ast
in
let
(annotated_ast, _typed_programs)
=
type_check_and_annotate_ast
~symbol_table:
(
Some
symbol_table) ast
in
let
multi_ir
=
lower_multi_program annotated_ast symbol_table
"
test_void_naked_return
"
in
(*
Verify the void function is in the multi-program IR
*)
let
has_log_func
=
List.
exists (
fun
func
->
func.
Kernelscript.Ir.
func_name
=
"
log_message
"
) (
Kernelscript.Ir.
get_kernel_functions multi_ir)
in
check
bool
"
void function with naked return should be accepted
"
true
has_log_func
with
|
exn
-> fail (
"
Void function with naked return should be accepted, but got:
"
^
Printexc.
to_string
exn
)
(*
* Test that void functions returning values are rejected
*)
let
test_void_function_with_return_value
()
=
let
program_text
=
{
|
@
helper
fn bad_void_func
()
-> void {
return
42
//
This
should fail
-
void function returning a value
}
@
xdp fn test_prog(ctx:
*xdp_md
) -> xdp_action {
bad_void_func
()
return
XDP_PASS
}
fn main
()
-> i32 {
return
0
}
|
}
in
try
let
ast
=
parse_string program_text
in
let
symbol_table
=
Test_utils.Helpers.
create_test_symbol_table ast
in
let
(annotated_ast, _typed_programs)
=
type_check_and_annotate_ast
~symbol_table:
(
Some
symbol_table) ast
in
let
_
=
lower_multi_program annotated_ast symbol_table
"
test_void_with_value
"
in
fail
"
Void function returning a value should be rejected
"
with
|
Type_error
(
msg
,
_
) ->
check
bool
"
correctly rejected void function with return value
"
true
(
String.
contains msg
'v'
||
String.
contains msg
'V'
||
String.
contains msg
'r'
)
|
_
->
fail
"
Expected Type_error for void function returning value
"
(*
* Test that void functions without return statements are accepted
*)
let
test_void_function_no_return
()
=
let
program_text
=
{
|
@
helper
fn setup_logging
()
-> void {
print(
"
Logging initialized
"
)
//
No
explicit return statement
}
@
xdp fn test_prog(ctx:
*xdp_md
) -> xdp_action {
setup_logging
()
return
XDP_PASS
}
fn main
()
-> i32 {
return
0
}
|
}
in
try
let
ast
=
parse_string program_text
in
let
symbol_table
=
Test_utils.Helpers.
create_test_symbol_table ast
in
let
(annotated_ast, _typed_programs)
=
type_check_and_annotate_ast
~symbol_table:
(
Some
symbol_table) ast
in
let
multi_ir
=
lower_multi_program annotated_ast symbol_table
"
test_void_no_return
"
in
(*
Verify the void function is in the multi-program IR
*)
let
has_setup_func
=
List.
exists (
fun
func
->
func.
Kernelscript.Ir.
func_name
=
"
setup_logging
"
) (
Kernelscript.Ir.
get_kernel_functions multi_ir)
in
check
bool
"
void function without return should be accepted
"
true
has_setup_func
with
|
exn
-> fail (
"
Void function without return should be accepted, but got:
"
^
Printexc.
to_string
exn
)
(*
* Test that void functions with conditional returns are handled correctly
*)
let
test_void_function_conditional_return
()
=
let
program_text
=
{
|
@
helper
fn conditional_log(should_log:
bool, msg: u32
) -> void {
if
(should_log) {
print(
"
Message:
"
, msg)
return
}
print(
"
No logging
"
)
return
}
@
xdp fn test_prog(ctx:
*xdp_md
) -> xdp_action {
conditional_log(
true
,
123
)
return
XDP_PASS
}
fn main
()
-> i32 {
return
0
}
|
}
in
try
let
ast
=
parse_string program_text
in
let
symbol_table
=
Test_utils.Helpers.
create_test_symbol_table ast
in
let
(annotated_ast, _typed_programs)
=
type_check_and_annotate_ast
~symbol_table:
(
Some
symbol_table) ast
in
let
multi_ir
=
lower_multi_program annotated_ast symbol_table
"
test_void_conditional
"
in
(*
Verify the void function is in the multi-program IR
*)
let
has_conditional_func
=
List.
exists (
fun
func
->
func.
Kernelscript.Ir.
func_name
=
"
conditional_log
"
) (
Kernelscript.Ir.
get_kernel_functions multi_ir)
in
check
bool
"
void function with conditional returns should be accepted
"
true
has_conditional_func
with
|
exn
-> fail (
"
Void function with conditional returns should be accepted, but got:
"
^
Printexc.
to_string
exn
)
(*
* Test that void functions with mixed return types are rejected
*)
let
test_void_function_mixed_returns
()
=
let
program_text
=
{
|
@
helper
fn bad_mixed_returns(flag:
bool
) -> void {
if
(flag) {
return
1
//
This
should fail
-
returning value
in
void
function
}
return
//
This
is
OK
-
naked
return
}
@
xdp
fn
test_prog
(
ctx
: *xdp_md
) -> xdp_action {
bad_mixed_returns(
true
)
return
XDP_PASS
}
fn main
()
-> i32 {
return
0
}
|
}
in
try
let
ast
=
parse_string program_text
in
let
symbol_table
=
Test_utils.Helpers.
create_test_symbol_table ast
in
let
(annotated_ast, _typed_programs)
=
type_check_and_annotate_ast
~symbol_table:
(
Some
symbol_table) ast
in
let
_
=
lower_multi_program annotated_ast symbol_table
"
test_void_mixed
"
in
fail
"
Void function with mixed return types should be rejected
"
with
|
Type_error
(
msg
,
_
) ->
check
bool
"
correctly rejected void function with mixed returns
"
true
(
String.
contains msg
'v'
||
String.
contains msg
'V'
||
String.
contains msg
'r'
)
|
_
->
fail
"
Expected Type_error for void function with mixed returns
"
(*
* Test void function code generation
*)
let
test_void_function_code_generation
()
=
let
program_text
=
{
|
@
helper
fn log_event(event_id:
u32
) -> void {
print(
"
Event:
"
, event_id)
return
}
@
xdp fn test_prog(ctx:
*xdp_md
) -> xdp_action {
log_event(
100
)
return
XDP_PASS
}
fn main
()
-> i32 {
return
0
}
|
}
in
try
let
ast
=
parse_string program_text
in
let
symbol_table
=
Test_utils.Helpers.
create_test_symbol_table ast
in
let
(annotated_ast, _typed_programs)
=
type_check_and_annotate_ast
~symbol_table:
(
Some
symbol_table) ast
in
let
multi_ir
=
lower_multi_program annotated_ast symbol_table
"
test_void_codegen
"
in
(*
Generate eBPF C code
*)
let
ebpf_code
=
generate_c_multi_program multi_ir
in
(*
Verify the void function is generated with correct signature
*)
check
bool
"
void function should have void return type in C
"
true
(
String.
contains ebpf_code
'v'
&&
String.
contains ebpf_code
'l'
);
(*
Note: There's a known issue where void function calls are assigned to variables in C generation
*)
(*
This doesn't affect correctness but could be optimized in the future
*)
()
with
|
exn
-> fail (
"
Void function code generation failed:
"
^
Printexc.
to_string
exn
)
(*
* Test userspace void functions
*)
let
test_userspace_void_function
()
=
let
program_text
=
{
|
fn cleanup_resources
()
-> void {
print(
"
Cleaning up resources
"
)
return
}
fn main
()
-> i32 {
cleanup_resources
()
return
0
}
|
}
in
try
let
ast
=
parse_string program_text
in
let
symbol_table
=
Test_utils.Helpers.
create_test_symbol_table ast
in
let
(_annotated_ast, _typed_programs)
=
type_check_and_annotate_ast
~symbol_table:
(
Some
symbol_table) ast
in
(*
If we get here without exceptions, the userspace void function was accepted
*)
(*
We don't need to generate IR for userspace-only tests, type checking is sufficient
*)
()
with
|
exn
-> fail (
"
Userspace void function should be accepted, but got:
"
^
Printexc.
to_string
exn
)
(*
* Test that void functions can't be used in expressions
*)
let
test_void_function_in_expression
()
=
let
program_text
=
{
|
@
helper
fn log_and_return_void
()
-> void {
print(
"
Logging
"
)
return
}
@
xdp fn test_prog(ctx:
*xdp_md
) -> xdp_action {
var result
=
log_and_return_void
()
//
This
should fail
-
void function
in
expression
return
XDP_PASS
}
fn main
()
-> i32 {
return
0
}
|
}
in
try
let
ast
=
parse_string program_text
in
let
symbol_table
=
Test_utils.Helpers.
create_test_symbol_table ast
in
let
(annotated_ast, _typed_programs)
=
type_check_and_annotate_ast
~symbol_table:
(
Some
symbol_table) ast
in
let
_
=
lower_multi_program annotated_ast symbol_table
"
test_void_in_expr
"
in
fail
"
Void function used in expression should be rejected
"
with
|
Type_error
(
msg
,
_
) ->
check
bool
"
correctly rejected void function in expression
"
true
(
String.
contains msg
'v'
||
String.
contains msg
'V'
||
String.
contains msg
'e'
)
|
_
->
fail
"
Expected Type_error for void function in expression
"
(*
* Test extern kfunc with void return type
*)
let
test_extern_void_kfunc
()
=
let
program_text
=
{
|
extern custom_void_kfunc(value:
u32
) -> void
@
xdp fn test_prog(ctx:
*xdp_md
) -> xdp_action {
custom_void_kfunc(
42
)
return
XDP_PASS
}
fn main
()
-> i32 {
return
0
}
|
}
in
try
let
ast
=
parse_string program_text
in
let
symbol_table
=
Test_utils.Helpers.
create_test_symbol_table ast
in
let
(annotated_ast, _typed_programs)
=
type_check_and_annotate_ast
~symbol_table:
(
Some
symbol_table) ast
in
let
multi_ir
=
lower_multi_program annotated_ast symbol_table
"
test_extern_void
"
in
(*
Verify the program compiles successfully
*)
let
has_xdp_prog
=
List.
exists (
fun
prog
->
prog.
Kernelscript.Ir.
name
=
"
test_prog
"
) (
Kernelscript.Ir.
get_programs multi_ir)
in
check
bool
"
extern void kfunc should be accepted
"
true
has_xdp_prog
with
|
exn
-> fail (
"
Extern void kfunc should be accepted, but got:
"
^
Printexc.
to_string
exn
)
(*
* Test void function with complex control flow
*)
let
test_void_function_complex_control_flow
()
=
let
program_text
=
{
|
@
helper
fn complex_void_func(mode:
u32
) -> void {
if
(mode
==
1
) {
print(
"
Mode 1
"
)
return
}
else
if
(mode
==
2
) {
print(
"
Mode 2
"
)
return
}
else
{
print(
"
Default mode
"
)
//
Implicit
return at end
}
}
@
xdp fn test_prog(ctx:
*xdp_md
) -> xdp_action {
complex_void_func(
1
)
return
XDP_PASS
}
fn main
()
-> i32 {
return
0
}
|
}
in
try
let
ast
=
parse_string program_text
in
let
symbol_table
=
Test_utils.Helpers.
create_test_symbol_table ast
in
let
(annotated_ast, _typed_programs)
=
type_check_and_annotate_ast
~symbol_table:
(
Some
symbol_table) ast
in
let
multi_ir
=
lower_multi_program annotated_ast symbol_table
"
test_void_complex
"
in
(*
Verify the void function is in the multi-program IR
*)
let
has_complex_func
=
List.
exists (
fun
func
->
func.
Kernelscript.Ir.
func_name
=
"
complex_void_func
"
) (
Kernelscript.Ir.
get_kernel_functions multi_ir)
in
check
bool
"
void function with complex control flow should be accepted
"
true
has_complex_func
with
|
exn
-> fail (
"
Void function with complex control flow should be accepted, but got:
"
^
Printexc.
to_string
exn
)
(*
* Test void function call C code generation - regression test for void function call fix
*)
let
test_void_function_call_c_generation
()
=
let
program_text
=
{
|
@
helper fn set_qos_mark(ctx:
*__sk_buff, class: str(16
)) -> void { }
@
tc(
"
ingress
"
) fn qos_marker(ctx:
*__sk_buff
) -> i32 {
set_qos_mark(ctx,
"
high_priority
"
)
return
0
}
|
}
in
let
ast
=
parse_string program_text
in
let
symbol_table
=
Kernelscript.Symbol_table.
build_symbol_table ast
in
let
(typed_ast, _)
=
type_check_and_annotate_ast ast
in
let
ir
=
generate_ir typed_ast symbol_table
"
test_void
"
in
(*
Generate eBPF C code
*)
let
(c_code, _)
=
Kernelscript.Ebpf_c_codegen.
compile_multi_to_c_with_analysis ir
in
(*
Check that void function is declared correctly
*)
check
bool
"
void function declaration
"
true
(contains_substr c_code
"
void set_qos_mark(struct __sk_buff* ctx, str_16_t class)
"
);
(*
Check that void function call does NOT generate temporary variable assignment
*)
check
bool
"
no temporary variable for void call
"
false
(contains_substr c_code
"
void var_
"
);
(*
Check that void function call is generated correctly without assignment
*)
check
bool
"
correct void function call
"
true
(contains_substr c_code
"
set_qos_mark(ctx,
"
);
(*
Ensure the call is a standalone statement, not an assignment
*)
check
bool
"
void call as statement
"
true
(contains_substr c_code
"
set_qos_mark(ctx, str_lit_1);
"
);
(*
Ensure no invalid C syntax like "void var_X = function_call()"
*)
let
lines
=
String.
split_on_char
'\n'
c_code
in
let
has_invalid_void_assignment
=
List.
exists (
fun
line
->
contains_substr line
"
void
"
&&
contains_substr line
"
=
"
&&
contains_substr line
"
set_qos_mark
"
) lines
in
check
bool
"
no invalid void assignment
"
false
has_invalid_void_assignment
let
void_function_tests
=
[
(
"
void_function_naked_return
"
,
`Quick
, test_void_function_naked_return);
(
"
void_function_with_return_value
"
,
`Quick
, test_void_function_with_return_value);
(
"
void_function_no_return
"
,
`Quick
, test_void_function_no_return);
(
"
void_function_conditional_return
"
,
`Quick
, test_void_function_conditional_return);
(
"
void_function_mixed_returns
"
,
`Quick
, test_void_function_mixed_returns);
(
"
void_function_code_generation
"
,
`Quick
, test_void_function_code_generation);
(
"
userspace_void_function
"
,
`Quick
, test_userspace_void_function);
(
"
void_function_in_expression
"
,
`Quick
, test_void_function_in_expression);
(
"
extern_void_kfunc
"
,
`Quick
, test_extern_void_kfunc);
(
"
void_function_complex_control_flow
"
,
`Quick
, test_void_function_complex_control_flow);
(
"
void_function_call_c_generation
"
,
`Quick
, test_void_function_call_c_generation);
]
let
()
=
run
"
Void Function Tests
"
[
(
"
void_functions
"
, void_function_tests);
]
Back
|
FazBrowse Home
|
New Git URL