Skip to content

Commit 4cc6b59

Browse files
authored
CN: Parallelise and caputure output in CN CI (#703)
* CN: Add Python for running CN tests This allows us to parallelise some of the testing easily, and also use diff-based tests rather than just relying on return codes. * CN: Switch to Python script and diffs The docker CI uses run-cn.sh so keeping it for now. * CN: Tidy up lemmma CI Not enabling it just yet because (a) it's not under active development and (b) I want to sort out caching first so that rebuilding Cerberus and opam don't eat up any savings from parallelising. * Generalise test script The test script now requires a (JSON) config file with documented attributes, and does not default to a test directory or executable. It also includes a `--dry-run` flag to see what command is being run. * CN: Use Python for running CN VIP tests * Swap order of args in diff-prog
1 parent 21ec7e0 commit 4cc6b59

File tree

277 files changed

+1956
-160
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

277 files changed

+1956
-160
lines changed

.github/workflows/ci-cn-spec-testing.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,5 +80,5 @@ jobs:
8080
run: |
8181
opam switch ${{ matrix.version }}
8282
eval $(opam env --switch=${{ matrix.version }})
83-
cd tests; USE_OPAM='' ./run-cn-test-gen.sh
83+
cd tests; ./run-cn-test-gen.sh
8484

.github/workflows/ci-cn.yml

+7-7
Original file line numberDiff line numberDiff line change
@@ -71,28 +71,28 @@ jobs:
7171
run: |
7272
opam switch ${{ matrix.version }}
7373
eval $(opam env --switch=${{ matrix.version }})
74-
USE_OPAM='' cd backend/cn && dune build @fmt
74+
cd backend/cn && dune build @fmt
7575
7676
- name: Checkout cn-tutorial
7777
uses: actions/checkout@v4
7878
with:
7979
repository: rems-project/cn-tutorial
8080
path: cn-tutorial
8181

82-
- name: Run CN CI tests
82+
- name: Run CN tests
8383
run: |
8484
opam switch ${{ matrix.version }}
8585
eval $(opam env --switch=${{ matrix.version }})
86-
cd tests; USE_OPAM='' ./run-cn.sh
86+
./tests/diff-prog.py cn tests/cn/verify.json 2> diff.patch || (cat diff.patch; exit 1)
8787
88-
- name: Run CN Tutorial CI tests
88+
- name: Run CN Tutorial tests
8989
run: |
9090
opam switch ${{ matrix.version }}
9191
eval $(opam env --switch=${{ matrix.version }})
92-
USE_OPAM='' tests/run-cn-tutorial-ci.sh cn-tutorial
92+
tests/run-cn-tutorial-ci.sh cn-tutorial
9393
94-
- name: Run CN VIP CI tests
94+
- name: Run CN VIP tests
9595
run: |
9696
opam switch ${{ matrix.version }}
9797
eval $(opam env --switch=${{ matrix.version }})
98-
cd tests; USE_OPAM='' ./run-cn-vip.sh
98+
tests/run-cn-vip.sh

.github/workflows/ci-pr-bench.yml.disabled

+2-2
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ jobs:
9090
run: |
9191
opam switch ${{ matrix.version }}
9292
eval $(opam env --switch=${{ matrix.version }})
93-
cd tests; USE_OPAM='' ./run-ci-benchmarks.sh
93+
cd tests; ./run-ci-benchmarks.sh
9494
mv benchmark-data.json ${{ env.PR_DATA }}
9595
cd ..
9696

@@ -117,7 +117,7 @@ jobs:
117117
run: |
118118
opam switch ${{ matrix.version }}
119119
eval $(opam env --switch=${{ matrix.version }})
120-
cd tests; USE_OPAM='' ./run-ci-benchmarks.sh; mv benchmark-data.json ${{ env.BASE_DATA }}
120+
cd tests; ./run-ci-benchmarks.sh; mv benchmark-data.json ${{ env.BASE_DATA }}
121121
cd ..
122122

123123
- name: Compare results

tests/cn/alloc_create.c.verify

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
return code: 0
2+
[1/1]: main -- pass

tests/cn/alloc_token.c.verify

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
return code: 0
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
return code: 1
2+
[1/1]: g1 -- fail
3+
tests/cn/and_or_precedence.error.c:15:13: error: Unprovable constraint
4+
/*@ assert (false); @*/
5+
^~~~~~~~~~~~~~~
6+
Constraint from tests/cn/and_or_precedence.error.c:15:13:
7+
/*@ assert (false); @*/
8+
^~~~~~~~~~~~~~~
9+
State file: file:///tmp/state__and_or_precedence.error.c__g1.html

tests/cn/append.c.verify

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
return code: 0
2+
[1/2]: IntList_append -- pass
3+
[2/2]: split -- pass

tests/cn/arith_type.error.c.verify

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
return code: 1
2+
tests/cn/arith_type.error.c:8:21: error: Type error
3+
let x = negate() + true;
4+
^
5+
Expression 'true' has type 'boolean'.
6+
I expected it to have type 'integer' because of tests/cn/arith_type.error.c:8:10:
7+
let x = negate() + true;
8+
~~~~~~^~

tests/cn/arrow_access.c.verify

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
return code: 0
2+
[1/2]: arrow_access_1 -- pass
3+
[2/2]: arrow_access_2 -- pass
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
return code: 2
2+
tests/cn/assert_on_toplevel.error.c:2:5: error: unexpected token before 'assert'
3+
parsing "cn_toplevel'": expected "cn_toplevel"
4+
assert @*/
5+
^~~~~~

tests/cn/b_or.c.verify

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
return code: 0
2+
[1/1]: f -- pass

tests/cn/b_xor.c.verify

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
return code: 0
2+
[1/1]: f -- pass

tests/cn/bad_col.error.c.verify

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
return code: 1
2+
tests/cn/bad_col.error.c:3:32: error: unexpected token after '+' and before 'function'
3+
parsing "add_expr": seen "add_expr PLUS", expecting "mul_expr"
4+
x < 2147483647 + function; @*/
5+
^~~~~~~~
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
return code: 1
2+
tests/cn/bad_constructor_user.error.c:9:19: error: Type error
3+
Cons { head : 0, tail : Nil {} }
4+
^
5+
Expression '0' has type 'integer'.
6+
I expected it to have type 'i32' because of tests/cn/bad_constructor_user.error.c:9:5:
7+
Cons { head : 0, tail : Nil {} }
8+
~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
return code: 1
2+
tests/cn/bad_function_call.error.c:7:12: error: Type error
3+
id_int(x)
4+
^
5+
Expression 'x' has type 'i32'.
6+
I expected it to have type 'integer' because of tests/cn/bad_function_call.error.c:2:1:
7+
function (integer) id_int(integer x) {
8+
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

tests/cn/bad_record.error.c.verify

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
return code: 2
2+
tests/cn/bad_record.error.c:3:43: error: field `x' duplicated
3+
type_synonym wrong = { integer x, integer x }
4+
^

tests/cn/bad_record2.error.c.verify

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
return code: 2
2+
tests/cn/bad_record2.error.c:6:15: error: field `x' duplicated
3+
{ x: p.x, x: p.y }
4+
^

tests/cn/bad_recursion.error.c.verify

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
return code: 1
2+
tests/cn/bad_recursion.error.c:3:1: error: Illegal datatype definition.
3+
Constructor argument 'b' is given type 'map<u8, datatype bad>', which indirectly refers to 'datatype bad'.
4+
Indirect recursion via map, set, record, or tuple types is not permitted.
5+
datatype bad { Bad { map<u8, datatype bad> b } }
6+
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
return code: 1
2+
[1/1]: inc -- fail
3+
tests/cn/bad_resource_var.error.c:1:1: error: Unprovable constraint
4+
void inc(int* p)
5+
~~~~~^~~~~~~~~~~
6+
Constraint from tests/cn/bad_resource_var.error.c:5:13:
7+
X2 < 2147483647i32; @*/
8+
^~~~~~~~~~~~~~~~~~~
9+
State file: file:///tmp/state__bad_resource_var.error.c__inc.html
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
return code: 1
2+
tests/cn/before_from_bytes.error.c:6:9: warning: experimental keyword 'to_bytes' (use of experimental features is discouraged)
3+
/*@ to_bytes Owned<int>(p); @*/
4+
^~~~~~~~
5+
tests/cn/before_from_bytes.error.c:7:9: warning: extract: index added, no resources (yet) extracted.
6+
/*@ extract Owned<char>, 2u64; @*/
7+
^~~~~~~~~~~~~~~~~~~~~~~~~~
8+
[1/1]: main -- fail
9+
tests/cn/before_from_bytes.error.c:8:5: error: Missing resource for writing
10+
p_char[2] = 0xff;
11+
~~~~~~~~~~^~~~~~
12+
Resource needed: Block<char>(&&x[(u64)2'i32])
13+
State file: file:///tmp/state__before_from_bytes.error.c__main.html
+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
return code: 1
2+
[1/1]: main -- fail
3+
tests/cn/before_to_bytes.error.c:6:5: error: Missing resource for writing
4+
p_char[2] = 0xff;
5+
~~~~~~~~~~^~~~~~
6+
Resource needed: Block<char>(&&x[(u64)2'i32])
7+
State file: file:///tmp/state__before_to_bytes.error.c__main.html

tests/cn/bitwise_and.c.verify

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
return code: 0
2+
[1/1]: main -- pass
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
return code: 1
2+
tests/cn/bitwise_and_type_left.error.c:3:17: error: Ill-typed application of binary operation '&' .
3+
/*@ assert (0 & 1i32 == 0i32); @*/
4+
~~^~~~~~
5+
'0' has type 'integer', '1'i32' has type 'i32'.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
return code: 1
2+
tests/cn/bitwise_and_type_right.error.c:3:24: error: Type error
3+
/*@ assert (0i32 & 1 == 0i32); @*/
4+
^
5+
Expression '1' has type 'integer'.
6+
I expected it to have type 'i32' because of tests/cn/bitwise_and_type_right.error.c:3:17:
7+
/*@ assert (0i32 & 1 == 0i32); @*/
8+
^

tests/cn/bitwise_compl.c.verify

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
return code: 0
2+
[1/1]: main -- pass
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
return code: 0
2+
[1/1]: main -- pass
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
return code: 1
2+
tests/cn/bitwise_compl_type.error.c:3:18: error: Mismatched types.
3+
/*@ assert (~0 == -1); @*/
4+
^
5+
Expected value of type 'bitvector' but found value of type 'integer'

tests/cn/block_type.c.verify

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
return code: 0
2+
[1/2]: block_notype_1 -- pass
3+
[2/2]: block_notype_2 -- pass

tests/cn/builtin_ctz.c.verify

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
return code: 0
2+
[1/1]: f -- pass

tests/cn/builtin_ctz_val.c.verify

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
return code: 0
2+
[1/1]: f -- pass

tests/cn/cn_inline.c.verify

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
return code: 0
2+
tests/cn/cn_inline.c:13:5: warning: experimental keyword 'cn_function' (use of experimental features is discouraged)
3+
/*@ cn_function lookup_size_shift_cn; @*/
4+
^~~~~~~~~~~
5+
[1/2]: lookup_size_shift -- pass
6+
[2/2]: f -- pass
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
return code: 1
2+
tests/cn/cnfunction_mismatched_args1.error.c:6:5: warning: experimental keyword 'cn_function' (use of experimental features is discouraged)
3+
/*@ cn_function bw_or; @*/
4+
^~~~~~~~~~~
5+
tests/cn/cnfunction_mismatched_args1.error.c:5:1: error: mismatched argument number for c_bw_or -> bw_or
6+
int c_bw_or(int x)
7+
~~~~^~~~~~~~~~~~~~
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
return code: 1
2+
tests/cn/cnfunction_mismatched_args2.error.c:6:5: warning: experimental keyword 'cn_function' (use of experimental features is discouraged)
3+
/*@ cn_function bw_or; @*/
4+
^~~~~~~~~~~
5+
tests/cn/cnfunction_mismatched_args2.error.c:5:1: error: mismatched argument number for c_bw_or -> bw_or
6+
int c_bw_or(int x, int y, int z)
7+
~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
return code: 1
2+
tests/cn/cnfunction_mismatched_args3.error.c:6:5: warning: experimental keyword 'cn_function' (use of experimental features is discouraged)
3+
/*@ cn_function bw_or; @*/
4+
^~~~~~~~~~~
5+
tests/cn/cnfunction_mismatched_args3.error.c:5:1: error: mismatched arguments: (u32 y) and (i32 y)
6+
int c_bw_or(int x, int y)
7+
~~~~^~~~~~~~~~~~~~~~~~~~~
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
return code: 1
2+
tests/cn/cnfunction_mismatched_args4.error.c:6:5: warning: experimental keyword 'cn_function' (use of experimental features is discouraged)
3+
/*@ cn_function bw_or; @*/
4+
^~~~~~~~~~~
5+
tests/cn/cnfunction_mismatched_args4.error.c:6:5: error: cn_function: return-type mismatch:
6+
c_bw_or : i32 -> bw_or : u32
7+
/*@ cn_function bw_or; @*/
8+
^~~~~~~~~~~~~~~~~~

tests/cn/copy_alloc_id.c.verify

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
return code: 0
2+
[1/3]: f1 -- pass
3+
[2/3]: f2 -- pass
4+
[3/3]: main -- pass

tests/cn/copy_alloc_id.error.c.verify

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
return code: 1
2+
[1/2]: f -- fail
3+
[2/2]: main -- pass
4+
tests/cn/copy_alloc_id.error.c:4:12: error: Pointer `p` needs allocation ID
5+
int* q = __cerbvar_copy_alloc_id(p_int + 0ULL, p);
6+
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7+
(UB missing short message): UB_CERB004_unspecified__copy_alloc_id
8+
State file: file:///tmp/state__copy_alloc_id.error.c__f.html
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
return code: 1
2+
[1/2]: f -- fail
3+
[2/2]: main -- pass
4+
tests/cn/copy_alloc_id2.error.c:10:12: error: Pointer `p` needs to be live for copy_alloc_id
5+
int* q = __cerbvar_copy_alloc_id(p_int + 0ULL, p);
6+
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7+
Need an Alloc or Owned in context with same allocation id
8+
State file: file:///tmp/state__copy_alloc_id2.error.c__f.html

tests/cn/create_rdonly.c.verify

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
return code: 0
2+
[1/1]: main -- pass

tests/cn/disj_nonnull.c.verify

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
return code: 0
2+
[1/2]: globals -- pass
3+
[2/2]: main -- pass

tests/cn/division.c.verify

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
return code: 0
2+
[1/1]: division -- pass

tests/cn/division_by_0.error.c.verify

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
return code: 1
2+
[1/1]: division -- fail
3+
tests/cn/division_by_0.error.c:6:12: error: Undefined behaviour
4+
return x / y;
5+
~~^~~
6+
the value of the second operand of a '/' operator is zero (§6.5.5#5, sentence 2)
7+
State file: file:///tmp/state__division_by_0.error.c__division.html

tests/cn/division_casting.c.verify

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
return code: 0
2+
[1/1]: division -- pass

tests/cn/division_precedence.c.verify

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
return code: 0
2+
[1/3]: divide_no_parenthesis -- pass
3+
[2/3]: multiply_then_divide -- pass
4+
[3/3]: divide_multiply_add_subtract -- pass
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
return code: 1
2+
tests/cn/division_return_sign.error.c:7:25: error: Type error
3+
ensures return == x/y; @*/
4+
^
5+
Expression 'y' has type 'u32'.
6+
I expected it to have type 'i32' because of tests/cn/division_return_sign.error.c:7:23:
7+
ensures return == x/y; @*/
8+
^
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
return code: 1
2+
[1/1]: different_size -- fail
3+
tests/cn/division_return_size.error.c:9:5: error: integer value not representable at type signed int
4+
return x / y;
5+
^~~~~~~~~~~~~
6+
Value: (i64)x / y
7+
State file: file:///tmp/state__division_return_size.error.c__different_size.html
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
return code: 0
2+
[1/3]: divide_by_ten -- pass
3+
[2/3]: divide_by_neg_ten -- pass
4+
[3/3]: division_diff_sign -- pass

tests/cn/doubling.c.verify

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
return code: 0
2+
[1/2]: add_self -- pass
3+
[2/2]: add_self_twice -- pass
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
return code: 1
2+
tests/cn/duplicate_datatype_var.error.c:5:22: error: Re-using member name x within datatype definition.
3+
Single { integer x }
4+
^
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
return code: 2
2+
tests/cn/duplicate_pattern_var.error.c:15:43: error: redeclaration of variable
3+
Cons { head : Point { x : a , y : a } , tail : tail } => { a + b + sum(tail) }
4+
^

tests/cn/enum_and_and.c.verify

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
return code: 0
2+
[1/1]: foo -- pass

tests/cn/extract_verbose.c.verify

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
return code: 0
2+
tests/cn/extract_verbose.c:10:27: warning: 'extract' expects a 'u64', but '1' with type 'integer' was provided. This will become an error in the future.
3+
/*@ extract Owned<int>, 1; @*/
4+
^
5+
tests/cn/extract_verbose.c:11:27: warning: 'extract' expects a 'u64', but '1' with type 'integer' was provided. This will become an error in the future.
6+
/*@ extract Owned<int>, 1; @*/
7+
^
8+
tests/cn/extract_verbose.c:14:27: warning: 'extract' expects a 'u64', but '12' with type 'integer' was provided. This will become an error in the future.
9+
/*@ extract Owned<int>, 12; @*/
10+
^
11+
tests/cn/extract_verbose.c:10:7: warning: extract: index added, no resources (yet) extracted.
12+
/*@ extract Owned<int>, 1; @*/
13+
^~~~~~~~~~~~~~~~~~~~~~
14+
tests/cn/extract_verbose.c:11:7: warning: extract: index added, no resources (yet) extracted.
15+
/*@ extract Owned<int>, 1; @*/
16+
^~~~~~~~~~~~~~~~~~~~~~
17+
tests/cn/extract_verbose.c:13:7: warning: extract: index added, no resources (yet) extracted.
18+
/*@ extract Owned<int>, 1u64; @*/
19+
^~~~~~~~~~~~~~~~~~~~~~~~~
20+
tests/cn/extract_verbose.c:14:7: warning: extract: index added, no resources (yet) extracted.
21+
/*@ extract Owned<int>, 12; @*/
22+
^~~~~~~~~~~~~~~~~~~~~~~
23+
[1/1]: f -- pass
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
return code: 1
2+
[1/1]: inc -- fail
3+
tests/cn/failing_postcond.error.c:5:5: error: Unprovable constraint
4+
return x + 1;
5+
^~~~~~~~~~~~~
6+
Constraint from tests/cn/failing_postcond.error.c:3:13:
7+
/*@ ensures return < 2147483647i32; @*/
8+
^~~~~~~~~~~~~~~~~~~~~~~
9+
State file: file:///tmp/state__failing_postcond.error.c__inc.html
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
return code: 1
2+
tests/cn/failing_precond.error.c:2:18: error: Type error
3+
/*@ requires x < 2147483647; @*/
4+
^
5+
Expression '2147483647' has type 'integer'.
6+
I expected it to have type 'i32' because of tests/cn/failing_precond.error.c:2:14:
7+
/*@ requires x < 2147483647; @*/
8+
^

tests/cn/forloop_with_decl.c.verify

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
return code: 0
2+
[1/1]: for_with_decl -- pass

0 commit comments

Comments
 (0)