# Copyright (c) Microsoft Corporation. # Licensed under the MIT License. # Serialization Test Suite # Tests round-trip serialization of compiled RVM programs # Covers all instruction types, large programs, and edge cases cases: - note: serialization_basic_arithmetic description: Serialize and deserialize simple arithmetic program example_rego: "5 + 3" literals: - 5 - 3 instructions: - "Load { dest: 0, literal_idx: 0 }" - "Load { dest: 1, literal_idx: 1 }" - "Add { dest: 2, left: 0, right: 1 }" - "Return { value: 2 }" want_result: 8 - note: serialization_comparisons description: Serialize comparison instructions example_rego: "10 > 5 && 3 < 7" literals: - 10 - 5 - 3 - 7 instructions: - "Load { dest: 0, literal_idx: 0 }" - "Load { dest: 1, literal_idx: 1 }" - "Gt { dest: 2, left: 0, right: 1 }" - "Load { dest: 3, literal_idx: 2 }" - "Load { dest: 4, literal_idx: 3 }" - "Lt { dest: 5, left: 3, right: 4 }" - "And { dest: 6, left: 2, right: 5 }" - "Return { value: 6 }" want_result: true - note: serialization_array_create description: Serialize ArrayCreate with instruction_params example_rego: "[1, 2, 3]" literals: - 1 - 2 - 3 instruction_params: array_create_params: - dest: 0 elements: [1, 2, 3] instructions: - "Load { dest: 1, literal_idx: 0 }" - "Load { dest: 2, literal_idx: 1 }" - "Load { dest: 3, literal_idx: 2 }" - "ArrayCreate { params_index: 0 }" - "Return { value: 0 }" want_result: [1, 2, 3] - note: serialization_object_create description: Serialize ObjectCreate with complex params example_rego: "{\"a\": 1, \"b\": 2}" literals: - "a" - 1 - "b" - 2 - {} instruction_params: object_create_params: - dest: 0 template_literal_idx: 4 literal_key_fields: [] fields: - [1, 2] - [3, 4] instructions: - "Load { dest: 1, literal_idx: 0 }" - "Load { dest: 2, literal_idx: 1 }" - "Load { dest: 3, literal_idx: 2 }" - "Load { dest: 4, literal_idx: 3 }" - "ObjectCreate { params_index: 0 }" - "Return { value: 0 }" want_result: {"a": 1, "b": 2} - note: serialization_set_operations description: Serialize set creation and operations example_rego: "{1, 2, 3}" literals: - 1 - 2 - 3 instructions: - "SetNew { dest: 0 }" - "Load { dest: 1, literal_idx: 0 }" - "SetAdd { set: 0, value: 1 }" - "Load { dest: 2, literal_idx: 1 }" - "SetAdd { set: 0, value: 2 }" - "Load { dest: 3, literal_idx: 2 }" - "SetAdd { set: 0, value: 3 }" - "Return { value: 0 }" want_result: set!: - 1 - 2 - 3 - note: serialization_loop_foreach description: Serialize ForEach loop with params example_rego: "[x | x = [1, 2, 3][_]]" literals: - 1 - 2 - 3 instruction_params: array_create_params: - dest: 0 elements: [1, 2, 3] loop_params: - mode: "ForEach" collection: 0 key_reg: 4 value_reg: 5 result_reg: 9 body_start: 6 loop_end: 8 instructions: - "Load { dest: 1, literal_idx: 0 }" - "Load { dest: 2, literal_idx: 1 }" - "Load { dest: 3, literal_idx: 2 }" - "ArrayCreate { params_index: 0 }" - "ArrayNew { dest: 6 }" - "LoopStart { params_index: 0 }" - "ArrayPush { arr: 6, value: 5 }" - "LoopNext { body_start: 6, loop_end: 8 }" - "Return { value: 6 }" want_result: [1, 2, 3] - note: serialization_loop_any description: Serialize Any loop example_rego: "some x in [1, 2, 3]; x > 2" literals: - 1 - 2 - 3 instruction_params: array_create_params: - dest: 0 elements: [1, 2, 3] loop_params: - mode: "Existential" collection: 0 key_reg: 4 value_reg: 5 result_reg: 6 body_start: 5 loop_end: 8 instructions: - "Load { dest: 1, literal_idx: 0 }" - "Load { dest: 2, literal_idx: 1 }" - "Load { dest: 3, literal_idx: 2 }" - "ArrayCreate { params_index: 0 }" - "LoopStart { params_index: 0 }" - "Gt { dest: 8, left: 5, right: 2 }" - "AssertCondition { condition: 8 }" - "LoopNext { body_start: 5, loop_end: 8 }" - "Return { value: 6 }" want_result: true - note: serialization_comprehension_array description: Serialize array comprehension example_rego: "[x * 2 | x = [1, 2, 3][_]]" literals: - 1 - 2 - 3 instruction_params: array_create_params: - dest: 0 elements: [1, 2, 3] loop_params: - mode: "ForEach" collection: 0 key_reg: 4 value_reg: 5 result_reg: 9 body_start: 6 loop_end: 9 instructions: - "Load { dest: 1, literal_idx: 0 }" - "Load { dest: 2, literal_idx: 1 }" - "Load { dest: 3, literal_idx: 2 }" - "ArrayCreate { params_index: 0 }" - "ArrayNew { dest: 7 }" - "LoopStart { params_index: 0 }" - "Mul { dest: 6, left: 5, right: 2 }" - "ArrayPush { arr: 7, value: 6 }" - "LoopNext { body_start: 6, loop_end: 9 }" - "Return { value: 7 }" want_result: [2, 4, 6] - note: serialization_indexed_access description: Serialize indexing instructions example_rego: "data.users[0].name" literals: - {"users": [{"name": "Alice"}, {"name": "Bob"}]} - "users" - 0 - "name" instruction_params: chained_index_params: - dest: 4 root: 0 path_components: - literal_idx: 1 - literal_idx: 2 - literal_idx: 3 instructions: - "Load { dest: 0, literal_idx: 0 }" - "Load { dest: 1, literal_idx: 1 }" - "Load { dest: 2, literal_idx: 2 }" - "Load { dest: 3, literal_idx: 3 }" - "ChainedIndex { params_index: 0 }" - "Return { value: 4 }" want_result: "Alice" - note: serialization_conditional_branching description: Serialize conditional instructions example_rego: "if true then 1 else 2" literals: - 1 - 2 instructions: - "LoadTrue { dest: 0 }" - "AssertCondition { condition: 0 }" - "Load { dest: 1, literal_idx: 0 }" - "Return { value: 1 }" want_result: 1 - note: serialization_null_and_undefined description: Serialize null and undefined handling example_rego: "null" literals: [] instructions: - "LoadNull { dest: 0 }" - "Return { value: 0 }" want_result: null - note: serialization_mixed_types description: Serialize program with all value types example_rego: "[1, \"text\", true, false, null, [2, 3], {\"k\": \"v\"}]" literals: - 1 - "text" - 2 - 3 - "k" - "v" - {} instruction_params: array_create_params: - dest: 6 elements: [3, 4] - dest: 0 elements: [1, 2, 7, 8, 9, 6, 10] object_create_params: - dest: 10 template_literal_idx: 6 literal_key_fields: [] fields: - [5, 11] instructions: - "Load { dest: 1, literal_idx: 0 }" - "Load { dest: 2, literal_idx: 1 }" - "Load { dest: 3, literal_idx: 2 }" - "Load { dest: 4, literal_idx: 3 }" - "ArrayCreate { params_index: 0 }" - "LoadTrue { dest: 7 }" - "LoadFalse { dest: 8 }" - "LoadNull { dest: 9 }" - "Load { dest: 5, literal_idx: 4 }" - "Load { dest: 11, literal_idx: 5 }" - "ObjectCreate { params_index: 0 }" - "ArrayCreate { params_index: 1 }" - "Return { value: 0 }" want_result: [1, "text", true, false, null, [2, 3], {"k": "v"}] - note: serialization_large_program_50_instructions description: Large program with many instructions (stress test) example_rego: "Complex computation chain" literals: - 1 - 2 - 3 - 4 - 5 instructions: - "Load { dest: 0, literal_idx: 0 }" - "Load { dest: 1, literal_idx: 1 }" - "Add { dest: 2, left: 0, right: 1 }" - "Load { dest: 3, literal_idx: 2 }" - "Mul { dest: 4, left: 2, right: 3 }" - "Load { dest: 5, literal_idx: 3 }" - "Sub { dest: 6, left: 4, right: 5 }" - "Load { dest: 7, literal_idx: 4 }" - "Div { dest: 8, left: 6, right: 7 }" - "Load { dest: 9, literal_idx: 0 }" - "Add { dest: 10, left: 8, right: 9 }" - "Load { dest: 11, literal_idx: 1 }" - "Mul { dest: 12, left: 10, right: 11 }" - "Load { dest: 13, literal_idx: 2 }" - "Add { dest: 14, left: 12, right: 13 }" - "Load { dest: 15, literal_idx: 3 }" - "Sub { dest: 16, left: 14, right: 15 }" - "Load { dest: 17, literal_idx: 4 }" - "Mul { dest: 18, left: 16, right: 17 }" - "Load { dest: 19, literal_idx: 0 }" - "Div { dest: 20, left: 18, right: 19 }" - "Load { dest: 21, literal_idx: 1 }" - "Add { dest: 22, left: 20, right: 21 }" - "Load { dest: 23, literal_idx: 2 }" - "Mul { dest: 24, left: 22, right: 23 }" - "Load { dest: 25, literal_idx: 3 }" - "Sub { dest: 26, left: 24, right: 25 }" - "Load { dest: 27, literal_idx: 4 }" - "Add { dest: 28, left: 26, right: 27 }" - "Load { dest: 29, literal_idx: 0 }" - "Mul { dest: 30, left: 28, right: 29 }" - "Load { dest: 31, literal_idx: 1 }" - "Div { dest: 32, left: 30, right: 31 }" - "Load { dest: 33, literal_idx: 2 }" - "Add { dest: 34, left: 32, right: 33 }" - "Load { dest: 35, literal_idx: 3 }" - "Sub { dest: 36, left: 34, right: 35 }" - "Load { dest: 37, literal_idx: 4 }" - "Mul { dest: 38, left: 36, right: 37 }" - "Load { dest: 39, literal_idx: 0 }" - "Add { dest: 40, left: 38, right: 39 }" - "Load { dest: 41, literal_idx: 1 }" - "Sub { dest: 42, left: 40, right: 41 }" - "Load { dest: 43, literal_idx: 2 }" - "Mul { dest: 44, left: 42, right: 43 }" - "Load { dest: 45, literal_idx: 3 }" - "Div { dest: 46, left: 44, right: 45 }" - "Load { dest: 47, literal_idx: 4 }" - "Add { dest: 48, left: 46, right: 47 }" - "Return { value: 48 }" want_result: 98 - note: serialization_large_literal_table description: Program with many literal values literals: - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - "a" - "b" - "c" - "d" - "e" - [1, 2, 3] - {"key": "value"} - true - false - null instructions: - "Load { dest: 0, literal_idx: 0 }" - "Load { dest: 1, literal_idx: 5 }" - "Add { dest: 2, left: 0, right: 1 }" - "Load { dest: 3, literal_idx: 10 }" - "Load { dest: 4, literal_idx: 15 }" - "Return { value: 2 }" want_result: 7 - note: serialization_nested_structures description: Serialize deeply nested data structures example_rego: "[{\"a\": [1, {\"b\": [2, 3]}]}]" literals: - 1 - 2 - 3 - "b" - "a" - {} instruction_params: array_create_params: - dest: 3 elements: [2, 4] - dest: 1 elements: [5, 6] - dest: 0 elements: [7] object_create_params: - dest: 6 template_literal_idx: 5 literal_key_fields: [] fields: - [8, 3] - dest: 7 template_literal_idx: 5 literal_key_fields: [] fields: - [9, 1] instructions: - "Load { dest: 5, literal_idx: 0 }" - "Load { dest: 2, literal_idx: 1 }" - "Load { dest: 4, literal_idx: 2 }" - "ArrayCreate { params_index: 0 }" - "Load { dest: 8, literal_idx: 3 }" - "ObjectCreate { params_index: 0 }" - "ArrayCreate { params_index: 1 }" - "Load { dest: 9, literal_idx: 4 }" - "ObjectCreate { params_index: 1 }" - "ArrayCreate { params_index: 2 }" - "Return { value: 0 }" want_result: [{"a": [1, {"b": [2, 3]}]}]