Skip to main content

flux_vm_tests/
lib.rs

1//! Certification test vectors for the FLUX constraint enforcement VM.
2
3/// FLUX bytecode opcodes
4pub mod opcodes {
5    pub const PUSH: u8 = 0x00;
6    pub const POP: u8 = 0x01;
7    pub const ADD: u8 = 0x06;
8    pub const SUB: u8 = 0x07;
9    pub const MUL: u8 = 0x08;
10    pub const AND: u8 = 0x09;
11    pub const OR: u8 = 0x0A;
12    pub const XOR: u8 = 0x0B;
13    pub const NOT: u8 = 0x0C;
14    pub const EQ: u8 = 0x0F;
15    pub const NEQ: u8 = 0x10;
16    pub const LT: u8 = 0x11;
17    pub const GT: u8 = 0x12;
18    pub const JUMP: u8 = 0x15;
19    pub const JZ: u8 = 0x16;
20    pub const HALT: u8 = 0x1A;
21    pub const ASSERT: u8 = 0x1B;
22    pub const GUARD_TRAP: u8 = 0x20;
23    pub const NOP: u8 = 0x27;
24}
25
26/// Certification test vector: bytecode + expected result
27pub struct TestVector {
28    pub name: &'static str,
29    pub bytecode: &'static [u8],
30    pub expected_stack_top: u8,
31    pub should_halt: bool,
32    pub category: &'static str,
33}
34
35/// All 15 certification test vectors
36pub fn all_vectors() -> Vec<TestVector> {
37    use opcodes::*;
38    vec![
39        TestVector { name: "identity", bytecode: &[PUSH, 42, HALT], expected_stack_top: 42, should_halt: true, category: "basic" },
40        TestVector { name: "add_3_4", bytecode: &[PUSH, 3, PUSH, 4, ADD, HALT], expected_stack_top: 7, should_halt: true, category: "arithmetic" },
41        TestVector { name: "mul_6_7", bytecode: &[PUSH, 6, PUSH, 7, MUL, HALT], expected_stack_top: 42, should_halt: true, category: "arithmetic" },
42        TestVector { name: "sub_10_3", bytecode: &[PUSH, 10, PUSH, 3, SUB, HALT], expected_stack_top: 7, should_halt: true, category: "arithmetic" },
43        TestVector { name: "and_mask", bytecode: &[PUSH, 0xFF, PUSH, 0x0F, AND, HALT], expected_stack_top: 0x0F, should_halt: true, category: "bitwise" },
44        TestVector { name: "or_combine", bytecode: &[PUSH, 0xF0, PUSH, 0x0F, OR, HALT], expected_stack_top: 0xFF, should_halt: true, category: "bitwise" },
45        TestVector { name: "xor_toggle", bytecode: &[PUSH, 0xAA, PUSH, 0x55, XOR, HALT], expected_stack_top: 0xFF, should_halt: true, category: "bitwise" },
46        TestVector { name: "not_invert", bytecode: &[PUSH, 0x00, NOT, HALT], expected_stack_top: 0xFF, should_halt: true, category: "bitwise" },
47        TestVector { name: "eq_same", bytecode: &[PUSH, 7, PUSH, 7, EQ, HALT], expected_stack_top: 1, should_halt: true, category: "comparison" },
48        TestVector { name: "neq_diff", bytecode: &[PUSH, 3, PUSH, 5, NEQ, HALT], expected_stack_top: 1, should_halt: true, category: "comparison" },
49        TestVector { name: "lt_check", bytecode: &[PUSH, 3, PUSH, 5, LT, HALT], expected_stack_top: 1, should_halt: true, category: "comparison" },
50        TestVector { name: "gt_check", bytecode: &[PUSH, 5, PUSH, 3, GT, HALT], expected_stack_top: 1, should_halt: true, category: "comparison" },
51        TestVector { name: "jz_skip", bytecode: &[PUSH, 0, JZ, 7, PUSH, 99, HALT, PUSH, 42, HALT], expected_stack_top: 42, should_halt: true, category: "control_flow" },
52        TestVector { name: "assert_pass", bytecode: &[PUSH, 1, ASSERT, PUSH, 77, HALT], expected_stack_top: 77, should_halt: true, category: "safety" },
53        TestVector { name: "nops", bytecode: &[NOP, NOP, PUSH, 13, HALT], expected_stack_top: 13, should_halt: true, category: "basic" },
54    ]
55}
56
57#[cfg(test)]
58mod tests {
59    use super::*;
60    use flux_vm::FluxVM;
61
62    #[test]
63    fn run_all_vectors() {
64        for tv in all_vectors() {
65            let mut vm = FluxVM::new(100);
66            let result = vm.execute(tv.bytecode, 100);
67            assert!(result.is_ok(), "Test '{}' failed: {:?}", tv.name, result);
68            assert_eq!(tv.should_halt, vm.is_halted(), "Test '{}' halt mismatch", tv.name);
69            if tv.should_halt {
70                assert_eq!(Some(tv.expected_stack_top), vm.stack_top(), "Test '{}' stack top mismatch", tv.name);
71            }
72        }
73    }
74}