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. *) open Alcotest open Kernelscript.Ast open Kernelscript.Type_checker open Kernelscript.Ir_generator open Kernelscript.Ebpf_c_codegen open Kernelscript.Ir (** Helper functions *) let dummy_pos = { line = 1; column = 1; filename = "test_struct_init.ks" } let parse_string s = let lexbuf = Lexing.from_string s in Kernelscript.Parser.program Kernelscript.Lexer.token lexbuf (** 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 (** Helper to generate IR and C code from program text *) let generate_c_from_program program_text program_name = (* Initialize context codegens first *) Kernelscript_context.Xdp_codegen.register (); Kernelscript_context.Tc_codegen.register (); let ast = parse_string program_text in let symbol_table = Test_utils.Helpers.create_test_symbol_table ast in let (annotated_ast, _) = type_check_and_annotate_ast ~symbol_table:(Some symbol_table) ast in let ir_multi_prog = generate_ir annotated_ast symbol_table program_name in (* Generate C code *) let c_code = generate_c_multi_program ir_multi_prog in c_code (** Test 1: Basic struct initialization with simple types *) let test_basic_struct_initialization () = let program_text = {| struct PacketInfo { size: u64, action: u32, } @xdp fn packet_filter(ctx: *xdp_md) -> xdp_action { var packet_size = ctx->data_end - ctx->data var info = PacketInfo { size: packet_size, action: 2, } if (info.size > 1500) { return 1 } return info.action } fn main() -> i32 { return 0 } |} in try let c_code = generate_c_from_program program_text "packet_filter" in (* Verify struct definition is generated *) check bool "struct definition generated" true (contains_substr c_code "struct PacketInfo"); check bool "size field defined" true (contains_substr c_code "__u64 size"); check bool "action field defined" true (contains_substr c_code "__u32 action"); (* Verify struct initialization syntax *) check bool "struct literal assignment found" true (contains_substr c_code "(struct PacketInfo){"); check bool "field initialization syntax" true (contains_substr c_code ".size ="); check bool "action field initialization" true (contains_substr c_code ".action = 2"); (* Verify field access works *) check bool "field access generated" true (contains_substr c_code ".size"); check bool "return field access" true (contains_substr c_code ".action") with | exn -> fail ("Basic struct initialization test failed: " ^ Printexc.to_string exn) (** Test 2: Struct initialization with different data types *) let test_struct_with_different_types () = let program_text = {| struct ConfigData { mode: u64, flags: u32, } @xdp fn config_filter(ctx: *xdp_md) -> xdp_action { var packet_size = ctx->data_end - ctx->data var info = ConfigData { mode: packet_size, flags: 42, } if (info.mode > 1500) { return 1 } return info.flags } fn main() -> i32 { return 0 } |} in try let c_code = generate_c_from_program program_text "config_filter" in (* Verify all data types are correctly generated *) check bool "struct ConfigData defined" true (contains_substr c_code "struct ConfigData"); check bool "u64 mode field defined" true (contains_substr c_code "__u64 mode"); check bool "u32 flags field defined" true (contains_substr c_code "__u32 flags"); (* Verify struct initialization syntax *) check bool "struct literal syntax" true (contains_substr c_code "(struct ConfigData){"); check bool "flags literal assignment" true (contains_substr c_code ".flags = 42") with | exn -> fail ("Different types struct test failed: " ^ Printexc.to_string exn) (** Test 3: Struct initialization with variables *) let test_struct_initialization_with_variables () = let program_text = {| struct VariableTest { size: u64, action: u32, } @xdp fn variable_test(ctx: *xdp_md) -> xdp_action { var packet_size = ctx->data_end - ctx->data var info = VariableTest { size: packet_size, action: 3, } if (info.size > 1500) { return 1 } return info.action } fn main() -> i32 { return 0 } |} in try let c_code = generate_c_from_program program_text "variable_test" in (* Verify struct definition *) check bool "VariableTest struct defined" true (contains_substr c_code "struct VariableTest"); check bool "__u64 size field" true (contains_substr c_code "__u64 size"); check bool "__u32 action field" true (contains_substr c_code "__u32 action"); (* Verify struct compound literal syntax *) check bool "compound literal syntax" true (contains_substr c_code "(struct VariableTest){"); check bool "literal field assignment" true (contains_substr c_code ".action = 3") with | exn -> fail ("Variable struct initialization test failed: " ^ Printexc.to_string exn) (** Test 4: Multiple struct definitions and initializations *) let test_multiple_struct_definitions () = let program_text = {| struct Header { version: u8, flags: u8, } struct Payload { size: u32, data_type: u16, } @xdp fn multi_struct(ctx: *xdp_md) -> xdp_action { var hdr = Header { version: 1, flags: 0, } var payload = Payload { size: 1024, data_type: 42, } if (hdr.version == 1 && payload.size > 0) { return 2 } return 1 } fn main() -> i32 { return 0 } |} in try let c_code = generate_c_from_program program_text "multi_struct" in (* Verify both struct definitions are generated *) check bool "Header struct defined" true (contains_substr c_code "struct Header"); check bool "Payload struct defined" true (contains_substr c_code "struct Payload"); (* Verify both struct initializations *) check bool "Header initialization" true (contains_substr c_code "(struct Header){"); check bool "Payload initialization" true (contains_substr c_code "(struct Payload){"); (* Verify field assignments for both structs *) check bool "Header version assignment" true (contains_substr c_code ".version = 1"); check bool "Header flags assignment" true (contains_substr c_code ".flags = 0"); check bool "Payload size assignment" true (contains_substr c_code ".size = 1024"); check bool "Payload data_type assignment" true (contains_substr c_code ".data_type = 42") with | exn -> fail ("Multiple struct definitions test failed: " ^ Printexc.to_string exn) (** Test 5: Nested struct usage (assignment and field access) *) let test_nested_struct_usage () = let program_text = {| struct FieldTest { size: u64, action: u32, } @xdp fn field_test(ctx: *xdp_md) -> xdp_action { var packet_size = ctx->data_end - ctx->data var info = FieldTest { size: packet_size, action: 4, } if (info.size > 1500) { return 1 } return info.action } fn main() -> i32 { return 0 } |} in try let c_code = generate_c_from_program program_text "field_test" in (* Verify struct definition *) check bool "FieldTest struct defined" true (contains_substr c_code "struct FieldTest"); check bool "__u64 size field" true (contains_substr c_code "__u64 size"); check bool "__u32 action field" true (contains_substr c_code "__u32 action"); (* Verify struct initialization *) check bool "struct literal syntax" true (contains_substr c_code "(struct FieldTest){"); check bool "field initialization" true (contains_substr c_code ".action = 4") with | exn -> fail ("Nested struct usage test failed: " ^ Printexc.to_string exn) (** Test 6: IR generation verification for struct literals *) let test_ir_struct_literal_generation () = let program_text = {| struct TestStruct { field1: u32, field2: u64, } @xdp fn test_ir(ctx: *xdp_md) -> xdp_action { var test_obj = TestStruct { field1: 42, field2: 1000, } return test_obj.field1 } 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, _) = type_check_and_annotate_ast ~symbol_table:(Some symbol_table) ast in let ir_multi_prog = generate_ir annotated_ast symbol_table "test_ir" in (* Extract the main function from IR *) let test_program = List.find (fun prog -> prog.name = "test_ir") (get_programs ir_multi_prog) in let main_func = test_program.entry_function in (* Look for IRStructLiteral in the instructions *) let has_struct_literal = ref false in let check_instruction instr = match instr.instr_desc with | IRAssign (_, expr) -> (match expr.expr_desc with | IRStructLiteral (struct_name, _) -> if struct_name = "TestStruct" then has_struct_literal := true | _ -> ()) | IRVariableDecl (_, _, Some expr) -> (match expr.expr_desc with | IRStructLiteral (struct_name, _) -> if struct_name = "TestStruct" then has_struct_literal := true | _ -> ()) | _ -> () in List.iter (fun block -> List.iter check_instruction block.instructions ) main_func.basic_blocks; check bool "IRStructLiteral generated in IR" true !has_struct_literal with | exn -> fail ("IR struct literal generation test failed: " ^ Printexc.to_string exn) (** Test 7: Struct initialization in function parameters and returns *) let test_struct_as_function_parameter () = let program_text = {| struct Parameter { size: u64, action: u32, } @xdp fn param_test(ctx: *xdp_md) -> xdp_action { var packet_size = ctx->data_end - ctx->data var info = Parameter { size: packet_size, action: 5, } if (info.size > 1500) { return 1 } return info.action } fn main() -> i32 { return 0 } |} in try let c_code = generate_c_from_program program_text "param_test" in (* Verify struct definition *) check bool "Parameter struct defined" true (contains_substr c_code "struct Parameter"); check bool "__u64 size field" true (contains_substr c_code "__u64 size"); check bool "__u32 action field" true (contains_substr c_code "__u32 action"); (* Verify struct initialization and field access *) check bool "struct initialization" true (contains_substr c_code "(struct Parameter){"); check bool "action field assignment" true (contains_substr c_code ".action = 5") with | exn -> fail ("Struct as function parameter test failed: " ^ Printexc.to_string exn) (** All struct initialization tests *) let tests = [ "test_basic_struct_initialization", `Quick, test_basic_struct_initialization; "test_multiple_struct_definitions", `Quick, test_multiple_struct_definitions; "test_ir_struct_literal_generation", `Quick, test_ir_struct_literal_generation; ] let () = Alcotest.run "Struct Initialization Tests" [ "struct_initialization", tests ]

Back | FazBrowse Home | New Git URL