1
#![allow(warnings)]
2
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
3

            
4
#[cfg(test)]
5
mod tests {
6
    use std::ffi::CString;
7

            
8
    use super::*;
9

            
10
    // solutions
11
    static mut X_VAL: i32 = 0;
12
    static mut Y_VAL: i32 = 0;
13
    static mut Z_VAL: i32 = 0;
14

            
15
    #[no_mangle]
16
    pub extern "C" fn hello_from_rust() -> bool {
17
        unsafe {
18
            X_VAL = printMatrix_getValue(0) as _;
19
            Y_VAL = printMatrix_getValue(1) as _;
20
            Z_VAL = printMatrix_getValue(2) as _;
21
            return true;
22
        }
23
    }
24

            
25
    #[test]
26
    fn xyz_raw() {
27
        // A simple constraints model, manually written using FFI functions.
28
        // Testing to see if it does not segfault.
29
        // Results can be manually inspected in the outputted minion logs.
30
        unsafe {
31
            // See https://rust-lang.github.io/rust-bindgen/cpp.html
32
            let options = searchOptions_new();
33
            let args = searchMethod_new();
34
            let instance = instance_new();
35

            
36
            let x_str = CString::new("x").expect("bad x");
37
            let y_str = CString::new("y").expect("bad y");
38
            let z_str = CString::new("z").expect("bad z");
39

            
40
            newVar_ffi(instance, x_str.as_ptr() as _, VariableType_VAR_BOUND, 1, 3);
41
            newVar_ffi(instance, y_str.as_ptr() as _, VariableType_VAR_BOUND, 2, 4);
42
            newVar_ffi(instance, z_str.as_ptr() as _, VariableType_VAR_BOUND, 1, 5);
43

            
44
            let x = getVarByName(instance, x_str.as_ptr() as _);
45
            let y = getVarByName(instance, y_str.as_ptr() as _);
46
            let z = getVarByName(instance, z_str.as_ptr() as _);
47

            
48
            // PRINT
49
            printMatrix_addVar(instance, x);
50
            printMatrix_addVar(instance, y);
51
            printMatrix_addVar(instance, z);
52

            
53
            // VARORDER
54
            let search_vars = vec_var_new();
55
            vec_var_push_back(search_vars as _, x);
56
            vec_var_push_back(search_vars as _, y);
57
            vec_var_push_back(search_vars as _, z);
58
            let search_order = searchOrder_new(search_vars as _, VarOrderEnum_ORDER_STATIC, false);
59
            instance_addSearchOrder(instance, search_order);
60

            
61
            // CONSTRAINTS
62
            let leq = constraint_new(ConstraintType_CT_LEQSUM);
63
            let geq = constraint_new(ConstraintType_CT_GEQSUM);
64
            let ineq = constraint_new(ConstraintType_CT_INEQ);
65

            
66
            let rhs_vars = vec_var_new();
67
            vec_var_push_back(rhs_vars, constantAsVar(4));
68

            
69
            // leq / geq : [var] [var]
70
            constraint_addList(leq, search_vars as _);
71
            constraint_addList(leq, rhs_vars as _);
72

            
73
            constraint_addList(geq, search_vars as _);
74
            constraint_addList(geq, rhs_vars as _);
75

            
76
            // ineq: [var] [var] [const]
77
            let x_vec = vec_var_new();
78
            vec_var_push_back(x_vec, x);
79

            
80
            let y_vec = vec_var_new();
81
            vec_var_push_back(y_vec, y);
82

            
83
            let const_vec = vec_int_new();
84
            vec_int_push_back(const_vec, -1);
85

            
86
            constraint_addList(ineq, x_vec as _);
87
            constraint_addList(ineq, y_vec as _);
88
            constraint_addConstantList(ineq, const_vec as _);
89

            
90
            instance_addConstraint(instance, leq);
91
            instance_addConstraint(instance, geq);
92
            instance_addConstraint(instance, ineq);
93

            
94
            let res = runMinion(options, args, instance, Some(hello_from_rust));
95

            
96
            // does it get this far?
97
            assert_eq!(res, 0);
98

            
99
            // test if solutions are correct
100
            assert_eq!(X_VAL, 1);
101
            assert_eq!(Y_VAL, 2);
102
            assert_eq!(Z_VAL, 1);
103
        }
104
    }
105
}