FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

GitHub Viewer

(* * 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 non-main function generation *) open OUnit2 open Kernelscript.Ast open Kernelscript.Symbol_table open Kernelscript.Type_checker open Kernelscript.Ir_generator open Kernelscript.Ebpf_c_codegen let test_pos = { line = 1; column = 1; filename = "test" } (** Test function parameter handling in eBPF C generation *) let test_function_parameters _ = (* Create a simple function: fn add(a: u32, b: u32) -> u32 { return a + b } *) let func_params = [("a", U32); ("b", U32)] in let return_expr = { expr_desc = BinaryOp ( { expr_desc = Identifier "a"; expr_pos = test_pos; expr_type = Some U32 }, Add, { expr_desc = Identifier "b"; expr_pos = test_pos; expr_type = Some U32 } ); expr_pos = test_pos; expr_type = Some U32; } in let func_body = [{ stmt_desc = Return (Some return_expr); stmt_pos = test_pos }] in let func_def = { func_name = "add"; func_params = func_params; func_return_type = Some U32; func_body = func_body; func_scope = Ast.Userspace; func_pos = test_pos; } in (* Create program containing this function *) let prog_def = { prog_name = "test_prog"; prog_target = None; prog_type = Xdp; prog_maps = []; prog_structs = []; prog_functions = [func_def]; prog_pos = test_pos; } in (* Create symbol table and type check *) let symbol_table = create_symbol_table () in let ast = [Program prog_def] in build_symbol_table symbol_table ast; let ctx = create_type_context () in let _ = type_check_multi_program ctx ast in (* Generate IR *) let ir_ctx = create_context symbol_table in let ir_program = lower_single_program ir_ctx prog_def [] in (* Generate eBPF C code *) let c_code = generate_c_program ir_program in (* Verify the generated code uses parameter names correctly *) assert_bool "Function should use parameter 'a'" (String.contains c_code 'a'); assert_bool "Function should use parameter 'b'" (String.contains c_code 'b'); assert_bool "Function should be named 'add'" (Str.string_match (Str.regexp ".*__u32 add(__u32 a, __u32 b).*") c_code 0); assert_bool "Function should use 'a + b'" (Str.string_match (Str.regexp ".*(a + b).*") c_code 0) (** Test program-scoped function calls *) let test_program_function_calls _ = (* Create helper function *) let helper_params = [("value", U32)] in let helper_return = { expr_desc = BinaryOp ( { expr_desc = Identifier "value"; expr_pos = test_pos; expr_type = Some U32 }, Mul, { expr_desc = Literal (IntLit (Signed64 2L, None)); expr_pos = test_pos; expr_type = Some U32 } ); expr_pos = test_pos; expr_type = Some U32; } in let helper_body = [{ stmt_desc = Return (Some helper_return); stmt_pos = test_pos }] in let helper_func = { func_name = "helper"; func_params = helper_params; func_return_type = Some U32; func_body = helper_body; func_scope = Ast.Userspace; func_pos = test_pos; } in (* Create main function that calls helper *) let main_params = [("ctx", xdp_md)] in let helper_call = { expr_desc = FunctionCall ("helper", [ { expr_desc = Literal (IntLit (Signed64 10L, None)); expr_pos = test_pos; expr_type = Some U32 } ]); expr_pos = test_pos; expr_type = Some U32; } in let main_stmt = { stmt_desc = Declaration ("result", Some U32, helper_call); stmt_pos = test_pos } in let main_return = { stmt_desc = Return (Some { expr_desc = Identifier "XDP_PASS"; expr_pos = test_pos; expr_type = Some xdp_action }); stmt_pos = test_pos } in let main_func = { func_name = "main"; func_params = main_params; func_return_type = Some xdp_action; func_body = [main_stmt; main_return]; func_scope = Ast.Userspace; func_pos = test_pos; } in (* Create program with both functions *) let prog_def = { prog_name = "test_prog"; prog_target = None; prog_type = Xdp; prog_maps = []; prog_structs = []; prog_functions = [helper_func; main_func]; prog_pos = test_pos; } in (* Process and generate code *) let symbol_table = create_symbol_table () in let ast = [Program prog_def] in build_symbol_table symbol_table ast; let ctx = create_type_context () in let _ = type_check_multi_program ctx ast in let ir_ctx = create_context symbol_table in let ir_program = lower_single_program ir_ctx prog_def [] in let c_code = generate_c_program ir_program in (* Verify both functions are generated *) assert_bool "Should generate helper function" (Str.string_match (Str.regexp ".*__u32 helper(__u32 value).*") c_code 0); assert_bool "Should generate main function" (Str.string_match (Str.regexp ".*int test_prog(struct xdp_md\\* ctx).*") c_code 0); assert_bool "Helper should use parameter correctly" (Str.string_match (Str.regexp ".*(value \\* 2).*") c_code 0); assert_bool "Main should call helper" (Str.string_match (Str.regexp ".*helper(10).*") c_code 0) (** Test functions with multiple parameters *) let test_multiple_parameters _ = (* Create function with 3 parameters *) let func_params = [("a", U32); ("b", U32); ("c", U32)] in let expr1 = { expr_desc = BinaryOp ( { expr_desc = Identifier "a"; expr_pos = test_pos; expr_type = Some U32 }, Add, { expr_desc = Identifier "b"; expr_pos = test_pos; expr_type = Some U32 } ); expr_pos = test_pos; expr_type = Some U32; } in let return_expr = { expr_desc = BinaryOp (expr1, Add, { expr_desc = Identifier "c"; expr_pos = test_pos; expr_type = Some U32 }); expr_pos = test_pos; expr_type = Some U32; } in let func_body = [{ stmt_desc = Return (Some return_expr); stmt_pos = test_pos }] in let func_def = { func_name = "add_three"; func_params = func_params; func_return_type = Some U32; func_body = func_body; func_scope = Ast.Userspace; func_pos = test_pos; } in (* Create minimal program *) let main_func = { func_name = "main"; func_params = [("ctx", xdp_md)]; func_return_type = Some xdp_action; func_body = [{ stmt_desc = Return (Some { expr_desc = Identifier "XDP_PASS"; expr_pos = test_pos; expr_type = Some xdp_action }); stmt_pos = test_pos }]; func_scope = Ast.Userspace; func_pos = test_pos; } in let prog_def = { prog_name = "test_prog"; prog_target = None; prog_type = Xdp; prog_maps = []; prog_structs = []; prog_functions = [func_def; main_func]; prog_pos = test_pos; } in (* Process and generate *) let symbol_table = create_symbol_table () in let ast = [Program prog_def] in build_symbol_table symbol_table ast; let ctx = create_type_context () in let _ = type_check_multi_program ctx ast in let ir_ctx = create_context symbol_table in let ir_program = lower_single_program ir_ctx prog_def [] in let c_code = generate_c_program ir_program in (* Verify all parameters are used correctly *) assert_bool "Should use parameter 'a'" (String.contains c_code 'a'); assert_bool "Should use parameter 'b'" (String.contains c_code 'b'); assert_bool "Should use parameter 'c'" (String.contains c_code 'c'); assert_bool "Function signature should be correct" (Str.string_match (Str.regexp ".*__u32 add_three(__u32 a, __u32 b, __u32 c).*") c_code 0) let suite = "Function Generation Tests" >::: [ "test_function_parameters" >:: test_function_parameters; "test_program_function_calls" >:: test_program_function_calls; "test_multiple_parameters" >:: test_multiple_parameters; ] let () = run_test_tt_main suite

Back | FazBrowse Home | New Git URL