1 | module sync |
2 | |
3 | // vtest flaky: true |
4 | // vtest retry: 6 |
5 | |
6 | // ATTENTION! Do not use this file as an example! |
7 | // For that, please look at `channel_select_2_test.v` or `channel_select_3_test.v` |
8 | // This test case uses the implementation in `sync/channels.v` directly |
9 | // in order to test it independently from the support in the core language |
10 | import os |
11 | import time |
12 | |
13 | fn test_should_run_flaky_test() { |
14 | if os.getenv('VTEST_RUN_FLAKY') != '1' { |
15 | eprintln('> skipping running flaky test, set VTEST_RUN_FLAKY to 1, to run it') |
16 | exit(0) |
17 | } |
18 | assert true |
19 | } |
20 | |
21 | fn do_rec_i64(mut ch Channel) { |
22 | mut sum := i64(0) |
23 | for _ in 0 .. 300 { |
24 | mut a := i64(0) |
25 | ch.pop(&a) |
26 | sum += a |
27 | } |
28 | assert sum == 300 * (300 - 1) / 2 |
29 | } |
30 | |
31 | fn do_send_int(mut ch Channel) { |
32 | for i in 0 .. 300 { |
33 | ch.push(&i) |
34 | } |
35 | } |
36 | |
37 | fn do_send_u8(mut ch Channel) { |
38 | for i in 0 .. 300 { |
39 | ii := u8(i) |
40 | ch.push(&ii) |
41 | } |
42 | } |
43 | |
44 | fn do_send_i64(mut ch Channel) { |
45 | for i in 0 .. 300 { |
46 | ii := i64(i) |
47 | ch.push(&ii) |
48 | } |
49 | } |
50 | |
51 | fn test_select() { |
52 | mut chi := new_channel[int](0) |
53 | mut chl := new_channel[i64](1) |
54 | mut chb := new_channel[u8](10) |
55 | mut recch := new_channel[i64](0) |
56 | spawn do_rec_i64(mut recch) |
57 | spawn do_send_int(mut chi) |
58 | spawn do_send_u8(mut chb) |
59 | spawn do_send_i64(mut chl) |
60 | mut channels := [chi, recch, chl, chb] |
61 | directions := [Direction.pop, .push, .pop, .pop] |
62 | mut sum := i64(0) |
63 | mut rl := i64(0) |
64 | mut ri := int(0) |
65 | mut rb := u8(0) |
66 | mut sl := i64(0) |
67 | mut objs := [voidptr(&ri), &sl, &rl, &rb] |
68 | for _ in 0 .. 1200 { |
69 | idx := channel_select(mut channels, directions, mut objs, time.infinite) |
70 | match idx { |
71 | 0 { |
72 | sum += ri |
73 | } |
74 | 1 { |
75 | sl++ |
76 | } |
77 | 2 { |
78 | sum += rl |
79 | } |
80 | 3 { |
81 | sum += rb |
82 | } |
83 | else { |
84 | println('got ${idx} (timeout)') |
85 | } |
86 | } |
87 | } |
88 | // Use Gauß' formula for the first 2 contributions |
89 | // the 3rd contribution is `byte` and must be seen modulo 256 |
90 | expected_sum := 2 * (300 * (300 - 1) / 2) + 256 * (256 - 1) / 2 + 44 * (44 - 1) / 2 |
91 | assert sum == expected_sum |
92 | } |