17
17
-module (unit_SUITE ).
18
18
19
19
-include_lib (" common_test/include/ct.hrl" ).
20
+ -include_lib (" rabbit_common/include/rabbit.hrl" ).
20
21
21
22
-compile (export_all ).
22
23
@@ -28,6 +29,15 @@ all() ->
28
29
groups () ->
29
30
[
30
31
{parallel_tests , [parallel ], [
32
+ {basic_header_handling , [parallel ], [
33
+ write_table_with_invalid_existing_type ,
34
+ invalid_existing_headers ,
35
+ disparate_invalid_header_entries_accumulate_separately ,
36
+ corrupt_or_invalid_headers_are_overwritten ,
37
+ invalid_same_header_entry_accumulation
38
+ ]},
39
+ pg_local ,
40
+ priority_queue ,
31
41
{resource_monitor , [parallel ], [
32
42
parse_information_unit
33
43
]},
@@ -42,15 +52,274 @@ groups() ->
42
52
]},
43
53
{vm_memory_monitor , [parallel ], [
44
54
parse_line_linux
45
- ]}
55
+ ]},
56
+ version_equivalance
46
57
]}
47
58
].
48
59
49
60
init_per_group (_ , Config ) -> Config .
50
61
end_per_group (_ , Config ) -> Config .
51
62
63
+ % % -------------------------------------------------------------------
64
+ % % basic_header_handling.
65
+ % % -------------------------------------------------------------------
66
+
67
+ -define (XDEATH_TABLE ,
68
+ [{<<" reason" >>, longstr , <<" blah" >>},
69
+ {<<" queue" >>, longstr , <<" foo.bar.baz" >>},
70
+ {<<" exchange" >>, longstr , <<" my-exchange" >>},
71
+ {<<" routing-keys" >>, array , []}]).
72
+
73
+ -define (ROUTE_TABLE , [{<<" redelivered" >>, bool , <<" true" >>}]).
74
+
75
+ -define (BAD_HEADER (K ), {<<K >>, longstr , <<" bad " , K >>}).
76
+ -define (BAD_HEADER2 (K , Suf ), {<<K >>, longstr , <<" bad " , K , Suf >>}).
77
+ -define (FOUND_BAD_HEADER (K ), {<<K >>, array , [{longstr , <<" bad " , K >>}]}).
78
+
79
+ write_table_with_invalid_existing_type (_Config ) ->
80
+ prepend_check (<<" header1" >>, ? XDEATH_TABLE , [? BAD_HEADER (" header1" )]).
81
+
82
+ invalid_existing_headers (_Config ) ->
83
+ Headers =
84
+ prepend_check (<<" header2" >>, ? ROUTE_TABLE , [? BAD_HEADER (" header2" )]),
85
+ {array , [{table , ? ROUTE_TABLE }]} =
86
+ rabbit_misc :table_lookup (Headers , <<" header2" >>),
87
+ passed .
88
+
89
+ disparate_invalid_header_entries_accumulate_separately (_Config ) ->
90
+ BadHeaders = [? BAD_HEADER (" header2" )],
91
+ Headers = prepend_check (<<" header2" >>, ? ROUTE_TABLE , BadHeaders ),
92
+ Headers2 = prepend_check (<<" header1" >>, ? XDEATH_TABLE ,
93
+ [? BAD_HEADER (" header1" ) | Headers ]),
94
+ {table , [? FOUND_BAD_HEADER (" header1" ),
95
+ ? FOUND_BAD_HEADER (" header2" )]} =
96
+ rabbit_misc :table_lookup (Headers2 , ? INVALID_HEADERS_KEY ),
97
+ passed .
98
+
99
+ corrupt_or_invalid_headers_are_overwritten (_Config ) ->
100
+ Headers0 = [? BAD_HEADER (" header1" ),
101
+ ? BAD_HEADER (" x-invalid-headers" )],
102
+ Headers1 = prepend_check (<<" header1" >>, ? XDEATH_TABLE , Headers0 ),
103
+ {table ,[? FOUND_BAD_HEADER (" header1" ),
104
+ ? FOUND_BAD_HEADER (" x-invalid-headers" )]} =
105
+ rabbit_misc :table_lookup (Headers1 , ? INVALID_HEADERS_KEY ),
106
+ passed .
107
+
108
+ invalid_same_header_entry_accumulation (_Config ) ->
109
+ BadHeader1 = ? BAD_HEADER2 (" header1" , " a" ),
110
+ Headers = prepend_check (<<" header1" >>, ? ROUTE_TABLE , [BadHeader1 ]),
111
+ Headers2 = prepend_check (<<" header1" >>, ? ROUTE_TABLE ,
112
+ [? BAD_HEADER2 (" header1" , " b" ) | Headers ]),
113
+ {table , InvalidHeaders } =
114
+ rabbit_misc :table_lookup (Headers2 , ? INVALID_HEADERS_KEY ),
115
+ {array , [{longstr ,<<" bad header1b" >>},
116
+ {longstr ,<<" bad header1a" >>}]} =
117
+ rabbit_misc :table_lookup (InvalidHeaders , <<" header1" >>),
118
+ passed .
119
+
120
+ prepend_check (HeaderKey , HeaderTable , Headers ) ->
121
+ Headers1 = rabbit_basic :prepend_table_header (
122
+ HeaderKey , HeaderTable , Headers ),
123
+ {table , Invalid } =
124
+ rabbit_misc :table_lookup (Headers1 , ? INVALID_HEADERS_KEY ),
125
+ {Type , Value } = rabbit_misc :table_lookup (Headers , HeaderKey ),
126
+ {array , [{Type , Value } | _ ]} =
127
+ rabbit_misc :table_lookup (Invalid , HeaderKey ),
128
+ Headers1 .
129
+
130
+ % % -------------------------------------------------------------------
131
+ % % pg_local.
132
+ % % -------------------------------------------------------------------
133
+
134
+ pg_local (_Config ) ->
135
+ [P , Q ] = [spawn (fun () -> receive X -> X end end ) || _ <- [x , x ]],
136
+ check_pg_local (ok , [], []),
137
+ check_pg_local (pg_local :join (a , P ), [P ], []),
138
+ check_pg_local (pg_local :join (b , P ), [P ], [P ]),
139
+ check_pg_local (pg_local :join (a , P ), [P , P ], [P ]),
140
+ check_pg_local (pg_local :join (a , Q ), [P , P , Q ], [P ]),
141
+ check_pg_local (pg_local :join (b , Q ), [P , P , Q ], [P , Q ]),
142
+ check_pg_local (pg_local :join (b , Q ), [P , P , Q ], [P , Q , Q ]),
143
+ check_pg_local (pg_local :leave (a , P ), [P , Q ], [P , Q , Q ]),
144
+ check_pg_local (pg_local :leave (b , P ), [P , Q ], [Q , Q ]),
145
+ check_pg_local (pg_local :leave (a , P ), [Q ], [Q , Q ]),
146
+ check_pg_local (pg_local :leave (a , P ), [Q ], [Q , Q ]),
147
+ [begin X ! done ,
148
+ Ref = erlang :monitor (process , X ),
149
+ receive {'DOWN' , Ref , process , X , _Info } -> ok end
150
+ end || X <- [P , Q ]],
151
+ check_pg_local (ok , [], []),
152
+ passed .
153
+
154
+ check_pg_local (ok , APids , BPids ) ->
155
+ ok = pg_local :sync (),
156
+ [true , true ] = [lists :sort (Pids ) == lists :sort (pg_local :get_members (Key )) ||
157
+ {Key , Pids } <- [{a , APids }, {b , BPids }]].
158
+
159
+ % % -------------------------------------------------------------------
160
+ % % priority_queue.
161
+ % % -------------------------------------------------------------------
162
+
163
+ priority_queue (_Config ) ->
164
+
165
+ false = priority_queue :is_queue (not_a_queue ),
166
+
167
+ % % empty Q
168
+ Q = priority_queue :new (),
169
+ {true , true , 0 , [], []} = test_priority_queue (Q ),
170
+
171
+ % % 1-4 element no-priority Q
172
+ true = lists :all (fun (X ) -> X =:= passed end ,
173
+ lists :map (fun test_simple_n_element_queue /1 ,
174
+ lists :seq (1 , 4 ))),
175
+
176
+ % % 1-element priority Q
177
+ Q1 = priority_queue :in (foo , 1 , priority_queue :new ()),
178
+ {true , false , 1 , [{1 , foo }], [foo ]} =
179
+ test_priority_queue (Q1 ),
180
+
181
+ % % 2-element same-priority Q
182
+ Q2 = priority_queue :in (bar , 1 , Q1 ),
183
+ {true , false , 2 , [{1 , foo }, {1 , bar }], [foo , bar ]} =
184
+ test_priority_queue (Q2 ),
185
+
186
+ % % 2-element different-priority Q
187
+ Q3 = priority_queue :in (bar , 2 , Q1 ),
188
+ {true , false , 2 , [{2 , bar }, {1 , foo }], [bar , foo ]} =
189
+ test_priority_queue (Q3 ),
190
+
191
+ % % 1-element negative priority Q
192
+ Q4 = priority_queue :in (foo , - 1 , priority_queue :new ()),
193
+ {true , false , 1 , [{- 1 , foo }], [foo ]} = test_priority_queue (Q4 ),
194
+
195
+ % % merge 2 * 1-element no-priority Qs
196
+ Q5 = priority_queue :join (priority_queue :in (foo , Q ),
197
+ priority_queue :in (bar , Q )),
198
+ {true , false , 2 , [{0 , foo }, {0 , bar }], [foo , bar ]} =
199
+ test_priority_queue (Q5 ),
200
+
201
+ % % merge 1-element no-priority Q with 1-element priority Q
202
+ Q6 = priority_queue :join (priority_queue :in (foo , Q ),
203
+ priority_queue :in (bar , 1 , Q )),
204
+ {true , false , 2 , [{1 , bar }, {0 , foo }], [bar , foo ]} =
205
+ test_priority_queue (Q6 ),
206
+
207
+ % % merge 1-element priority Q with 1-element no-priority Q
208
+ Q7 = priority_queue :join (priority_queue :in (foo , 1 , Q ),
209
+ priority_queue :in (bar , Q )),
210
+ {true , false , 2 , [{1 , foo }, {0 , bar }], [foo , bar ]} =
211
+ test_priority_queue (Q7 ),
212
+
213
+ % % merge 2 * 1-element same-priority Qs
214
+ Q8 = priority_queue :join (priority_queue :in (foo , 1 , Q ),
215
+ priority_queue :in (bar , 1 , Q )),
216
+ {true , false , 2 , [{1 , foo }, {1 , bar }], [foo , bar ]} =
217
+ test_priority_queue (Q8 ),
218
+
219
+ % % merge 2 * 1-element different-priority Qs
220
+ Q9 = priority_queue :join (priority_queue :in (foo , 1 , Q ),
221
+ priority_queue :in (bar , 2 , Q )),
222
+ {true , false , 2 , [{2 , bar }, {1 , foo }], [bar , foo ]} =
223
+ test_priority_queue (Q9 ),
224
+
225
+ % % merge 2 * 1-element different-priority Qs (other way around)
226
+ Q10 = priority_queue :join (priority_queue :in (bar , 2 , Q ),
227
+ priority_queue :in (foo , 1 , Q )),
228
+ {true , false , 2 , [{2 , bar }, {1 , foo }], [bar , foo ]} =
229
+ test_priority_queue (Q10 ),
230
+
231
+ % % merge 2 * 2-element multi-different-priority Qs
232
+ Q11 = priority_queue :join (Q6 , Q5 ),
233
+ {true , false , 4 , [{1 , bar }, {0 , foo }, {0 , foo }, {0 , bar }],
234
+ [bar , foo , foo , bar ]} = test_priority_queue (Q11 ),
235
+
236
+ % % and the other way around
237
+ Q12 = priority_queue :join (Q5 , Q6 ),
238
+ {true , false , 4 , [{1 , bar }, {0 , foo }, {0 , bar }, {0 , foo }],
239
+ [bar , foo , bar , foo ]} = test_priority_queue (Q12 ),
240
+
241
+ % % merge with negative priorities
242
+ Q13 = priority_queue :join (Q4 , Q5 ),
243
+ {true , false , 3 , [{0 , foo }, {0 , bar }, {- 1 , foo }], [foo , bar , foo ]} =
244
+ test_priority_queue (Q13 ),
245
+
246
+ % % and the other way around
247
+ Q14 = priority_queue :join (Q5 , Q4 ),
248
+ {true , false , 3 , [{0 , foo }, {0 , bar }, {- 1 , foo }], [foo , bar , foo ]} =
249
+ test_priority_queue (Q14 ),
250
+
251
+ % % joins with empty queues:
252
+ Q1 = priority_queue :join (Q , Q1 ),
253
+ Q1 = priority_queue :join (Q1 , Q ),
254
+
255
+ % % insert with priority into non-empty zero-priority queue
256
+ Q15 = priority_queue :in (baz , 1 , Q5 ),
257
+ {true , false , 3 , [{1 , baz }, {0 , foo }, {0 , bar }], [baz , foo , bar ]} =
258
+ test_priority_queue (Q15 ),
259
+
260
+ % % 1-element infinity priority Q
261
+ Q16 = priority_queue :in (foo , infinity , Q ),
262
+ {true , false , 1 , [{infinity , foo }], [foo ]} = test_priority_queue (Q16 ),
263
+
264
+ % % add infinity to 0-priority Q
265
+ Q17 = priority_queue :in (foo , infinity , priority_queue :in (bar , Q )),
266
+ {true , false , 2 , [{infinity , foo }, {0 , bar }], [foo , bar ]} =
267
+ test_priority_queue (Q17 ),
268
+
269
+ % % and the other way around
270
+ Q18 = priority_queue :in (bar , priority_queue :in (foo , infinity , Q )),
271
+ {true , false , 2 , [{infinity , foo }, {0 , bar }], [foo , bar ]} =
272
+ test_priority_queue (Q18 ),
273
+
274
+ % % add infinity to mixed-priority Q
275
+ Q19 = priority_queue :in (qux , infinity , Q3 ),
276
+ {true , false , 3 , [{infinity , qux }, {2 , bar }, {1 , foo }], [qux , bar , foo ]} =
277
+ test_priority_queue (Q19 ),
278
+
279
+ % % merge the above with a negative priority Q
280
+ Q20 = priority_queue :join (Q19 , Q4 ),
281
+ {true , false , 4 , [{infinity , qux }, {2 , bar }, {1 , foo }, {- 1 , foo }],
282
+ [qux , bar , foo , foo ]} = test_priority_queue (Q20 ),
283
+
284
+ % % merge two infinity priority queues
285
+ Q21 = priority_queue :join (priority_queue :in (foo , infinity , Q ),
286
+ priority_queue :in (bar , infinity , Q )),
287
+ {true , false , 2 , [{infinity , foo }, {infinity , bar }], [foo , bar ]} =
288
+ test_priority_queue (Q21 ),
289
+
290
+ % % merge two mixed priority with infinity queues
291
+ Q22 = priority_queue :join (Q18 , Q20 ),
292
+ {true , false , 6 , [{infinity , foo }, {infinity , qux }, {2 , bar }, {1 , foo },
293
+ {0 , bar }, {- 1 , foo }], [foo , qux , bar , foo , bar , foo ]} =
294
+ test_priority_queue (Q22 ),
295
+
296
+ passed .
297
+
298
+ priority_queue_in_all (Q , L ) ->
299
+ lists :foldl (fun (X , Acc ) -> priority_queue :in (X , Acc ) end , Q , L ).
300
+
301
+ priority_queue_out_all (Q ) ->
302
+ case priority_queue :out (Q ) of
303
+ {empty , _ } -> [];
304
+ {{value , V }, Q1 } -> [V | priority_queue_out_all (Q1 )]
305
+ end .
306
+
307
+ test_priority_queue (Q ) ->
308
+ {priority_queue :is_queue (Q ),
309
+ priority_queue :is_empty (Q ),
310
+ priority_queue :len (Q ),
311
+ priority_queue :to_list (Q ),
312
+ priority_queue_out_all (Q )}.
313
+
314
+ test_simple_n_element_queue (N ) ->
315
+ Items = lists :seq (1 , N ),
316
+ Q = priority_queue_in_all (priority_queue :new (), Items ),
317
+ ToListRes = [{0 , X } || X <- Items ],
318
+ {true , false , N , ToListRes , Items } = test_priority_queue (Q ),
319
+ passed .
320
+
52
321
% % ---------------------------------------------------------------------------
53
- % % rabbit_resource_monitor .
322
+ % % resource_monitor .
54
323
% % ---------------------------------------------------------------------------
55
324
56
325
parse_information_unit (_Config ) ->
@@ -210,3 +479,17 @@ parse_line_linux(_Config) ->
210
479
{" MemTotal 502968 kB" , {'MemTotal' , 515039232 }},
211
480
{" MemTotal 50296866 " , {'MemTotal' , 50296866 }}]),
212
481
ok .
482
+
483
+ % % ---------------------------------------------------------------------------
484
+ % % Unordered tests (originally from rabbit_tests.erl).
485
+ % % ---------------------------------------------------------------------------
486
+
487
+ version_equivalance (_Config ) ->
488
+ true = rabbit_misc :version_minor_equivalent (" 3.0.0" , " 3.0.0" ),
489
+ true = rabbit_misc :version_minor_equivalent (" 3.0.0" , " 3.0.1" ),
490
+ true = rabbit_misc :version_minor_equivalent (" %%VSN%%" , " %%VSN%%" ),
491
+ false = rabbit_misc :version_minor_equivalent (" 3.0.0" , " 3.1.0" ),
492
+ false = rabbit_misc :version_minor_equivalent (" 3.0.0" , " 3.0" ),
493
+ false = rabbit_misc :version_minor_equivalent (" 3.0.0" , " 3.0.0.1" ),
494
+ false = rabbit_misc :version_minor_equivalent (" 3.0.0" , " 3.0.foo" ),
495
+ passed .
0 commit comments