v2 / vlib / v / tests / concurrency / shared_assign_test.v
171 lines · 148 sloc · 3.05 KB · 92a2ba8fd56c8d476e229695e7dcf324e9e44ceb
Raw
1import os
2import rand
3
4const vexe = @VEXE
5
6struct Foo {
7mut:
8 a int
9}
10
11fn Foo.new_non_ref() Foo {
12 return Foo{}
13}
14
15fn Foo.new_ref() &Foo {
16 return &Foo{}
17}
18
19fn get_map_non_ref() map[int]int {
20 return {
21 0: 0
22 }
23}
24
25fn get_map_ref() &map[int]int {
26 return &{
27 0: 0
28 }
29}
30
31fn get_array() []int {
32 return [0]
33}
34
35fn test_assign_from_call_expr() {
36 shared foo1 := Foo.new_non_ref()
37 rlock foo1 {
38 assert foo1.a == 0
39 }
40
41 shared foo2 := Foo.new_ref()
42 rlock foo2 {
43 assert foo2.a == 0
44 }
45
46 shared map1 := get_map_non_ref()
47 rlock map1 {
48 assert map1[0] == 0
49 }
50
51 shared map2 := get_map_ref()
52 rlock map2 {
53 assert map2[0] == 0
54 }
55
56 shared arr := get_array()
57 rlock arr {
58 assert arr[0] == 0
59 }
60}
61
62fn get_int_array(arr [3]int) []int {
63 return [arr[0], arr[1], arr[2]]
64}
65
66fn get_foo_array(arr [3]Foo) []Foo {
67 return [arr[0], arr[1], arr[2]]
68}
69
70fn test_assign_from_call_expr_with_fixed_array() {
71 shared arr_int := get_int_array([1, 2, 3]!)
72 lock arr_int {
73 assert arr_int == [1, 2, 3]
74 }
75
76 shared arr_foo := get_foo_array([Foo.new_non_ref(), Foo.new_non_ref(),
77 Foo.new_non_ref()]!)
78 lock arr_foo {
79 assert arr_foo == [Foo.new_non_ref(), Foo.new_non_ref(),
80 Foo.new_non_ref()]
81 }
82}
83
84fn test_re_assign_array() {
85 shared arr := [1, 2, 3]
86 lock arr {
87 arr[0] = 0
88 assert arr == [0, 2, 3]
89 arr = [0, 0, 0]
90 assert arr == [0, 0, 0]
91 }
92}
93
94fn test_re_assign_struct() {
95 shared st := Foo{}
96 lock st {
97 st.a = 1
98 assert st.a == 1
99 st = Foo{2}
100 assert st.a == 2
101 }
102}
103
104fn test_re_assign_map() {
105 shared m := map[int]int{}
106 lock m {
107 m[0] = 0
108 assert m[0] == 0
109 m = {
110 0: 1
111 }
112 assert m[0] == 1
113 }
114}
115
116struct SharedAssignStructA {
117 commands []string
118}
119
120struct SharedAssignStructB {
121 s SharedAssignStructA
122}
123
124fn test_assign_from_pointer_ident_with_nested_struct() {
125 mut src := &SharedAssignStructB{}
126 shared shared_copy := src
127 shared spread_copy := SharedAssignStructB{
128 ...src
129 }
130 rlock shared_copy, spread_copy {
131 assert shared_copy.s.commands == []string{}
132 assert spread_copy.s.commands == []string{}
133 }
134}
135
136fn test_assign_from_pointer_ident_emits_shared_copy_in_c_output() {
137 tmp_dir := os.join_path(os.vtmp_dir(), 'shared_assign_cgen_${rand.ulid()}')
138 os.mkdir_all(tmp_dir) or { panic(err) }
139 defer {
140 os.rmdir_all(tmp_dir) or {}
141 }
142 source_path := os.join_path(tmp_dir, 'main.v')
143 c_path := os.join_path(tmp_dir, 'main.c')
144 source := [
145 'module main',
146 '',
147 'struct StructA {',
148 '\tcommands []string',
149 '}',
150 '',
151 'struct StructB {',
152 '\ts StructA',
153 '}',
154 '',
155 'fn main() {',
156 '\tmut src := &StructB{}',
157 '\tshared copy := src',
158 '\trlock copy {',
159 '\t\tprintln(copy.s)',
160 '\t}',
161 '}',
162 ].join_lines()
163 os.write_file(source_path, source) or { panic(err) }
164 res :=
165 os.execute('${os.quoted_path(vexe)} -o ${os.quoted_path(c_path)} ${os.quoted_path(source_path)}')
166 assert res.exit_code == 0, res.output
167 csrc := os.read_file(c_path) or { panic(err) }
168 assert csrc.contains('__shared__main__StructB* copy = (__shared__main__StructB*)__dup__shared__main__StructB')
169 assert csrc.contains('*src}, sizeof(__shared__main__StructB))')
170 assert !csrc.contains('__shared__main__StructB* copy = src;')
171}
172