mirror of
https://github.com/microsoft/regorus.git
synced 2026-08-05 02:16:11 +00:00
* feat!: add Rego Virtual Machine (RVM) implementation This commit introduces a register-based virtual machine for executing Rego policies with bytecode-style instructions. Unlike the existing tree-walking interpreter, the RVM compiles policies into instruction sequences that operate on virtual registers, offering better performance and optimization potential. Core Components: Instruction Set Architecture: - Define instruction types for data operations, control flow, and builtins - Implement instruction parameter encoding and display formatting - Add instruction parser with comprehensive test coverage Virtual Machine Engine: - Register-based execution model with program counter management - Loop execution supporting iterators, comprehensions, and quantifiers - Function call handling with argument evaluation and context management - Rule evaluation with default value resolution and virtual data support - Arithmetic and comparison operation implementations Program Representation: - Program listing builder with instruction sequencing - Rule tree construction for organizing policy rules - Binary and JSON serialization for compiled programs - Recompilation support for program modification Testing Infrastructure: - Extensive YAML test suites covering all VM features - Rust unit tests for VM execution and instruction parsing - Test suites for loops, comprehensions, builtins, and control flow BREAKING CHANGE: Introduces new VM execution path alongside interpreter Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com> * docs: add detailed RVM architecture references Introduce architecture.md explaining program artifacts, serialization, and runtime subsystems. Document the full opcode catalog in instruction-set.md, including operands, parameter tables, and outcomes. Walk through execution flow, stacks, and operational guidance in vm-runtime.md, tying the runtime to the new architecture docs. Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com> --------- Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
278 lines
13 KiB
YAML
278 lines
13 KiB
YAML
# Copyright (c) Microsoft Corporation.
|
|
# Licensed under the MIT License.
|
|
|
|
# Default Rules Infrastructure Test Suite
|
|
# Tests the VM infrastructure support for default rule evaluation
|
|
# These tests verify that the VM can properly handle complete rules with default fallbacks
|
|
|
|
cases:
|
|
- note: vm_default_rule_boolean_false
|
|
description: Test VM default rule evaluation with boolean false value
|
|
example_rego: "default allow := false; allow := true if { false }"
|
|
literals:
|
|
- false
|
|
- true
|
|
rule_infos:
|
|
- rule_type: "Complete"
|
|
definitions: [[2]] # Rule definition starts at instruction 2
|
|
default_literal_index: 0 # Points to literal index 0 (false)
|
|
instructions:
|
|
- "CallRule { dest: 0, rule_index: 0 }" # Call the complete rule
|
|
- "Return { value: 0 }" # Return result
|
|
- "RuleInit { result_reg: 1, rule_index: 0 }" # Initialize rule execution
|
|
- "Load { dest: 2, literal_idx: 0 }" # Load false condition
|
|
- "AssertCondition { condition: 2 }" # Assert condition (will fail)
|
|
- "Load { dest: 3, literal_idx: 1 }" # Load true result
|
|
- "Move { dest: 1, src: 3 }" # Move result to result register
|
|
- "RuleReturn" # Return from rule
|
|
want_result: false # Should return default value when condition fails
|
|
|
|
- note: vm_default_rule_boolean_true
|
|
description: Test VM default rule evaluation with boolean true value
|
|
example_rego: "default enabled := true; enabled := false if { false }"
|
|
literals:
|
|
- true
|
|
- false
|
|
rule_infos:
|
|
- rule_type: "Complete"
|
|
definitions: [[2]] # Rule definition starts at instruction 2
|
|
default_literal_index: 0 # Points to literal index 0 (true)
|
|
instructions:
|
|
- "CallRule { dest: 0, rule_index: 0 }" # Call the complete rule
|
|
- "Return { value: 0 }" # Return result
|
|
- "RuleInit { result_reg: 1, rule_index: 0 }" # Initialize rule execution
|
|
- "Load { dest: 2, literal_idx: 1 }" # Load false condition
|
|
- "AssertCondition { condition: 2 }" # Assert condition (will fail)
|
|
- "Load { dest: 3, literal_idx: 1 }" # Load false result
|
|
- "Move { dest: 1, src: 3 }" # Move result to result register
|
|
- "RuleReturn" # Return from rule
|
|
want_result: true # Should return default value when condition fails
|
|
|
|
- note: vm_default_rule_string_value
|
|
description: Test VM default rule evaluation with string value
|
|
example_rego: "default message := \"default\"; message := \"success\" if { false }"
|
|
literals:
|
|
- "default"
|
|
- "success"
|
|
- false
|
|
rule_infos:
|
|
- rule_type: "Complete"
|
|
definitions: [[2]] # Rule definition starts at instruction 2
|
|
default_literal_index: 0 # Points to literal index 0 ("default")
|
|
instructions:
|
|
- "CallRule { dest: 0, rule_index: 0 }" # Call the complete rule
|
|
- "Return { value: 0 }" # Return result
|
|
- "RuleInit { result_reg: 1, rule_index: 0 }" # Initialize rule execution
|
|
- "Load { dest: 2, literal_idx: 2 }" # Load false condition
|
|
- "AssertCondition { condition: 2 }" # Assert condition (will fail)
|
|
- "Load { dest: 3, literal_idx: 1 }" # Load success result
|
|
- "Move { dest: 1, src: 3 }" # Move result to result register
|
|
- "RuleReturn" # Return from rule
|
|
want_result: "default" # Should return default value when condition fails
|
|
|
|
- note: vm_default_rule_number_value
|
|
description: Test VM default rule evaluation with numeric value
|
|
example_rego: "default count := 0; count := 10 if { false }"
|
|
literals:
|
|
- 0
|
|
- 10
|
|
- false
|
|
rule_infos:
|
|
- rule_type: "Complete"
|
|
definitions: [[2]] # Rule definition starts at instruction 2
|
|
default_literal_index: 0 # Points to literal index 0 (0)
|
|
instructions:
|
|
- "CallRule { dest: 0, rule_index: 0 }" # Call the complete rule
|
|
- "Return { value: 0 }" # Return result
|
|
- "RuleInit { result_reg: 1, rule_index: 0 }" # Initialize rule execution
|
|
- "Load { dest: 2, literal_idx: 2 }" # Load false condition
|
|
- "AssertCondition { condition: 2 }" # Assert condition (will fail)
|
|
- "Load { dest: 3, literal_idx: 1 }" # Load 10 result
|
|
- "Move { dest: 1, src: 3 }" # Move result to result register
|
|
- "RuleReturn" # Return from rule
|
|
want_result: 0 # Should return default value when condition fails
|
|
|
|
- note: vm_default_rule_array_value
|
|
description: Test VM default rule evaluation with array value
|
|
example_rego: "default items := [\"default\"]; items := [\"success\"] if { false }"
|
|
literals:
|
|
- ["default"]
|
|
- ["success"]
|
|
- false
|
|
rule_infos:
|
|
- rule_type: "Complete"
|
|
definitions: [[2]] # Rule definition starts at instruction 2
|
|
default_literal_index: 0 # Points to literal index 0 (["default"])
|
|
instructions:
|
|
- "CallRule { dest: 0, rule_index: 0 }" # Call the complete rule
|
|
- "Return { value: 0 }" # Return result
|
|
- "RuleInit { result_reg: 1, rule_index: 0 }" # Initialize rule execution
|
|
- "Load { dest: 2, literal_idx: 2 }" # Load false condition
|
|
- "AssertCondition { condition: 2 }" # Assert condition (will fail)
|
|
- "Load { dest: 3, literal_idx: 1 }" # Load success array
|
|
- "Move { dest: 1, src: 3 }" # Move result to result register
|
|
- "RuleReturn" # Return from rule
|
|
want_result: ["default"] # Should return default value when condition fails
|
|
|
|
- note: vm_default_rule_object_value
|
|
description: Test VM default rule evaluation with object value
|
|
example_rego: "default config := {\"mode\": \"safe\"}; config := {\"mode\": \"fast\"} if { false }"
|
|
literals:
|
|
- {"mode": "safe"}
|
|
- {"mode": "fast"}
|
|
- false
|
|
rule_infos:
|
|
- rule_type: "Complete"
|
|
definitions: [[2]] # Rule definition starts at instruction 2
|
|
default_literal_index: 0 # Points to literal index 0 ({"mode": "safe"})
|
|
instructions:
|
|
- "CallRule { dest: 0, rule_index: 0 }" # Call the complete rule
|
|
- "Return { value: 0 }" # Return result
|
|
- "RuleInit { result_reg: 1, rule_index: 0 }" # Initialize rule execution
|
|
- "Load { dest: 2, literal_idx: 2 }" # Load false condition
|
|
- "AssertCondition { condition: 2 }" # Assert condition (will fail)
|
|
- "Load { dest: 3, literal_idx: 1 }" # Load fast config
|
|
- "Move { dest: 1, src: 3 }" # Move result to result register
|
|
- "RuleReturn" # Return from rule
|
|
want_result:
|
|
mode: "safe" # Should return default value when condition fails
|
|
|
|
- note: vm_default_rule_null_value
|
|
description: Test VM default rule evaluation with null value
|
|
example_rego: "default optional := null; optional := \"value\" if { false }"
|
|
literals:
|
|
- null
|
|
- "value"
|
|
- false
|
|
rule_infos:
|
|
- rule_type: "Complete"
|
|
definitions: [[2]] # Rule definition starts at instruction 2
|
|
default_literal_index: 0 # Points to literal index 0 (null)
|
|
instructions:
|
|
- "CallRule { dest: 0, rule_index: 0 }" # Call the complete rule
|
|
- "Return { value: 0 }" # Return result
|
|
- "RuleInit { result_reg: 1, rule_index: 0 }" # Initialize rule execution
|
|
- "Load { dest: 2, literal_idx: 2 }" # Load false condition
|
|
- "AssertCondition { condition: 2 }" # Assert condition (will fail)
|
|
- "Load { dest: 3, literal_idx: 1 }" # Load string value
|
|
- "Move { dest: 1, src: 3 }" # Move result to result register
|
|
- "RuleReturn" # Return from rule
|
|
want_result: null # Should return default value when condition fails
|
|
|
|
- note: vm_default_rule_multiple_definitions_fail
|
|
description: Test VM default rule when multiple definitions all fail
|
|
example_rego: "default result := \"fallback\"; result := \"first\" if { false }; result := \"second\" if { false }"
|
|
literals:
|
|
- "fallback"
|
|
- "first"
|
|
- "second"
|
|
- false
|
|
rule_infos:
|
|
- rule_type: "Complete"
|
|
definitions: [[2], [7]] # Two rule definitions
|
|
default_literal_index: 0 # Points to literal index 0 ("fallback")
|
|
instructions:
|
|
- "CallRule { dest: 0, rule_index: 0 }" # Call the complete rule
|
|
- "Return { value: 0 }" # Return result
|
|
# First definition
|
|
- "RuleInit { result_reg: 1, rule_index: 0 }" # Initialize rule execution
|
|
- "Load { dest: 2, literal_idx: 3 }" # Load false condition
|
|
- "AssertCondition { condition: 2 }" # Assert condition (will fail)
|
|
- "Load { dest: 3, literal_idx: 1 }" # Load first result
|
|
- "Move { dest: 1, src: 3 }" # Move result to result register
|
|
- "RuleReturn" # Return from rule
|
|
# Second definition
|
|
- "RuleInit { result_reg: 1, rule_index: 0 }" # Initialize rule execution
|
|
- "Load { dest: 4, literal_idx: 3 }" # Load false condition
|
|
- "AssertCondition { condition: 4 }" # Assert condition (will fail)
|
|
- "Load { dest: 5, literal_idx: 2 }" # Load second result
|
|
- "Move { dest: 1, src: 5 }" # Move result to result register
|
|
- "RuleReturn" # Return from rule
|
|
want_result: "fallback" # Should return default value when all definitions fail
|
|
|
|
- note: vm_default_rule_successful_condition
|
|
description: Test VM rule evaluation when condition succeeds (should not use default)
|
|
example_rego: "default allow := false; allow := true if { true }"
|
|
literals:
|
|
- false
|
|
- true
|
|
rule_infos:
|
|
- rule_type: "Complete"
|
|
definitions: [[2]] # Rule definition starts at instruction 2
|
|
default_literal_index: 0 # Points to literal index 0 (false) - should not be used
|
|
instructions:
|
|
- "CallRule { dest: 0, rule_index: 0 }" # Call the complete rule
|
|
- "Return { value: 0 }" # Return result
|
|
- "RuleInit { result_reg: 1, rule_index: 0 }" # Initialize rule execution
|
|
- "Load { dest: 2, literal_idx: 1 }" # Load true condition
|
|
- "AssertCondition { condition: 2 }" # Assert condition (will succeed)
|
|
- "Load { dest: 3, literal_idx: 1 }" # Load true result
|
|
- "Move { dest: 1, src: 3 }" # Move result to result register
|
|
- "RuleReturn" # Return from rule
|
|
want_result: true # Should return successful rule result, not default
|
|
|
|
- note: vm_default_rule_complex_object
|
|
description: Test VM default rule with complex nested object
|
|
example_rego: "default settings := complex_default; settings := complex_success if { false }"
|
|
literals:
|
|
- {
|
|
"timeout": 30,
|
|
"retries": 3,
|
|
"features": {
|
|
"logging": true,
|
|
"monitoring": false
|
|
},
|
|
"endpoints": ["api1", "api2"]
|
|
}
|
|
- {
|
|
"timeout": 60,
|
|
"retries": 5,
|
|
"features": {
|
|
"logging": false,
|
|
"monitoring": true
|
|
},
|
|
"endpoints": ["api3", "api4"]
|
|
}
|
|
- false
|
|
rule_infos:
|
|
- rule_type: "Complete"
|
|
definitions: [[2]] # Rule definition starts at instruction 2
|
|
default_literal_index: 0 # Points to literal index 0 (complex default object)
|
|
instructions:
|
|
- "CallRule { dest: 0, rule_index: 0 }" # Call the complete rule
|
|
- "Return { value: 0 }" # Return result
|
|
- "RuleInit { result_reg: 1, rule_index: 0 }" # Initialize rule execution
|
|
- "Load { dest: 2, literal_idx: 2 }" # Load false condition
|
|
- "AssertCondition { condition: 2 }" # Assert condition (will fail)
|
|
- "Load { dest: 3, literal_idx: 1 }" # Load success object
|
|
- "Move { dest: 1, src: 3 }" # Move result to result register
|
|
- "RuleReturn" # Return from rule
|
|
want_result:
|
|
timeout: 30
|
|
retries: 3
|
|
features:
|
|
logging: true
|
|
monitoring: false
|
|
endpoints: ["api1", "api2"] # Should return default complex object
|
|
|
|
- note: vm_no_default_rule_undefined
|
|
description: Test VM rule without default returns undefined when definition fails
|
|
example_rego: "allow := true if { false } # No default rule"
|
|
literals:
|
|
- true
|
|
- false
|
|
rule_infos:
|
|
- rule_type: "Complete"
|
|
definitions: [[2]] # Rule definition starts at instruction 2
|
|
# No default_literal_index - should return undefined
|
|
instructions:
|
|
- "CallRule { dest: 0, rule_index: 0 }" # Call the complete rule
|
|
- "Return { value: 0 }" # Return result
|
|
- "RuleInit { result_reg: 1, rule_index: 0 }" # Initialize rule execution
|
|
- "Load { dest: 2, literal_idx: 1 }" # Load false condition
|
|
- "AssertCondition { condition: 2 }" # Assert condition (will fail)
|
|
- "Load { dest: 3, literal_idx: 0 }" # Load true result
|
|
- "Move { dest: 1, src: 3 }" # Move result to result register
|
|
- "RuleReturn" # Return from rule
|
|
want_result: "#undefined" # Should return undefined when no default and definition fails
|