Line data Source code
1 : // Copyright (c) 2012-2024 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // https://snapwebsites.org/project/eventdispatcher
4 : // contact@m2osw.com
5 : //
6 : // This program is free software: you can redistribute it and/or modify
7 : // it under the terms of the GNU General Public License as published by
8 : // the Free Software Foundation, either version 3 of the License, or
9 : // (at your option) any later version.
10 : //
11 : // This program is distributed in the hope that it will be useful,
12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : // GNU General Public License for more details.
15 : //
16 : // You should have received a copy of the GNU General Public License
17 : // along with this program. If not, see <https://www.gnu.org/licenses/>.
18 :
19 : // this diagnostic has to be turned off "globally" so the catch2 does not
20 : // generate the warning on the floating point == operator
21 : //
22 : #pragma GCC diagnostic ignored "-Wfloat-equal"
23 :
24 : // self
25 : //
26 : #include "catch_main.h"
27 :
28 :
29 :
30 : // reporter
31 : //
32 : #include <eventdispatcher/reporter/executor.h>
33 :
34 : #include <eventdispatcher/reporter/instruction_factory.h>
35 : #include <eventdispatcher/reporter/parser.h>
36 : #include <eventdispatcher/reporter/variable_address.h>
37 : #include <eventdispatcher/reporter/variable_array.h>
38 : #include <eventdispatcher/reporter/variable_floating_point.h>
39 : #include <eventdispatcher/reporter/variable_integer.h>
40 : #include <eventdispatcher/reporter/variable_list.h>
41 : #include <eventdispatcher/reporter/variable_regex.h>
42 : #include <eventdispatcher/reporter/variable_string.h>
43 : #include <eventdispatcher/reporter/variable_timestamp.h>
44 : #include <eventdispatcher/reporter/variable_void.h>
45 :
46 :
47 : // libaddr
48 : //
49 : #include <libaddr/addr_parser.h>
50 :
51 :
52 : // eventdispatcher
53 : //
54 : #include <eventdispatcher/communicator.h>
55 : #include <eventdispatcher/exception.h>
56 : #include <eventdispatcher/tcp_client_connection.h>
57 : #include <eventdispatcher/tcp_client_permanent_message_connection.h>
58 :
59 :
60 : // snapdev
61 : //
62 : #include <snapdev/gethostname.h>
63 :
64 :
65 : // last include
66 : //
67 : #include <snapdev/poison.h>
68 :
69 :
70 :
71 : namespace
72 : {
73 :
74 :
75 :
76 : constexpr char const * const g_program_sleep_func =
77 : "call(label: func_sleep)\n"
78 : "exit(timeout: 1)\n"
79 : "label(name: func_sleep)\n"
80 : "sleep(seconds: 2.5)\n"
81 : "return()\n"
82 : ;
83 :
84 : constexpr char const * const g_program_sort_func =
85 : "set_variable(name: s1, value: 'hello')\n"
86 : "set_variable(name: s2, value: 'world')\n"
87 : "set_variable(name: s3, value: 'who')\n"
88 : "set_variable(name: s4, value: 'are')\n"
89 : "set_variable(name: s5, value: 'you?')\n"
90 : "sort(var1: s1, var2: s2, var3: s3, var4: s4, var5: s5)\n"
91 :
92 : "set_variable(name: i1, value: 506)\n"
93 : "set_variable(name: i2, value: 1003)\n"
94 : "set_variable(name: i3, value: 73)\n"
95 : "set_variable(name: i4, value: 1004)\n"
96 : "set_variable(name: i5, value: -3)\n"
97 : "sort(var1: i1, var2: i2, var3: i3, var4: i4, var5: i5)\n"
98 :
99 : "set_variable(name: f1, value: 50.6)\n"
100 : "set_variable(name: f2, value: -10.103)\n"
101 : "set_variable(name: f3, value: 73.5)\n"
102 : "set_variable(name: f4, value: 1.004)\n"
103 : "set_variable(name: f5, value: -0.3)\n"
104 : "sort(var1: f1, var2: f2, var3: f3, var4: f4, var5: f5)\n"
105 :
106 : "exit()\n"
107 : ;
108 :
109 : constexpr char const * const g_program_start_thread =
110 : "set_variable(name: test, value: 33)\n"
111 : "set_variable(name: test_copy_between_dollars, value: \"$${test}$\")\n"
112 : "run()\n"
113 : "set_variable(name: runner, value: 6.07)\n"
114 : "set_variable(name: runner_copy_as_is, value: \"runner = ${runner}\", type: string)\n"
115 : "set_variable(name: time_limit, value: @1713934141.107805991, type: timestamp)\n"
116 : "set_variable(name: time_limit_copy, value: \"limit: ${time_limit}\")\n"
117 : "set_variable(name: time_from_float, value: \"1713934141.107805991\", type: timestamp)\n"
118 : "set_variable(name: host_ip, value: <127.7.3.51>)\n"
119 : "set_variable(name: host_ip_copy, value: \"Host is at ${host_ip} address\")\n"
120 : "set_variable(name: time_and_host_ip, value: \"time ${time_limit} and address ${host_ip}...\")\n"
121 : "strlen(variable_name: length, string: ${time_and_host_ip})\n"
122 : ;
123 :
124 : constexpr char const * const g_program_start_thread_twice =
125 : "set_variable(name: test, value: 33)\n"
126 : "run()\n"
127 : "set_variable(name: runner, value: 6.07)\n"
128 : "run()\n" // second run() is forbidden
129 : ;
130 :
131 : constexpr char const * const g_program_verify_computation_integer =
132 : "set_variable(name: t01, value: 3)\n"
133 :
134 : "set_variable(name: t11, value: -3)\n"
135 : "set_variable(name: t12, value: +3)\n"
136 :
137 : "set_variable(name: t21, value: 3 + 2)\n"
138 : "set_variable(name: t22, value: -(3 + 2))\n"
139 : "set_variable(name: t23, value: 20 - 4)\n"
140 : "set_variable(name: t24, value: 3 * 2)\n"
141 : "set_variable(name: t25, value: 20 / 4)\n"
142 : "set_variable(name: t26, value: 27 % 11)\n"
143 :
144 : "set_variable(name: t31, value: 3 + 2 * 5)\n"
145 : "set_variable(name: t32, value: -7 + 15 / 3)\n"
146 : "set_variable(name: t33, value: +2 + 15 % 7)\n"
147 :
148 : "set_variable(name: t41, value: (3 + 2) * 5)\n"
149 : "set_variable(name: t42, value: (-7 + 15) / 3)\n"
150 : "set_variable(name: t43, value: (+2 + 15) % 7)\n"
151 : ;
152 :
153 : constexpr char const * const g_program_verify_computation_floating_point =
154 : "set_variable(name: t01, value: 3.01)\n"
155 :
156 : "set_variable(name: t11, value: -3.5)\n"
157 : "set_variable(name: t12, value: +3.2)\n"
158 :
159 : "set_variable(name: t21ff, value: 3.01 + 2.45)\n"
160 : "set_variable(name: t21if, value: 3 + 2.54)\n"
161 : "set_variable(name: t21fi, value: 3.01 + 2)\n"
162 : "set_variable(name: t22ff, value: -(3.5 + 2.5))\n"
163 : "set_variable(name: t22if, value: -(3 + 2.11))\n"
164 : "set_variable(name: t22fi, value: -(3.07 + 2))\n"
165 : "set_variable(name: t23ff, value: 20.07 - 4.13)\n"
166 : "set_variable(name: t23if, value: 20 - 4.78)\n"
167 : "set_variable(name: t23fi, value: 20.91 - 4)\n"
168 : "set_variable(name: t24ff, value: 3.41 * 2.14)\n"
169 : "set_variable(name: t24if, value: 3 * 2.67)\n"
170 : "set_variable(name: t24fi, value: 3.32 * 2)\n"
171 : "set_variable(name: t25ff, value: 20.83 / 4.07)\n"
172 : "set_variable(name: t25if, value: 20 / 4.4)\n"
173 : "set_variable(name: t25fi, value: 20.93 / 4)\n"
174 : "set_variable(name: t26ff, value: 27.27 % 11.11)\n"
175 : "set_variable(name: t26if, value: 27 % 11.88)\n"
176 : "set_variable(name: t26fi, value: 27.72 % 11)\n"
177 :
178 : "set_variable(name: t31fff, value: 3.03 + 2.2 * 5.9)\n"
179 : "set_variable(name: t31iff, value: 3 + 2.5 * 5.7)\n"
180 : "set_variable(name: t31fif, value: 3.2 + 2 * 5.3)\n"
181 : "set_variable(name: t31ffi, value: 3.07 + 2.28 * 5)\n"
182 : "set_variable(name: t31iif, value: 3 + 2 * 5.67)\n"
183 : "set_variable(name: t31ifi, value: 3 + 2.56 * 5)\n"
184 : "set_variable(name: t31fii, value: 3.33 + 2 * 5)\n"
185 : "set_variable(name: t32fff, value: -7.11 + 15.7 / 3.06)\n"
186 : "set_variable(name: t32iff, value: -7 + 15.25 / 3.31)\n"
187 : "set_variable(name: t32fif, value: -7.78 + 15 / 3.77)\n"
188 : "set_variable(name: t32ffi, value: -7.09 + 15.34 / 3)\n"
189 : "set_variable(name: t32iif, value: -7 + 15 / 3.30)\n"
190 : "set_variable(name: t32ifi, value: -7 + 15.09 / 3)\n"
191 : "set_variable(name: t32fii, value: -7.94 + 15 / 3)\n"
192 : "set_variable(name: t33fff, value: +2.21 + 15.16 % 7.8)\n"
193 : "set_variable(name: t33iff, value: +2 + 15.12 % 7.93)\n"
194 : "set_variable(name: t33fif, value: +2.58 + 15 % 7.63)\n"
195 : "set_variable(name: t33ffi, value: +2.12 + 15.09 % 7)\n"
196 : "set_variable(name: t33iif, value: +2 + 15 % 7.19)\n"
197 : "set_variable(name: t33ifi, value: +2 + 15.18 % 7)\n"
198 : "set_variable(name: t33fii, value: +2.17 + 15 % 7)\n"
199 :
200 : "set_variable(name: t41fff, value: (3.45 + 2.06) * 5.55)\n"
201 : "set_variable(name: t41iff, value: (3 + 2.17) * 5.07)\n"
202 : "set_variable(name: t41fif, value: (3.37 + 2) * 5.12)\n"
203 : "set_variable(name: t41ffi, value: (3.45 + 2.67) * 5)\n"
204 : "set_variable(name: t41iif, value: (3 + 2) * 5.3)\n"
205 : "set_variable(name: t41ifi, value: (3 + 2.9) * 5)\n"
206 : "set_variable(name: t41fii, value: (3.4 + 2) * 5)\n"
207 : "set_variable(name: t42fff, value: (-7.4 + 15.15) / 3.93)\n"
208 : "set_variable(name: t42iff, value: (-7 + 15.21) / 3.43)\n"
209 : "set_variable(name: t42fif, value: (-7.72 + 15) / 3.31)\n"
210 : "set_variable(name: t42ffi, value: (-7.43 + 15.89) / 3)\n"
211 : "set_variable(name: t42iif, value: (-7 + 15) / 3.4)\n"
212 : "set_variable(name: t42ifi, value: (-7 + 15.09) / 3)\n"
213 : "set_variable(name: t42fii, value: (-7.73 + 15) / 3)\n"
214 : "set_variable(name: t43fff, value: (+2.25 + 15.36) % 7.47)\n"
215 : "set_variable(name: t43iff, value: (+2 + 15.16) % 7.38)\n"
216 : "set_variable(name: t43fif, value: (+2.51 + 15) % 7.59)\n"
217 : "set_variable(name: t43ffi, value: (+2.4 + 15.3) % 7)\n"
218 : "set_variable(name: t43iif, value: (+2 + 15) % 7.0)\n"
219 : "set_variable(name: t43ifi, value: (+2 + 15.8) % 7)\n"
220 : "set_variable(name: t43fii, value: (+2.07 + 15) % 7)\n"
221 : ;
222 :
223 : constexpr char const * const g_program_verify_computation_timestamp =
224 : "set_variable(name: t01, value: @123 + 5)\n"
225 : "set_variable(name: t02, value: 33 + @123)\n"
226 : "set_variable(name: t03, value: @123 - 5)\n"
227 : "set_variable(name: t04, value: 33 - @123)\n"
228 :
229 : "set_variable(name: t11, value: @123 + 5.09)\n"
230 : "set_variable(name: t12, value: 33.501923821 + @123)\n"
231 : "set_variable(name: t13, value: @123 - 5.001)\n"
232 : "set_variable(name: t14, value: 333.98201992 - @123)\n"
233 :
234 : "set_variable(name: t21, value: -@123)\n"
235 : "set_variable(name: t22, value: +@123)\n"
236 :
237 : "set_variable(name: t31, value: @300.561 - @123.231)\n"
238 : "set_variable(name: t32, value: @34.3123 + @123.9984312)\n"
239 : ;
240 :
241 : constexpr char const * const g_program_verify_hex =
242 : "hex(variable_name: t01, value: 0x1a4fd2)\n"
243 : "hex(variable_name: t02, value: 0xabcdef, uppercase: 0)\n"
244 : "hex(variable_name: t03, value: 0xabcdef, uppercase: 1)\n"
245 : "hex(variable_name: t04, value: 1, width: 8)\n"
246 : "hex(variable_name: t05, value: 0xabcdef, uppercase: 1, width: 8)\n"
247 : ;
248 :
249 : constexpr char const * const g_program_verify_now =
250 : "now(variable_name: about_now)\n"
251 : "exit()\n"
252 : ;
253 :
254 : constexpr char const * const g_program_verify_max_pid =
255 : "max_pid(variable_name: top_pid)\n"
256 : "exit()\n"
257 : ;
258 :
259 : constexpr char const * const g_program_verify_random =
260 : "random(variable_name: any_number)\n"
261 : "random(variable_name: positive, negative: 0)\n"
262 : "random(variable_name: positive_or_negative, negative: 1)\n"
263 : "exit()\n"
264 : ;
265 :
266 : constexpr char const * const g_program_verify_hostname =
267 : "hostname(variable_name: host_name)\n"
268 : "exit()\n"
269 : ;
270 :
271 : constexpr char const * const g_program_verify_kill_number =
272 : "kill(signal: 18)\n"
273 : "exit()\n"
274 : ;
275 :
276 : constexpr char const * const g_program_verify_kill_identifier =
277 : "kill(signal: SIGCONT)\n"
278 : "exit()\n"
279 : ;
280 :
281 : constexpr char const * const g_program_verify_kill_string =
282 : "kill(signal: \"cont\")\n"
283 : "exit()\n"
284 : ;
285 :
286 : constexpr char const * const g_program_verify_kill_unsupported_timestamp =
287 : "kill(signal: @123.3342)\n"
288 :
289 : "exit(error_message: \"test is expected to fail before reaching this statement.\")\n"
290 : ;
291 :
292 : constexpr char const * const g_program_verify_kill_integer_too_large =
293 : "kill(signal: 100)\n"
294 :
295 : "exit(error_message: \"test is expected to fail before reaching this statement.\")\n"
296 : ;
297 :
298 : constexpr char const * const g_program_verify_kill_unknown_signal_name =
299 : "kill(signal: \"unknown\")\n"
300 :
301 : "exit(error_message: \"test is expected to fail before reaching this statement.\")\n"
302 : ;
303 :
304 : constexpr char const * const g_program_verify_computation_address =
305 : "set_variable(name: t01, value: <127.0.0.1> + 256)\n"
306 : "set_variable(name: t02, value: 256 + <192.168.3.57>)\n"
307 : "set_variable(name: t03, value: <172.131.4.1> - 256)\n"
308 :
309 : "set_variable(name: t11, value: <10.5.34.255> - <10.5.33.0>)\n"
310 : ;
311 :
312 : constexpr char const * const g_program_verify_computation_concatenation =
313 : "set_variable(name: t01, value: ident + ifier)\n"
314 :
315 : "set_variable(name: t11, value: 'single' + ' ' + 'string')\n"
316 : "set_variable(name: t12, value: 'single' + \" \" + 'string')\n"
317 : "set_variable(name: t13, value: 'single' + ' ' + \"string\")\n"
318 : "set_variable(name: t14, value: \"double\" + \" \" + \"string\")\n"
319 :
320 : "set_variable(name: t21, value: +identify)\n"
321 : "set_variable(name: t22, value: +'single string')\n"
322 : "set_variable(name: t23, value: +\"double string\")\n"
323 :
324 : "set_variable(name: t31, value: 'single' + 36)\n"
325 : "set_variable(name: t32, value: 258 + 'single')\n"
326 : "set_variable(name: t33, value: \"string\" + 102)\n"
327 : "set_variable(name: t34, value: 5005 + \"double\")\n"
328 :
329 : "set_variable(name: t41, value: 'single' + `[0-9]+`)\n"
330 : "set_variable(name: t42, value: `[0-9]+` + 'single')\n"
331 : "set_variable(name: t43, value: \"string\" + `[0-9]+`)\n"
332 : "set_variable(name: t44, value: `[0-9]+` + \"double\")\n"
333 : "set_variable(name: t45, value: 'a|b' + `[0-9]+`)\n"
334 : "set_variable(name: t46, value: `[0-9]+` + 'c{3,9}')\n"
335 : "set_variable(name: t47, value: \"[a-z]?\" + `[0-9]+`)\n"
336 : "set_variable(name: t48, value: `[0-9]+` + \"a?b?c?\")\n"
337 : "set_variable(name: t49, value: `[0-9]+` + `(a|b|c)?`)\n"
338 : ;
339 :
340 : constexpr char const * const g_program_verify_computation_string_repeat =
341 : "set_variable(name: t01, value: 'abc' * 3)\n"
342 : "set_variable(name: t02, value: \"xyz\" * 5)\n"
343 : "set_variable(name: t03, value: \"zero\" * 0)\n"
344 : "set_variable(name: t04, value: \"one\" * 1)\n"
345 : ;
346 :
347 : constexpr char const * const g_program_verify_variable_in_string =
348 : "set_variable(name: foo, value: 'abc')\n"
349 : "set_variable(name: bar, value: \"[${foo}]\")\n"
350 : ;
351 :
352 : constexpr char const * const g_program_accept_one_message =
353 : "run()\n"
354 : "listen(address: <127.0.0.1:20002>, connection_type: messenger)\n"
355 : "label(name: wait_message)\n"
356 : "clear_message()\n"
357 : "wait(timeout: 10.0, mode: wait)\n" // first wait reacts on connect(), second wait receives the REGISTER message
358 : "has_message()\n"
359 : "if(false: wait_message)\n"
360 : "show_message()\n"
361 : "verify_message(command: `^REGISTER$`, required_parameters: { service: responder, version: 1 }, optional_parameters: { commands: \"READY,HELP,STOP\" }, forbidden_parameters: { forbidden })\n"
362 : "save_parameter_value(parameter_name: command, variable_name: command)\n"
363 : "save_parameter_value(parameter_name: version, variable_name: register_version)\n"
364 : "save_parameter_value(parameter_name: service, variable_name: register_service, type: identifier)\n"
365 : "send_message(command: READY, sent_server: reporter_test_extension, sent_service: test_processor, server: reporter_test, service: accept_one_message, parameters: { status: alive, version: 9 })\n"
366 : "wait(timeout: 10.0, mode: drain)\n"
367 : "disconnect()\n"
368 : "exit()\n"
369 : ;
370 :
371 : constexpr char const * const g_program_receive_unwanted_message =
372 : "run()\n"
373 : "listen(address: <127.0.0.1:20002>)\n"
374 : "label(name: wait_message)\n"
375 : "clear_message()\n"
376 : "wait(timeout: 10.0, mode: wait)\n"
377 : "has_message()\n"
378 : "if(false: wait_message)\n"
379 : "show_message()\n"
380 : "verify_message(command: REGISTER, required_parameters: { service: responder, version: `^[0-9]+$` }, optional_parameters: { commands: \"READY,HELP,STOP\" }, forbidden_parameters: { forbidden })\n"
381 : "save_parameter_value(parameter_name: version, variable_name: register_version, type: integer)\n"
382 : "send_message(command: READY, parameters: { version: 9 })\n"
383 : "print(message: \"nearly done\")\n"
384 : "exit(timeout: 2.5)\n"
385 : ;
386 :
387 : constexpr char const * const g_program_send_unsupported_message_parameter_type =
388 : "run()\n"
389 : "listen(address: <127.0.0.1:20002>)\n"
390 : "label(name: wait_message)\n"
391 : "clear_message()\n"
392 : "wait(timeout: 10.0, mode: wait)\n" // first wait reacts on connect(), second wait receives the REGISTER message
393 : "has_message()\n"
394 : "if(false: wait_message)\n"
395 : "show_message()\n"
396 : "verify_message(command: REGISTER, required_parameters: { service: responder, version: 1 }, optional_parameters: { commands: \"READY,HELP,STOP\" }, forbidden_parameters: { forbidden })\n"
397 : "save_parameter_value(parameter_name: version, variable_name: register_version, type: integer)\n"
398 : "send_message(command: READY, parameters: { status: 3.05 })\n" // floating point not yet supported
399 : "wait(timeout: 1.0, mode: drain)\n"
400 : ;
401 :
402 : constexpr char const * const g_program_send_invalid_parameter_value_type =
403 : "run()\n"
404 : "listen(address: <127.0.0.1:20002>)\n"
405 : "label(name: wait_message)\n"
406 : "clear_message()\n"
407 : "wait(timeout: 10.0, mode: wait)\n"
408 : "has_message()\n"
409 : "if(false: wait_message)\n"
410 : "show_message()\n"
411 : "verify_message(command: REGISTER, required_parameters: { service: responder, version: 1 }, optional_parameters: { commands: \"READY,HELP,STOP\" }, forbidden_parameters: { forbidden })\n"
412 : "save_parameter_value(parameter_name: service, variable_name: register_version, type: integer)\n" // service is not an integer
413 : "send_message(command: READY, parameters: { status: \"3.05\" })\n"
414 : "wait(timeout: 1.0, mode: drain)\n"
415 : ;
416 :
417 : constexpr char const * const g_program_save_parameter_of_type_timestamp =
418 : "run()\n"
419 : "listen(address: <127.0.0.1:20002>, connection_type: messenger)\n"
420 : "label(name: wait_message)\n"
421 : "wait(timeout: 10.0, mode: wait)\n"
422 : "has_message()\n"
423 : "if(false: wait_message)\n"
424 : "show_message()\n"
425 : "verify_message(command: REGISTER, required_parameters: { service: responder, version: 1 }, optional_parameters: { commands: \"READY,HELP,STOP\" }, forbidden_parameters: { forbidden })\n"
426 : "save_parameter_value(parameter_name: version, variable_name: register_version, type: integer)\n"
427 : "save_parameter_value(parameter_name: large_number, variable_name: default_integer, type: integer)\n"
428 : "send_message(command: READY, parameters: { status: \"3.05\", date: @1715440881.543723981 })\n"
429 : "clear_message()\n"
430 : "label(name: wait_second_message)\n"
431 : "wait(timeout: 10.0, mode: wait)\n"
432 : "has_message()\n"
433 : "if(false: wait_second_message)\n"
434 : "show_message()\n"
435 : "verify_message(command: TIMED, required_parameters: { now: `^[0-9]+(\\\\.[0-9]+)?$` } )\n"
436 : "save_parameter_value(parameter_name: now, variable_name: timed_value, type: timestamp)\n"
437 : "verify_message(command: TIMED, required_parameters: { now: ${timed_value} } )\n" // this time we try with a timestamp parameter
438 : "save_parameter_value(parameter_name: not_defined, variable_name: default_time, type: timestamp)\n"
439 : "exit()\n"
440 : ;
441 :
442 : constexpr char const * const g_program_save_parameter_with_unknown_type =
443 : "run()\n"
444 : "listen(address: <127.0.0.1:20002>)\n"
445 : "label(name: wait_message)\n"
446 : "clear_message()\n"
447 : "wait(timeout: 10.0, mode: wait)\n"
448 : "has_message()\n"
449 : "if(false: wait_message)\n"
450 : "show_message()\n"
451 : "verify_message(command: REGISTER, required_parameters: { service: responder, version: 1 }, optional_parameters: { commands: \"READY,HELP,STOP\" }, forbidden_parameters: { forbidden })\n"
452 : "save_parameter_value(parameter_name: service, variable_name: register_version, type: void)\n" // "void" is not a supported type here
453 : "send_message(command: READY, parameters: { status: \"3.05\" })\n"
454 : "wait(timeout: 1.0, mode: drain)\n"
455 : ;
456 :
457 : constexpr char const * const g_program_undefined_variable =
458 : "has_type(name: undefined_variable, type: void)\n"
459 : "if(unordered: it_worked)\n"
460 : "exit(error_message: \"undefined variable not properly detected.\")\n"
461 : "label(name: it_worked)\n"
462 : "exit()\n"
463 : ;
464 :
465 : constexpr char const * const g_program_integer_variable =
466 : "set_variable(name: my_int, value: 33)\n"
467 : "has_type(name: my_int, type: string)\n"
468 : "if(false: not_string)\n"
469 : "exit(error_message: \"integer variable detected as a string.\")\n"
470 : "label(name: not_string)\n"
471 : "has_type(name: my_int, type: integer)\n"
472 : "if(true: is_integer)\n"
473 : "exit(error_message: \"integer variable not properly detected as such.\")\n"
474 : "label(name: is_integer)\n"
475 : "exit()\n"
476 : ;
477 :
478 : constexpr char const * const g_program_string_variable =
479 : "set_variable(name: my_str, value: \"3.3\")\n"
480 : "has_type(name: my_str, type: floating_point)\n"
481 : "if(false: not_floating_point)\n"
482 : "exit(error_message: \"string variable detected as a floating_point.\")\n"
483 : "label(name: not_floating_point)\n"
484 : "has_type(name: my_str, type: string)\n"
485 : "if(true: is_string)\n"
486 : "exit(error_message: \"string variable not properly detected as such.\")\n"
487 : "label(name: is_string)\n"
488 : "exit()\n"
489 : ;
490 :
491 : constexpr char const * const g_program_if_variable =
492 : "if(variable: not_defined, unordered: not_defined_worked)\n"
493 : "exit(error_message: \"if(variable: <undefined>) failed test.\")\n"
494 : "label(name: not_defined_worked)\n"
495 :
496 : // >, >=, !=, true, ordered
497 : "set_variable(name: my_var, value: 5)\n"
498 : "if(variable: my_var, greater: positive_greater_int_worked)\n"
499 : "exit(error_message: \"if(variable: <positive integer> + greater) failed test.\")\n"
500 : "label(name: positive_greater_int_worked)\n"
501 : "if(variable: my_var, greater_or_equal: positive_greater_or_equal_int_worked)\n"
502 : "exit(error_message: \"if(variable: <positive integer> + greater_or_equal) failed test.\")\n"
503 : "label(name: positive_greater_or_equal_int_worked)\n"
504 : "if(variable: my_var, not_equal: positive_not_equal_int_worked)\n"
505 : "exit(error_message: \"if(variable: <positive integer> + not_equal) failed test.\")\n"
506 : "label(name: positive_not_equal_int_worked)\n"
507 : "if(variable: my_var, true: positive_true_int_worked)\n"
508 : "exit(error_message: \"if(variable: <positive integer> + true) failed test.\")\n"
509 : "label(name: positive_true_int_worked)\n"
510 : "if(variable: my_var, ordered: positive_ordered_int_worked)\n"
511 : "exit(error_message: \"if(variable: <positive integer> + ordered) failed test.\")\n"
512 : "label(name: positive_ordered_int_worked)\n"
513 :
514 : // <, <=, !=, true, ordered
515 : "set_variable(name: my_var, value: -5)\n"
516 : "if(variable: my_var, less: negative_less_int_worked)\n"
517 : "exit(error_message: \"if(variable: <negative integer> + less) failed test.\")\n"
518 : "label(name: negative_less_int_worked)\n"
519 : "if(variable: my_var, less_or_equal: negative_less_or_equal_int_worked)\n"
520 : "exit(error_message: \"if(variable: <negative integer> + less_or_equal) failed test.\")\n"
521 : "label(name: negative_less_or_equal_int_worked)\n"
522 : "if(variable: my_var, not_equal: negative_not_equal_int_worked)\n"
523 : "exit(error_message: \"if(variable: <negative integer> + not_equal) failed test.\")\n"
524 : "label(name: negative_not_equal_int_worked)\n"
525 : "if(variable: my_var, true: negative_true_int_worked)\n"
526 : "exit(error_message: \"if(variable: <negative integer> + true) failed test.\")\n"
527 : "label(name: negative_true_int_worked)\n"
528 : "if(variable: my_var, ordered: negative_ordered_int_worked)\n"
529 : "exit(error_message: \"if(variable: <negative integer> + ordered) failed test.\")\n"
530 : "label(name: negative_ordered_int_worked)\n"
531 :
532 : // ==, false, ordered
533 : "set_variable(name: my_var, value: 0)\n"
534 : "if(variable: my_var, equal: zero_equal_int_worked)\n"
535 : "exit(error_message: \"if(variable: <zero integer> + equal) failed test.\")\n"
536 : "label(name: zero_equal_int_worked)\n"
537 : "if(variable: my_var, less_or_equal: zero_less_or_equal_int_worked)\n"
538 : "exit(error_message: \"if(variable: <negative integer> + less_or_equal) failed test.\")\n"
539 : "label(name: zero_less_or_equal_int_worked)\n"
540 : "if(variable: my_var, greater_or_equal: zero_greater_or_equal_int_worked)\n"
541 : "exit(error_message: \"if(variable: <negative integer> + greater_or_equal) failed test.\")\n"
542 : "label(name: zero_greater_or_equal_int_worked)\n"
543 : "if(variable: my_var, false: zero_false_int_worked)\n"
544 : "exit(error_message: \"if(variable: <negative integer> + false) failed test.\")\n"
545 : "label(name: zero_false_int_worked)\n"
546 : "if(variable: my_var, ordered: zero_ordered_int_worked)\n"
547 : "exit(error_message: \"if(variable: <negative integer> + ordered) failed test.\")\n"
548 : "label(name: zero_ordered_int_worked)\n"
549 :
550 : // >, >=, !=, true, ordered
551 : "set_variable(name: my_var, value: 7.3)\n"
552 : "if(variable: my_var, greater: positive_greater_flt_worked)\n"
553 : "exit(error_message: \"if(variable: <positive floating point> + greater) failed test.\")\n"
554 : "label(name: positive_greater_flt_worked)\n"
555 : "if(variable: my_var, greater_or_equal: positive_greater_or_equal_flt_worked)\n"
556 : "exit(error_message: \"if(variable: <positive floating point> + greater_or_equal) failed test.\")\n"
557 : "label(name: positive_greater_or_equal_flt_worked)\n"
558 : "if(variable: my_var, not_equal: positive_not_equal_flt_worked)\n"
559 : "exit(error_message: \"if(variable: <positive floating point> + not_equal) failed test.\")\n"
560 : "label(name: positive_not_equal_flt_worked)\n"
561 : "if(variable: my_var, true: positive_true_flt_worked)\n"
562 : "exit(error_message: \"if(variable: <positive floating point> + true) failed test.\")\n"
563 : "label(name: positive_true_flt_worked)\n"
564 : "if(variable: my_var, ordered: positive_ordered_flt_worked)\n"
565 : "exit(error_message: \"if(variable: <positive floating point> + ordered) failed test.\")\n"
566 : "label(name: positive_ordered_flt_worked)\n"
567 :
568 : // <, <=, !=, true, ordered
569 : "set_variable(name: my_var, value: -7.3)\n"
570 : "if(variable: my_var, less: negative_less_flt_worked)\n"
571 : "exit(error_message: \"if(variable: <negative floating point> + less) failed test.\")\n"
572 : "label(name: negative_less_flt_worked)\n"
573 : "if(variable: my_var, less_or_equal: negative_less_or_equal_flt_worked)\n"
574 : "exit(error_message: \"if(variable: <negative integer> + less_or_equal) failed test.\")\n"
575 : "label(name: negative_less_or_equal_flt_worked)\n"
576 : "if(variable: my_var, not_equal: negative_not_equal_flt_worked)\n"
577 : "exit(error_message: \"if(variable: <negative integer> + not_equal) failed test.\")\n"
578 : "label(name: negative_not_equal_flt_worked)\n"
579 : "if(variable: my_var, true: negative_true_flt_worked)\n"
580 : "exit(error_message: \"if(variable: <negative integer> + true) failed test.\")\n"
581 : "label(name: negative_true_flt_worked)\n"
582 : "if(variable: my_var, ordered: negative_ordered_flt_worked)\n"
583 : "exit(error_message: \"if(variable: <negative integer> + ordered) failed test.\")\n"
584 : "label(name: negative_ordered_flt_worked)\n"
585 :
586 : // ==, false, ordered
587 : "set_variable(name: my_var, value: 0.0)\n"
588 : "if(variable: my_var, equal: zero_equal_flt_worked)\n"
589 : "exit(error_message: \"if(variable: <zero floating point> + equal) failed test.\")\n"
590 : "label(name: zero_equal_flt_worked)\n"
591 : "if(variable: my_var, less_or_equal: zero_less_or_equal_flt_worked)\n"
592 : "exit(error_message: \"if(variable: <negative integer> + less_or_equal) failed test.\")\n"
593 : "label(name: zero_less_or_equal_flt_worked)\n"
594 : "if(variable: my_var, greater_or_equal: zero_greater_or_equal_flt_worked)\n"
595 : "exit(error_message: \"if(variable: <negative integer> + greater_or_equal) failed test.\")\n"
596 : "label(name: zero_greater_or_equal_flt_worked)\n"
597 : "if(variable: my_var, false: zero_false_flt_worked)\n"
598 : "exit(error_message: \"if(variable: <negative integer> + false) failed test.\")\n"
599 : "label(name: zero_false_flt_worked)\n"
600 : "if(variable: my_var, ordered: zero_ordered_flt_worked)\n"
601 : "exit(error_message: \"if(variable: <negative integer> + ordered) failed test.\")\n"
602 : "label(name: zero_ordered_flt_worked)\n"
603 :
604 : // unordered
605 : "set_variable(name: my_var, value: NaN)\n"
606 : "if(variable: my_var, unordered: unordered_flt_worked)\n"
607 : "exit(error_message: \"if(variable: <unordered floating point>) failed test.\")\n"
608 : "label(name: unordered_flt_worked)\n"
609 :
610 : "exit()\n"
611 : ;
612 :
613 : constexpr char const * const g_program_compare_and_if =
614 : // integer greater/less
615 : "set_variable(name: a, value: 13)\n"
616 : "set_variable(name: b, value: 10)\n"
617 : "compare(expression: ${a} <=> ${b})\n"
618 : "if(greater: integer_greater)\n"
619 : "exit(error_message: \"if(greater: 13 <=> 10) failed test.\")\n"
620 : "label(name: integer_greater)\n"
621 :
622 : "compare(expression: ${b} <=> ${a})\n"
623 : "if(less: integer_less)\n"
624 : "exit(error_message: \"if(less: 10 <=> 13) failed test.\")\n"
625 : "label(name: integer_less)\n"
626 :
627 : "compare(expression: ${a} <=> ${a})\n"
628 : "if(equal: integer_equal)\n"
629 : "exit(error_message: \"if(equal: 13 <=> 13) failed test.\")\n"
630 : "label(name: integer_equal)\n"
631 :
632 : // floating point greater/less
633 : "set_variable(name: c, value: 13.41)\n"
634 : "set_variable(name: d, value: 9.05)\n"
635 : "compare(expression: ${c} <=> ${d})\n"
636 : "if(greater: floating_point_greater)\n"
637 : "exit(error_message: \"if(greater: 13.41 <=> 9.05) failed test.\")\n"
638 : "label(name: floating_point_greater)\n"
639 :
640 : "compare(expression: ${d} <=> ${c})\n"
641 : "if(less: floating_point_less)\n"
642 : "exit(error_message: \"if(less: 9.05 <=> 13.41) failed test.\")\n"
643 : "label(name: floating_point_less)\n"
644 :
645 : "compare(expression: ${d} <=> ${d})\n"
646 : "if(equal: floating_point_equal)\n"
647 : "exit(error_message: \"if(equal: 9.05 <=> 9.05) failed test.\")\n"
648 : "label(name: floating_point_equal)\n"
649 :
650 : // floating point vs integer greater/less
651 : "set_variable(name: c2, value: 13.0)\n"
652 : "set_variable(name: d2, value: 10.0)\n"
653 : "compare(expression: ${a} <=> ${d})\n"
654 : "if(greater: integer_floating_point_greater)\n"
655 : "exit(error_message: \"if(greater: 13 <=> 9.05) failed test.\")\n"
656 : "label(name: integer_floating_point_greater)\n"
657 :
658 : "compare(expression: ${d} <=> ${b})\n"
659 : "if(less: floating_point_integer_less)\n"
660 : "exit(error_message: \"if(less: 9.05 <=> 10) failed test.\")\n"
661 : "label(name: floating_point_integer_less)\n"
662 :
663 : "compare(expression: ${d2} <=> ${b})\n"
664 : "if(equal: floating_point_integer_equal)\n"
665 : "exit(error_message: \"if(equal: 10.0 <=> 10) failed test.\")\n"
666 : "label(name: floating_point_integer_equal)\n"
667 :
668 : "compare(expression: ${a} <=> ${c2})\n"
669 : "if(equal: integer_floating_point_equal)\n"
670 : "exit(error_message: \"if(equal: 10 <=> 10.0) failed test.\")\n"
671 : "label(name: integer_floating_point_equal)\n"
672 :
673 : "compare(expression: ${b} <=> ${c2})\n"
674 : "if(less: integer_floating_point_less)\n"
675 : "exit(error_message: \"if(less: 10 <=> 13.0) failed test.\")\n"
676 : "label(name: integer_floating_point_less)\n"
677 :
678 : "compare(expression: ${c} <=> ${a})\n"
679 : "if(greater: floating_point_integer_greater)\n"
680 : "exit(error_message: \"if(greater: 13.41 <=> 13) failed test.\")\n"
681 : "label(name: floating_point_integer_greater)\n"
682 :
683 : // timestamp greater/less (same as integers)
684 : "now(variable_name: now)\n"
685 : "set_variable(name: e, value: ${now} + 0.3)\n"
686 : "set_variable(name: f, value: ${now} - 0.05)\n"
687 : "compare(expression: ${e} <=> ${f})\n"
688 : "if(greater: timestamp_greater)\n"
689 : "exit(error_message: \"if(greater: now + 0.3 <=> now - 0x05) failed test.\")\n"
690 : "label(name: timestamp_greater)\n"
691 :
692 : "compare(expression: ${f} <=> ${e})\n"
693 : "if(less: timestamp_less)\n"
694 : "exit(error_message: \"if(less: now - 0.05 <=> now + 0.3) failed test.\")\n"
695 : "label(name: timestamp_less)\n"
696 :
697 : "compare(expression: ${f} <=> ${f})\n"
698 : "if(equal: timestamp_equal)\n"
699 : "exit(error_message: \"if(equal: now - 0.05 <=> now - 0.05) failed test.\")\n"
700 : "label(name: timestamp_equal)\n"
701 :
702 : // double strings greater/less/equal
703 : "set_variable(name: g, value: \"str9\")\n"
704 : "set_variable(name: h, value: \"str2\")\n"
705 : "compare(expression: ${g} <=> ${h})\n"
706 : "if(greater: double_string_greater)\n"
707 : "exit(error_message: \"if(greater: \\\"str9\\\" <=> \\\"str2\\\") failed test.\")\n"
708 : "label(name: double_string_greater)\n"
709 :
710 : "compare(expression: ${h} <=> ${g})\n"
711 : "if(less: double_string_less)\n"
712 : "exit(error_message: \"if(less: \\\"str2\\\" <=> \\\"str9\\\") failed test.\")\n"
713 : "label(name: double_string_less)\n"
714 :
715 : "compare(expression: ${h} <=> ${h})\n"
716 : "if(equal: double_string_equal)\n"
717 : "exit(error_message: \"if(equal: \\\"str2\\\" <=> \\\"str2\\\") failed test.\")\n"
718 : "label(name: double_string_equal)\n"
719 :
720 : // single strings greater/less
721 : "set_variable(name: i, value: 'str8')\n"
722 : "set_variable(name: j, value: 'str5')\n"
723 : "compare(expression: ${i} <=> ${j})\n"
724 : "if(greater: single_string_greater)\n"
725 : "exit(error_message: \"if(greater: 'str9' <=> 'str2') failed test.\")\n"
726 : "label(name: single_string_greater)\n"
727 :
728 : "compare(expression: ${j} <=> ${i})\n"
729 : "if(less: single_string_less)\n"
730 : "exit(error_message: \"if(less: 'str2' <=> 'str9') failed test.\")\n"
731 : "label(name: single_string_less)\n"
732 :
733 : // mixed strings greater/less
734 : "compare(expression: ${g} <=> ${j})\n"
735 : "if(greater: mixed_string_greater)\n"
736 : "exit(error_message: \"if(greater: \\\"str9\\\" <=> 'str5') failed test.\")\n"
737 : "label(name: mixed_string_greater)\n"
738 :
739 : "compare(expression: ${i} <=> ${g})\n"
740 : "if(less: mixed_string_less)\n"
741 : "exit(error_message: \"if(less: 'str8' <=> \\\"str9\\\") failed test.\")\n"
742 : "label(name: mixed_string_less)\n"
743 :
744 : // address greater/less
745 : "set_variable(name: k, value: <127.0.0.100>)\n"
746 : "set_variable(name: l, value: <10.127.0.100>)\n"
747 : "compare(expression: ${k} <=> ${l})\n"
748 : "if(greater: address_greater)\n"
749 : "exit(error_message: \"if(greater: <127.0.0.100> <=> <10.127.0.100>) failed test.\")\n"
750 : "label(name: address_greater)\n"
751 :
752 : "compare(expression: ${l} <=> ${k})\n"
753 : "if(less: address_less)\n"
754 : "exit(error_message: \"if(less: <10.127.0.100> <=> <127.0.0.100>) failed test.\")\n"
755 : "label(name: address_less)\n"
756 :
757 : "compare(expression: ${l} <=> ${l})\n"
758 : "if(equal: address_equal)\n"
759 : "exit(error_message: \"if(equal: <10.127.0.100> <=> <10.127.0.100>) failed test.\")\n"
760 : "label(name: address_equal)\n"
761 :
762 : "exit()\n"
763 : ;
764 :
765 : constexpr char const * const g_program_compare_with_incompatible_types =
766 : // cannot compare an integer vs string
767 : "set_variable(name: a, value: 13)\n"
768 : "set_variable(name: b, value: 'a string')\n"
769 : "compare(expression: ${a} <=> ${b})\n"
770 :
771 : "exit(error_message: \"test is expected to fail before reaching this statement.\")\n"
772 : ;
773 :
774 : constexpr char const * const g_program_compare_with_non_integer =
775 : // compare expression must be an integer
776 : "compare(expression: 'string')\n"
777 :
778 : "exit(error_message: \"test is expected to fail before reaching this statement.\")\n"
779 : ;
780 :
781 : constexpr char const * const g_program_compare_with_bad_positive_integer =
782 : // compare expression must be between -2 and +1
783 : "compare(expression: 5)\n"
784 :
785 : "exit(error_message: \"test is expected to fail before reaching this statement.\")\n"
786 : ;
787 :
788 : constexpr char const * const g_program_compare_with_bad_negative_integer =
789 : // compare expression must be between -2 and +1
790 : "compare(expression: -10)\n"
791 :
792 : "exit(error_message: \"test is expected to fail before reaching this statement.\")\n"
793 : ;
794 :
795 : constexpr char const * const g_program_print_message =
796 : "print(message: \"testing print()\")\n"
797 : "exit()\n"
798 : ;
799 :
800 : constexpr char const * const g_program_error_message =
801 : "exit(error_message: \"testing exit with an error\")\n"
802 : ;
803 :
804 : constexpr char const * const g_program_no_condition =
805 : "if(true: exit)\n"
806 : "label(name: exit)\n"
807 : ;
808 :
809 : constexpr char const * const g_program_two_listen =
810 : "listen(address: <127.0.0.1:20002>)\n"
811 : "listen(address: <127.0.0.1:20003>)\n"
812 : ;
813 :
814 : constexpr char const * const g_program_label_bad_type =
815 : "label(name: 123)\n"
816 : ;
817 :
818 : constexpr char const * const g_program_exit_bad_type =
819 : "exit(error_message: 12.3)\n"
820 : ;
821 :
822 : constexpr char const * const g_program_unsupported_addition_address_address =
823 : "set_variable(name: bad, value: <127.0.0.1:80> + <127.0.1.5:81>)\n"
824 : ;
825 :
826 : constexpr char const * const g_program_unsupported_addition_address_string =
827 : "set_variable(name: bad, value: <127.0.0.1:80> + '127.0.1.5:81')\n"
828 : ;
829 :
830 : constexpr char const * const g_program_unsupported_addition_string_address =
831 : "set_variable(name: bad, value: '127.0.0.1:80' + <127.0.1.5:81>)\n"
832 : ;
833 :
834 : constexpr char const * const g_program_unsupported_addition_address_identifier =
835 : "set_variable(name: bad, value: <127.0.0.1:80> + alpha)\n"
836 : ;
837 :
838 : constexpr char const * const g_program_unsupported_addition_identifier_address =
839 : "set_variable(name: bad, value: beta + <127.0.1.5:81>)\n"
840 : ;
841 :
842 : constexpr char const * const g_program_unsupported_addition_identifier_string =
843 : "set_variable(name: bad, value: this + '127.0.1.5:81')\n"
844 : ;
845 :
846 : constexpr char const * const g_program_unsupported_addition_string_identifier =
847 : "set_variable(name: bad, value: '127.0.0.1:80' + that)\n"
848 : ;
849 :
850 : constexpr char const * const g_program_unsupported_subtraction_address_string =
851 : "set_variable(name: bad, value: <127.0.0.1:80> - '127.0.1.5:81')\n"
852 : ;
853 :
854 : constexpr char const * const g_program_unsupported_subtraction_string_address =
855 : "set_variable(name: bad, value: '127.0.0.1:80' - <127.0.1.5:81>)\n"
856 : ;
857 :
858 : constexpr char const * const g_program_unsupported_subtraction_address_identifier =
859 : "set_variable(name: bad, value: <127.0.0.1:80> - alpha)\n"
860 : ;
861 :
862 : constexpr char const * const g_program_unsupported_subtraction_identifier_address =
863 : "set_variable(name: bad, value: beta - <127.0.1.5:81>)\n"
864 : ;
865 :
866 : constexpr char const * const g_program_unsupported_subtraction_identifier_string =
867 : "set_variable(name: bad, value: this - '127.0.1.5:81')\n"
868 : ;
869 :
870 : constexpr char const * const g_program_unsupported_subtraction_string_identifier =
871 : "set_variable(name: bad, value: '127.0.0.1:80' - that)\n"
872 : ;
873 :
874 : constexpr char const * const g_program_unsupported_multiplication_address_address =
875 : "set_variable(name: bad, value: <127.0.0.1:80> * <192.168.2.2:443>)\n"
876 : ;
877 :
878 : constexpr char const * const g_program_unsupported_multiplication_address_string =
879 : "set_variable(name: bad, value: <127.0.0.1:80> * 'invalid')\n"
880 : ;
881 :
882 : constexpr char const * const g_program_unsupported_multiplication_string_address =
883 : "set_variable(name: bad, value: 'invalid' * <127.0.0.1:80>)\n"
884 : ;
885 :
886 : constexpr char const * const g_program_unsupported_multiplication_address_identifier =
887 : "set_variable(name: bad, value: <127.0.0.1:80> * invalid)\n"
888 : ;
889 :
890 : constexpr char const * const g_program_unsupported_multiplication_identifier_address =
891 : "set_variable(name: bad, value: invalid * <127.0.0.1:80>)\n"
892 : ;
893 :
894 : constexpr char const * const g_program_unsupported_multiplication_identifier_string =
895 : "set_variable(name: bad, value: 'invalid' * invalid)\n"
896 : ;
897 :
898 : constexpr char const * const g_program_unsupported_multiplication_string_identifier =
899 : "set_variable(name: bad, value: invalid * \"invalid\")\n"
900 : ;
901 :
902 : constexpr char const * const g_program_unsupported_multiplication_string_string =
903 : "set_variable(name: bad, value: 'invalid' * \"invalid\")\n"
904 : ;
905 :
906 : constexpr char const * const g_program_unsupported_multiplication_identifier_identifier =
907 : "set_variable(name: bad, value: invalid * not_valid)\n"
908 : ;
909 :
910 : constexpr char const * const g_program_unsupported_division_address_address =
911 : "set_variable(name: bad, value: <127.0.0.1:80> / <192.168.2.2:443>)\n"
912 : ;
913 :
914 : constexpr char const * const g_program_unsupported_division_address_string =
915 : "set_variable(name: bad, value: <127.0.0.1:80> / 'invalid')\n"
916 : ;
917 :
918 : constexpr char const * const g_program_unsupported_division_string_address =
919 : "set_variable(name: bad, value: 'invalid' / <127.0.0.1:80>)\n"
920 : ;
921 :
922 : constexpr char const * const g_program_unsupported_division_address_identifier =
923 : "set_variable(name: bad, value: <127.0.0.1:80> / invalid)\n"
924 : ;
925 :
926 : constexpr char const * const g_program_unsupported_division_identifier_address =
927 : "set_variable(name: bad, value: invalid / <127.0.0.1:80>)\n"
928 : ;
929 :
930 : constexpr char const * const g_program_unsupported_division_identifier_string =
931 : "set_variable(name: bad, value: 'invalid' / invalid)\n"
932 : ;
933 :
934 : constexpr char const * const g_program_unsupported_division_string_identifier =
935 : "set_variable(name: bad, value: invalid / \"invalid\")\n"
936 : ;
937 :
938 : constexpr char const * const g_program_unsupported_division_string_string =
939 : "set_variable(name: bad, value: 'invalid' / \"invalid\")\n"
940 : ;
941 :
942 : constexpr char const * const g_program_unsupported_division_identifier_identifier =
943 : "set_variable(name: bad, value: invalid / not_valid)\n"
944 : ;
945 :
946 : constexpr char const * const g_program_unsupported_modulo_address_address =
947 : "set_variable(name: bad, value: <127.0.0.1:80> % <192.168.2.2:443>)\n"
948 : ;
949 :
950 : constexpr char const * const g_program_unsupported_modulo_address_string =
951 : "set_variable(name: bad, value: <127.0.0.1:80> % 'invalid')\n"
952 : ;
953 :
954 : constexpr char const * const g_program_unsupported_modulo_string_address =
955 : "set_variable(name: bad, value: 'invalid' % <127.0.0.1:80>)\n"
956 : ;
957 :
958 : constexpr char const * const g_program_unsupported_modulo_address_identifier =
959 : "set_variable(name: bad, value: <127.0.0.1:80> % invalid)\n"
960 : ;
961 :
962 : constexpr char const * const g_program_unsupported_modulo_identifier_address =
963 : "set_variable(name: bad, value: invalid % <127.0.0.1:80>)\n"
964 : ;
965 :
966 : constexpr char const * const g_program_unsupported_modulo_identifier_string =
967 : "set_variable(name: bad, value: invalid % \"invalid\")\n"
968 : ;
969 :
970 : constexpr char const * const g_program_unsupported_modulo_string_identifier =
971 : "set_variable(name: bad, value: 'invalid' % invalid)\n"
972 : ;
973 :
974 : constexpr char const * const g_program_unsupported_modulo_string_string =
975 : "set_variable(name: bad, value: 'invalid' % \"invalid\")\n"
976 : ;
977 :
978 : constexpr char const * const g_program_unsupported_modulo_identifier_identifier =
979 : "set_variable(name: bad, value: invalid % not_valid)\n"
980 : ;
981 :
982 : constexpr char const * const g_program_unsupported_negation_single_string =
983 : "set_variable(name: bad, value: -'string')\n"
984 : ;
985 :
986 : constexpr char const * const g_program_unsupported_negation_double_string =
987 : "set_variable(name: bad, value: -\"string\")\n"
988 : ;
989 :
990 : constexpr char const * const g_program_unsupported_negation_address =
991 : "set_variable(name: bad, value: -<127.0.0.1:80>)\n"
992 : ;
993 :
994 : constexpr char const * const g_program_unterminated_double_string_variable =
995 : "set_variable(name: my_var, value: \"blah\")\n"
996 : "set_variable(name: missing_close, value: \"ref. ${my_var\")\n"
997 : ;
998 :
999 : constexpr char const * const g_program_regex_in_double_string_variable =
1000 : "set_variable(name: my_regex, value: `[a-z]+`)\n"
1001 : "set_variable(name: missing_close, value: \"ref. ${my_regex}\")\n"
1002 : ;
1003 :
1004 : constexpr char const * const g_program_primary_variable_references =
1005 : "set_variable(name: my_string_var, value: \"foo\")\n"
1006 : "set_variable(name: longer_string_var, value: ${my_string_var})\n"
1007 : "set_variable(name: my_integer_var, value: 41)\n"
1008 : "set_variable(name: longer_integer_var, value: ${my_integer_var})\n"
1009 : "set_variable(name: my_floating_point_var, value: 303.601)\n"
1010 : "set_variable(name: longer_floating_point_var, value: ${my_floating_point_var})\n"
1011 : "set_variable(name: my_identifier_var, value: bar)\n"
1012 : "set_variable(name: longer_identifier_var, value: ${my_identifier_var})\n"
1013 : "set_variable(name: my_regex_var, value: `^[regex]$`)\n"
1014 : "set_variable(name: longer_regex_var, value: ${my_regex_var})\n"
1015 : "set_variable(name: my_address_var, value: <10.12.14.16:89>)\n"
1016 : "set_variable(name: longer_address_var, value: ${my_address_var})\n"
1017 : "set_variable(name: my_timestamp_var, value: @1714241733.419438123)\n"
1018 : "set_variable(name: longer_timestamp_var, value: ${my_timestamp_var})\n"
1019 : ;
1020 :
1021 : constexpr char const * const g_program_raw_tcp_connection =
1022 : "run()\n"
1023 : "listen(address: <127.0.0.1:20002>, connection_type: tcp)\n"
1024 : "label(name: wait_next_message)\n"
1025 : "clear_data()\n"
1026 : "label(name: wait_data)\n"
1027 : "wait(timeout: 12, mode: wait)\n"
1028 : "has_data(min_size: 4)\n"
1029 : "if(false: wait_data)\n"
1030 : "show_data(size: 4)\n"
1031 : "verify_data(values: [ 0x50, 0x49, 0x4E, 0x47 ])\n" // PING
1032 : "show_data(size: 4)\n" // this will display <empty>
1033 : "has_data(min_size: 1)\n"
1034 : "if(true: unexpected_data)\n"
1035 : "send_data(values: [ 0x50, 0x4F, 0x4E, 0x47 ])\n" // PONG
1036 : "wait(timeout: 10, mode: drain)\n"
1037 : "disconnect()\n"
1038 : "exit()\n"
1039 : "label(name: unexpected_data)\n"
1040 : "exit(error_message: \"found data when there should be none after the verify_data()\")\n"
1041 : ;
1042 :
1043 : constexpr char const * const g_program_prinbee_binary_message =
1044 : "run()\n"
1045 : "listen(address: <127.0.0.1:20002>, connection_type: tcp)\n"
1046 : "label(name: wait_next_message)\n"
1047 : "clear_data()\n"
1048 : "label(name: wait_data)\n"
1049 : "wait(timeout: 12, mode: wait)\n"
1050 : "has_data(min_size: 4)\n"
1051 : "if(false: wait_data)\n"
1052 : "show_data(size: 24)\n"
1053 : // magic (bm) version flags name (PING) size CRC16 x 2 (fake here) data
1054 : "verify_data(values: [ 0x62, 0x6D, 0x01, 0x00, 0x50, 0x49, 0x4E, 0x47, 0x08, 0x00, 0x00, 0x00, 0xAA, 0x55, 0xEE, 0x77, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF ])\n"
1055 : "show_data(size: 24)\n" // this will display <empty>
1056 : "has_data(min_size: 1)\n"
1057 : "if(true: unexpected_data)\n"
1058 : // reply with a PONG and no data (size = 0)
1059 : "send_data(values: [ 0x62, 0x6D, 0x01, 0x00, 0x50, 0x4F, 0x4E, 0x47, 0x00, 0x00, 0x00, 0x00, 0x55, 0xAA, 0x33, 0xCC ])\n"
1060 : "wait(timeout: 10, mode: drain)\n"
1061 : "disconnect()\n"
1062 : "exit()\n"
1063 : "label(name: unexpected_data)\n"
1064 : "exit(error_message: \"found data when there should be none after the verify_data()\")\n"
1065 : ;
1066 :
1067 : constexpr char const * const g_program_raw_tcp_connection_read_too_large =
1068 : "run()\n"
1069 : "listen(address: <127.0.0.1:20002>, connection_type: tcp)\n"
1070 : "label(name: wait_next_message)\n"
1071 : "clear_data()\n"
1072 : "label(name: wait_data)\n"
1073 : "wait(timeout: 12, mode: wait)\n"
1074 : "has_data(min_size: 4)\n"
1075 : "if(false: wait_data)\n"
1076 : "show_data(size: 4)\n"
1077 : "verify_data(values: [ 0x50, 0x49, 0x4E, 0x47, 0x53 ])\n" // try to compare 5 bytes instead of 4
1078 : "exit(error_message: \"verify_data() did not fail\")\n"
1079 : ;
1080 :
1081 : constexpr char const * const g_program_raw_tcp_connection_verify_fails =
1082 : "run()\n"
1083 : "listen(address: <127.0.0.1:20002>, connection_type: tcp)\n"
1084 : "label(name: wait_next_message)\n"
1085 : "clear_data()\n"
1086 : "label(name: wait_data)\n"
1087 : "wait(timeout: 12, mode: wait)\n"
1088 : "has_data(min_size: 4)\n"
1089 : "if(false: wait_data)\n"
1090 : "show_data(size: 4)\n"
1091 : "verify_data(values: [ 0x49, 0x50, 0x4E, 0x47 ])\n" // IPNG instead of PING
1092 : "exit(error_message: \"verify_data() did not fail\")\n"
1093 : ;
1094 :
1095 : constexpr char const * const g_program_raw_tcp_connection_send_invalid_value_too_large =
1096 : "run()\n"
1097 : "listen(address: <127.0.0.1:20002>, connection_type: tcp)\n"
1098 : "label(name: wait_next_message)\n"
1099 : "clear_data()\n"
1100 : "label(name: wait_data)\n"
1101 : "wait(timeout: 12, mode: wait)\n"
1102 : "has_data(min_size: 4)\n"
1103 : "if(false: wait_data)\n"
1104 : "show_data(size: 4)\n"
1105 : "verify_data(values: [ 0x50, 0x49, 0x4E, 0x47 ])\n" // PING
1106 : "show_data(size: 4)\n" // this will display <empty>
1107 : "has_data(min_size: 1)\n"
1108 : "if(true: unexpected_data)\n"
1109 : "send_data(values: [ 0x50, 0x4F, 0x100, 0x47 ])\n" // PO?G
1110 : "exit(error_message: \"send_data() did not fail\")\n"
1111 : ;
1112 :
1113 : constexpr char const * const g_program_raw_tcp_connection_send_invalid_value_too_small =
1114 : "run()\n"
1115 : "listen(address: <127.0.0.1:20002>, connection_type: tcp)\n"
1116 : "label(name: wait_next_message)\n"
1117 : "clear_data()\n"
1118 : "label(name: wait_data)\n"
1119 : "wait(timeout: 12, mode: wait)\n"
1120 : "has_data(min_size: 4)\n"
1121 : "if(false: wait_data)\n"
1122 : "show_data(size: 4)\n"
1123 : "verify_data(values: [ 0x50, 0x49, 0x4E, 0x47 ])\n" // PING
1124 : "show_data(size: 4)\n" // this will display <empty>
1125 : "has_data(min_size: 1)\n"
1126 : "if(true: unexpected_data)\n"
1127 : "send_data(values: [ 0x50, 0x4F, -129, 0x47 ])\n" // PO?G
1128 : "exit(error_message: \"send_data() did not fail\")\n"
1129 : ;
1130 :
1131 : constexpr char const * const g_program_raw_tcp_connection_send_empty_array =
1132 : "run()\n"
1133 : "listen(address: <127.0.0.1:20002>, connection_type: tcp)\n"
1134 : "label(name: wait_next_message)\n"
1135 : "clear_data()\n"
1136 : "label(name: wait_data)\n"
1137 : "wait(timeout: 12, mode: wait)\n"
1138 : "has_data(min_size: 4)\n"
1139 : "if(false: wait_data)\n"
1140 : "show_data(size: 4)\n"
1141 : "verify_data(values: [ 0x50, 0x49, 0x4E, 0x47 ])\n" // PING
1142 : "show_data(size: 4)\n" // this will display <empty>
1143 : "has_data(min_size: 1)\n"
1144 : "if(true: unexpected_data)\n"
1145 : "send_data(values: [])\n" // empty is not valid
1146 : "exit(error_message: \"send_data() did not fail\")\n"
1147 : ;
1148 :
1149 : constexpr char const * const g_program_raw_tcp_connection_verify_empty_array =
1150 : "run()\n"
1151 : "listen(address: <127.0.0.1:20002>, connection_type: tcp)\n"
1152 : "label(name: wait_next_message)\n"
1153 : "clear_data()\n"
1154 : "label(name: wait_data)\n"
1155 : "wait(timeout: 12, mode: wait)\n"
1156 : "has_data(min_size: 4)\n"
1157 : "if(false: wait_data)\n"
1158 : "show_data(size: 4)\n"
1159 : "verify_data(values: [])\n" // empty is not valid
1160 : "exit(error_message: \"verify_data() did not fail\")\n"
1161 : ;
1162 :
1163 : constexpr char const * const g_program_wrong_primary_variable_reference =
1164 : "set_variable(name: my_var, value: foo)\n"
1165 : "set_variable(name: longer_var, value: ${wrong_name})\n"
1166 : ;
1167 :
1168 : constexpr char const * const g_program_double_string_variable_without_name =
1169 : "set_variable(name: missing_close, value: \"ref. ${} is empty\")\n"
1170 : ;
1171 :
1172 : constexpr char const * const g_program_unsupported_negation_repeat =
1173 : "set_variable(name: bad, value: 'string' * -5)\n"
1174 : ;
1175 :
1176 : constexpr char const * const g_program_unsupported_large_repeat =
1177 : "set_variable(name: bad, value: 'string' * 1001)\n"
1178 : ;
1179 :
1180 : constexpr char const * const g_program_bad_exit =
1181 : "exit(error_message: \"bad error occurred!\", timeout: 3.001)\n"
1182 : ;
1183 :
1184 : constexpr char const * const g_program_bad_exit_timeout =
1185 : "exit(timeout: 'bad')\n"
1186 : ;
1187 :
1188 : constexpr char const * const g_program_bad_print_message =
1189 : "print(message: string_expected)\n"
1190 : ;
1191 :
1192 : constexpr char const * const g_program_send_message_without_connection =
1193 : "send_message(server: \"world\", service: cluckd, command: WITHOUT_CONNECTION)\n"
1194 : ;
1195 :
1196 : constexpr char const * const g_program_send_data_without_connection =
1197 : "send_data(values: [ 1, 2, 3 ])\n"
1198 : ;
1199 :
1200 : constexpr char const * const g_program_if_invalid_type =
1201 : "set_variable(name: my_str, value: \"bad\")\n"
1202 : "if(variable: my_str, unordered: unused)\n"
1203 : "exit(error_message: \"if() did not fail.\")\n"
1204 : "label(name: unused)\n"
1205 : "exit(error_message: \"if() branched unexpectendly.\")\n"
1206 : ;
1207 :
1208 : constexpr char const * const g_program_wait_outside_thread =
1209 : "wait(timeout: 10)\n"
1210 : ;
1211 :
1212 : constexpr char const * const g_program_wait_invalid_mode =
1213 : "run()\n"
1214 : "wait(timeout: 10, mode: not_this_one)\n"
1215 : ;
1216 :
1217 : constexpr char const * const g_program_wait_no_connections =
1218 : "run()\n"
1219 : "wait(timeout: 10, mode: wait)\n"
1220 : ;
1221 :
1222 : constexpr char const * const g_program_invalid_string_to_timestamp_cast =
1223 : "set_variable(name: time_limit, value: '1713b34141.10780g991', type: timestamp)\n"
1224 : ;
1225 :
1226 : constexpr char const * const g_program_unknown_string_cast =
1227 : "set_variable(name: time_limit, value: 'not important', type: unknown)\n"
1228 : ;
1229 :
1230 : constexpr char const * const g_program_unknown_timestamp_cast =
1231 : "set_variable(name: time_limit, value: @123.456, type: unknown)\n"
1232 : ;
1233 :
1234 : constexpr char const * const g_program_unknown_source_cast =
1235 : "set_variable(name: time_limit, value: <127.127.127.127>, type: string)\n"
1236 : ;
1237 :
1238 : constexpr char const * const g_program_sort_var1_missing =
1239 : "set_variable(name: s2, value: 'err33')\n"
1240 : "set_variable(name: s3, value: 'err13')\n"
1241 : "sort(var2: s2, var3: s3)\n"
1242 : ;
1243 :
1244 : constexpr char const * const g_program_sort_var1_not_string =
1245 : "sort(var1: 33)\n"
1246 : ;
1247 :
1248 : constexpr char const * const g_program_sort_var1_not_found =
1249 : "sort(var1: not_defined)\n"
1250 : ;
1251 :
1252 : constexpr char const * const g_program_sort_wrong_type =
1253 : // note that with time we are likely to support all types and thus
1254 : // this test may stop working
1255 : //
1256 : "set_variable(name: w1, value: <127.0.0.1>)\n"
1257 : "sort(var1: w1)\n"
1258 : ;
1259 :
1260 : constexpr char const * const g_program_sort_mixed_types =
1261 : "set_variable(name: s1, value: 'err13')\n"
1262 : "set_variable(name: s2, value: 33)\n"
1263 : "set_variable(name: s3, value: 'more')\n"
1264 : "sort(var1: s1, var2: s2, var3: s3)\n"
1265 : ;
1266 :
1267 : constexpr char const * const g_program_listen_with_unknown_connection_type =
1268 : "listen(address: <127.0.0.1:20002>, connection_type: unknown)\n"
1269 : ;
1270 :
1271 :
1272 : constexpr char const * const g_program_verify_message_fail_sent_server =
1273 : "run()\n"
1274 : "listen(address: <127.0.0.1:20002>)\n"
1275 : "label(name: wait_message)\n"
1276 : "clear_message()\n"
1277 : "wait(timeout: 12, mode: wait)\n"
1278 : "has_message()\n"
1279 : "if(false: wait_message)\n"
1280 : "show_message()\n"
1281 : "verify_message(command: REGISTER, sent_server: not_this_one)\n"
1282 : "exit()\n"
1283 : ;
1284 :
1285 : constexpr char const * const g_program_verify_message_fail_sent_service =
1286 : "run()\n"
1287 : "listen(address: <127.0.0.1:20002>)\n"
1288 : "label(name: wait_message)\n"
1289 : "clear_message()\n"
1290 : "wait(timeout: 12, mode: wait)\n"
1291 : "has_message()\n"
1292 : "if(false: wait_message)\n"
1293 : "show_message()\n"
1294 : "verify_message(command: REGISTER, sent_service: not_this_one)\n"
1295 : "exit()\n"
1296 : ;
1297 :
1298 : constexpr char const * const g_program_verify_message_fail_server =
1299 : "run()\n"
1300 : "listen(address: <127.0.0.1:20002>)\n"
1301 : "label(name: wait_message)\n"
1302 : "clear_message()\n"
1303 : "wait(timeout: 12, mode: wait)\n"
1304 : "has_message()\n"
1305 : "if(false: wait_message)\n"
1306 : "show_message()\n"
1307 : "verify_message(command: REGISTER, server: not_this_one)\n"
1308 : "exit()\n"
1309 : ;
1310 :
1311 : constexpr char const * const g_program_verify_message_fail_service =
1312 : "run()\n"
1313 : "listen(address: <127.0.0.1:20002>)\n"
1314 : "label(name: wait_message)\n"
1315 : "clear_message()\n"
1316 : "wait(timeout: 12, mode: wait)\n"
1317 : "has_message()\n"
1318 : "if(false: wait_message)\n"
1319 : "show_message()\n"
1320 : "verify_message(command: REGISTER, service: not_this_one)\n"
1321 : "exit()\n"
1322 : ;
1323 :
1324 : constexpr char const * const g_program_verify_message_fail_command =
1325 : "run()\n"
1326 : "listen(address: <127.0.0.1:20002>)\n"
1327 : "label(name: wait_message)\n"
1328 : "clear_message()\n"
1329 : "wait(timeout: 12, mode: wait)\n"
1330 : "has_message()\n"
1331 : "if(false: wait_message)\n"
1332 : "show_message()\n"
1333 : "verify_message(command: NOT_THIS_ONE)\n"
1334 : "exit()\n"
1335 : ;
1336 :
1337 : constexpr char const * const g_program_verify_message_fail_forbidden =
1338 : "run()\n"
1339 : "listen(address: <127.0.0.1:20002>)\n"
1340 : "label(name: wait_message)\n"
1341 : "clear_message()\n"
1342 : "wait(timeout: 12, mode: wait)\n"
1343 : "has_message()\n"
1344 : "if(false: wait_message)\n"
1345 : "show_message()\n"
1346 : "verify_message(command: REGISTER, forbidden_parameters: { version })\n"
1347 : "exit()\n"
1348 : ;
1349 :
1350 : constexpr char const * const g_program_verify_message_fail_required =
1351 : "run()\n"
1352 : "listen(address: <127.0.0.1:20002>)\n"
1353 : "label(name: wait_message)\n"
1354 : "clear_message()\n"
1355 : "wait(timeout: 12, mode: wait)\n"
1356 : "has_message()\n"
1357 : "if(false: wait_message)\n"
1358 : "show_message()\n"
1359 : "verify_message(command: REGISTER, required_parameters: { not_this_one: 123 })\n"
1360 : "exit()\n"
1361 : ;
1362 :
1363 : constexpr char const * const g_program_verify_message_fail_required_int_value =
1364 : "run()\n"
1365 : "listen(address: <127.0.0.1:20002>)\n"
1366 : "label(name: wait_message)\n"
1367 : "clear_message()\n"
1368 : "wait(timeout: 12, mode: wait)\n"
1369 : "has_message()\n"
1370 : "if(false: wait_message)\n"
1371 : "show_message()\n"
1372 : "verify_message(command: REGISTER, required_parameters: { version: 200 })\n"
1373 : "exit()\n"
1374 : ;
1375 :
1376 : constexpr char const * const g_program_verify_message_fail_required_str_value =
1377 : "run()\n"
1378 : "listen(address: <127.0.0.1:20002>)\n"
1379 : "label(name: wait_message)\n"
1380 : "clear_message()\n"
1381 : "wait(timeout: 12, mode: wait)\n"
1382 : "has_message()\n"
1383 : "if(false: wait_message)\n"
1384 : "show_message()\n"
1385 : "verify_message(command: REGISTER, required_parameters: { service: not_this_one })\n"
1386 : "exit()\n"
1387 : ;
1388 :
1389 : constexpr char const * const g_program_verify_message_fail_required_long_str_value =
1390 : "run()\n"
1391 : "listen(address: <127.0.0.1:20002>)\n"
1392 : "label(name: wait_message)\n"
1393 : "clear_message()\n"
1394 : "wait(timeout: 12, mode: wait)\n"
1395 : "has_message()\n"
1396 : "if(false: wait_message)\n"
1397 : "show_message()\n"
1398 : "verify_message(command: REGISTER, required_parameters: { service: 'responder' * 15 })\n"
1399 : "exit()\n"
1400 : ;
1401 :
1402 : constexpr char const * const g_program_verify_message_fail_required_flt_value =
1403 : "run()\n"
1404 : "listen(address: <127.0.0.1:20002>)\n"
1405 : "label(name: wait_message)\n"
1406 : "clear_message()\n"
1407 : "wait(timeout: 12, mode: wait)\n"
1408 : "has_message()\n"
1409 : "if(false: wait_message)\n"
1410 : "show_message()\n"
1411 : "verify_message(command: REGISTER, required_parameters: { version: 1.0 })\n"
1412 : "exit()\n"
1413 : ;
1414 :
1415 : constexpr char const * const g_program_verify_message_fail_required_timestamp_value =
1416 : "run()\n"
1417 : "listen(address: <127.0.0.1:20002>)\n"
1418 : "label(name: wait_message)\n"
1419 : "clear_message()\n"
1420 : "wait(timeout: 12, mode: wait)\n"
1421 : "has_message()\n"
1422 : "if(false: wait_message)\n"
1423 : "show_message()\n"
1424 : "verify_message(command: REGISTER, required_parameters: { version: @123 })\n"
1425 : "exit()\n"
1426 : ;
1427 :
1428 : constexpr char const * const g_program_verify_message_fail_timestamp_command =
1429 : "run()\n"
1430 : "listen(address: <127.0.0.1:20002>)\n"
1431 : "label(name: wait_message)\n"
1432 : "clear_message()\n"
1433 : "wait(timeout: 12, mode: wait)\n"
1434 : "has_message()\n"
1435 : "if(false: wait_message)\n"
1436 : "show_message()\n"
1437 : "verify_message(command: @123.678, required_parameters: { version: 1 })\n"
1438 : "exit()\n"
1439 : ;
1440 :
1441 : constexpr char const * const g_program_verify_message_fail_unexpected_command =
1442 : "run()\n"
1443 : "listen(address: <127.0.0.1:20002>)\n"
1444 : "label(name: wait_message)\n"
1445 : "clear_message()\n"
1446 : "wait(timeout: 12, mode: wait)\n"
1447 : "has_message()\n"
1448 : "if(false: wait_message)\n"
1449 : "show_message()\n"
1450 : "verify_message(command: `^NOT_THIS_ONE$`, required_parameters: { version: 1 })\n"
1451 : "exit()\n"
1452 : ;
1453 :
1454 : constexpr char const * const g_program_last_wait =
1455 : "run()\n"
1456 : "listen(address: <127.0.0.1:20002>)\n"
1457 : "label(name: wait_message)\n"
1458 : "clear_message()\n"
1459 : "wait(timeout: 10.0, mode: wait)\n"
1460 : "has_message()\n"
1461 : "if(false: wait_message)\n"
1462 : "show_message()\n"
1463 : "verify_message(command: REGISTER, required_parameters: { service: responder, version: 1 }, optional_parameters: { commands: \"READY,HELP,STOP\" }, forbidden_parameters: { forbidden })\n"
1464 : "send_message(command: READY, sent_server: reporter_test_extension, sent_service: test_processor, server: reporter_test, service: accept_one_message, parameters: { status: alive })\n"
1465 : "wait(timeout: 1.0, mode: drain)\n" // hope that send_message() is small enough that a single wait is sufficient to send it
1466 : "wait(timeout: 1.0)\n"
1467 : "disconnect()\n"
1468 : "exit()\n"
1469 : ;
1470 :
1471 : constexpr char const * const g_program_regex_parameter_no_match =
1472 : "run()\n"
1473 : "listen(address: <127.0.0.1:20002>)\n"
1474 : "label(name: wait_message)\n"
1475 : "clear_message()\n"
1476 : "wait(timeout: 10.0, mode: wait)\n"
1477 : "has_message()\n"
1478 : "if(false: wait_message)\n"
1479 : "show_message()\n"
1480 : "verify_message(command: REGISTER, required_parameters: { service: responder, version: `_[a-z]+` }, optional_parameters: { commands: \"READY,HELP,STOP\" }, forbidden_parameters: { forbidden })\n"
1481 : "send_message(command: READY, sent_server: reporter_test_extension, sent_service: test_processor, server: reporter_test, service: accept_one_message, parameters: { status: alive })\n"
1482 : "wait(timeout: 1.0, mode: drain)\n"
1483 : "wait(timeout: 1.0)\n"
1484 : "disconnect()\n"
1485 : "exit()\n"
1486 : ;
1487 :
1488 : constexpr char const * const g_program_wait_for_nothing =
1489 : "run()\n"
1490 : "listen(address: <127.0.0.1:20002>)\n"
1491 : "label(name: wait_message)\n"
1492 : "clear_message()\n"
1493 : "wait(timeout: 10.0, mode: wait)\n" // first wait reacts on connect(), second wait receives the REGISTER message
1494 : "has_message()\n"
1495 : "if(false: wait_message)\n"
1496 : "show_message()\n"
1497 : "verify_message(command: REGISTER, required_parameters: { service: responder, version: 1 }, optional_parameters: { commands: \"READY,HELP,STOP\" }, forbidden_parameters: { forbidden })\n"
1498 : "send_message(command: READY, sent_server: reporter_test_extension, sent_service: test_processor, server: reporter_test, service: accept_one_message, parameters: { status: alive })\n"
1499 : "wait(timeout: 1.0, mode: drain)\n"
1500 : "wait(timeout: 1.0)\n"
1501 : "wait(timeout: 1.0)\n" // one too many wait(), it will time out
1502 : "exit()\n"
1503 : ;
1504 :
1505 : constexpr char const * const g_program_wait_for_timeout =
1506 : "run()\n"
1507 : "listen(address: <127.0.0.1:20002>)\n"
1508 : "label(name: wait_message)\n"
1509 : "clear_message()\n"
1510 : "wait(timeout: 10.0, mode: wait)\n" // first wait reacts on connect(), second wait receives the REGISTER message
1511 : "has_message()\n"
1512 : "if(false: wait_message)\n"
1513 : "show_message()\n"
1514 : "verify_message(command: REGISTER, required_parameters: { service: responder, version: 1 }, optional_parameters: { commands: \"READY,HELP,STOP\" }, forbidden_parameters: { forbidden })\n"
1515 : "send_message(command: READY, sent_server: reporter_test_extension, sent_service: test_processor, server: reporter_test, service: accept_one_message, parameters: { status: alive })\n"
1516 : "wait(timeout: 1.0, mode: drain)\n"
1517 : "wait(timeout: 1.0)\n"
1518 : "wait(timeout: 1.0, mode: timeout)\n" // one extra wait(), which will time out
1519 : "exit()\n"
1520 : ;
1521 :
1522 :
1523 :
1524 : struct expected_trace_t
1525 : {
1526 : SNAP_CATCH2_NAMESPACE::reporter::callback_reason_t const
1527 : f_reason = SNAP_CATCH2_NAMESPACE::reporter::callback_reason_t::CALLBACK_REASON_BEFORE_CALL;
1528 : char const * const f_name = nullptr;
1529 : };
1530 : #define TRACE_EXPECT(reason, name) { .f_reason = SNAP_CATCH2_NAMESPACE::reporter::callback_reason_t::CALLBACK_REASON_##reason##_CALL, .f_name = #name }
1531 :
1532 :
1533 : constexpr expected_trace_t const g_verify_starting_thread[] =
1534 : {
1535 : TRACE_EXPECT(BEFORE, set_variable),
1536 : TRACE_EXPECT(AFTER, set_variable),
1537 : TRACE_EXPECT(BEFORE, set_variable),
1538 : TRACE_EXPECT(AFTER, set_variable),
1539 : TRACE_EXPECT(BEFORE, run),
1540 : TRACE_EXPECT(AFTER, run),
1541 : TRACE_EXPECT(BEFORE, set_variable),
1542 : TRACE_EXPECT(AFTER, set_variable),
1543 : TRACE_EXPECT(BEFORE, set_variable),
1544 : TRACE_EXPECT(AFTER, set_variable),
1545 : TRACE_EXPECT(BEFORE, set_variable),
1546 : TRACE_EXPECT(AFTER, set_variable),
1547 : TRACE_EXPECT(BEFORE, set_variable),
1548 : TRACE_EXPECT(AFTER, set_variable),
1549 : TRACE_EXPECT(BEFORE, set_variable),
1550 : TRACE_EXPECT(AFTER, set_variable),
1551 : TRACE_EXPECT(BEFORE, set_variable),
1552 : TRACE_EXPECT(AFTER, set_variable),
1553 : TRACE_EXPECT(BEFORE, set_variable),
1554 : TRACE_EXPECT(AFTER, set_variable),
1555 : TRACE_EXPECT(BEFORE, set_variable),
1556 : TRACE_EXPECT(AFTER, set_variable),
1557 : TRACE_EXPECT(BEFORE, strlen),
1558 : TRACE_EXPECT(AFTER, strlen),
1559 : {}
1560 : };
1561 :
1562 :
1563 : constexpr expected_trace_t const g_verify_raw_tcp_connection[] =
1564 : {
1565 : TRACE_EXPECT(BEFORE, run),
1566 : TRACE_EXPECT(AFTER, run),
1567 : TRACE_EXPECT(BEFORE, listen),
1568 : TRACE_EXPECT(AFTER, listen),
1569 : TRACE_EXPECT(BEFORE, label),
1570 : TRACE_EXPECT(AFTER, label),
1571 : TRACE_EXPECT(BEFORE, clear_data),
1572 : TRACE_EXPECT(AFTER, clear_data),
1573 : TRACE_EXPECT(BEFORE, label),
1574 : TRACE_EXPECT(AFTER, label),
1575 : TRACE_EXPECT(BEFORE, wait),
1576 : TRACE_EXPECT(AFTER, wait),
1577 : TRACE_EXPECT(BEFORE, has_data),
1578 : TRACE_EXPECT(AFTER, has_data),
1579 : TRACE_EXPECT(BEFORE, if),
1580 : TRACE_EXPECT(AFTER, if),
1581 : TRACE_EXPECT(BEFORE, label),
1582 : TRACE_EXPECT(AFTER, label),
1583 : TRACE_EXPECT(BEFORE, wait),
1584 : TRACE_EXPECT(AFTER, wait),
1585 : TRACE_EXPECT(BEFORE, has_data),
1586 : TRACE_EXPECT(AFTER, has_data),
1587 : TRACE_EXPECT(BEFORE, if),
1588 : TRACE_EXPECT(AFTER, if),
1589 : TRACE_EXPECT(BEFORE, show_data),
1590 : TRACE_EXPECT(AFTER, show_data),
1591 : TRACE_EXPECT(BEFORE, verify_data),
1592 : TRACE_EXPECT(AFTER, verify_data),
1593 : TRACE_EXPECT(BEFORE, send_data),
1594 : TRACE_EXPECT(AFTER, send_data),
1595 : TRACE_EXPECT(BEFORE, wait),
1596 : TRACE_EXPECT(AFTER, wait),
1597 : TRACE_EXPECT(BEFORE, disconnect),
1598 : TRACE_EXPECT(AFTER, disconnect),
1599 : TRACE_EXPECT(BEFORE, exit),
1600 : TRACE_EXPECT(AFTER, exit),
1601 : TRACE_EXPECT(BEFORE, end), // generate an error
1602 : {}
1603 : };
1604 :
1605 :
1606 : class trace
1607 : {
1608 : public:
1609 1 : trace(expected_trace_t const * expected_trace)
1610 1 : : f_expected_trace(expected_trace)
1611 : {
1612 1 : }
1613 :
1614 : trace(trace const &) = delete;
1615 :
1616 1 : ~trace()
1617 : {
1618 : // make sure we reached the end of the list
1619 : //
1620 1 : CATCH_REQUIRE(f_expected_trace[f_pos].f_name == nullptr);
1621 1 : }
1622 :
1623 : trace operator = (trace const &) = delete;
1624 :
1625 24 : void callback(SNAP_CATCH2_NAMESPACE::reporter::state & s, SNAP_CATCH2_NAMESPACE::reporter::callback_reason_t reason)
1626 : {
1627 24 : SNAP_CATCH2_NAMESPACE::reporter::statement::pointer_t stmt(s.get_running_statement());
1628 24 : std::string const & name(stmt->get_instruction()->get_name());
1629 : std::cerr
1630 24 : << "--------------------- TRACE: pos: "
1631 : << f_pos
1632 24 : << " reason: "
1633 : << static_cast<int>(reason)
1634 : << " name: \""
1635 : << name
1636 24 : << "\"\n";
1637 :
1638 : // here we can be in the thread so DO NOT USE CATCH_... macros
1639 : //
1640 24 : if(f_expected_trace[f_pos].f_name == nullptr)
1641 : {
1642 : std::cerr
1643 0 : << "tracer error: got more calls ("
1644 0 : << f_pos + 1
1645 0 : << ") to tracer than expected.\n";
1646 : throw std::runtime_error(
1647 : "got more calls ("
1648 0 : + std::to_string(f_pos + 1)
1649 0 : + ") to tracer than expected.");
1650 : }
1651 :
1652 24 : if(f_expected_trace[f_pos].f_reason != reason)
1653 : {
1654 : std::cerr
1655 0 : << "tracer error: unexpected reason at position "
1656 : << f_pos
1657 0 : << " (got "
1658 : << static_cast<int>(reason)
1659 0 : << ", expected "
1660 0 : << static_cast<int>(f_expected_trace[f_pos].f_reason)
1661 0 : << ").\n";
1662 : throw std::runtime_error(
1663 : "unexpected reason at position "
1664 0 : + std::to_string(f_pos)
1665 0 : + " (got "
1666 0 : + std::to_string(static_cast<int>(reason))
1667 0 : + ", expected "
1668 0 : + std::to_string(static_cast<int>(f_expected_trace[f_pos].f_reason))
1669 0 : + ").");
1670 : }
1671 :
1672 24 : if(f_expected_trace[f_pos].f_name != name)
1673 : {
1674 : std::cerr
1675 0 : << "tracer error: unexpected instruction at position "
1676 : << f_pos
1677 : << " (got \""
1678 : << name
1679 : << "\", expected \""
1680 0 : << f_expected_trace[f_pos].f_name
1681 0 : << "\").\n";
1682 : throw std::runtime_error(
1683 : "unexpected instruction at position "
1684 0 : + std::to_string(f_pos)
1685 0 : + " (got "
1686 0 : + name
1687 0 : + ", expected "
1688 0 : + f_expected_trace[f_pos].f_name
1689 0 : + ").");
1690 : }
1691 :
1692 24 : ++f_pos;
1693 48 : }
1694 :
1695 : private:
1696 : int f_pos = 0;
1697 : expected_trace_t const * f_expected_trace = nullptr;
1698 : };
1699 :
1700 :
1701 : class messenger_responder // an equivalent to a client
1702 : : public ed::tcp_client_permanent_message_connection
1703 : {
1704 : public:
1705 : typedef std::shared_ptr<messenger_responder> pointer_t;
1706 :
1707 : enum class sequence_t
1708 : {
1709 : SEQUENCE_ONE_MESSAGE,
1710 : SEQUENCE_UNWANTED_MESSAGE,
1711 : SEQUENCE_TIMED_MESSAGE,
1712 : SEQUENCE_READY_HELP_MESSAGE,
1713 : SEQUENCE_READY_THROW,
1714 : SEQUENCE_READY_THROW_WHAT,
1715 : };
1716 :
1717 28 : messenger_responder(
1718 : addr::addr const & a
1719 : , ed::mode_t mode
1720 : , sequence_t sequence
1721 : , int timeout = 500'000) // or ed::DEFAULT_PAUSE_BEFORE_RECONNECTING
1722 28 : : tcp_client_permanent_message_connection(
1723 : a
1724 : , mode
1725 : , timeout
1726 : , true
1727 : , "responder") // service name
1728 84 : , f_sequence(sequence)
1729 : {
1730 84 : set_name("messenger_responder"); // connection name
1731 28 : set_timeout_delay(500'000); // 0.5 seconds
1732 28 : }
1733 :
1734 27 : virtual void process_connected() override
1735 : {
1736 : // always register at the time we connect
1737 : //
1738 27 : tcp_client_permanent_message_connection::process_connected();
1739 27 : register_service();
1740 27 : }
1741 :
1742 12 : virtual void process_message(ed::message & msg) override
1743 : {
1744 12 : ++f_step;
1745 : std::cout
1746 12 : << "--- \"client\" message ("
1747 : << f_step
1748 : << "): "
1749 12 : << msg
1750 12 : << std::endl;
1751 :
1752 12 : bool disconnect_all(false);
1753 :
1754 12 : if(f_step == 1)
1755 : {
1756 8 : if(msg.get_command() != "READY")
1757 : {
1758 : throw std::runtime_error(
1759 : "first message expected to be READY, got "
1760 0 : + msg.get_command()
1761 0 : + " instead.");
1762 : }
1763 24 : if(msg.has_parameter("version"))
1764 : {
1765 : // there are cases where I put a version as an integer
1766 : //
1767 3 : std::int64_t version(msg.get_integer_parameter("version"));
1768 1 : if(version != 9)
1769 : {
1770 : throw std::runtime_error(
1771 : "READY version value invalid; expected 9, got "
1772 0 : + std::to_string(version)
1773 0 : + " instead.");
1774 : }
1775 : }
1776 24 : if(msg.has_parameter("date"))
1777 : {
1778 : // there are cases where I put a date as a timespec_ex (a timestamp in the language)
1779 : //
1780 3 : snapdev::timespec_ex date(msg.get_timespec_parameter("date"));
1781 1 : if(date != snapdev::timespec_ex(1715440881, 543723981))
1782 : {
1783 : throw std::runtime_error(
1784 : "READY date value invalid; expected 1715440881.543723981, got "
1785 0 : + date.to_timestamp()
1786 0 : + " instead.");
1787 : }
1788 : }
1789 : }
1790 :
1791 12 : switch(f_sequence)
1792 : {
1793 4 : case sequence_t::SEQUENCE_ONE_MESSAGE:
1794 4 : disconnect_all = true;
1795 4 : break;
1796 :
1797 0 : case sequence_t::SEQUENCE_UNWANTED_MESSAGE:
1798 : {
1799 0 : ed::message unwanted;
1800 0 : unwanted.reply_to(msg);
1801 0 : unwanted.set_command("UNWANTED");
1802 0 : unwanted.add_parameter("serial", 7209);
1803 0 : if(!send_message(unwanted, false))
1804 : {
1805 0 : throw std::runtime_error("could not send UNWANTED message");
1806 : }
1807 0 : }
1808 : break;
1809 :
1810 1 : case sequence_t::SEQUENCE_TIMED_MESSAGE:
1811 : {
1812 1 : ed::message unwanted;
1813 1 : unwanted.reply_to(msg);
1814 3 : unwanted.set_command("TIMED");
1815 3 : unwanted.add_parameter("now", snapdev::now());
1816 1 : if(!send_message(unwanted, false))
1817 : {
1818 0 : throw std::runtime_error("could not send TIMED message");
1819 : }
1820 1 : }
1821 : break;
1822 :
1823 3 : case sequence_t::SEQUENCE_READY_HELP_MESSAGE:
1824 3 : switch(f_step)
1825 : {
1826 1 : case 1:
1827 : // done in this case
1828 1 : break;
1829 :
1830 1 : case 2:
1831 1 : if(msg.get_command() != "HELP")
1832 : {
1833 : throw std::runtime_error(
1834 : "second message expected to be HELP, got "
1835 0 : + msg.get_command()
1836 0 : + " instead.");
1837 : }
1838 :
1839 : {
1840 1 : ed::message commands;
1841 1 : commands.reply_to(msg);
1842 3 : commands.set_sent_from_server("reporter_test");
1843 3 : commands.set_sent_from_service("commands_message");
1844 3 : commands.set_command("COMMANDS");
1845 5 : commands.add_parameter("list", "HELP,READY,STOP");
1846 : //std::cerr << "--- respond with COMMANDS\n";
1847 1 : if(!send_message(commands, false))
1848 : {
1849 0 : throw std::runtime_error("could not send COMMANDS message");
1850 : }
1851 1 : }
1852 : break;
1853 :
1854 1 : case 3:
1855 1 : if(msg.get_command() != "STOP")
1856 : {
1857 : throw std::runtime_error(
1858 : "third message expected to be STOP, got "
1859 0 : + msg.get_command()
1860 0 : + " instead.");
1861 : }
1862 :
1863 1 : disconnect_all = true;
1864 1 : break;
1865 :
1866 0 : default:
1867 0 : throw std::runtime_error("reached step 4 of SEQUENCE_READY_HELP_MESSAGE?");
1868 :
1869 : }
1870 3 : break;
1871 :
1872 2 : case sequence_t::SEQUENCE_READY_THROW:
1873 2 : switch(f_step)
1874 : {
1875 1 : case 1:
1876 : // done in this case
1877 1 : break;
1878 :
1879 1 : case 2:
1880 1 : if(msg.get_command() != "HELP")
1881 : {
1882 : throw std::runtime_error(
1883 : "second message expected to be HELP, got "
1884 0 : + msg.get_command()
1885 0 : + " instead.");
1886 : }
1887 :
1888 : // got the help message, now do a "legitimate" throw
1889 : //
1890 1 : throw std::runtime_error("testing that the executor catches these exceptions.");
1891 :
1892 0 : default:
1893 0 : throw std::runtime_error("reached step 4 of SEQUENCE_READY_THROW?");
1894 :
1895 : }
1896 1 : break;
1897 :
1898 2 : case sequence_t::SEQUENCE_READY_THROW_WHAT:
1899 2 : switch(f_step)
1900 : {
1901 1 : case 1:
1902 : // done in this case
1903 1 : break;
1904 :
1905 1 : case 2:
1906 1 : if(msg.get_command() != "HELP")
1907 : {
1908 : throw std::runtime_error(
1909 : "second message expected to be HELP, got "
1910 0 : + msg.get_command()
1911 0 : + " instead.");
1912 : }
1913 :
1914 : // got the help message, now do a "legitimate" throw
1915 : //
1916 : struct my_exception
1917 : {
1918 : int code = 0;
1919 : };
1920 1 : throw my_exception({5});
1921 :
1922 0 : default:
1923 0 : throw std::runtime_error("reached step 4 of SEQUENCE_READY_THROW_WHAT?");
1924 :
1925 : }
1926 1 : break;
1927 :
1928 : }
1929 :
1930 10 : if(disconnect_all)
1931 : {
1932 5 : remove_from_communicator();
1933 :
1934 5 : ed::connection::pointer_t timer_ptr(f_timer.lock());
1935 5 : if(timer_ptr != nullptr)
1936 : {
1937 5 : timer_ptr->remove_from_communicator();
1938 : }
1939 5 : }
1940 10 : }
1941 :
1942 23 : void set_timer(ed::connection::pointer_t done_timer)
1943 : {
1944 23 : f_timer = done_timer;
1945 23 : }
1946 :
1947 : private:
1948 : // the sequence & step define the next action
1949 : //
1950 : sequence_t f_sequence = sequence_t::SEQUENCE_ONE_MESSAGE;
1951 : int f_step = 0;
1952 : ed::connection::weak_pointer_t
1953 : f_timer = ed::connection::weak_pointer_t();
1954 : };
1955 :
1956 :
1957 : class messenger_timer
1958 : : public ed::timer
1959 : {
1960 : public:
1961 : typedef std::shared_ptr<messenger_timer> pointer_t;
1962 :
1963 23 : messenger_timer(messenger_responder::pointer_t m)
1964 23 : : timer(10'000'000)
1965 23 : , f_messenger(m)
1966 : {
1967 69 : set_name("messenger_timer");
1968 23 : }
1969 :
1970 2 : void process_timeout()
1971 : {
1972 : // call default function(s)
1973 : //
1974 2 : timer::process_timeout();
1975 :
1976 2 : remove_from_communicator();
1977 2 : f_messenger->remove_from_communicator();
1978 2 : f_timed_out = true;
1979 2 : }
1980 :
1981 22 : bool timed_out_prima() const
1982 : {
1983 22 : return f_timed_out;
1984 : }
1985 :
1986 : private:
1987 : messenger_responder::pointer_t f_messenger = messenger_responder::pointer_t();
1988 : bool f_timed_out = false;
1989 : };
1990 :
1991 :
1992 :
1993 :
1994 : class permanent_binary_responder // an equivalent to a client
1995 : : public ed::timer
1996 : {
1997 : public:
1998 : typedef std::shared_ptr<permanent_binary_responder> pointer_t;
1999 :
2000 : enum class sequence_t
2001 : {
2002 : SEQUENCE_PING_PONG,
2003 : SEQUENCE_PRINBEE_MESSAGE
2004 : };
2005 :
2006 : class binary_responder
2007 : : public ed::tcp_client_connection
2008 : {
2009 : public:
2010 : typedef std::shared_ptr<binary_responder> pointer_t;
2011 :
2012 8 : binary_responder(
2013 : permanent_binary_responder * parent
2014 : , addr::addr const & a
2015 : , ed::mode_t mode)
2016 8 : : tcp_client_connection(
2017 : a
2018 : , mode)
2019 8 : , f_parent(parent)
2020 : {
2021 24 : set_name("binary_responder"); // connection name
2022 8 : }
2023 :
2024 : binary_responder(binary_responder const &) = delete;
2025 : binary_responder & operator = (binary_responder const &) = delete;
2026 :
2027 2 : virtual void process_read() override
2028 : {
2029 2 : f_parent->process_read();
2030 2 : }
2031 :
2032 : private:
2033 : permanent_binary_responder * f_parent = nullptr;
2034 : };
2035 :
2036 8 : permanent_binary_responder(
2037 : addr::addr const & a
2038 : , ed::mode_t mode
2039 : , sequence_t sequence
2040 : , int timeout = 500'000) // or ed::DEFAULT_PAUSE_BEFORE_RECONNECTING
2041 8 : : timer(timeout)
2042 8 : , f_address(a)
2043 8 : , f_mode(mode)
2044 8 : , f_sequence(sequence)
2045 8 : , f_timeout(timeout)
2046 : {
2047 24 : set_name("permanent_binary_responder"); // connection name
2048 8 : set_timeout_delay(f_timeout); // 0.5 seconds
2049 8 : set_enable(true); // be explicit that we want the timer to ping us
2050 8 : }
2051 :
2052 0 : virtual int get_socket() const override
2053 : {
2054 0 : if(f_responder != nullptr)
2055 : {
2056 0 : return f_responder->get_socket();
2057 : }
2058 0 : return -1;
2059 : }
2060 :
2061 8 : virtual void process_timeout() override
2062 : {
2063 : try
2064 : {
2065 24 : f_responder = std::make_shared<binary_responder>(
2066 16 : this
2067 8 : , f_address
2068 16 : , f_mode);
2069 : }
2070 0 : catch(ed::failed_connecting const & e)
2071 : {
2072 : // try again later (keep timer enabled)
2073 : //
2074 0 : return;
2075 0 : }
2076 : // other errors are not legally expected
2077 :
2078 8 : ed::communicator::instance()->add_connection(f_responder);
2079 :
2080 : // we're connected, disable the timer
2081 : //
2082 8 : set_enable(false);
2083 :
2084 : // send a PING and expect a PONG as a reply
2085 : //
2086 8 : switch(f_sequence)
2087 : {
2088 7 : case sequence_t::SEQUENCE_PING_PONG:
2089 : {
2090 7 : constexpr char const ping[] = { 'P', 'I', 'N', 'G' };
2091 7 : ssize_t const written(f_responder->write(ping, sizeof(ping)));
2092 7 : if(written != sizeof(ping))
2093 : {
2094 0 : throw std::runtime_error("could not send PING message");
2095 : }
2096 : }
2097 : break;
2098 :
2099 1 : case sequence_t::SEQUENCE_PRINBEE_MESSAGE:
2100 : {
2101 1 : constexpr char const msg[] = {
2102 : 'b', 'm', // magic ([b]inary [m]essage)
2103 : 1, // version
2104 : 0, // flags (none)
2105 : 'P', 'I', 'N', 'G', // message name
2106 : 8, 0, 0, 0, // size (little endian)
2107 : static_cast<char>(0xaa), 0x55, // CRC16 of data (fake)
2108 : static_cast<char>(0xee), 0x77, // CRC16 of message header
2109 : 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, static_cast<char>(0xFF) // the data
2110 : };
2111 1 : ssize_t const written(f_responder->write(msg, sizeof(msg)));
2112 1 : if(written != sizeof(msg))
2113 : {
2114 0 : throw std::runtime_error("could not send the Prinbee message");
2115 : }
2116 : }
2117 : break;
2118 :
2119 : }
2120 : }
2121 :
2122 : // this is called from the f_responder object (since this very object
2123 : // is just a connection with a timer, no actual socket)
2124 : //
2125 2 : virtual void process_read() override
2126 : {
2127 : // first we want the size
2128 : //
2129 2 : std::size_t size(0);
2130 2 : switch(f_sequence)
2131 : {
2132 1 : case sequence_t::SEQUENCE_PING_PONG:
2133 1 : size = 4UL;
2134 1 : break;
2135 :
2136 1 : case sequence_t::SEQUENCE_PRINBEE_MESSAGE:
2137 1 : size = 16UL;
2138 1 : break;
2139 :
2140 : }
2141 2 : if(size > sizeof(f_buffer))
2142 : {
2143 0 : throw std::runtime_error("size not supported (f_buffer too small)");
2144 : }
2145 :
2146 : // second we load `size` bytes, if possible, if not, just return early
2147 : //
2148 4 : while(f_buffer_size < size)
2149 : {
2150 2 : ssize_t const r(f_responder->read(f_buffer, size - f_buffer_size));
2151 2 : if(r < 0)
2152 : {
2153 0 : throw std::runtime_error("unexpected I/O error reading data from binary socket");
2154 : }
2155 2 : if(r == 0)
2156 : {
2157 : // EAGAIN or EOF, but for socket(), we don't really get EOF
2158 : //
2159 0 : return;
2160 : }
2161 2 : f_buffer_size += r;
2162 : }
2163 :
2164 : // we have a complete buffer, verify that it has the value we expect
2165 : //
2166 2 : ++f_step;
2167 : std::cout
2168 2 : << "--- "
2169 : << f_step
2170 2 : << ". binary client message ---"
2171 2 : << std::endl;
2172 :
2173 2 : switch(f_sequence)
2174 : {
2175 1 : case sequence_t::SEQUENCE_PING_PONG:
2176 1 : if(f_buffer[0] != 'P'
2177 1 : || f_buffer[1] != 'O'
2178 1 : || f_buffer[2] != 'N'
2179 1 : || f_buffer[3] != 'G')
2180 : {
2181 0 : throw std::runtime_error("expected PONG binary message.");
2182 : }
2183 1 : f_complete = true;
2184 1 : break;
2185 :
2186 1 : case sequence_t::SEQUENCE_PRINBEE_MESSAGE:
2187 1 : if(f_buffer[ 0] != 'b'
2188 1 : || f_buffer[ 1] != 'm'
2189 1 : || f_buffer[ 2] != 1
2190 1 : || f_buffer[ 3] != 0
2191 1 : || f_buffer[ 4] != 'P'
2192 1 : || f_buffer[ 5] != 'O'
2193 1 : || f_buffer[ 6] != 'N'
2194 1 : || f_buffer[ 7] != 'G'
2195 1 : || f_buffer[ 8] != 0
2196 1 : || f_buffer[ 9] != 0
2197 1 : || f_buffer[10] != 0
2198 1 : || f_buffer[11] != 0
2199 1 : || f_buffer[12] != 0x55
2200 1 : || f_buffer[13] != static_cast<char>(0xaa)
2201 1 : || f_buffer[14] != 0x33
2202 1 : || f_buffer[15] != static_cast<char>(0xcc))
2203 : {
2204 0 : throw std::runtime_error("expected PONG prinbee message.");
2205 : }
2206 1 : f_complete = true;
2207 1 : break;
2208 :
2209 : }
2210 :
2211 : // done with that buffer, reset the position/size
2212 : //
2213 2 : f_buffer_size = 0;
2214 :
2215 : //if(disconnect_all)
2216 : //{
2217 : // remove_from_communicator();
2218 : //
2219 : // ed::connection::pointer_t timer_ptr(f_timer.lock());
2220 : // if(timer_ptr != nullptr)
2221 : // {
2222 : // timer_ptr->remove_from_communicator();
2223 : // }
2224 : //}
2225 : }
2226 :
2227 8 : virtual void connection_removed() override
2228 : {
2229 8 : if(!f_complete)
2230 : {
2231 0 : throw std::runtime_error("binary responder not marked as complete.");
2232 : }
2233 :
2234 8 : if(f_responder != nullptr)
2235 : {
2236 8 : f_responder->remove_from_communicator();
2237 8 : f_responder.reset();
2238 : }
2239 8 : }
2240 :
2241 6 : void mark_complete()
2242 : {
2243 6 : f_complete = true;
2244 6 : }
2245 :
2246 : //void set_timer(ed::connection::pointer_t done_timer)
2247 : //{
2248 : // f_timer = done_timer;
2249 : //}
2250 :
2251 : private:
2252 : addr::addr f_address = addr::addr();
2253 : ed::mode_t f_mode = ed::mode_t::MODE_PLAIN;
2254 : sequence_t f_sequence = sequence_t::SEQUENCE_PING_PONG;
2255 : int f_step = 0;
2256 : int f_timeout = 500'000;
2257 : char f_buffer[4096] = {};
2258 : std::size_t f_buffer_size = 0; // number of bytes read so far
2259 : binary_responder::pointer_t f_responder = binary_responder::pointer_t();
2260 : bool f_complete = false;
2261 : };
2262 :
2263 :
2264 :
2265 :
2266 :
2267 :
2268 : } // no name namespace
2269 :
2270 :
2271 :
2272 19 : CATCH_TEST_CASE("reporter_executor", "[executor][reporter]")
2273 : {
2274 19 : CATCH_START_SECTION("reporter_executor: verify sleep in a function")
2275 : {
2276 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("program_sleep_func.rprtr", g_program_sleep_func));
2277 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
2278 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
2279 1 : p->parse_program();
2280 :
2281 1 : CATCH_REQUIRE(s->get_statement_size() == 5);
2282 :
2283 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
2284 1 : snapdev::timespec_ex const start(snapdev::now());
2285 1 : e->start();
2286 1 : CATCH_REQUIRE(e->run());
2287 1 : snapdev::timespec_ex const duration(snapdev::now() - start);
2288 1 : CATCH_REQUIRE(duration.tv_sec >= 2); // we slept for 2.5 seconds, so we expect at least start + 2 seconds
2289 1 : }
2290 19 : CATCH_END_SECTION()
2291 :
2292 19 : CATCH_START_SECTION("reporter_executor: verify sort function")
2293 : {
2294 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("program_sleep_func.rprtr", g_program_sort_func));
2295 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
2296 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
2297 1 : p->parse_program();
2298 :
2299 1 : CATCH_REQUIRE(s->get_statement_size() == 19);
2300 :
2301 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
2302 1 : e->start();
2303 1 : CATCH_REQUIRE(e->run());
2304 :
2305 1 : CATCH_REQUIRE(s->get_exit_code() == 0);
2306 :
2307 : // *** STRING ***
2308 : struct verify_string_t
2309 : {
2310 : char const * f_name = nullptr;
2311 : char const * f_value = nullptr;
2312 : };
2313 :
2314 : // verify that the resulting set of variable is indeed sorted
2315 1 : verify_string_t string_verify[] =
2316 : {
2317 : { "s1", "are" },
2318 : { "s2", "hello" },
2319 : { "s3", "who" },
2320 : { "s4", "world" },
2321 : { "s5", "you?" },
2322 : };
2323 :
2324 6 : for(auto const & v : string_verify)
2325 : {
2326 : //std::cerr << "--- testing \"" << v.f_name << "\".\n";
2327 15 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t var(s->get_variable(v.f_name));
2328 5 : CATCH_REQUIRE(var != nullptr);
2329 5 : CATCH_REQUIRE(var->get_name() == v.f_name);
2330 5 : CATCH_REQUIRE(var->get_type() == "string");
2331 5 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_string>(var)->get_string() == v.f_value);
2332 5 : }
2333 :
2334 : // *** INTEGER ***
2335 : struct verify_integer_t
2336 : {
2337 : char const * f_name = nullptr;
2338 : int f_value = 0;
2339 : };
2340 :
2341 : // verify that the resulting set of variable is indeed sorted
2342 1 : verify_integer_t integer_verify[] =
2343 : {
2344 : { "i1", -3 },
2345 : { "i2", 73 },
2346 : { "i3", 506 },
2347 : { "i4", 1003 },
2348 : { "i5", 1004 },
2349 : };
2350 :
2351 6 : for(auto const & v : integer_verify)
2352 : {
2353 : //std::cerr << "--- testing \"" << v.f_name << "\".\n";
2354 15 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t var(s->get_variable(v.f_name));
2355 5 : CATCH_REQUIRE(var != nullptr);
2356 5 : CATCH_REQUIRE(var->get_name() == v.f_name);
2357 5 : CATCH_REQUIRE(var->get_type() == "integer");
2358 5 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(var)->get_integer() == v.f_value);
2359 5 : }
2360 :
2361 : // *** FLOATING POINT ***
2362 : struct verify_floating_point_t
2363 : {
2364 : char const * f_name = nullptr;
2365 : double f_value = 0.0;
2366 : };
2367 :
2368 : // verify that the resulting set of variable is indeed sorted
2369 1 : verify_floating_point_t floating_point_verify[] =
2370 : {
2371 : { "f1", -10.103 },
2372 : { "f2", -0.3 },
2373 : { "f3", 1.004 },
2374 : { "f4", 50.6 },
2375 : { "f5", 73.5 },
2376 : };
2377 :
2378 6 : for(auto const & v : floating_point_verify)
2379 : {
2380 : //std::cerr << "--- testing \"" << v.f_name << "\".\n";
2381 15 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t var(s->get_variable(v.f_name));
2382 5 : CATCH_REQUIRE(var != nullptr);
2383 5 : CATCH_REQUIRE(var->get_name() == v.f_name);
2384 5 : CATCH_REQUIRE(var->get_type() == "floating_point");
2385 5 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_floating_point>(var)->get_floating_point() == v.f_value);
2386 5 : }
2387 1 : }
2388 19 : CATCH_END_SECTION()
2389 :
2390 19 : CATCH_START_SECTION("reporter_executor: verify starting the thread")
2391 : {
2392 1 : trace tracer(g_verify_starting_thread);
2393 :
2394 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("program_start_thread.rprtr", g_program_start_thread));
2395 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
2396 :
2397 : // use std::bind() to avoid copies of the tracer object
2398 : //
2399 1 : s->set_trace_callback(std::bind(&trace::callback, &tracer, std::placeholders::_1, std::placeholders::_2));
2400 :
2401 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
2402 1 : p->parse_program();
2403 :
2404 1 : CATCH_REQUIRE(s->get_statement_size() == 12);
2405 :
2406 : // before we run the script, there are no such variables
2407 : //
2408 3 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t var(s->get_variable("test"));
2409 1 : CATCH_REQUIRE(var == nullptr);
2410 3 : var = s->get_variable("test_copy_between_dollars");
2411 1 : CATCH_REQUIRE(var == nullptr);
2412 3 : var = s->get_variable("runner");
2413 1 : CATCH_REQUIRE(var == nullptr);
2414 3 : var = s->get_variable("runner_copy_as_is");
2415 1 : CATCH_REQUIRE(var == nullptr);
2416 3 : var = s->get_variable("time_limit");
2417 1 : CATCH_REQUIRE(var == nullptr);
2418 3 : var = s->get_variable("time_limit_copy");
2419 1 : CATCH_REQUIRE(var == nullptr);
2420 3 : var = s->get_variable("time_from_float");
2421 1 : CATCH_REQUIRE(var == nullptr);
2422 3 : var = s->get_variable("host_ip");
2423 1 : CATCH_REQUIRE(var == nullptr);
2424 3 : var = s->get_variable("host_ip_copy");
2425 1 : CATCH_REQUIRE(var == nullptr);
2426 3 : var = s->get_variable("time_and_host_ip");
2427 1 : CATCH_REQUIRE(var == nullptr);
2428 3 : var = s->get_variable("length");
2429 1 : CATCH_REQUIRE(var == nullptr);
2430 :
2431 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
2432 1 : e->start();
2433 1 : CATCH_REQUIRE(e->run());
2434 :
2435 3 : var = s->get_variable("test");
2436 1 : CATCH_REQUIRE(var != nullptr);
2437 1 : CATCH_REQUIRE(var->get_name() == "test");
2438 1 : CATCH_REQUIRE(var->get_type() == "integer");
2439 1 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(var)->get_integer() == 33);
2440 :
2441 3 : var = s->get_variable("test_copy_between_dollars");
2442 1 : CATCH_REQUIRE(var != nullptr);
2443 1 : CATCH_REQUIRE(var->get_name() == "test_copy_between_dollars");
2444 1 : CATCH_REQUIRE(var->get_type() == "string");
2445 1 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_string>(var)->get_string() == "$33$");
2446 :
2447 3 : var = s->get_variable("runner");
2448 1 : CATCH_REQUIRE(var != nullptr);
2449 1 : CATCH_REQUIRE(var->get_name() == "runner");
2450 1 : CATCH_REQUIRE(var->get_type() == "floating_point");
2451 1 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_floating_point>(var)->get_floating_point() == 6.07);
2452 :
2453 3 : var = s->get_variable("runner_copy_as_is");
2454 1 : CATCH_REQUIRE(var != nullptr);
2455 1 : CATCH_REQUIRE(var->get_name() == "runner_copy_as_is");
2456 1 : CATCH_REQUIRE(var->get_type() == "string");
2457 1 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_string>(var)->get_string() == "runner = 6.07");
2458 :
2459 3 : var = s->get_variable("time_limit");
2460 1 : CATCH_REQUIRE(var != nullptr);
2461 1 : CATCH_REQUIRE(var->get_name() == "time_limit");
2462 1 : CATCH_REQUIRE(var->get_type() == "timestamp");
2463 1 : snapdev::timespec_ex const time_limit(1713934141, 107805991);
2464 1 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_timestamp>(var)->get_timestamp() == time_limit);
2465 :
2466 3 : var = s->get_variable("time_limit_copy");
2467 1 : CATCH_REQUIRE(var != nullptr);
2468 1 : CATCH_REQUIRE(var->get_name() == "time_limit_copy");
2469 1 : CATCH_REQUIRE(var->get_type() == "string");
2470 1 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_string>(var)->get_string() == "limit: 1713934141.107805991");
2471 :
2472 3 : var = s->get_variable("host_ip");
2473 1 : CATCH_REQUIRE(var != nullptr);
2474 1 : CATCH_REQUIRE(var->get_name() == "host_ip");
2475 1 : CATCH_REQUIRE(var->get_type() == "address");
2476 1 : addr::addr a;
2477 1 : sockaddr_in ip = {
2478 : .sin_family = AF_INET,
2479 1 : .sin_port = htons(0),
2480 : .sin_addr = {
2481 1 : .s_addr = htonl(0x7f070333),
2482 : },
2483 : .sin_zero = {},
2484 1 : };
2485 1 : a.set_ipv4(ip);
2486 1 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_address>(var)->get_address() == a);
2487 :
2488 3 : var = s->get_variable("host_ip_copy");
2489 1 : CATCH_REQUIRE(var != nullptr);
2490 1 : CATCH_REQUIRE(var->get_name() == "host_ip_copy");
2491 1 : CATCH_REQUIRE(var->get_type() == "string");
2492 1 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_string>(var)->get_string() == "Host is at 127.7.3.51 address");
2493 :
2494 3 : var = s->get_variable("time_and_host_ip");
2495 1 : CATCH_REQUIRE(var != nullptr);
2496 1 : CATCH_REQUIRE(var->get_name() == "time_and_host_ip");
2497 1 : CATCH_REQUIRE(var->get_type() == "string");
2498 1 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_string>(var)->get_string() == "time 1713934141.107805991 and address 127.7.3.51...");
2499 :
2500 3 : var = s->get_variable("length");
2501 1 : CATCH_REQUIRE(var != nullptr);
2502 1 : CATCH_REQUIRE(var->get_name() == "length");
2503 1 : CATCH_REQUIRE(var->get_type() == "integer");
2504 1 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(var)->get_integer() == 51);
2505 1 : }
2506 19 : CATCH_END_SECTION()
2507 :
2508 19 : CATCH_START_SECTION("reporter_executor: verify computation (integers)")
2509 : {
2510 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("verify_computation_integer.rprtr", g_program_verify_computation_integer));
2511 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
2512 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
2513 1 : p->parse_program();
2514 :
2515 1 : CATCH_REQUIRE(s->get_statement_size() == 15);
2516 :
2517 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
2518 1 : e->start();
2519 1 : CATCH_REQUIRE(e->run());
2520 :
2521 1 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t var;
2522 :
2523 3 : var = s->get_variable("t01");
2524 1 : CATCH_REQUIRE(var != nullptr);
2525 1 : CATCH_REQUIRE(var->get_name() == "t01");
2526 1 : CATCH_REQUIRE(var->get_type() == "integer");
2527 1 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(var)->get_integer() == 3);
2528 :
2529 3 : var = s->get_variable("t11");
2530 1 : CATCH_REQUIRE(var != nullptr);
2531 1 : CATCH_REQUIRE(var->get_name() == "t11");
2532 1 : CATCH_REQUIRE(var->get_type() == "integer");
2533 1 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(var)->get_integer() == -3);
2534 :
2535 3 : var = s->get_variable("t12");
2536 1 : CATCH_REQUIRE(var != nullptr);
2537 1 : CATCH_REQUIRE(var->get_name() == "t12");
2538 1 : CATCH_REQUIRE(var->get_type() == "integer");
2539 1 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(var)->get_integer() == +3);
2540 :
2541 3 : var = s->get_variable("t21");
2542 1 : CATCH_REQUIRE(var != nullptr);
2543 1 : CATCH_REQUIRE(var->get_name() == "t21");
2544 1 : CATCH_REQUIRE(var->get_type() == "integer");
2545 1 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(var)->get_integer() == 3 + 2);
2546 :
2547 3 : var = s->get_variable("t22");
2548 1 : CATCH_REQUIRE(var != nullptr);
2549 1 : CATCH_REQUIRE(var->get_name() == "t22");
2550 1 : CATCH_REQUIRE(var->get_type() == "integer");
2551 1 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(var)->get_integer() == -(3 + 2));
2552 :
2553 3 : var = s->get_variable("t23");
2554 1 : CATCH_REQUIRE(var != nullptr);
2555 1 : CATCH_REQUIRE(var->get_name() == "t23");
2556 1 : CATCH_REQUIRE(var->get_type() == "integer");
2557 1 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(var)->get_integer() == 20 - 4);
2558 :
2559 3 : var = s->get_variable("t24");
2560 1 : CATCH_REQUIRE(var != nullptr);
2561 1 : CATCH_REQUIRE(var->get_name() == "t24");
2562 1 : CATCH_REQUIRE(var->get_type() == "integer");
2563 1 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(var)->get_integer() == 3 * 2);
2564 :
2565 3 : var = s->get_variable("t25");
2566 1 : CATCH_REQUIRE(var != nullptr);
2567 1 : CATCH_REQUIRE(var->get_name() == "t25");
2568 1 : CATCH_REQUIRE(var->get_type() == "integer");
2569 1 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(var)->get_integer() == 20 / 4);
2570 :
2571 3 : var = s->get_variable("t26");
2572 1 : CATCH_REQUIRE(var != nullptr);
2573 1 : CATCH_REQUIRE(var->get_name() == "t26");
2574 1 : CATCH_REQUIRE(var->get_type() == "integer");
2575 1 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(var)->get_integer() == 27 % 11);
2576 :
2577 3 : var = s->get_variable("t31");
2578 1 : CATCH_REQUIRE(var != nullptr);
2579 1 : CATCH_REQUIRE(var->get_name() == "t31");
2580 1 : CATCH_REQUIRE(var->get_type() == "integer");
2581 1 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(var)->get_integer() == 3 + 2 * 5);
2582 :
2583 3 : var = s->get_variable("t32");
2584 1 : CATCH_REQUIRE(var != nullptr);
2585 1 : CATCH_REQUIRE(var->get_name() == "t32");
2586 1 : CATCH_REQUIRE(var->get_type() == "integer");
2587 1 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(var)->get_integer() == -7 + 15 / 3);
2588 :
2589 3 : var = s->get_variable("t33");
2590 1 : CATCH_REQUIRE(var != nullptr);
2591 1 : CATCH_REQUIRE(var->get_name() == "t33");
2592 1 : CATCH_REQUIRE(var->get_type() == "integer");
2593 1 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(var)->get_integer() == +2 + 15 % 7);
2594 :
2595 3 : var = s->get_variable("t41");
2596 1 : CATCH_REQUIRE(var != nullptr);
2597 1 : CATCH_REQUIRE(var->get_name() == "t41");
2598 1 : CATCH_REQUIRE(var->get_type() == "integer");
2599 1 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(var)->get_integer() == (3 + 2) * 5);
2600 :
2601 3 : var = s->get_variable("t42");
2602 1 : CATCH_REQUIRE(var != nullptr);
2603 1 : CATCH_REQUIRE(var->get_name() == "t42");
2604 1 : CATCH_REQUIRE(var->get_type() == "integer");
2605 1 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(var)->get_integer() == (-7 + 15) / 3);
2606 :
2607 3 : var = s->get_variable("t43");
2608 1 : CATCH_REQUIRE(var != nullptr);
2609 1 : CATCH_REQUIRE(var->get_name() == "t43");
2610 1 : CATCH_REQUIRE(var->get_type() == "integer");
2611 1 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(var)->get_integer() == (+2 + 15) % 7);
2612 1 : }
2613 19 : CATCH_END_SECTION()
2614 :
2615 19 : CATCH_START_SECTION("reporter_executor: verify computation (floating points)")
2616 : {
2617 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("verify_computation_floating_point.rprtr", g_program_verify_computation_floating_point));
2618 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
2619 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
2620 1 : p->parse_program();
2621 :
2622 1 : CATCH_REQUIRE(s->get_statement_size() == 63);
2623 :
2624 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
2625 1 : e->start();
2626 1 : CATCH_REQUIRE(e->run());
2627 :
2628 : struct verify_t
2629 : {
2630 : char const * f_name = nullptr;
2631 : double f_value = 0.0;
2632 : };
2633 :
2634 1 : verify_t verify[] =
2635 : {
2636 : { "t01", 3.01 },
2637 : { "t11", -3.5 },
2638 : { "t12", +3.2 },
2639 : { "t21ff", 3.01 + 2.45 },
2640 : { "t21if", 3 + 2.54 },
2641 : { "t21fi", 3.01 + 2 },
2642 : { "t22ff", -(3.5 + 2.5) },
2643 : { "t22if", -(3 + 2.11) },
2644 : { "t22fi", -(3.07 + 2) },
2645 : { "t23ff", 20.07 - 4.13 },
2646 : { "t23if", 20 - 4.78 },
2647 : { "t23fi", 20.91 - 4 },
2648 : { "t24ff", 3.41 * 2.14 },
2649 : { "t24if", 3 * 2.67 },
2650 : { "t24fi", 3.32 * 2 },
2651 : { "t25ff", 20.83 / 4.07 },
2652 : { "t25if", 20 / 4.4 },
2653 : { "t25fi", 20.93 / 4 },
2654 : { "t26ff", fmod(27.27, 11.11) },
2655 : { "t26if", fmod(27, 11.88) },
2656 : { "t26fi", fmod(27.72, 11) },
2657 : { "t31fff", 3.03 + 2.2 * 5.9 },
2658 : { "t31iff", 3 + 2.5 * 5.7 },
2659 : { "t31fif", 3.2 + 2 * 5.3 },
2660 : { "t31ffi", 3.07 + 2.28 * 5 },
2661 : { "t31iif", 3 + 2 * 5.67 },
2662 : { "t31ifi", 3 + 2.56 * 5 },
2663 : { "t31fii", 3.33 + 2 * 5 },
2664 : { "t32fff", -7.11 + 15.7 / 3.06 },
2665 : { "t32iff", -7 + 15.25 / 3.31 },
2666 : { "t32fif", -7.78 + 15 / 3.77 },
2667 : { "t32ffi", -7.09 + 15.34 / 3 },
2668 : { "t32iif", -7 + 15 / 3.30 },
2669 : { "t32ifi", -7 + 15.09 / 3 },
2670 : { "t32fii", -7.94 + 15 / 3 },
2671 : { "t33fff", +2.21 + fmod(15.16, 7.8) },
2672 : { "t33iff", +2 + fmod(15.12, 7.93) },
2673 : { "t33fif", +2.58 + fmod(15, 7.63) },
2674 : { "t33ffi", +2.12 + fmod(15.09, 7) },
2675 : { "t33iif", +2 + fmod(15, 7.19) },
2676 : { "t33ifi", +2 + fmod(15.18, 7) },
2677 : { "t33fii", +2.17 + fmod(15, 7) },
2678 : { "t41fff", (3.45 + 2.06) * 5.55 },
2679 : { "t41iff", (3 + 2.17) * 5.07 },
2680 : { "t41fif", (3.37 + 2) * 5.12 },
2681 : { "t41ffi", (3.45 + 2.67) * 5 },
2682 : { "t41iif", (3 + 2) * 5.3 },
2683 : { "t41ifi", (3 + 2.9) * 5 },
2684 : { "t41fii", (3.4 + 2) * 5 },
2685 : { "t42fff", (-7.4 + 15.15) / 3.93 },
2686 : { "t42iff", (-7 + 15.21) / 3.43 },
2687 : { "t42fif", (-7.72 + 15) / 3.31 },
2688 : { "t42ffi", (-7.43 + 15.89) / 3 },
2689 : { "t42iif", (-7 + 15) / 3.4 },
2690 : { "t42ifi", (-7 + 15.09) / 3 },
2691 : { "t42fii", (-7.73 + 15) / 3 },
2692 : { "t43fff", fmod((+2.25 + 15.36), 7.47) },
2693 : { "t43iff", fmod((+2 + 15.16), 7.38) },
2694 : { "t43fif", fmod((+2.51 + 15), 7.59) },
2695 : { "t43ffi", fmod((+2.4 + 15.3), 7) },
2696 : { "t43iif", fmod((+2 + 15), 7.0) },
2697 : { "t43ifi", fmod((+2 + 15.8), 7) },
2698 : { "t43fii", fmod((+2.07 + 15), 7) },
2699 : };
2700 :
2701 1 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t var;
2702 64 : for(auto const & v : verify)
2703 : {
2704 : //std::cerr << "--- testing \"" << v.f_name << "\".\n";
2705 189 : var = s->get_variable(v.f_name);
2706 63 : CATCH_REQUIRE(var != nullptr);
2707 63 : CATCH_REQUIRE(var->get_name() == v.f_name);
2708 63 : CATCH_REQUIRE(var->get_type() == "floating_point");
2709 63 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_floating_point>(var)->get_floating_point() == v.f_value);
2710 : }
2711 1 : }
2712 19 : CATCH_END_SECTION()
2713 :
2714 19 : CATCH_START_SECTION("reporter_executor: verify computation (timestamp)")
2715 : {
2716 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("verify_computation_timestamp.rprtr", g_program_verify_computation_timestamp));
2717 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
2718 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
2719 1 : p->parse_program();
2720 :
2721 1 : CATCH_REQUIRE(s->get_statement_size() == 12);
2722 :
2723 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
2724 1 : e->start();
2725 1 : CATCH_REQUIRE(e->run());
2726 :
2727 : struct verify_t
2728 : {
2729 : char const * f_name = nullptr;
2730 : snapdev::timespec_ex f_value = snapdev::timespec_ex();
2731 : };
2732 :
2733 1 : verify_t verify[] =
2734 : {
2735 : { "t01", { 123 + 5, 0 } },
2736 : { "t02", { 33 + 123, 0 } },
2737 : { "t03", { 123 - 5, 0 } },
2738 : { "t04", { 33 - 123, 0 } },
2739 : { "t11", { 123 + 5, 89'999'999 } },
2740 : { "t12", { 33 + 123, 501'923'820 } },
2741 : { "t13", { 123 - 6, 999'000'000 } },
2742 : { "t14", { 333 - 123, 982'019'920 } },
2743 : { "t21", { -123, 0 } },
2744 : { "t22", { 123, 0 } },
2745 : { "t31", { 177, 330'000'000 } },
2746 : { "t32", { 158, 310'731'200 } },
2747 1 : };
2748 :
2749 1 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t var;
2750 13 : for(auto const & v : verify)
2751 : {
2752 : //std::cerr << "--- testing \"" << v.f_name << "\".\n";
2753 36 : var = s->get_variable(v.f_name);
2754 12 : CATCH_REQUIRE(var != nullptr);
2755 12 : CATCH_REQUIRE(var->get_name() == v.f_name);
2756 12 : CATCH_REQUIRE(var->get_type() == "timestamp");
2757 12 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_timestamp>(var)->get_timestamp() == v.f_value);
2758 : }
2759 1 : }
2760 19 : CATCH_END_SECTION()
2761 :
2762 19 : CATCH_START_SECTION("reporter_executor: verify hex() function")
2763 : {
2764 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("verify_computation_timestamp.rprtr", g_program_verify_hex));
2765 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
2766 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
2767 1 : p->parse_program();
2768 :
2769 1 : CATCH_REQUIRE(s->get_statement_size() == 5);
2770 :
2771 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
2772 1 : e->start();
2773 1 : CATCH_REQUIRE(e->run());
2774 :
2775 : struct verify_t
2776 : {
2777 : char const * f_name = nullptr;
2778 : char const * f_value = nullptr;
2779 : };
2780 :
2781 1 : verify_t verify[] =
2782 : {
2783 : { "t01", "1a4fd2" },
2784 : { "t02", "abcdef" },
2785 : { "t03", "ABCDEF" },
2786 : { "t04", "00000001" },
2787 : { "t05", "00ABCDEF" },
2788 : };
2789 :
2790 1 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t var;
2791 6 : for(auto const & v : verify)
2792 : {
2793 15 : var = s->get_variable(v.f_name);
2794 5 : CATCH_REQUIRE(var != nullptr);
2795 5 : CATCH_REQUIRE(var->get_name() == v.f_name);
2796 5 : CATCH_REQUIRE(var->get_type() == "string");
2797 5 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_string>(var)->get_string() == v.f_value);
2798 : }
2799 1 : }
2800 19 : CATCH_END_SECTION()
2801 :
2802 19 : CATCH_START_SECTION("reporter_executor: verify now()")
2803 : {
2804 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("verify_now.rprtr", g_program_verify_now));
2805 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
2806 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
2807 1 : p->parse_program();
2808 :
2809 1 : CATCH_REQUIRE(s->get_statement_size() == 2);
2810 :
2811 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
2812 1 : e->start();
2813 1 : CATCH_REQUIRE(e->run());
2814 :
2815 1 : CATCH_REQUIRE(s->get_exit_code() == 0);
2816 :
2817 1 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t var;
2818 3 : var = s->get_variable("about_now");
2819 1 : CATCH_REQUIRE(var != nullptr);
2820 1 : CATCH_REQUIRE(var->get_name() == "about_now");
2821 1 : CATCH_REQUIRE(var->get_type() == "timestamp");
2822 1 : snapdev::timespec_ex const value(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_timestamp>(var)->get_timestamp());
2823 1 : snapdev::timespec_ex const now(snapdev::now());
2824 1 : snapdev::timespec_ex const lower_value(now - snapdev::timespec_ex(1, 0));
2825 1 : CATCH_REQUIRE(lower_value <= value);
2826 1 : CATCH_REQUIRE(now >= value);
2827 1 : }
2828 19 : CATCH_END_SECTION()
2829 :
2830 19 : CATCH_START_SECTION("reporter_executor: verify max_pid()")
2831 : {
2832 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("verify_max_pid.rprtr", g_program_verify_max_pid));
2833 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
2834 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
2835 1 : p->parse_program();
2836 :
2837 1 : CATCH_REQUIRE(s->get_statement_size() == 2);
2838 :
2839 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
2840 1 : e->start();
2841 1 : CATCH_REQUIRE(e->run());
2842 :
2843 1 : CATCH_REQUIRE(s->get_exit_code() == 0);
2844 :
2845 1 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t var;
2846 3 : var = s->get_variable("top_pid");
2847 1 : CATCH_REQUIRE(var != nullptr);
2848 1 : CATCH_REQUIRE(var->get_name() == "top_pid");
2849 1 : CATCH_REQUIRE(var->get_type() == "integer");
2850 1 : std::int64_t const value(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(var)->get_integer());
2851 1 : CATCH_REQUIRE(cppthread::get_pid_max() == value);
2852 1 : }
2853 19 : CATCH_END_SECTION()
2854 :
2855 19 : CATCH_START_SECTION("reporter_executor: verify random()")
2856 : {
2857 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("verify_random.rprtr", g_program_verify_random));
2858 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
2859 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
2860 1 : p->parse_program();
2861 :
2862 1 : CATCH_REQUIRE(s->get_statement_size() == 4);
2863 :
2864 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
2865 1 : e->start();
2866 1 : CATCH_REQUIRE(e->run());
2867 :
2868 1 : CATCH_REQUIRE(s->get_exit_code() == 0);
2869 :
2870 1 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t var;
2871 3 : var = s->get_variable("any_number");
2872 1 : CATCH_REQUIRE(var != nullptr);
2873 1 : CATCH_REQUIRE(var->get_name() == "any_number");
2874 1 : CATCH_REQUIRE(var->get_type() == "integer");
2875 :
2876 3 : var = s->get_variable("positive");
2877 1 : CATCH_REQUIRE(var != nullptr);
2878 1 : CATCH_REQUIRE(var->get_name() == "positive");
2879 1 : CATCH_REQUIRE(var->get_type() == "integer");
2880 1 : std::int64_t const value(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(var)->get_integer());
2881 1 : CATCH_REQUIRE(value >= 0);
2882 :
2883 3 : var = s->get_variable("positive_or_negative");
2884 1 : CATCH_REQUIRE(var != nullptr);
2885 1 : CATCH_REQUIRE(var->get_name() == "positive_or_negative");
2886 1 : CATCH_REQUIRE(var->get_type() == "integer");
2887 1 : }
2888 19 : CATCH_END_SECTION()
2889 :
2890 19 : CATCH_START_SECTION("reporter_executor: verify hostname")
2891 : {
2892 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("verify_now.rprtr", g_program_verify_hostname));
2893 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
2894 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
2895 1 : p->parse_program();
2896 :
2897 1 : CATCH_REQUIRE(s->get_statement_size() == 2);
2898 :
2899 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
2900 1 : e->start();
2901 1 : CATCH_REQUIRE(e->run());
2902 :
2903 1 : CATCH_REQUIRE(s->get_exit_code() == 0);
2904 :
2905 1 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t var;
2906 3 : var = s->get_variable("host_name");
2907 1 : CATCH_REQUIRE(var != nullptr);
2908 1 : CATCH_REQUIRE(var->get_name() == "host_name");
2909 1 : CATCH_REQUIRE(var->get_type() == "string");
2910 1 : std::string const host_name(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_string>(var)->get_string());
2911 1 : std::string const expected_name(snapdev::gethostname());
2912 1 : CATCH_REQUIRE(expected_name == host_name);
2913 1 : }
2914 19 : CATCH_END_SECTION()
2915 :
2916 19 : CATCH_START_SECTION("reporter_executor: verify kill with number")
2917 : {
2918 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("verify_kill_number.rprtr", g_program_verify_kill_number));
2919 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
2920 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
2921 1 : p->parse_program();
2922 :
2923 1 : CATCH_REQUIRE(s->get_statement_size() == 2);
2924 :
2925 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
2926 1 : e->start();
2927 1 : CATCH_REQUIRE(e->run());
2928 :
2929 1 : CATCH_REQUIRE(s->get_exit_code() == 0);
2930 1 : }
2931 19 : CATCH_END_SECTION()
2932 :
2933 19 : CATCH_START_SECTION("reporter_executor: verify kill with identifier")
2934 : {
2935 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("verify_kill_identifier.rprtr", g_program_verify_kill_identifier));
2936 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
2937 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
2938 1 : p->parse_program();
2939 :
2940 1 : CATCH_REQUIRE(s->get_statement_size() == 2);
2941 :
2942 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
2943 1 : e->start();
2944 1 : CATCH_REQUIRE(e->run());
2945 :
2946 1 : CATCH_REQUIRE(s->get_exit_code() == 0);
2947 1 : }
2948 19 : CATCH_END_SECTION()
2949 :
2950 19 : CATCH_START_SECTION("reporter_executor: verify kill with string")
2951 : {
2952 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("verify_kill_string.rprtr", g_program_verify_kill_string));
2953 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
2954 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
2955 1 : p->parse_program();
2956 :
2957 1 : CATCH_REQUIRE(s->get_statement_size() == 2);
2958 :
2959 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
2960 1 : e->start();
2961 1 : CATCH_REQUIRE(e->run());
2962 :
2963 1 : CATCH_REQUIRE(s->get_exit_code() == 0);
2964 1 : }
2965 19 : CATCH_END_SECTION()
2966 :
2967 19 : CATCH_START_SECTION("reporter_executor: verify computation (address)")
2968 : {
2969 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("verify_computation_address.rprtr", g_program_verify_computation_address));
2970 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
2971 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
2972 1 : p->parse_program();
2973 :
2974 1 : CATCH_REQUIRE(s->get_statement_size() == 4);
2975 :
2976 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
2977 1 : e->start();
2978 1 : CATCH_REQUIRE(e->run());
2979 :
2980 : //"set_variable(name: t01, value: <127.0.0.1> + 256)\n"
2981 : //"set_variable(name: t02, value: 256 + <192.168.3.57>)\n"
2982 : //"set_variable(name: t03, value: <172.131.4.1> - 256)\n"
2983 : //"set_variable(name: t11, value: <10.5.34.255> - <10.5.33.0>)\n"
2984 :
2985 1 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t var;
2986 1 : addr::addr a;
2987 :
2988 3 : var = s->get_variable("t01");
2989 1 : CATCH_REQUIRE(var != nullptr);
2990 1 : CATCH_REQUIRE(var->get_name() == "t01");
2991 1 : CATCH_REQUIRE(var->get_type() == "address");
2992 3 : a = addr::string_to_addr("127.0.1.1");
2993 1 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_address>(var)->get_address() == a);
2994 :
2995 3 : var = s->get_variable("t02");
2996 1 : CATCH_REQUIRE(var != nullptr);
2997 1 : CATCH_REQUIRE(var->get_name() == "t02");
2998 1 : CATCH_REQUIRE(var->get_type() == "address");
2999 3 : a = addr::string_to_addr("192.168.4.57");
3000 1 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_address>(var)->get_address() == a);
3001 :
3002 3 : var = s->get_variable("t03");
3003 1 : CATCH_REQUIRE(var != nullptr);
3004 1 : CATCH_REQUIRE(var->get_name() == "t03");
3005 1 : CATCH_REQUIRE(var->get_type() == "address");
3006 3 : a = addr::string_to_addr("172.131.3.1");
3007 1 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_address>(var)->get_address() == a);
3008 :
3009 3 : var = s->get_variable("t11");
3010 1 : CATCH_REQUIRE(var != nullptr);
3011 1 : CATCH_REQUIRE(var->get_name() == "t11");
3012 1 : CATCH_REQUIRE(var->get_type() == "integer");
3013 1 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(var)->get_integer() == 511);
3014 1 : }
3015 19 : CATCH_END_SECTION()
3016 :
3017 19 : CATCH_START_SECTION("reporter_executor: verify computation (concatenation)")
3018 : {
3019 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("verify_computation_concatenation.rprtr", g_program_verify_computation_concatenation));
3020 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
3021 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
3022 1 : p->parse_program();
3023 :
3024 1 : CATCH_REQUIRE(s->get_statement_size() == 21);
3025 :
3026 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
3027 1 : e->start();
3028 1 : CATCH_REQUIRE(e->run());
3029 :
3030 : struct verify_t
3031 : {
3032 : char const * f_name = nullptr;
3033 : char const * f_value = nullptr;
3034 : char const * f_type = nullptr;
3035 : };
3036 :
3037 1 : verify_t verify[] =
3038 : {
3039 : { "t01", "identifier", "identifier" },
3040 : { "t11", "single string", "string" },
3041 : { "t12", "single string", "string" },
3042 : { "t13", "single string", "string" },
3043 : { "t14", "double string", "string" },
3044 : { "t21", "identify", "identifier" },
3045 : { "t22", "single string", "string" },
3046 : { "t23", "double string", "string" },
3047 : { "t31", "single36", "string" },
3048 : { "t32", "258single", "string" },
3049 : { "t33", "string102", "string" },
3050 : { "t34", "5005double", "string" },
3051 : { "t41", "single[0-9]+", "regex" },
3052 : { "t42", "[0-9]+single", "regex" },
3053 : { "t43", "string[0-9]+", "regex" },
3054 : { "t44", "[0-9]+double", "regex" },
3055 : { "t45", "a\\|b[0-9]+", "regex" },
3056 : { "t46", "[0-9]+c\\{3,9\\}", "regex" },
3057 : { "t47", "\\[a-z\\]\\?[0-9]+", "regex" },
3058 : { "t48", "[0-9]+a\\?b\\?c\\?", "regex" },
3059 : { "t49", "[0-9]+(a|b|c)?", "regex" },
3060 : };
3061 :
3062 1 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t var;
3063 22 : for(auto const & v : verify)
3064 : {
3065 : //std::cerr << "--- testing \"" << v.f_name << "\".\n";
3066 63 : var = s->get_variable(v.f_name);
3067 21 : CATCH_REQUIRE(var != nullptr);
3068 21 : CATCH_REQUIRE(var->get_name() == v.f_name);
3069 21 : CATCH_REQUIRE(var->get_type() == v.f_type);
3070 21 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_string>(var)->get_string() == v.f_value);
3071 : }
3072 1 : }
3073 19 : CATCH_END_SECTION()
3074 :
3075 19 : CATCH_START_SECTION("reporter_executor: verify computation (string repeat)")
3076 : {
3077 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("verify_computation_string_repeat.rprtr", g_program_verify_computation_string_repeat));
3078 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
3079 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
3080 1 : p->parse_program();
3081 :
3082 1 : CATCH_REQUIRE(s->get_statement_size() == 4);
3083 :
3084 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
3085 1 : e->start();
3086 1 : CATCH_REQUIRE(e->run());
3087 :
3088 : struct verify_t
3089 : {
3090 : char const * f_name = nullptr;
3091 : char const * f_value = nullptr;
3092 : };
3093 :
3094 1 : verify_t verify[] =
3095 : {
3096 : { "t01", "abcabcabc" },
3097 : { "t02", "xyzxyzxyzxyzxyz" },
3098 : { "t03", "" },
3099 : { "t04", "one" },
3100 : };
3101 :
3102 1 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t var;
3103 5 : for(auto const & v : verify)
3104 : {
3105 : //std::cerr << "--- testing \"" << v.f_name << "\".\n";
3106 12 : var = s->get_variable(v.f_name);
3107 4 : CATCH_REQUIRE(var != nullptr);
3108 4 : CATCH_REQUIRE(var->get_name() == v.f_name);
3109 4 : CATCH_REQUIRE(var->get_type() == "string");
3110 4 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_string>(var)->get_string() == v.f_value);
3111 : }
3112 1 : }
3113 19 : CATCH_END_SECTION()
3114 :
3115 19 : CATCH_START_SECTION("reporter_executor: verify variable in string")
3116 : {
3117 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("verify_variable_in_string.rprtr", g_program_verify_variable_in_string));
3118 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
3119 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
3120 1 : p->parse_program();
3121 :
3122 1 : CATCH_REQUIRE(s->get_statement_size() == 2);
3123 :
3124 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
3125 1 : e->start();
3126 1 : CATCH_REQUIRE(e->run());
3127 :
3128 : struct verify_t
3129 : {
3130 : char const * f_name = nullptr;
3131 : char const * f_value = nullptr;
3132 : };
3133 :
3134 1 : verify_t verify[] =
3135 : {
3136 : { "foo", "abc" },
3137 : { "bar", "[abc]" },
3138 : };
3139 :
3140 1 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t var;
3141 3 : for(auto const & v : verify)
3142 : {
3143 : //std::cerr << "--- testing \"" << v.f_name << "\".\n";
3144 6 : var = s->get_variable(v.f_name);
3145 2 : CATCH_REQUIRE(var != nullptr);
3146 2 : CATCH_REQUIRE(var->get_name() == v.f_name);
3147 2 : CATCH_REQUIRE(var->get_type() == "string");
3148 2 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_string>(var)->get_string() == v.f_value);
3149 : }
3150 1 : }
3151 19 : CATCH_END_SECTION()
3152 :
3153 19 : CATCH_START_SECTION("reporter_executor: print() + message")
3154 : {
3155 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("print_message.rprtr", g_program_print_message));
3156 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
3157 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
3158 1 : p->parse_program();
3159 :
3160 1 : CATCH_REQUIRE(s->get_statement_size() == 2);
3161 :
3162 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
3163 1 : e->start();
3164 :
3165 1 : CATCH_REQUIRE(s->get_exit_code() == 0);
3166 1 : }
3167 19 : CATCH_END_SECTION()
3168 19 : }
3169 :
3170 :
3171 9 : CATCH_TEST_CASE("reporter_executor_message", "[executor][reporter][message]")
3172 : {
3173 9 : CATCH_START_SECTION("reporter_executor_message: send/receive one message")
3174 : {
3175 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("program_accept_one_message.rprtr", g_program_accept_one_message));
3176 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
3177 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
3178 1 : p->parse_program();
3179 :
3180 1 : CATCH_REQUIRE(s->get_statement_size() == 16);
3181 :
3182 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
3183 1 : e->start();
3184 1 : addr::addr a;
3185 1 : sockaddr_in ip = {
3186 : .sin_family = AF_INET,
3187 1 : .sin_port = htons(20002),
3188 : .sin_addr = {
3189 1 : .s_addr = htonl(0x7f000001),
3190 : },
3191 : .sin_zero = {},
3192 1 : };
3193 1 : a.set_ipv4(ip);
3194 1 : messenger_responder::pointer_t messenger(std::make_shared<messenger_responder>(
3195 : a
3196 1 : , ed::mode_t::MODE_PLAIN
3197 2 : , messenger_responder::sequence_t::SEQUENCE_ONE_MESSAGE));
3198 1 : ed::communicator::instance()->add_connection(messenger);
3199 1 : messenger_timer::pointer_t timer(std::make_shared<messenger_timer>(messenger));
3200 1 : ed::communicator::instance()->add_connection(timer);
3201 1 : messenger->set_timer(timer);
3202 :
3203 1 : CATCH_REQUIRE(e->run());
3204 :
3205 : // if we exited because of our timer, then the test did not pass
3206 : //
3207 1 : CATCH_REQUIRE_FALSE(timer->timed_out_prima());
3208 :
3209 1 : CATCH_REQUIRE(s->get_exit_code() == 0);
3210 :
3211 3 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t var(s->get_variable("command"));
3212 1 : CATCH_REQUIRE(var != nullptr);
3213 1 : SNAP_CATCH2_NAMESPACE::reporter::variable_string::pointer_t v(std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_string>(var));
3214 1 : CATCH_REQUIRE(v != nullptr);
3215 1 : CATCH_REQUIRE(v->get_string() == "REGISTER");
3216 :
3217 3 : var = s->get_variable("register_version");
3218 1 : CATCH_REQUIRE(var != nullptr);
3219 1 : v = std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_string>(var);
3220 1 : CATCH_REQUIRE(v != nullptr);
3221 1 : CATCH_REQUIRE(v->get_string() == "1");
3222 :
3223 3 : var = s->get_variable("register_service");
3224 1 : CATCH_REQUIRE(var != nullptr);
3225 1 : v = std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_string>(var);
3226 1 : CATCH_REQUIRE(v != nullptr);
3227 1 : CATCH_REQUIRE(v->get_string() == "responder");
3228 1 : }
3229 9 : CATCH_END_SECTION()
3230 :
3231 9 : CATCH_START_SECTION("reporter_executor_message: receive one unwanted/unexpected message")
3232 : {
3233 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("program_receive_unwanted_message.rprtr", g_program_receive_unwanted_message));
3234 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
3235 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
3236 1 : p->parse_program();
3237 :
3238 1 : CATCH_REQUIRE(s->get_statement_size() == 13);
3239 :
3240 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
3241 1 : e->start();
3242 1 : addr::addr a;
3243 1 : sockaddr_in ip = {
3244 : .sin_family = AF_INET,
3245 1 : .sin_port = htons(20002),
3246 : .sin_addr = {
3247 1 : .s_addr = htonl(0x7f000001),
3248 : },
3249 : .sin_zero = {},
3250 1 : };
3251 1 : a.set_ipv4(ip);
3252 1 : messenger_responder::pointer_t messenger(std::make_shared<messenger_responder>(
3253 : a
3254 1 : , ed::mode_t::MODE_PLAIN
3255 2 : , messenger_responder::sequence_t::SEQUENCE_UNWANTED_MESSAGE));
3256 1 : ed::communicator::instance()->add_connection(messenger);
3257 1 : e->set_thread_done_callback([messenger]()
3258 : {
3259 1 : ed::communicator::instance()->remove_connection(messenger);
3260 1 : });
3261 :
3262 1 : CATCH_REQUIRE(e->run());
3263 :
3264 1 : CATCH_REQUIRE(s->get_exit_code() == 1);
3265 1 : }
3266 9 : CATCH_END_SECTION()
3267 :
3268 9 : CATCH_START_SECTION("reporter_executor_message: send message with unsupported parameter type fails")
3269 : {
3270 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("program_send_unsupported_message_parameter_type.rprtr", g_program_send_unsupported_message_parameter_type));
3271 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
3272 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
3273 1 : p->parse_program();
3274 :
3275 1 : CATCH_REQUIRE(s->get_statement_size() == 12);
3276 :
3277 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
3278 1 : e->start();
3279 1 : addr::addr a;
3280 1 : sockaddr_in ip = {
3281 : .sin_family = AF_INET,
3282 1 : .sin_port = htons(20002),
3283 : .sin_addr = {
3284 1 : .s_addr = htonl(0x7f000001),
3285 : },
3286 : .sin_zero = {},
3287 1 : };
3288 1 : a.set_ipv4(ip);
3289 1 : messenger_responder::pointer_t messenger(std::make_shared<messenger_responder>(
3290 : a
3291 1 : , ed::mode_t::MODE_PLAIN
3292 2 : , messenger_responder::sequence_t::SEQUENCE_UNWANTED_MESSAGE));
3293 1 : ed::communicator::instance()->add_connection(messenger);
3294 1 : e->set_thread_done_callback([messenger]()
3295 : {
3296 1 : ed::communicator::instance()->remove_connection(messenger);
3297 1 : });
3298 :
3299 1 : CATCH_REQUIRE(e->run());
3300 3 : CATCH_REQUIRE_THROWS_MATCHES(
3301 : e->stop()
3302 : , ed::runtime_error
3303 : , Catch::Matchers::ExceptionMessage(
3304 : "event_dispatcher_exception: message parameter type \"floating_point\" not supported yet."));
3305 :
3306 1 : CATCH_REQUIRE(s->get_exit_code() == -1);
3307 1 : }
3308 9 : CATCH_END_SECTION()
3309 :
3310 9 : CATCH_START_SECTION("reporter_executor_message: save message parameter identifier as an integer fails")
3311 : {
3312 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("program_send_invalid_parameter_value_type.rprtr", g_program_send_invalid_parameter_value_type));
3313 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
3314 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
3315 1 : p->parse_program();
3316 :
3317 1 : CATCH_REQUIRE(s->get_statement_size() == 12);
3318 :
3319 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
3320 1 : e->start();
3321 1 : addr::addr a;
3322 1 : sockaddr_in ip = {
3323 : .sin_family = AF_INET,
3324 1 : .sin_port = htons(20002),
3325 : .sin_addr = {
3326 1 : .s_addr = htonl(0x7f000001),
3327 : },
3328 : .sin_zero = {},
3329 1 : };
3330 1 : a.set_ipv4(ip);
3331 1 : messenger_responder::pointer_t messenger(std::make_shared<messenger_responder>(
3332 : a
3333 1 : , ed::mode_t::MODE_PLAIN
3334 2 : , messenger_responder::sequence_t::SEQUENCE_UNWANTED_MESSAGE));
3335 1 : ed::communicator::instance()->add_connection(messenger);
3336 1 : e->set_thread_done_callback([messenger]()
3337 : {
3338 1 : ed::communicator::instance()->remove_connection(messenger);
3339 1 : });
3340 :
3341 1 : CATCH_REQUIRE(e->run());
3342 3 : CATCH_REQUIRE_THROWS_MATCHES(
3343 : e->stop()
3344 : , ed::runtime_error
3345 : , Catch::Matchers::ExceptionMessage(
3346 : "event_dispatcher_exception: value \"responder\" not recognized as a valid integer."));
3347 :
3348 1 : CATCH_REQUIRE(s->get_exit_code() == -1);
3349 1 : }
3350 9 : CATCH_END_SECTION()
3351 :
3352 9 : CATCH_START_SECTION("reporter_executor_message: save message parameter of type timestamp")
3353 : {
3354 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("program_save_parameter_of_type_timestamp.rprtr", g_program_save_parameter_of_type_timestamp));
3355 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
3356 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
3357 1 : p->parse_program();
3358 :
3359 : //CATCH_REQUIRE(s->get_statement_size() == 19);
3360 :
3361 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
3362 1 : e->start();
3363 1 : addr::addr a;
3364 1 : sockaddr_in ip = {
3365 : .sin_family = AF_INET,
3366 1 : .sin_port = htons(20002),
3367 : .sin_addr = {
3368 1 : .s_addr = htonl(0x7f000001),
3369 : },
3370 : .sin_zero = {},
3371 1 : };
3372 1 : a.set_ipv4(ip);
3373 1 : messenger_responder::pointer_t messenger(std::make_shared<messenger_responder>(
3374 : a
3375 1 : , ed::mode_t::MODE_PLAIN
3376 2 : , messenger_responder::sequence_t::SEQUENCE_TIMED_MESSAGE));
3377 1 : ed::communicator::instance()->add_connection(messenger);
3378 1 : e->set_thread_done_callback([messenger]()
3379 : {
3380 1 : ed::communicator::instance()->remove_connection(messenger);
3381 1 : });
3382 :
3383 1 : CATCH_REQUIRE(e->run());
3384 1 : e->stop();
3385 :
3386 1 : CATCH_REQUIRE(s->get_exit_code() == 0);
3387 :
3388 3 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t var(s->get_variable("register_version"));
3389 1 : CATCH_REQUIRE(var != nullptr);
3390 1 : SNAP_CATCH2_NAMESPACE::reporter::variable_integer::pointer_t vi(std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(var));
3391 1 : CATCH_REQUIRE(vi != nullptr);
3392 1 : CATCH_REQUIRE(vi->get_type() == "integer");
3393 1 : CATCH_REQUIRE(vi->get_integer() == 1);
3394 :
3395 3 : var = s->get_variable("default_integer");
3396 1 : CATCH_REQUIRE(var != nullptr);
3397 1 : vi = std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(var);
3398 1 : CATCH_REQUIRE(vi != nullptr);
3399 1 : CATCH_REQUIRE(vi->get_type() == "integer");
3400 1 : CATCH_REQUIRE(vi->get_integer() == 0);
3401 :
3402 3 : var = s->get_variable("timed_value");
3403 1 : CATCH_REQUIRE(var != nullptr);
3404 1 : SNAP_CATCH2_NAMESPACE::reporter::variable_timestamp::pointer_t vts(std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_timestamp>(var));
3405 1 : CATCH_REQUIRE(vts != nullptr);
3406 1 : CATCH_REQUIRE(vts->get_type() == "timestamp");
3407 1 : snapdev::timespec_ex const param_timestamp(vts->get_timestamp());
3408 1 : snapdev::timespec_ex const now(snapdev::now());
3409 1 : snapdev::timespec_ex const minimum_value(now - snapdev::timespec_ex(1, 0));
3410 1 : CATCH_REQUIRE(param_timestamp >= minimum_value);
3411 1 : CATCH_REQUIRE(param_timestamp <= now);
3412 :
3413 3 : var = s->get_variable("default_time");
3414 1 : CATCH_REQUIRE(var != nullptr);
3415 1 : vts = std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_timestamp>(var);
3416 1 : CATCH_REQUIRE(vts != nullptr);
3417 1 : CATCH_REQUIRE(vts->get_type() == "timestamp");
3418 1 : CATCH_REQUIRE(vts->get_timestamp() == snapdev::timespec_ex());
3419 1 : }
3420 9 : CATCH_END_SECTION()
3421 :
3422 9 : CATCH_START_SECTION("reporter_executor_message: save message parameter with unknown type")
3423 : {
3424 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("program_save_parameter_with_unknown_type.rprtr", g_program_save_parameter_with_unknown_type));
3425 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
3426 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
3427 1 : p->parse_program();
3428 :
3429 1 : CATCH_REQUIRE(s->get_statement_size() == 12);
3430 :
3431 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
3432 1 : e->start();
3433 1 : addr::addr a;
3434 1 : sockaddr_in ip = {
3435 : .sin_family = AF_INET,
3436 1 : .sin_port = htons(20002),
3437 : .sin_addr = {
3438 1 : .s_addr = htonl(0x7f000001),
3439 : },
3440 : .sin_zero = {},
3441 1 : };
3442 1 : a.set_ipv4(ip);
3443 1 : messenger_responder::pointer_t messenger(std::make_shared<messenger_responder>(
3444 : a
3445 1 : , ed::mode_t::MODE_PLAIN
3446 2 : , messenger_responder::sequence_t::SEQUENCE_UNWANTED_MESSAGE));
3447 1 : ed::communicator::instance()->add_connection(messenger);
3448 1 : e->set_thread_done_callback([messenger]()
3449 : {
3450 1 : ed::communicator::instance()->remove_connection(messenger);
3451 1 : });
3452 :
3453 1 : CATCH_REQUIRE(e->run());
3454 3 : CATCH_REQUIRE_THROWS_MATCHES(
3455 : e->stop()
3456 : , ed::runtime_error
3457 : , Catch::Matchers::ExceptionMessage(
3458 : "event_dispatcher_exception: unsupported type \"void\" for save_parameter_value()."));
3459 :
3460 1 : CATCH_REQUIRE(s->get_exit_code() == -1);
3461 1 : }
3462 9 : CATCH_END_SECTION()
3463 :
3464 9 : CATCH_START_SECTION("reporter_executor_message: send & receive complete messages")
3465 : {
3466 : // in this case, load the program from a file
3467 : // to verify that this works as expected
3468 : //
3469 1 : std::string const source_dir(SNAP_CATCH2_NAMESPACE::g_source_dir());
3470 1 : std::string const filename(source_dir + "/tests/rprtr/send_and_receive_complete_messages");
3471 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(SNAP_CATCH2_NAMESPACE::reporter::create_lexer(filename));
3472 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
3473 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
3474 1 : p->parse_program();
3475 :
3476 1 : CATCH_REQUIRE(s->get_statement_size() == 34);
3477 :
3478 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
3479 1 : e->start();
3480 1 : addr::addr a;
3481 1 : sockaddr_in ip = {
3482 : .sin_family = AF_INET,
3483 1 : .sin_port = htons(20002),
3484 : .sin_addr = {
3485 1 : .s_addr = htonl(0x7f000001),
3486 : },
3487 : .sin_zero = {},
3488 1 : };
3489 1 : a.set_ipv4(ip);
3490 1 : messenger_responder::pointer_t messenger(std::make_shared<messenger_responder>(
3491 : a
3492 1 : , ed::mode_t::MODE_PLAIN
3493 2 : , messenger_responder::sequence_t::SEQUENCE_READY_HELP_MESSAGE));
3494 1 : ed::communicator::instance()->add_connection(messenger);
3495 1 : messenger_timer::pointer_t timer(std::make_shared<messenger_timer>(messenger));
3496 1 : ed::communicator::instance()->add_connection(timer);
3497 1 : messenger->set_timer(timer);
3498 :
3499 1 : CATCH_REQUIRE(e->run());
3500 :
3501 : // if we exited because of our timer, then the test did not pass
3502 : //
3503 1 : CATCH_REQUIRE_FALSE(timer->timed_out_prima());
3504 :
3505 1 : CATCH_REQUIRE(s->get_exit_code() == 0);
3506 :
3507 : // we unset that variable, make sure that worked
3508 : //
3509 3 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t var(s->get_variable("got_register"));
3510 1 : CATCH_REQUIRE(var == nullptr);
3511 :
3512 3 : var = s->get_variable("server");
3513 1 : CATCH_REQUIRE(var != nullptr);
3514 1 : SNAP_CATCH2_NAMESPACE::reporter::variable_string::pointer_t str(std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_string>(var));
3515 1 : CATCH_REQUIRE(str != nullptr);
3516 1 : CATCH_REQUIRE(str->get_type() == "string");
3517 1 : CATCH_REQUIRE(str->get_string() == "reporter_test_extension");
3518 :
3519 3 : var = s->get_variable("service");
3520 1 : CATCH_REQUIRE(var != nullptr);
3521 1 : str = std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_string>(var);
3522 1 : CATCH_REQUIRE(str != nullptr);
3523 1 : CATCH_REQUIRE(str->get_type() == "string");
3524 1 : CATCH_REQUIRE(str->get_string() == "test_processor");
3525 :
3526 3 : var = s->get_variable("sent_server");
3527 1 : CATCH_REQUIRE(var != nullptr);
3528 1 : str = std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_string>(var);
3529 1 : CATCH_REQUIRE(str != nullptr);
3530 1 : CATCH_REQUIRE(str->get_type() == "string");
3531 1 : CATCH_REQUIRE(str->get_string() == "reporter_test");
3532 :
3533 3 : var = s->get_variable("sent_service");
3534 1 : CATCH_REQUIRE(var != nullptr);
3535 1 : str = std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_string>(var);
3536 1 : CATCH_REQUIRE(str != nullptr);
3537 1 : CATCH_REQUIRE(str->get_type() == "string");
3538 1 : CATCH_REQUIRE(str->get_string() == "commands_message");
3539 1 : }
3540 9 : CATCH_END_SECTION()
3541 :
3542 9 : CATCH_START_SECTION("reporter_executor_message: verify last wait (disconnect -> HUP)")
3543 : {
3544 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("program_verify_last_wait.rprtr", g_program_last_wait));
3545 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
3546 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
3547 1 : p->parse_program();
3548 :
3549 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
3550 1 : e->start();
3551 1 : addr::addr a;
3552 1 : sockaddr_in ip = {
3553 : .sin_family = AF_INET,
3554 1 : .sin_port = htons(20002),
3555 : .sin_addr = {
3556 1 : .s_addr = htonl(0x7f000001),
3557 : },
3558 : .sin_zero = {},
3559 1 : };
3560 1 : a.set_ipv4(ip);
3561 1 : messenger_responder::pointer_t messenger(std::make_shared<messenger_responder>(
3562 : a
3563 1 : , ed::mode_t::MODE_PLAIN
3564 2 : , messenger_responder::sequence_t::SEQUENCE_ONE_MESSAGE));
3565 1 : ed::communicator::instance()->add_connection(messenger);
3566 1 : messenger_timer::pointer_t timer(std::make_shared<messenger_timer>(messenger));
3567 1 : ed::communicator::instance()->add_connection(timer);
3568 1 : messenger->set_timer(timer);
3569 1 : e->set_thread_done_callback([messenger, timer]()
3570 : {
3571 1 : ed::communicator::instance()->remove_connection(messenger);
3572 1 : ed::communicator::instance()->remove_connection(timer);
3573 1 : });
3574 1 : CATCH_REQUIRE(e->run());
3575 1 : e->stop();
3576 :
3577 : // if we exited because of our timer, then the test did not pass
3578 : //
3579 1 : CATCH_REQUIRE_FALSE(timer->timed_out_prima());
3580 :
3581 1 : CATCH_REQUIRE(s->get_exit_code() == 0);
3582 1 : }
3583 9 : CATCH_END_SECTION()
3584 :
3585 9 : CATCH_START_SECTION("reporter_executor_message: wait for timeout (to make sure we DO NOT receive extra messages)")
3586 : {
3587 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("program_wait_for_timeout.rprtr", g_program_wait_for_timeout));
3588 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
3589 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
3590 1 : p->parse_program();
3591 :
3592 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
3593 1 : e->start();
3594 1 : addr::addr a;
3595 1 : sockaddr_in ip = {
3596 : .sin_family = AF_INET,
3597 1 : .sin_port = htons(20002),
3598 : .sin_addr = {
3599 1 : .s_addr = htonl(0x7f000001),
3600 : },
3601 : .sin_zero = {},
3602 1 : };
3603 1 : a.set_ipv4(ip);
3604 1 : messenger_responder::pointer_t messenger(std::make_shared<messenger_responder>(
3605 : a
3606 1 : , ed::mode_t::MODE_PLAIN
3607 2 : , messenger_responder::sequence_t::SEQUENCE_ONE_MESSAGE));
3608 1 : ed::communicator::instance()->add_connection(messenger);
3609 1 : messenger_timer::pointer_t timer(std::make_shared<messenger_timer>(messenger));
3610 1 : ed::communicator::instance()->add_connection(timer);
3611 1 : messenger->set_timer(timer);
3612 1 : e->set_thread_done_callback([messenger, timer]()
3613 : {
3614 1 : ed::communicator::instance()->remove_connection(messenger);
3615 1 : ed::communicator::instance()->remove_connection(timer);
3616 1 : });
3617 1 : CATCH_REQUIRE(e->run());
3618 1 : e->stop();
3619 :
3620 1 : CATCH_REQUIRE_FALSE(timer->timed_out_prima());
3621 1 : CATCH_REQUIRE(s->get_exit_code() == 0);
3622 1 : }
3623 9 : CATCH_END_SECTION()
3624 9 : }
3625 :
3626 :
3627 10 : CATCH_TEST_CASE("reporter_executor_variables", "[executor][reporter][variable]")
3628 : {
3629 10 : CATCH_START_SECTION("reporter_executor_variables: undefined variable")
3630 : {
3631 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("program_undefined_variable.rprtr", g_program_undefined_variable));
3632 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
3633 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
3634 1 : p->parse_program();
3635 :
3636 1 : CATCH_REQUIRE(s->get_statement_size() == 5);
3637 :
3638 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
3639 1 : e->start();
3640 1 : CATCH_REQUIRE(e->run());
3641 :
3642 1 : CATCH_REQUIRE(s->get_exit_code() == 0);
3643 1 : }
3644 10 : CATCH_END_SECTION()
3645 :
3646 10 : CATCH_START_SECTION("reporter_executor_variables: detect integer variable")
3647 : {
3648 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("program_integer_variable.rprtr", g_program_integer_variable));
3649 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
3650 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
3651 1 : p->parse_program();
3652 :
3653 1 : CATCH_REQUIRE(s->get_statement_size() == 10);
3654 :
3655 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
3656 1 : e->start();
3657 1 : CATCH_REQUIRE(e->run());
3658 :
3659 1 : CATCH_REQUIRE(s->get_exit_code() == 0);
3660 1 : }
3661 10 : CATCH_END_SECTION()
3662 :
3663 10 : CATCH_START_SECTION("reporter_executor_variables: detect string variable")
3664 : {
3665 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("program_string_variable.rprtr", g_program_string_variable));
3666 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
3667 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
3668 1 : p->parse_program();
3669 :
3670 1 : CATCH_REQUIRE(s->get_statement_size() == 10);
3671 :
3672 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
3673 1 : e->start();
3674 1 : CATCH_REQUIRE(e->run());
3675 :
3676 1 : CATCH_REQUIRE(s->get_exit_code() == 0);
3677 1 : }
3678 10 : CATCH_END_SECTION()
3679 :
3680 10 : CATCH_START_SECTION("reporter_executor_variables: if variable")
3681 : {
3682 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("program_if_variable.rprtr", g_program_if_variable));
3683 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
3684 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
3685 1 : p->parse_program();
3686 :
3687 1 : CATCH_REQUIRE(s->get_statement_size() == 104);
3688 :
3689 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
3690 1 : e->start();
3691 1 : CATCH_REQUIRE(e->run());
3692 :
3693 1 : CATCH_REQUIRE(s->get_exit_code() == 0);
3694 1 : }
3695 10 : CATCH_END_SECTION()
3696 :
3697 10 : CATCH_START_SECTION("reporter_executor_variables: compare and if")
3698 : {
3699 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("program_compare_and_if.rprtr", g_program_compare_and_if));
3700 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
3701 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
3702 1 : p->parse_program();
3703 :
3704 1 : CATCH_REQUIRE(s->get_statement_size() == 116);
3705 :
3706 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
3707 1 : e->start();
3708 1 : CATCH_REQUIRE(e->run());
3709 :
3710 1 : CATCH_REQUIRE(s->get_exit_code() == 0);
3711 1 : }
3712 10 : CATCH_END_SECTION()
3713 :
3714 10 : CATCH_START_SECTION("reporter_executor_variables: void variable cloning")
3715 : {
3716 : // Note: at the moment there is no call to the clone() function
3717 : // inside the library, so make sure it works as expected
3718 : // within the test
3719 : //
3720 1 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t var(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::variable_void>("void_var"));
3721 1 : CATCH_REQUIRE(var != nullptr);
3722 :
3723 1 : SNAP_CATCH2_NAMESPACE::reporter::variable_void::pointer_t v(std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_void>(var));
3724 1 : CATCH_REQUIRE(v != nullptr);
3725 :
3726 3 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t clone(v->clone("clone"));
3727 1 : CATCH_REQUIRE(clone != nullptr);
3728 :
3729 1 : SNAP_CATCH2_NAMESPACE::reporter::variable_void::pointer_t c(std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_void>(clone));
3730 1 : CATCH_REQUIRE(c != nullptr);
3731 :
3732 3 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t clone2(var->clone("clone2"));
3733 1 : CATCH_REQUIRE(clone2 != nullptr);
3734 :
3735 1 : SNAP_CATCH2_NAMESPACE::reporter::variable_void::pointer_t c2(std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_void>(clone2));
3736 1 : CATCH_REQUIRE(c2 != nullptr);
3737 1 : }
3738 10 : CATCH_END_SECTION()
3739 :
3740 10 : CATCH_START_SECTION("reporter_executor_variables: list variable")
3741 : {
3742 : // Note: some of the list variable functions are not fully tested
3743 : // from within the app. so test more here
3744 : //
3745 1 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t list(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::variable_list>("list_var"));
3746 1 : CATCH_REQUIRE(list != nullptr);
3747 :
3748 1 : SNAP_CATCH2_NAMESPACE::reporter::variable_list::pointer_t l(std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_list>(list));
3749 1 : CATCH_REQUIRE(l != nullptr);
3750 :
3751 1 : CATCH_REQUIRE(l->get_item_size() == 0);
3752 :
3753 1 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t var1(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::variable_void>("void_var"));
3754 1 : CATCH_REQUIRE(var1 != nullptr);
3755 1 : l->add_item(var1);
3756 1 : CATCH_REQUIRE(l->get_item(0) == var1);
3757 1 : CATCH_REQUIRE(l->get_item(-1) == nullptr);
3758 1 : CATCH_REQUIRE(l->get_item(1) == nullptr);
3759 :
3760 1 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t var2(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>("integer_var"));
3761 1 : CATCH_REQUIRE(var2 != nullptr);
3762 1 : l->add_item(var2);
3763 1 : CATCH_REQUIRE(l->get_item(0) == var2); // this is a map so the order is sorted by variable name
3764 1 : CATCH_REQUIRE(l->get_item(-1) == nullptr);
3765 1 : CATCH_REQUIRE(l->get_item(1) == var1);
3766 1 : CATCH_REQUIRE(l->get_item(2) == nullptr);
3767 3 : CATCH_REQUIRE(l->get_item("void_var") == var1);
3768 3 : CATCH_REQUIRE(l->get_item("integer_var") == var2);
3769 3 : CATCH_REQUIRE(l->get_item("undefined_var") == nullptr);
3770 :
3771 5 : CATCH_REQUIRE_THROWS_MATCHES(
3772 : l->add_item(var1)
3773 : , ed::runtime_error
3774 : , Catch::Matchers::ExceptionMessage("event_dispatcher_exception: variable_list::add_item() trying to re-add item named \"void_var\"."));
3775 :
3776 5 : CATCH_REQUIRE_THROWS_MATCHES(
3777 : l->add_item(var2)
3778 : , ed::runtime_error
3779 : , Catch::Matchers::ExceptionMessage("event_dispatcher_exception: variable_list::add_item() trying to re-add item named \"integer_var\"."));
3780 :
3781 3 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t clone(list->clone("clone"));
3782 1 : CATCH_REQUIRE(clone != nullptr);
3783 1 : SNAP_CATCH2_NAMESPACE::reporter::variable_list::pointer_t l2(std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_list>(clone));
3784 1 : CATCH_REQUIRE(l2 != nullptr);
3785 :
3786 1 : CATCH_REQUIRE(l2->get_item(-1) == nullptr);
3787 1 : CATCH_REQUIRE(l2->get_item(2) == nullptr);
3788 :
3789 : // the items are also cloned so we can quickly test that they are not
3790 : // equal and then we can verify the type or the name
3791 : //
3792 1 : CATCH_REQUIRE(l2->get_item(0) != var1);
3793 1 : CATCH_REQUIRE(l2->get_item(1) != var1);
3794 1 : CATCH_REQUIRE(l2->get_item(0) != var2);
3795 1 : CATCH_REQUIRE(l2->get_item(1) != var2);
3796 :
3797 1 : CATCH_REQUIRE(l2->get_item(0)->get_type() == "integer");
3798 1 : CATCH_REQUIRE(l2->get_item(1)->get_type() == "void");
3799 :
3800 : // make sure original is still valid
3801 : //
3802 1 : CATCH_REQUIRE(l->get_item(0) == var2);
3803 1 : CATCH_REQUIRE(l->get_item(-1) == nullptr);
3804 1 : CATCH_REQUIRE(l->get_item(1) == var1);
3805 1 : CATCH_REQUIRE(l->get_item(2) == nullptr);
3806 1 : }
3807 10 : CATCH_END_SECTION()
3808 :
3809 10 : CATCH_START_SECTION("reporter_executor_variables: primary variable references")
3810 : {
3811 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("primary_variable_references.rprtr", g_program_primary_variable_references));
3812 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
3813 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
3814 1 : p->parse_program();
3815 :
3816 1 : CATCH_REQUIRE(s->get_statement_size() == 14);
3817 :
3818 3 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t var(s->get_variable("my_string_var"));
3819 1 : CATCH_REQUIRE(var == nullptr);
3820 3 : var = s->get_variable("longer_string_var");
3821 1 : CATCH_REQUIRE(var == nullptr);
3822 3 : var = s->get_variable("my_integer_var");
3823 1 : CATCH_REQUIRE(var == nullptr);
3824 3 : var = s->get_variable("longer_integer_var");
3825 1 : CATCH_REQUIRE(var == nullptr);
3826 3 : var = s->get_variable("my_floating_point_var");
3827 1 : CATCH_REQUIRE(var == nullptr);
3828 3 : var = s->get_variable("longer_floating_point_var");
3829 1 : CATCH_REQUIRE(var == nullptr);
3830 3 : var = s->get_variable("my_identifier_var");
3831 1 : CATCH_REQUIRE(var == nullptr);
3832 3 : var = s->get_variable("longer_identifier_var");
3833 1 : CATCH_REQUIRE(var == nullptr);
3834 3 : var = s->get_variable("my_regex_var");
3835 1 : CATCH_REQUIRE(var == nullptr);
3836 3 : var = s->get_variable("longer_regex_var");
3837 1 : CATCH_REQUIRE(var == nullptr);
3838 3 : var = s->get_variable("my_address_var");
3839 1 : CATCH_REQUIRE(var == nullptr);
3840 3 : var = s->get_variable("longer_address_var");
3841 1 : CATCH_REQUIRE(var == nullptr);
3842 3 : var = s->get_variable("my_timestamp_var");
3843 1 : CATCH_REQUIRE(var == nullptr);
3844 3 : var = s->get_variable("longer_timestamp_var");
3845 1 : CATCH_REQUIRE(var == nullptr);
3846 :
3847 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
3848 1 : e->start();
3849 1 : CATCH_REQUIRE(e->run());
3850 :
3851 3 : var = s->get_variable("my_string_var");
3852 1 : CATCH_REQUIRE(var != nullptr);
3853 1 : SNAP_CATCH2_NAMESPACE::reporter::variable_string::pointer_t vs(std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_string>(var));
3854 1 : CATCH_REQUIRE(vs != nullptr);
3855 1 : CATCH_REQUIRE(vs->get_type() == "string");
3856 1 : CATCH_REQUIRE(vs->get_string() == "foo");
3857 :
3858 3 : var = s->get_variable("longer_string_var");
3859 1 : CATCH_REQUIRE(var != nullptr);
3860 1 : vs = std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_string>(var);
3861 1 : CATCH_REQUIRE(vs != nullptr);
3862 1 : CATCH_REQUIRE(vs->get_type() == "string");
3863 1 : CATCH_REQUIRE(vs->get_string() == "foo");
3864 :
3865 3 : var = s->get_variable("my_integer_var");
3866 1 : CATCH_REQUIRE(var != nullptr);
3867 1 : SNAP_CATCH2_NAMESPACE::reporter::variable_integer::pointer_t vi(std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(var));
3868 1 : CATCH_REQUIRE(vi != nullptr);
3869 1 : CATCH_REQUIRE(vi->get_type() == "integer");
3870 1 : CATCH_REQUIRE(vi->get_integer() == 41);
3871 :
3872 3 : var = s->get_variable("longer_integer_var");
3873 1 : CATCH_REQUIRE(var != nullptr);
3874 1 : vi = std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(var);
3875 1 : CATCH_REQUIRE(vi != nullptr);
3876 1 : CATCH_REQUIRE(vi->get_type() == "integer");
3877 1 : CATCH_REQUIRE(vi->get_integer() == 41);
3878 :
3879 3 : var = s->get_variable("my_floating_point_var");
3880 1 : CATCH_REQUIRE(var != nullptr);
3881 1 : SNAP_CATCH2_NAMESPACE::reporter::variable_floating_point::pointer_t vf(std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_floating_point>(var));
3882 1 : CATCH_REQUIRE(vf != nullptr);
3883 1 : CATCH_REQUIRE(vf->get_type() == "floating_point");
3884 1 : CATCH_REQUIRE(vf->get_floating_point() == 303.601);
3885 :
3886 3 : var = s->get_variable("longer_floating_point_var");
3887 1 : CATCH_REQUIRE(var != nullptr);
3888 1 : vf = std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_floating_point>(var);
3889 1 : CATCH_REQUIRE(vf != nullptr);
3890 1 : CATCH_REQUIRE(vf->get_type() == "floating_point");
3891 1 : CATCH_REQUIRE(vf->get_floating_point() == 303.601);
3892 :
3893 3 : var = s->get_variable("my_identifier_var");
3894 1 : CATCH_REQUIRE(var != nullptr);
3895 1 : vs = std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_string>(var);
3896 1 : CATCH_REQUIRE(vs != nullptr);
3897 1 : CATCH_REQUIRE(vs->get_type() == "identifier");
3898 1 : CATCH_REQUIRE(vs->get_string() == "bar");
3899 :
3900 3 : var = s->get_variable("longer_identifier_var");
3901 1 : CATCH_REQUIRE(var != nullptr);
3902 1 : vs = std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_string>(var);
3903 1 : CATCH_REQUIRE(vs != nullptr);
3904 1 : CATCH_REQUIRE(vs->get_type() == "identifier");
3905 1 : CATCH_REQUIRE(vs->get_string() == "bar");
3906 :
3907 3 : var = s->get_variable("my_regex_var");
3908 1 : CATCH_REQUIRE(var != nullptr);
3909 1 : SNAP_CATCH2_NAMESPACE::reporter::variable_regex::pointer_t vre(std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_regex>(var));
3910 1 : CATCH_REQUIRE(vre != nullptr);
3911 1 : CATCH_REQUIRE(vre->get_type() == "regex");
3912 1 : CATCH_REQUIRE(vre->get_regex() == "^[regex]$");
3913 :
3914 3 : var = s->get_variable("longer_regex_var");
3915 1 : CATCH_REQUIRE(var != nullptr);
3916 1 : vre = std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_regex>(var);
3917 1 : CATCH_REQUIRE(vre != nullptr);
3918 1 : CATCH_REQUIRE(vre->get_type() == "regex");
3919 1 : CATCH_REQUIRE(vre->get_regex() == "^[regex]$");
3920 :
3921 1 : addr::addr a;
3922 1 : sockaddr_in ip = {
3923 : .sin_family = AF_INET,
3924 1 : .sin_port = htons(89),
3925 : .sin_addr = {
3926 1 : .s_addr = htonl(0x0A0C0E10),
3927 : },
3928 : .sin_zero = {},
3929 1 : };
3930 1 : a.set_ipv4(ip);
3931 :
3932 3 : var = s->get_variable("my_address_var");
3933 1 : CATCH_REQUIRE(var != nullptr);
3934 1 : SNAP_CATCH2_NAMESPACE::reporter::variable_address::pointer_t va(std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_address>(var));
3935 1 : CATCH_REQUIRE(va != nullptr);
3936 1 : CATCH_REQUIRE(va->get_type() == "address");
3937 1 : CATCH_REQUIRE(va->get_address() == a);
3938 :
3939 3 : var = s->get_variable("longer_address_var");
3940 1 : CATCH_REQUIRE(var != nullptr);
3941 1 : va = std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_address>(var);
3942 1 : CATCH_REQUIRE(va != nullptr);
3943 1 : CATCH_REQUIRE(va->get_type() == "address");
3944 1 : CATCH_REQUIRE(va->get_address() == a);
3945 :
3946 1 : snapdev::timespec_ex const expected_timestamp{ 1714241733, 419438123 };
3947 :
3948 3 : var = s->get_variable("my_timestamp_var");
3949 1 : CATCH_REQUIRE(var != nullptr);
3950 1 : SNAP_CATCH2_NAMESPACE::reporter::variable_timestamp::pointer_t vts(std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_timestamp>(var));
3951 1 : CATCH_REQUIRE(vts != nullptr);
3952 1 : CATCH_REQUIRE(vts->get_type() == "timestamp");
3953 1 : CATCH_REQUIRE(vts->get_timestamp() == expected_timestamp);
3954 :
3955 3 : var = s->get_variable("longer_timestamp_var");
3956 1 : CATCH_REQUIRE(var != nullptr);
3957 1 : vts = std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_timestamp>(var);
3958 1 : CATCH_REQUIRE(vts != nullptr);
3959 1 : CATCH_REQUIRE(vts->get_type() == "timestamp");
3960 1 : CATCH_REQUIRE(vts->get_timestamp() == expected_timestamp);
3961 :
3962 1 : CATCH_REQUIRE(s->get_exit_code() == -1);
3963 1 : }
3964 10 : CATCH_END_SECTION()
3965 :
3966 10 : CATCH_START_SECTION("reporter_executor_variables: primary variable reference with wrong name")
3967 : {
3968 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("primary_variable_reference.rprtr", g_program_wrong_primary_variable_reference));
3969 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
3970 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
3971 1 : p->parse_program();
3972 :
3973 1 : CATCH_REQUIRE(s->get_statement_size() == 2);
3974 :
3975 3 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t var(s->get_variable("my_var"));
3976 1 : CATCH_REQUIRE(var == nullptr);
3977 3 : var = s->get_variable("longer_var");
3978 1 : CATCH_REQUIRE(var == nullptr);
3979 :
3980 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
3981 1 : e->start();
3982 1 : CATCH_REQUIRE(e->run());
3983 :
3984 3 : var = s->get_variable("my_var");
3985 1 : CATCH_REQUIRE(var != nullptr);
3986 1 : SNAP_CATCH2_NAMESPACE::reporter::variable_string::pointer_t v(std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_string>(var));
3987 1 : CATCH_REQUIRE(v != nullptr);
3988 1 : CATCH_REQUIRE(v->get_string() == "foo");
3989 :
3990 3 : var = s->get_variable("longer_var");
3991 1 : CATCH_REQUIRE(var != nullptr);
3992 1 : v = std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_string>(var);
3993 1 : CATCH_REQUIRE(v != nullptr);
3994 1 : CATCH_REQUIRE(v->get_string() == ""); // wrong name so we get an empty string
3995 :
3996 1 : CATCH_REQUIRE(s->get_exit_code() == -1);
3997 1 : }
3998 10 : CATCH_END_SECTION()
3999 :
4000 10 : CATCH_START_SECTION("reporter_executor_variables: array variable cloning")
4001 : {
4002 : // Note: at the moment there is no call to the clone() function
4003 : // inside the library, so make sure it works as expected
4004 : // within the test
4005 : //
4006 1 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t var(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::variable_array>("array_var"));
4007 1 : CATCH_REQUIRE(var != nullptr);
4008 :
4009 1 : SNAP_CATCH2_NAMESPACE::reporter::variable_array::pointer_t v(std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_array>(var));
4010 1 : CATCH_REQUIRE(v != nullptr);
4011 :
4012 1 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t i1(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>("int_a"));
4013 1 : std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(i1)->set_integer(123);
4014 1 : v->add_item(i1);
4015 :
4016 1 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t i2(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>("int_b"));
4017 1 : std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(i2)->set_integer(456);
4018 1 : v->add_item(i2);
4019 :
4020 1 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t i3(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>("int_c"));
4021 1 : std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(i3)->set_integer(789);
4022 1 : v->add_item(i3);
4023 :
4024 1 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t t1(v->get_item(0));
4025 1 : CATCH_REQUIRE(t1 != nullptr);
4026 1 : SNAP_CATCH2_NAMESPACE::reporter::variable_integer::pointer_t p1(std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(t1));
4027 1 : CATCH_REQUIRE(p1->get_integer() == 123);
4028 :
4029 1 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t t2(v->get_item(1));
4030 1 : CATCH_REQUIRE(t2 != nullptr);
4031 1 : SNAP_CATCH2_NAMESPACE::reporter::variable_integer::pointer_t p2(std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(t2));
4032 1 : CATCH_REQUIRE(p2->get_integer() == 456);
4033 :
4034 1 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t t3(v->get_item(2));
4035 1 : CATCH_REQUIRE(t3 != nullptr);
4036 1 : SNAP_CATCH2_NAMESPACE::reporter::variable_integer::pointer_t p3(std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(t3));
4037 1 : CATCH_REQUIRE(p3->get_integer() == 789);
4038 :
4039 1 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t t4(v->get_item(3));
4040 1 : CATCH_REQUIRE(t4 == nullptr);
4041 :
4042 3 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t clone(v->clone("clone"));
4043 1 : CATCH_REQUIRE(clone != nullptr);
4044 :
4045 1 : SNAP_CATCH2_NAMESPACE::reporter::variable_array::pointer_t c(std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_array>(clone));
4046 1 : CATCH_REQUIRE(c != nullptr);
4047 :
4048 3 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t clone2(var->clone("clone2"));
4049 1 : CATCH_REQUIRE(clone2 != nullptr);
4050 :
4051 1 : SNAP_CATCH2_NAMESPACE::reporter::variable_array::pointer_t c2(std::dynamic_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_array>(clone2));
4052 1 : CATCH_REQUIRE(c2 != nullptr);
4053 1 : }
4054 10 : CATCH_END_SECTION()
4055 10 : }
4056 :
4057 :
4058 1 : CATCH_TEST_CASE("reporter_executor_state", "[executor][reporter][error]")
4059 : {
4060 1 : CATCH_START_SECTION("reporter_executor_state: add and read data from the state")
4061 : {
4062 11 : for(int count(0); count < 10; ++count)
4063 : {
4064 10 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4065 :
4066 10 : CATCH_REQUIRE(s->get_server_pid() == getpid());
4067 10 : CATCH_REQUIRE(s->data_size() == 0);
4068 :
4069 10 : SNAP_CATCH2_NAMESPACE::reporter::connection_data_t buf;
4070 10 : CATCH_REQUIRE(s->read_data(buf, 1024) == -1);
4071 :
4072 : // clear has no effect here
4073 : //
4074 10 : s->clear_data();
4075 :
4076 10 : CATCH_REQUIRE(s->get_server_pid() == getpid());
4077 10 : CATCH_REQUIRE(s->data_size() == 0);
4078 :
4079 10 : CATCH_REQUIRE(s->read_data(buf, 1024) == -1);
4080 :
4081 10 : std::size_t total(0);
4082 30 : std::vector<std::size_t> sizes(10);
4083 110 : for(int i(0); i < 10; ++i)
4084 : {
4085 100 : sizes[i] = rand() % (1024 * 4) + 1;
4086 100 : total += sizes[i];
4087 : }
4088 :
4089 30 : SNAP_CATCH2_NAMESPACE::reporter::connection_data_t data(total);
4090 231115 : for(std::size_t i(0); i < total; ++i)
4091 : {
4092 231105 : data[i] = rand();
4093 : }
4094 :
4095 10 : std::size_t offset(0);
4096 110 : for(int i(0); i < 10; ++i)
4097 : {
4098 100 : SNAP_CATCH2_NAMESPACE::reporter::connection_data_pointer_t d(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::connection_data_t>(data.data() + offset, data.data() + offset + sizes[i]));
4099 100 : s->add_data(d);
4100 100 : offset += sizes[i];
4101 100 : CATCH_REQUIRE(s->data_size() == static_cast<ssize_t>(offset));
4102 100 : }
4103 10 : CATCH_REQUIRE(s->data_size() == static_cast<ssize_t>(total));
4104 :
4105 10 : offset = 0;
4106 3626 : while(offset < total)
4107 : {
4108 3616 : std::size_t const expected_size(std::min(64UL, total - offset));
4109 3616 : CATCH_REQUIRE(s->read_data(buf, 64) == static_cast<int>(expected_size));
4110 3616 : CATCH_REQUIRE(buf.size() == expected_size);
4111 234721 : for(std::size_t i(0); i < expected_size; ++i)
4112 : {
4113 231105 : CATCH_REQUIRE(buf[i] == data[offset + i]);
4114 : }
4115 3616 : offset += expected_size;
4116 : }
4117 :
4118 : // here the clear has an effect
4119 : //
4120 10 : s->clear_data();
4121 10 : CATCH_REQUIRE(s->data_size() == 0);
4122 10 : CATCH_REQUIRE(s->read_data(buf, 1024) == -1);
4123 10 : }
4124 : }
4125 1 : CATCH_END_SECTION()
4126 1 : }
4127 :
4128 2 : CATCH_TEST_CASE("reporter_tcp_connection", "[executor][reporter][error]")
4129 : {
4130 2 : CATCH_START_SECTION("reporter_tcp_connection: test raw TCP connection")
4131 : {
4132 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("raw_tcp_connection.rprtr", g_program_raw_tcp_connection));
4133 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4134 :
4135 : // the tracer is really practical to debug, but the possible double wait()
4136 : // can make it break; so I keep it commented by default
4137 : //trace tracer(g_verify_raw_tcp_connection);
4138 : //s->set_trace_callback(std::bind(&trace::callback, &tracer, std::placeholders::_1, std::placeholders::_2));
4139 :
4140 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
4141 1 : p->parse_program();
4142 :
4143 1 : CATCH_REQUIRE(s->get_statement_size() == 19);
4144 :
4145 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
4146 1 : e->start();
4147 1 : addr::addr a;
4148 1 : sockaddr_in ip = {
4149 : .sin_family = AF_INET,
4150 1 : .sin_port = htons(20002),
4151 : .sin_addr = {
4152 1 : .s_addr = htonl(0x7f000001),
4153 : },
4154 : .sin_zero = {},
4155 1 : };
4156 1 : a.set_ipv4(ip);
4157 1 : permanent_binary_responder::pointer_t binary_responder(std::make_shared<permanent_binary_responder>(
4158 : a
4159 1 : , ed::mode_t::MODE_PLAIN
4160 2 : , permanent_binary_responder::sequence_t::SEQUENCE_PING_PONG));
4161 1 : ed::communicator::instance()->add_connection(binary_responder);
4162 :
4163 1 : e->set_thread_done_callback([binary_responder]()
4164 : {
4165 1 : ed::communicator::instance()->remove_connection(binary_responder);
4166 1 : });
4167 :
4168 1 : CATCH_REQUIRE(e->run());
4169 :
4170 1 : CATCH_REQUIRE(s->get_exit_code() == 0);
4171 1 : }
4172 2 : CATCH_END_SECTION()
4173 :
4174 2 : CATCH_START_SECTION("reporter_tcp_connection: test prinbee like message")
4175 : {
4176 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("prinbee_binary_message.rprtr", g_program_prinbee_binary_message));
4177 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4178 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
4179 1 : p->parse_program();
4180 :
4181 1 : CATCH_REQUIRE(s->get_statement_size() == 19);
4182 :
4183 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
4184 1 : e->start();
4185 1 : addr::addr a;
4186 1 : sockaddr_in ip = {
4187 : .sin_family = AF_INET,
4188 1 : .sin_port = htons(20002),
4189 : .sin_addr = {
4190 1 : .s_addr = htonl(0x7f000001),
4191 : },
4192 : .sin_zero = {},
4193 1 : };
4194 1 : a.set_ipv4(ip);
4195 1 : permanent_binary_responder::pointer_t binary_responder(std::make_shared<permanent_binary_responder>(
4196 : a
4197 1 : , ed::mode_t::MODE_PLAIN
4198 2 : , permanent_binary_responder::sequence_t::SEQUENCE_PRINBEE_MESSAGE));
4199 1 : ed::communicator::instance()->add_connection(binary_responder);
4200 :
4201 1 : e->set_thread_done_callback([binary_responder]()
4202 : {
4203 1 : ed::communicator::instance()->remove_connection(binary_responder);
4204 1 : });
4205 :
4206 1 : CATCH_REQUIRE(e->run());
4207 :
4208 1 : CATCH_REQUIRE(s->get_exit_code() == 0);
4209 1 : }
4210 2 : CATCH_END_SECTION()
4211 2 : }
4212 :
4213 :
4214 47 : CATCH_TEST_CASE("reporter_executor_error", "[executor][reporter][error]")
4215 : {
4216 47 : CATCH_START_SECTION("reporter_executor_error: if() before any condition")
4217 : {
4218 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("if_too_soon.rprtr", g_program_no_condition));
4219 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4220 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
4221 1 : p->parse_program();
4222 :
4223 1 : CATCH_REQUIRE(s->get_statement_size() == 2);
4224 :
4225 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
4226 3 : CATCH_REQUIRE_THROWS_MATCHES(
4227 : e->start()
4228 : , ed::runtime_error
4229 : , Catch::Matchers::ExceptionMessage(
4230 : "event_dispatcher_exception: trying to use a 'compare' result when none are currently defined."));
4231 :
4232 3 : CATCH_REQUIRE_THROWS_MATCHES(
4233 : s->set_compare(SNAP_CATCH2_NAMESPACE::reporter::compare_t::COMPARE_UNDEFINED)
4234 : , ed::runtime_error
4235 : , Catch::Matchers::ExceptionMessage(
4236 : "event_dispatcher_exception: 'compare' cannot be set to \"undefined\"."));
4237 1 : }
4238 47 : CATCH_END_SECTION()
4239 :
4240 47 : CATCH_START_SECTION("reporter_executor_error: compare() with incompatible types")
4241 : {
4242 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("compare_with_incompatible_types.rprtr", g_program_compare_with_incompatible_types));
4243 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4244 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
4245 1 : p->parse_program();
4246 :
4247 1 : CATCH_REQUIRE(s->get_statement_size() == 4);
4248 :
4249 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
4250 3 : CATCH_REQUIRE_THROWS_MATCHES(
4251 : e->start()
4252 : , ed::runtime_error
4253 : , Catch::Matchers::ExceptionMessage(
4254 : "event_dispatcher_exception: compare_with_incompatible_types.rprtr:3: unsupported compare (token types: 3 <=> 39)."));
4255 1 : }
4256 47 : CATCH_END_SECTION()
4257 :
4258 47 : CATCH_START_SECTION("reporter_executor_error: compare() with non-integer result")
4259 : {
4260 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("compare_with_non_integer.rprtr", g_program_compare_with_non_integer));
4261 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4262 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
4263 1 : p->parse_program();
4264 :
4265 1 : CATCH_REQUIRE(s->get_statement_size() == 2);
4266 :
4267 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
4268 3 : CATCH_REQUIRE_THROWS_MATCHES(
4269 : e->start()
4270 : , ed::runtime_error
4271 : , Catch::Matchers::ExceptionMessage(
4272 : "event_dispatcher_exception: compare_with_non_integer.rprtr:1: parameter type mismatch for expression, expected \"integer\", got \"string\" instead."));
4273 1 : }
4274 47 : CATCH_END_SECTION()
4275 :
4276 47 : CATCH_START_SECTION("reporter_executor_error: compare() with bad positive integer result")
4277 : {
4278 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("compare_with_bad_positive_integer.rprtr", g_program_compare_with_bad_positive_integer));
4279 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4280 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
4281 1 : p->parse_program();
4282 :
4283 1 : CATCH_REQUIRE(s->get_statement_size() == 2);
4284 :
4285 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
4286 3 : CATCH_REQUIRE_THROWS_MATCHES(
4287 : e->start()
4288 : , ed::runtime_error
4289 : , Catch::Matchers::ExceptionMessage(
4290 : "event_dispatcher_exception: compare_with_bad_positive_integer.rprtr:1: unsupported integer in compare(), values are limited to -2 to 1."));
4291 1 : }
4292 47 : CATCH_END_SECTION()
4293 :
4294 47 : CATCH_START_SECTION("reporter_executor_error: compare() with bad negative integer result")
4295 : {
4296 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("compare_with_bad_negative_integer.rprtr", g_program_compare_with_bad_negative_integer));
4297 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4298 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
4299 1 : p->parse_program();
4300 :
4301 1 : CATCH_REQUIRE(s->get_statement_size() == 2);
4302 :
4303 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
4304 3 : CATCH_REQUIRE_THROWS_MATCHES(
4305 : e->start()
4306 : , ed::runtime_error
4307 : , Catch::Matchers::ExceptionMessage(
4308 : "event_dispatcher_exception: compare_with_bad_negative_integer.rprtr:1: unsupported integer in compare(), values are limited to -2 to 1."));
4309 1 : }
4310 47 : CATCH_END_SECTION()
4311 :
4312 47 : CATCH_START_SECTION("reporter_executor_error: kill() with invalid parameter type (timestamp)")
4313 : {
4314 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("kill_unsupported_timestamp.rprtr", g_program_verify_kill_unsupported_timestamp));
4315 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4316 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
4317 1 : p->parse_program();
4318 :
4319 1 : CATCH_REQUIRE(s->get_statement_size() == 2);
4320 :
4321 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
4322 3 : CATCH_REQUIRE_THROWS_MATCHES(
4323 : e->start()
4324 : , ed::runtime_error
4325 : , Catch::Matchers::ExceptionMessage(
4326 : "event_dispatcher_exception: kill_unsupported_timestamp.rprtr:1: kill(signal: ...) unsupported parameter type."));
4327 1 : }
4328 47 : CATCH_END_SECTION()
4329 :
4330 47 : CATCH_START_SECTION("reporter_executor_error: kill() with too large an integer")
4331 : {
4332 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("kill_integer_too_large.rprtr", g_program_verify_kill_integer_too_large));
4333 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4334 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
4335 1 : p->parse_program();
4336 :
4337 1 : CATCH_REQUIRE(s->get_statement_size() == 2);
4338 :
4339 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
4340 3 : CATCH_REQUIRE_THROWS_MATCHES(
4341 : e->start()
4342 : , ed::runtime_error
4343 : , Catch::Matchers::ExceptionMessage(
4344 : "event_dispatcher_exception: kill_integer_too_large.rprtr:1: kill(signal: ...) unknown signal."));
4345 1 : }
4346 47 : CATCH_END_SECTION()
4347 :
4348 47 : CATCH_START_SECTION("reporter_executor_error: kill() with an unknown signal name")
4349 : {
4350 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("kill_unknown_signal_name.rprtr", g_program_verify_kill_unknown_signal_name));
4351 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4352 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
4353 1 : p->parse_program();
4354 :
4355 1 : CATCH_REQUIRE(s->get_statement_size() == 2);
4356 :
4357 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
4358 3 : CATCH_REQUIRE_THROWS_MATCHES(
4359 : e->start()
4360 : , ed::runtime_error
4361 : , Catch::Matchers::ExceptionMessage(
4362 : "event_dispatcher_exception: kill_unknown_signal_name.rprtr:1: kill(signal: ...) unknown signal."));
4363 1 : }
4364 47 : CATCH_END_SECTION()
4365 :
4366 47 : CATCH_START_SECTION("reporter_executor_error: exit() + error message")
4367 : {
4368 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("exit_error_message.rprtr", g_program_error_message));
4369 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4370 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
4371 1 : p->parse_program();
4372 :
4373 1 : CATCH_REQUIRE(s->get_statement_size() == 1);
4374 :
4375 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
4376 1 : e->start();
4377 :
4378 1 : CATCH_REQUIRE(s->get_exit_code() == 1);
4379 1 : }
4380 47 : CATCH_END_SECTION()
4381 :
4382 47 : CATCH_START_SECTION("reporter_executor_error: listen() + listen()")
4383 : {
4384 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("two_listen.rprtr", g_program_two_listen));
4385 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4386 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
4387 1 : p->parse_program();
4388 :
4389 1 : CATCH_REQUIRE(s->get_statement_size() == 2);
4390 :
4391 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
4392 3 : CATCH_REQUIRE_THROWS_MATCHES(
4393 : e->start()
4394 : , ed::runtime_error
4395 : , Catch::Matchers::ExceptionMessage(
4396 : "event_dispatcher_exception: the listen() instruction cannot be reused without an intermediate disconnect() instruction."));
4397 1 : }
4398 47 : CATCH_END_SECTION()
4399 :
4400 47 : CATCH_START_SECTION("reporter_executor_error: label(name: ...) does not accept integers")
4401 : {
4402 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("label_bad_type.rprtr", g_program_label_bad_type));
4403 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4404 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
4405 :
4406 : // label is a special case which we test in the state.cpp way before
4407 : // we reach the executor... (so this is not really an executor test)
4408 : //
4409 3 : CATCH_REQUIRE_THROWS_MATCHES(
4410 : p->parse_program()
4411 : , ed::runtime_error
4412 : , Catch::Matchers::ExceptionMessage(
4413 : "event_dispatcher_exception: the value of the \"name\" parameter of the \"label\" statement must be an identifier."));
4414 1 : }
4415 47 : CATCH_END_SECTION()
4416 :
4417 47 : CATCH_START_SECTION("reporter_executor_error: exit(error_message: ...) does not accept floating points")
4418 : {
4419 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("exit_bad_type.rprtr", g_program_exit_bad_type));
4420 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4421 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
4422 1 : p->parse_program();
4423 :
4424 1 : CATCH_REQUIRE(s->get_statement_size() == 1);
4425 :
4426 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
4427 3 : CATCH_REQUIRE_THROWS_MATCHES(
4428 : e->start()
4429 : , ed::runtime_error
4430 : , Catch::Matchers::ExceptionMessage(
4431 : "event_dispatcher_exception: exit_bad_type.rprtr:1: parameter type mismatch for error_message, expected \"string\", got \"floating_point\" instead."));
4432 1 : }
4433 47 : CATCH_END_SECTION()
4434 :
4435 47 : CATCH_START_SECTION("reporter_executor_error: verify starting the thread twice")
4436 : {
4437 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("program_start_thread_twice.rprtr", g_program_start_thread_twice));
4438 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4439 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
4440 1 : p->parse_program();
4441 :
4442 1 : CATCH_REQUIRE(s->get_statement_size() == 4);
4443 :
4444 : // before we run the script, there are no such variables
4445 : //
4446 3 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t var(s->get_variable("test"));
4447 1 : CATCH_REQUIRE(var == nullptr);
4448 3 : var = s->get_variable("runner");
4449 1 : CATCH_REQUIRE(var == nullptr);
4450 :
4451 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
4452 1 : e->start();
4453 1 : CATCH_REQUIRE(e->run());
4454 3 : CATCH_REQUIRE_THROWS_MATCHES(
4455 : e->stop()
4456 : , ed::runtime_error
4457 : , Catch::Matchers::ExceptionMessage(
4458 : "event_dispatcher_exception: run() instruction found when already running in the background."));
4459 :
4460 3 : var = s->get_variable("test");
4461 1 : CATCH_REQUIRE(var != nullptr);
4462 1 : CATCH_REQUIRE(var->get_name() == "test");
4463 1 : CATCH_REQUIRE(var->get_type() == "integer");
4464 1 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(var)->get_integer() == 33);
4465 :
4466 3 : var = s->get_variable("runner");
4467 1 : CATCH_REQUIRE(var != nullptr);
4468 1 : CATCH_REQUIRE(var->get_name() == "runner");
4469 1 : CATCH_REQUIRE(var->get_type() == "floating_point");
4470 1 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_floating_point>(var)->get_floating_point() == 6.07);
4471 1 : }
4472 47 : CATCH_END_SECTION()
4473 :
4474 47 : CATCH_START_SECTION("reporter_executor_error: <type> + <type> that are not valid")
4475 : {
4476 : struct bad_additions_t
4477 : {
4478 : char const * f_code = nullptr;
4479 : SNAP_CATCH2_NAMESPACE::reporter::token_t f_left_hand_side = SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ERROR;
4480 : SNAP_CATCH2_NAMESPACE::reporter::token_t f_right_hand_side = SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ERROR;
4481 : };
4482 1 : constexpr bad_additions_t const bad_additions[] =
4483 : {
4484 : {
4485 : g_program_unsupported_addition_address_address,
4486 : SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ADDRESS,
4487 : SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ADDRESS,
4488 : },
4489 : {
4490 : g_program_unsupported_addition_address_string,
4491 : SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ADDRESS,
4492 : SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_SINGLE_STRING,
4493 : },
4494 : {
4495 : g_program_unsupported_addition_string_address,
4496 : SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_SINGLE_STRING,
4497 : SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ADDRESS,
4498 : },
4499 : {
4500 : g_program_unsupported_addition_address_identifier,
4501 : SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ADDRESS,
4502 : SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_IDENTIFIER,
4503 : },
4504 : {
4505 : g_program_unsupported_addition_identifier_address,
4506 : SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_IDENTIFIER,
4507 : SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ADDRESS,
4508 : },
4509 : {
4510 : g_program_unsupported_addition_identifier_string,
4511 : SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_IDENTIFIER,
4512 : SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_SINGLE_STRING,
4513 : },
4514 : {
4515 : g_program_unsupported_addition_string_identifier,
4516 : SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_SINGLE_STRING,
4517 : SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_IDENTIFIER,
4518 : },
4519 : };
4520 :
4521 8 : for(auto const & ba : bad_additions)
4522 : {
4523 7 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("invalid_additions.rprtr", ba.f_code));
4524 7 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4525 7 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
4526 7 : p->parse_program();
4527 :
4528 7 : CATCH_REQUIRE(s->get_statement_size() == 1);
4529 :
4530 7 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
4531 7 : CATCH_REQUIRE_THROWS_MATCHES(
4532 : e->start()
4533 : , ed::runtime_error
4534 : , Catch::Matchers::ExceptionMessage(
4535 : "event_dispatcher_exception: unsupported addition (token types: "
4536 : + std::to_string(static_cast<int>(ba.f_left_hand_side))
4537 : + " + "
4538 : + std::to_string(static_cast<int>(ba.f_right_hand_side))
4539 : + ")."));
4540 7 : }
4541 : }
4542 47 : CATCH_END_SECTION()
4543 :
4544 47 : CATCH_START_SECTION("reporter_executor_error: <type> - <type> that are not valid")
4545 : {
4546 1 : constexpr char const * const bad_subtractions[] =
4547 : {
4548 : g_program_unsupported_subtraction_address_string,
4549 : g_program_unsupported_subtraction_string_address,
4550 : g_program_unsupported_subtraction_address_identifier,
4551 : g_program_unsupported_subtraction_identifier_address,
4552 : g_program_unsupported_subtraction_identifier_string,
4553 : g_program_unsupported_subtraction_string_identifier,
4554 : };
4555 :
4556 7 : for(auto const & program : bad_subtractions)
4557 : {
4558 : //std::cerr << "testing [" << program << "]\n";
4559 6 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("invalid_subtractions.rprtr", program));
4560 6 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4561 6 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
4562 6 : p->parse_program();
4563 :
4564 6 : CATCH_REQUIRE(s->get_statement_size() == 1);
4565 :
4566 6 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
4567 18 : CATCH_REQUIRE_THROWS_MATCHES(
4568 : e->start()
4569 : , ed::runtime_error
4570 : , Catch::Matchers::ExceptionMessage(
4571 : "event_dispatcher_exception: unsupported subtraction."));
4572 6 : }
4573 : }
4574 47 : CATCH_END_SECTION()
4575 :
4576 47 : CATCH_START_SECTION("reporter_executor_error: <type> * <type> that are not valid")
4577 : {
4578 1 : constexpr char const * const bad_multiplications[] =
4579 : {
4580 : g_program_unsupported_multiplication_address_address,
4581 : g_program_unsupported_multiplication_address_string,
4582 : g_program_unsupported_multiplication_string_address,
4583 : g_program_unsupported_multiplication_address_identifier,
4584 : g_program_unsupported_multiplication_identifier_address,
4585 : g_program_unsupported_multiplication_identifier_string,
4586 : g_program_unsupported_multiplication_string_identifier,
4587 : g_program_unsupported_multiplication_string_string,
4588 : g_program_unsupported_multiplication_identifier_identifier,
4589 : };
4590 :
4591 10 : for(auto const & program : bad_multiplications)
4592 : {
4593 : //std::cerr << "testing [" << program << "]\n";
4594 9 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("invalid_multiplications.rprtr", program));
4595 9 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4596 9 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
4597 9 : p->parse_program();
4598 :
4599 9 : CATCH_REQUIRE(s->get_statement_size() == 1);
4600 :
4601 9 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
4602 27 : CATCH_REQUIRE_THROWS_MATCHES(
4603 : e->start()
4604 : , ed::runtime_error
4605 : , Catch::Matchers::ExceptionMessage(
4606 : "event_dispatcher_exception: unsupported multiplication."));
4607 9 : }
4608 : }
4609 47 : CATCH_END_SECTION()
4610 :
4611 47 : CATCH_START_SECTION("reporter_executor_error: <type> / <type> that are not valid")
4612 : {
4613 1 : constexpr char const * const bad_divisions[] =
4614 : {
4615 : g_program_unsupported_division_address_address,
4616 : g_program_unsupported_division_address_string,
4617 : g_program_unsupported_division_string_address,
4618 : g_program_unsupported_division_address_identifier,
4619 : g_program_unsupported_division_identifier_address,
4620 : g_program_unsupported_division_identifier_string,
4621 : g_program_unsupported_division_string_identifier,
4622 : g_program_unsupported_division_string_string,
4623 : g_program_unsupported_division_identifier_identifier,
4624 : };
4625 :
4626 10 : for(auto const & program : bad_divisions)
4627 : {
4628 : //std::cerr << "testing [" << program << "]\n";
4629 9 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("invalid_divisions.rprtr", program));
4630 9 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4631 9 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
4632 9 : p->parse_program();
4633 :
4634 9 : CATCH_REQUIRE(s->get_statement_size() == 1);
4635 :
4636 9 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
4637 27 : CATCH_REQUIRE_THROWS_MATCHES(
4638 : e->start()
4639 : , ed::runtime_error
4640 : , Catch::Matchers::ExceptionMessage(
4641 : "event_dispatcher_exception: unsupported division."));
4642 9 : }
4643 : }
4644 47 : CATCH_END_SECTION()
4645 :
4646 47 : CATCH_START_SECTION("reporter_executor_error: <type> % <type> that are not valid")
4647 : {
4648 : struct bad_modulo_t
4649 : {
4650 : char const * const f_expr = nullptr;
4651 : SNAP_CATCH2_NAMESPACE::reporter::token_t f_lhs_token = SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ERROR;
4652 : SNAP_CATCH2_NAMESPACE::reporter::token_t f_rhs_token = SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ERROR;
4653 : };
4654 1 : constexpr bad_modulo_t const bad_modulos[] =
4655 : {
4656 : {
4657 : g_program_unsupported_modulo_address_address,
4658 : SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ADDRESS,
4659 : SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ADDRESS,
4660 : },
4661 : {
4662 : g_program_unsupported_modulo_address_string,
4663 : SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ADDRESS,
4664 : SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_SINGLE_STRING,
4665 : },
4666 : {
4667 : g_program_unsupported_modulo_string_address,
4668 : SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_SINGLE_STRING,
4669 : SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ADDRESS,
4670 : },
4671 : {
4672 : g_program_unsupported_modulo_address_identifier,
4673 : SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ADDRESS,
4674 : SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_IDENTIFIER,
4675 : },
4676 : {
4677 : g_program_unsupported_modulo_identifier_address,
4678 : SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_IDENTIFIER,
4679 : SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_ADDRESS,
4680 : },
4681 : {
4682 : g_program_unsupported_modulo_identifier_string,
4683 : SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_IDENTIFIER,
4684 : SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_SINGLE_STRING, // the type of string was already converted by this time
4685 : },
4686 : {
4687 : g_program_unsupported_modulo_string_identifier,
4688 : SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_SINGLE_STRING,
4689 : SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_IDENTIFIER,
4690 : },
4691 : {
4692 : g_program_unsupported_modulo_string_string,
4693 : SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_SINGLE_STRING,
4694 : SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_SINGLE_STRING, // the type of string was already converted by this time
4695 : },
4696 : {
4697 : g_program_unsupported_modulo_identifier_identifier,
4698 : SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_IDENTIFIER,
4699 : SNAP_CATCH2_NAMESPACE::reporter::token_t::TOKEN_IDENTIFIER,
4700 : },
4701 : };
4702 :
4703 10 : for(auto const & program : bad_modulos)
4704 : {
4705 : //std::cerr << "testing [" << program.f_expr << "]\n";
4706 9 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("invalid_modulos.rprtr", program.f_expr));
4707 9 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4708 9 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
4709 9 : p->parse_program();
4710 :
4711 9 : CATCH_REQUIRE(s->get_statement_size() == 1);
4712 :
4713 9 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
4714 9 : CATCH_REQUIRE_THROWS_MATCHES(
4715 : e->start()
4716 : , ed::runtime_error
4717 : , Catch::Matchers::ExceptionMessage(
4718 : "event_dispatcher_exception: unsupported modulo (types: "
4719 : + std::to_string(static_cast<int>(program.f_lhs_token))
4720 : + " and "
4721 : + std::to_string(static_cast<int>(program.f_rhs_token))
4722 : + ")."));
4723 9 : }
4724 : }
4725 47 : CATCH_END_SECTION()
4726 :
4727 47 : CATCH_START_SECTION("reporter_executor_error: -<types> that are not valid")
4728 : {
4729 1 : constexpr char const * const bad_negations[] =
4730 : {
4731 : g_program_unsupported_negation_single_string,
4732 : g_program_unsupported_negation_double_string,
4733 : g_program_unsupported_negation_address,
4734 : };
4735 :
4736 4 : for(auto const & program : bad_negations)
4737 : {
4738 3 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("invalid_negate.rprtr", program));
4739 3 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4740 3 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
4741 3 : p->parse_program();
4742 :
4743 3 : CATCH_REQUIRE(s->get_statement_size() == 1);
4744 :
4745 3 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
4746 9 : CATCH_REQUIRE_THROWS_MATCHES(
4747 : e->start()
4748 : , ed::runtime_error
4749 : , Catch::Matchers::ExceptionMessage(
4750 : "event_dispatcher_exception: unsupported negation."));
4751 3 : }
4752 : }
4753 47 : CATCH_END_SECTION()
4754 :
4755 47 : CATCH_START_SECTION("reporter_executor_error: variable reference without a '}'")
4756 : {
4757 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("invalid_negate.rprtr", g_program_unterminated_double_string_variable));
4758 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4759 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
4760 1 : p->parse_program();
4761 :
4762 1 : CATCH_REQUIRE(s->get_statement_size() == 2);
4763 :
4764 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
4765 3 : CATCH_REQUIRE_THROWS_MATCHES(
4766 : e->start()
4767 : , ed::runtime_error
4768 : , Catch::Matchers::ExceptionMessage(
4769 : "event_dispatcher_exception: invalid_negate.rprtr:2: found unclosed variable in \"ref. ${my_var\"."));
4770 1 : }
4771 47 : CATCH_END_SECTION()
4772 :
4773 47 : CATCH_START_SECTION("reporter_executor_error: regex variable in double string")
4774 : {
4775 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("invalid_negate.rprtr", g_program_regex_in_double_string_variable));
4776 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4777 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
4778 1 : p->parse_program();
4779 :
4780 1 : CATCH_REQUIRE(s->get_statement_size() == 2);
4781 :
4782 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
4783 3 : CATCH_REQUIRE_THROWS_MATCHES(
4784 : e->start()
4785 : , ed::runtime_error
4786 : , Catch::Matchers::ExceptionMessage(
4787 : "event_dispatcher_exception: found variable of type \"regex\" which is not yet supported in ${...}."));
4788 1 : }
4789 47 : CATCH_END_SECTION()
4790 :
4791 47 : CATCH_START_SECTION("reporter_executor_error: variable reference without a name")
4792 : {
4793 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("invalid_negate.rprtr", g_program_double_string_variable_without_name));
4794 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4795 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
4796 1 : p->parse_program();
4797 :
4798 1 : CATCH_REQUIRE(s->get_statement_size() == 1);
4799 :
4800 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
4801 3 : CATCH_REQUIRE_THROWS_MATCHES(
4802 : e->start()
4803 : , ed::runtime_error
4804 : , Catch::Matchers::ExceptionMessage(
4805 : "event_dispatcher_exception: invalid_negate.rprtr:1: found variable without a name in \"ref. ${} is empty\"."));
4806 1 : }
4807 47 : CATCH_END_SECTION()
4808 :
4809 47 : CATCH_START_SECTION("reporter_executor_error: <string> * <negative> is not valid")
4810 : {
4811 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("invalid_string_multiplication_negative.rprtr", g_program_unsupported_negation_repeat));
4812 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4813 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
4814 1 : p->parse_program();
4815 :
4816 1 : CATCH_REQUIRE(s->get_statement_size() == 1);
4817 :
4818 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
4819 3 : CATCH_REQUIRE_THROWS_MATCHES(
4820 : e->start()
4821 : , ed::runtime_error
4822 : , Catch::Matchers::ExceptionMessage(
4823 : "event_dispatcher_exception: string repeat needs to be positive and under 1001."));
4824 1 : }
4825 47 : CATCH_END_SECTION()
4826 :
4827 47 : CATCH_START_SECTION("reporter_executor_error: <string> * <large repeat> is not valid")
4828 : {
4829 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("invalid_string_multiplication_large.rprtr", g_program_unsupported_large_repeat));
4830 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4831 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
4832 1 : p->parse_program();
4833 :
4834 1 : CATCH_REQUIRE(s->get_statement_size() == 1);
4835 :
4836 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
4837 3 : CATCH_REQUIRE_THROWS_MATCHES(
4838 : e->start()
4839 : , ed::runtime_error
4840 : , Catch::Matchers::ExceptionMessage(
4841 : "event_dispatcher_exception: string repeat needs to be positive and under 1001."));
4842 1 : }
4843 47 : CATCH_END_SECTION()
4844 :
4845 47 : CATCH_START_SECTION("reporter_executor_error: exit() with timeout & error_message is invalid")
4846 : {
4847 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("bad_exit.rprtr", g_program_bad_exit));
4848 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4849 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
4850 1 : p->parse_program();
4851 :
4852 1 : CATCH_REQUIRE(s->get_statement_size() == 1);
4853 :
4854 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
4855 3 : CATCH_REQUIRE_THROWS_MATCHES(
4856 : e->start()
4857 : , ed::runtime_error
4858 : , Catch::Matchers::ExceptionMessage(
4859 : "event_dispatcher_exception: bad_exit.rprtr:1: \"timeout\" and \"error_message\" from the exit() instruction are mutually exclusive."));
4860 1 : }
4861 47 : CATCH_END_SECTION()
4862 :
4863 47 : CATCH_START_SECTION("reporter_executor_error: exit() with timeout which is not a number")
4864 : {
4865 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("bad_exit.rprtr", g_program_bad_exit_timeout));
4866 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4867 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
4868 1 : p->parse_program();
4869 :
4870 1 : CATCH_REQUIRE(s->get_statement_size() == 1);
4871 :
4872 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
4873 3 : CATCH_REQUIRE_THROWS_MATCHES(
4874 : e->start()
4875 : , ed::runtime_error
4876 : , Catch::Matchers::ExceptionMessage(
4877 : "event_dispatcher_exception: bad_exit.rprtr:1: parameter type mismatch for timeout, expected \"number\", got \"string\" instead."));
4878 1 : }
4879 47 : CATCH_END_SECTION()
4880 :
4881 47 : CATCH_START_SECTION("reporter_executor_error: exit() with timeout which is not a number")
4882 : {
4883 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("bad_print.rprtr", g_program_bad_print_message));
4884 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4885 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
4886 1 : p->parse_program();
4887 :
4888 1 : CATCH_REQUIRE(s->get_statement_size() == 1);
4889 :
4890 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
4891 3 : CATCH_REQUIRE_THROWS_MATCHES(
4892 : e->start()
4893 : , ed::runtime_error
4894 : , Catch::Matchers::ExceptionMessage(
4895 : "event_dispatcher_exception: bad_print.rprtr:1: parameter type mismatch for message, expected \"string\", got \"identifier\" instead."));
4896 1 : }
4897 47 : CATCH_END_SECTION()
4898 :
4899 47 : CATCH_START_SECTION("reporter_executor_error: send_message() when not connected")
4900 : {
4901 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("bad_send_message.rprtr", g_program_send_message_without_connection));
4902 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4903 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
4904 1 : p->parse_program();
4905 :
4906 1 : CATCH_REQUIRE(s->get_statement_size() == 1);
4907 :
4908 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
4909 3 : CATCH_REQUIRE_THROWS_MATCHES(
4910 : e->start()
4911 : , ed::runtime_error
4912 : , Catch::Matchers::ExceptionMessage(
4913 : "event_dispatcher_exception: send_message() has no connection to send a message to."));
4914 1 : }
4915 47 : CATCH_END_SECTION()
4916 :
4917 47 : CATCH_START_SECTION("reporter_executor_error: send_data() when not connected")
4918 : {
4919 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("bad_send_data.rprtr", g_program_send_data_without_connection));
4920 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4921 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
4922 1 : p->parse_program();
4923 :
4924 1 : CATCH_REQUIRE(s->get_statement_size() == 1);
4925 :
4926 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
4927 3 : CATCH_REQUIRE_THROWS_MATCHES(
4928 : e->start()
4929 : , ed::runtime_error
4930 : , Catch::Matchers::ExceptionMessage(
4931 : "event_dispatcher_exception: send_data() has no connection to send data."));
4932 1 : }
4933 47 : CATCH_END_SECTION()
4934 :
4935 47 : CATCH_START_SECTION("reporter_executor_error: if(variable) with invalid type")
4936 : {
4937 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("if_invalid_type.rprtr", g_program_if_invalid_type));
4938 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4939 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
4940 1 : p->parse_program();
4941 :
4942 1 : CATCH_REQUIRE(s->get_statement_size() == 5);
4943 :
4944 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
4945 3 : CATCH_REQUIRE_THROWS_MATCHES(
4946 : e->start()
4947 : , ed::runtime_error
4948 : , Catch::Matchers::ExceptionMessage(
4949 : "event_dispatcher_exception: if(variable: ...) only supports variables of type integer or floating point."));
4950 1 : }
4951 47 : CATCH_END_SECTION()
4952 :
4953 47 : CATCH_START_SECTION("reporter_executor_error: wait() before starting thread")
4954 : {
4955 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("wait_outside_thread.rprtr", g_program_wait_outside_thread));
4956 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4957 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
4958 1 : p->parse_program();
4959 :
4960 1 : CATCH_REQUIRE(s->get_statement_size() == 1);
4961 :
4962 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
4963 3 : CATCH_REQUIRE_THROWS_MATCHES(
4964 : e->start()
4965 : , ed::runtime_error
4966 : , Catch::Matchers::ExceptionMessage(
4967 : "event_dispatcher_exception: wait() used before run()."));
4968 1 : }
4969 47 : CATCH_END_SECTION()
4970 :
4971 47 : CATCH_START_SECTION("reporter_executor_error: wait() with invalid mode")
4972 : {
4973 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("program_wait_invalid_mode.rprtr", g_program_wait_invalid_mode));
4974 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
4975 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
4976 1 : p->parse_program();
4977 :
4978 1 : CATCH_REQUIRE(s->get_statement_size() == 2);
4979 :
4980 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
4981 1 : e->start();
4982 1 : addr::addr a;
4983 1 : sockaddr_in ip = {
4984 : .sin_family = AF_INET,
4985 1 : .sin_port = htons(20002),
4986 : .sin_addr = {
4987 1 : .s_addr = htonl(0x7f000001),
4988 : },
4989 : .sin_zero = {},
4990 1 : };
4991 1 : a.set_ipv4(ip);
4992 1 : messenger_responder::pointer_t messenger(std::make_shared<messenger_responder>(
4993 : a
4994 1 : , ed::mode_t::MODE_PLAIN
4995 2 : , messenger_responder::sequence_t::SEQUENCE_ONE_MESSAGE));
4996 1 : ed::communicator::instance()->add_connection(messenger);
4997 1 : messenger_timer::pointer_t timer(std::make_shared<messenger_timer>(messenger));
4998 1 : ed::communicator::instance()->add_connection(timer);
4999 1 : messenger->set_timer(timer);
5000 1 : e->set_thread_done_callback([messenger, timer]()
5001 : {
5002 1 : ed::communicator::instance()->remove_connection(messenger);
5003 1 : ed::communicator::instance()->remove_connection(timer);
5004 1 : });
5005 :
5006 1 : CATCH_REQUIRE(e->run());
5007 :
5008 : // the thread exception happens when e->stop() is called
5009 : //
5010 3 : CATCH_REQUIRE_THROWS_MATCHES(
5011 : e->stop()
5012 : , ed::runtime_error
5013 : , Catch::Matchers::ExceptionMessage("event_dispatcher_exception: program_wait_invalid_mode.rprtr:2: unknown mode \"not_this_one\" in wait()."));
5014 :
5015 1 : CATCH_REQUIRE(s->get_exit_code() == -1);
5016 1 : }
5017 47 : CATCH_END_SECTION()
5018 :
5019 47 : CATCH_START_SECTION("reporter_executor_error: wait() + drain without connections")
5020 : {
5021 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("program_wait_no_connection.rprtr", g_program_wait_no_connections));
5022 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
5023 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
5024 1 : p->parse_program();
5025 :
5026 1 : CATCH_REQUIRE(s->get_statement_size() == 2);
5027 :
5028 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
5029 1 : e->start();
5030 1 : CATCH_REQUIRE(e->run());
5031 :
5032 : // the thread exception happens when e->stop() is called
5033 : //
5034 3 : CATCH_REQUIRE_THROWS_MATCHES(
5035 : e->stop()
5036 : , ed::runtime_error
5037 : , Catch::Matchers::ExceptionMessage("event_dispatcher_exception: no connections to wait() on."));
5038 :
5039 1 : CATCH_REQUIRE(s->get_exit_code() == -1);
5040 1 : }
5041 47 : CATCH_END_SECTION()
5042 :
5043 47 : CATCH_START_SECTION("reporter_executor_error: try reading missing file")
5044 : {
5045 1 : std::string const source_dir(SNAP_CATCH2_NAMESPACE::g_source_dir());
5046 1 : std::string const filename(source_dir + "/tests/rprtr/not_this_one");
5047 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(SNAP_CATCH2_NAMESPACE::reporter::create_lexer(filename));
5048 1 : CATCH_REQUIRE(l == nullptr);
5049 1 : }
5050 47 : CATCH_END_SECTION()
5051 :
5052 47 : CATCH_START_SECTION("reporter_executor_error: verify that the executor::run() function does a try/catch as expected")
5053 : {
5054 : // in this case, load the program from a file
5055 : // to verify that this works as expected
5056 : //
5057 1 : std::string const source_dir(SNAP_CATCH2_NAMESPACE::g_source_dir());
5058 1 : std::string const filename(source_dir + "/tests/rprtr/send_and_receive_complete_messages");
5059 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(SNAP_CATCH2_NAMESPACE::reporter::create_lexer(filename));
5060 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
5061 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
5062 1 : p->parse_program();
5063 :
5064 1 : CATCH_REQUIRE(s->get_statement_size() == 34);
5065 :
5066 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
5067 1 : e->start();
5068 1 : addr::addr a;
5069 1 : sockaddr_in ip = {
5070 : .sin_family = AF_INET,
5071 1 : .sin_port = htons(20002),
5072 : .sin_addr = {
5073 1 : .s_addr = htonl(0x7f000001),
5074 : },
5075 : .sin_zero = {},
5076 1 : };
5077 1 : a.set_ipv4(ip);
5078 1 : messenger_responder::pointer_t messenger(std::make_shared<messenger_responder>(
5079 : a
5080 1 : , ed::mode_t::MODE_PLAIN
5081 1 : , messenger_responder::sequence_t::SEQUENCE_READY_THROW
5082 1 : , ed::DEFAULT_PAUSE_BEFORE_RECONNECTING));
5083 1 : ed::communicator::instance()->add_connection(messenger);
5084 1 : messenger_timer::pointer_t timer(std::make_shared<messenger_timer>(messenger));
5085 1 : ed::communicator::instance()->add_connection(timer);
5086 1 : messenger->set_timer(timer);
5087 :
5088 : // the exception capture in run() is not returned; it should be
5089 : // printed in the console, making it possible to see what happened
5090 : //
5091 1 : CATCH_REQUIRE_FALSE(e->run());
5092 :
5093 3 : CATCH_REQUIRE_THROWS_MATCHES(
5094 : e->stop()
5095 : , ed::runtime_error
5096 : , Catch::Matchers::ExceptionMessage("event_dispatcher_exception: ppoll() timed out."));
5097 :
5098 : // if we exited because of our timer, then the test did not pass
5099 : //
5100 1 : CATCH_REQUIRE_FALSE(timer->timed_out_prima());
5101 :
5102 1 : CATCH_REQUIRE(s->get_exit_code() == -1);
5103 :
5104 : // in this case, the variable does not get unset because the
5105 : // crash happens before we have the chance to do that
5106 : //
5107 3 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t var(s->get_variable("got_register"));
5108 1 : CATCH_REQUIRE(var != nullptr);
5109 1 : CATCH_REQUIRE(var->get_type() == "integer");
5110 1 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(var)->get_integer() == 1);
5111 1 : }
5112 47 : CATCH_END_SECTION()
5113 :
5114 47 : CATCH_START_SECTION("reporter_executor_error: verify that the executor::run() function does a try/catch of non-standard exceptions")
5115 : {
5116 : // in this case, load the program from a file
5117 : // to verify that this works as expected
5118 : //
5119 1 : std::string const source_dir(SNAP_CATCH2_NAMESPACE::g_source_dir());
5120 1 : std::string const filename(source_dir + "/tests/rprtr/send_and_receive_complete_messages");
5121 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(SNAP_CATCH2_NAMESPACE::reporter::create_lexer(filename));
5122 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
5123 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
5124 1 : p->parse_program();
5125 :
5126 1 : CATCH_REQUIRE(s->get_statement_size() == 34);
5127 :
5128 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
5129 1 : e->start();
5130 1 : addr::addr a;
5131 1 : sockaddr_in ip = {
5132 : .sin_family = AF_INET,
5133 1 : .sin_port = htons(20002),
5134 : .sin_addr = {
5135 1 : .s_addr = htonl(0x7f000001),
5136 : },
5137 : .sin_zero = {},
5138 1 : };
5139 1 : a.set_ipv4(ip);
5140 1 : messenger_responder::pointer_t messenger(std::make_shared<messenger_responder>(
5141 : a
5142 1 : , ed::mode_t::MODE_PLAIN
5143 2 : , messenger_responder::sequence_t::SEQUENCE_READY_THROW_WHAT));
5144 1 : ed::communicator::instance()->add_connection(messenger);
5145 1 : messenger_timer::pointer_t timer(std::make_shared<messenger_timer>(messenger));
5146 1 : ed::communicator::instance()->add_connection(timer);
5147 1 : messenger->set_timer(timer);
5148 :
5149 : // the exception capture in run() is not returned; it should be
5150 : // printed in the console, making it possible to see what happened
5151 : //
5152 1 : CATCH_REQUIRE_FALSE(e->run());
5153 :
5154 3 : CATCH_REQUIRE_THROWS_MATCHES(
5155 : e->stop()
5156 : , ed::runtime_error
5157 : , Catch::Matchers::ExceptionMessage("event_dispatcher_exception: ppoll() timed out."));
5158 :
5159 : // if we exited because of our timer, then the test did not pass
5160 : //
5161 1 : CATCH_REQUIRE_FALSE(timer->timed_out_prima());
5162 :
5163 1 : CATCH_REQUIRE(s->get_exit_code() == -1);
5164 :
5165 : // in this case, the variable does not get unset because the
5166 : // crash happens before we have the chance to do that
5167 : //
5168 3 : SNAP_CATCH2_NAMESPACE::reporter::variable::pointer_t var(s->get_variable("got_register"));
5169 1 : CATCH_REQUIRE(var != nullptr);
5170 1 : CATCH_REQUIRE(var->get_type() == "integer");
5171 1 : CATCH_REQUIRE(std::static_pointer_cast<SNAP_CATCH2_NAMESPACE::reporter::variable_integer>(var)->get_integer() == 1);
5172 1 : }
5173 47 : CATCH_END_SECTION()
5174 :
5175 47 : CATCH_START_SECTION("reporter_executor_error: verify that the run() instruction does throw")
5176 : {
5177 3 : SNAP_CATCH2_NAMESPACE::reporter::instruction::pointer_t inst(SNAP_CATCH2_NAMESPACE::reporter::get_instruction("run"));
5178 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
5179 :
5180 3 : CATCH_REQUIRE_THROWS_MATCHES(
5181 : inst->func(*s)
5182 : , ed::implementation_error
5183 : , Catch::Matchers::ExceptionMessage("implementation_error: run::func() was called when it should be intercepted by the executor."));
5184 1 : }
5185 47 : CATCH_END_SECTION()
5186 :
5187 47 : CATCH_START_SECTION("reporter_executor_error: invalid timestamp for set_variable() cast")
5188 : {
5189 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("program_invalid_string_to_timestamp_cast.rprtr", g_program_invalid_string_to_timestamp_cast));
5190 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
5191 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
5192 1 : p->parse_program();
5193 :
5194 1 : CATCH_REQUIRE(s->get_statement_size() == 1);
5195 :
5196 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
5197 :
5198 3 : CATCH_REQUIRE_THROWS_MATCHES(
5199 : e->start()
5200 : , ed::runtime_error
5201 : , Catch::Matchers::ExceptionMessage("event_dispatcher_exception: invalid timestamp, a valid floating point was expected (1713b34141.10780g991)."));
5202 :
5203 1 : CATCH_REQUIRE(s->get_exit_code() == -1);
5204 1 : }
5205 47 : CATCH_END_SECTION()
5206 :
5207 47 : CATCH_START_SECTION("reporter_executor_error: unknown string cast")
5208 : {
5209 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("program_unknown_string_cast.rprtr", g_program_unknown_string_cast));
5210 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
5211 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
5212 1 : p->parse_program();
5213 :
5214 1 : CATCH_REQUIRE(s->get_statement_size() == 1);
5215 :
5216 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
5217 :
5218 3 : CATCH_REQUIRE_THROWS_MATCHES(
5219 : e->start()
5220 : , ed::runtime_error
5221 : , Catch::Matchers::ExceptionMessage("event_dispatcher_exception: casting from \"string\" to \"unknown\" is not yet implemented."));
5222 :
5223 1 : CATCH_REQUIRE(s->get_exit_code() == -1);
5224 1 : }
5225 47 : CATCH_END_SECTION()
5226 :
5227 47 : CATCH_START_SECTION("reporter_executor_error: unknown timestamp cast")
5228 : {
5229 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("program_unknown_string_cast.rprtr", g_program_unknown_timestamp_cast));
5230 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
5231 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
5232 1 : p->parse_program();
5233 :
5234 1 : CATCH_REQUIRE(s->get_statement_size() == 1);
5235 :
5236 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
5237 :
5238 3 : CATCH_REQUIRE_THROWS_MATCHES(
5239 : e->start()
5240 : , ed::runtime_error
5241 : , Catch::Matchers::ExceptionMessage("event_dispatcher_exception: casting from \"timestamp\" to \"unknown\" is not yet implemented."));
5242 :
5243 1 : CATCH_REQUIRE(s->get_exit_code() == -1);
5244 1 : }
5245 47 : CATCH_END_SECTION()
5246 :
5247 47 : CATCH_START_SECTION("reporter_executor_error: unknown timestamp cast")
5248 : {
5249 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("program_unknown_timestamp_cast.rprtr", g_program_unknown_source_cast));
5250 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
5251 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
5252 1 : p->parse_program();
5253 :
5254 1 : CATCH_REQUIRE(s->get_statement_size() == 1);
5255 :
5256 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
5257 :
5258 : // this test will fail once we implement such; at some point, all the different types will be supported and we'll have to remove this test...
5259 3 : CATCH_REQUIRE_THROWS_MATCHES(
5260 : e->start()
5261 : , ed::runtime_error
5262 : , Catch::Matchers::ExceptionMessage("event_dispatcher_exception: casting from \"address\" to \"string\" is not yet implemented."));
5263 :
5264 1 : CATCH_REQUIRE(s->get_exit_code() == -1);
5265 1 : }
5266 47 : CATCH_END_SECTION()
5267 :
5268 47 : CATCH_START_SECTION("reporter_executor_error: sort() var1 missing")
5269 : {
5270 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("program_sort_var1_missing.rprtr", g_program_sort_var1_missing));
5271 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
5272 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
5273 :
5274 : // this fails way before the inst_sort.func() gets called
5275 : //
5276 3 : CATCH_REQUIRE_THROWS_MATCHES(
5277 : p->parse_program()
5278 : , ed::runtime_error
5279 : , Catch::Matchers::ExceptionMessage("event_dispatcher_exception: parameter \"var1\" is required by \"sort\"."));
5280 1 : }
5281 47 : CATCH_END_SECTION()
5282 :
5283 47 : CATCH_START_SECTION("reporter_executor_error: sort() var1 name must be a string")
5284 : {
5285 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("program_sort_var1_name_not_string.rprtr", g_program_sort_var1_not_string));
5286 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
5287 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
5288 1 : p->parse_program();
5289 :
5290 1 : CATCH_REQUIRE(s->get_statement_size() == 1);
5291 :
5292 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
5293 :
5294 : // this fails before tje inst_sort.func() gets called
5295 : //
5296 3 : CATCH_REQUIRE_THROWS_MATCHES(
5297 : e->start()
5298 : , ed::runtime_error
5299 : , Catch::Matchers::ExceptionMessage("event_dispatcher_exception: program_sort_var1_name_not_string.rprtr:1: parameter type mismatch for var1, expected \"string_or_identifier\", got \"integer\" instead."));
5300 :
5301 1 : CATCH_REQUIRE(s->get_exit_code() == -1);
5302 1 : }
5303 47 : CATCH_END_SECTION()
5304 :
5305 47 : CATCH_START_SECTION("reporter_executor_error: sort() var1 does not name an existing variable")
5306 : {
5307 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("program_sort_var1_not_found.rprtr", g_program_sort_var1_not_found));
5308 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
5309 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
5310 1 : p->parse_program();
5311 :
5312 1 : CATCH_REQUIRE(s->get_statement_size() == 1);
5313 :
5314 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
5315 :
5316 : // this fails before tje inst_sort.func() gets called
5317 : //
5318 3 : CATCH_REQUIRE_THROWS_MATCHES(
5319 : e->start()
5320 : , ed::runtime_error
5321 : , Catch::Matchers::ExceptionMessage("event_dispatcher_exception: program_sort_var1_not_found.rprtr:1: variable named \"not_defined\" not found."));
5322 :
5323 1 : CATCH_REQUIRE(s->get_exit_code() == -1);
5324 1 : }
5325 47 : CATCH_END_SECTION()
5326 :
5327 47 : CATCH_START_SECTION("reporter_executor_error: sort() does not accept all types yet")
5328 : {
5329 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("program_sort_wrong_type.rprtr", g_program_sort_wrong_type));
5330 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
5331 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
5332 1 : p->parse_program();
5333 :
5334 1 : CATCH_REQUIRE(s->get_statement_size() == 2);
5335 :
5336 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
5337 :
5338 : // this fails before tje inst_sort.func() gets called
5339 : //
5340 3 : CATCH_REQUIRE_THROWS_MATCHES(
5341 : e->start()
5342 : , ed::runtime_error
5343 : , Catch::Matchers::ExceptionMessage("event_dispatcher_exception: program_sort_wrong_type.rprtr:2:"
5344 : " sort only supports strings, integers, or floating points."));
5345 :
5346 1 : CATCH_REQUIRE(s->get_exit_code() == -1);
5347 1 : }
5348 47 : CATCH_END_SECTION()
5349 :
5350 47 : CATCH_START_SECTION("reporter_executor_error: sort() does not accept mixed types")
5351 : {
5352 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("program_sort_mixed_types.rprtr", g_program_sort_mixed_types));
5353 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
5354 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
5355 1 : p->parse_program();
5356 :
5357 1 : CATCH_REQUIRE(s->get_statement_size() == 4);
5358 :
5359 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
5360 :
5361 : // this fails before tje inst_sort.func() gets called
5362 : //
5363 3 : CATCH_REQUIRE_THROWS_MATCHES(
5364 : e->start()
5365 : , ed::runtime_error
5366 : , Catch::Matchers::ExceptionMessage("event_dispatcher_exception: program_sort_mixed_types.rprtr:4:"
5367 : " sort only supports one type of data (\"string\" in this case) for all the specified variables. \"integer\" is not compatible."));
5368 :
5369 1 : CATCH_REQUIRE(s->get_exit_code() == -1);
5370 1 : }
5371 47 : CATCH_END_SECTION()
5372 :
5373 47 : CATCH_START_SECTION("reporter_executor_error: listen() with unknown connection type")
5374 : {
5375 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("listen_with_unknown_connection_type.rprtr", g_program_listen_with_unknown_connection_type));
5376 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
5377 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
5378 1 : p->parse_program();
5379 :
5380 1 : CATCH_REQUIRE(s->get_statement_size() == 1);
5381 :
5382 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
5383 3 : CATCH_REQUIRE_THROWS_MATCHES(
5384 : e->start()
5385 : , ed::runtime_error
5386 : , Catch::Matchers::ExceptionMessage(
5387 : "event_dispatcher_exception: unknown type \"unknown\" for listen()."));
5388 1 : }
5389 47 : CATCH_END_SECTION()
5390 47 : }
5391 :
5392 :
5393 3 : CATCH_TEST_CASE("reporter_executor_error_message", "[executor][reporter][error]")
5394 : {
5395 3 : CATCH_START_SECTION("reporter_executor_error_message: verify message fails")
5396 : {
5397 : struct bad_verification_t
5398 : {
5399 : char const * const f_program = nullptr;
5400 : char const * const f_error = nullptr;
5401 : };
5402 1 : bad_verification_t const bad_verifications[] =
5403 : {
5404 : {
5405 : g_program_verify_message_fail_sent_server,
5406 : "event_dispatcher_exception: program_verify_message_fail.rprtr:9: message expected \"sent_server\", set to \"\", to match \"not_this_one\".",
5407 : },
5408 : {
5409 : g_program_verify_message_fail_sent_service,
5410 : "event_dispatcher_exception: program_verify_message_fail.rprtr:9: message expected \"sent_service\", set to \"\", to match \"not_this_one\".",
5411 : },
5412 : {
5413 : g_program_verify_message_fail_server,
5414 : "event_dispatcher_exception: program_verify_message_fail.rprtr:9: message expected \"server\", set to \"\", to match \"not_this_one\".",
5415 : },
5416 : {
5417 : g_program_verify_message_fail_service,
5418 : "event_dispatcher_exception: program_verify_message_fail.rprtr:9: message expected \"service\", set to \"\", to match \"not_this_one\".",
5419 : },
5420 : {
5421 : g_program_verify_message_fail_command,
5422 : "event_dispatcher_exception: program_verify_message_fail.rprtr:9: message expected \"command\", set to \"REGISTER\", to match \"NOT_THIS_ONE\".",
5423 : },
5424 : {
5425 : g_program_verify_message_fail_forbidden,
5426 : "event_dispatcher_exception: program_verify_message_fail.rprtr:9: message forbidden parameter \"version\" was found in this message.",
5427 : },
5428 : {
5429 : g_program_verify_message_fail_required,
5430 : "event_dispatcher_exception: program_verify_message_fail.rprtr:9: message required parameter \"not_this_one\" was not found in this message.",
5431 : },
5432 : {
5433 : g_program_verify_message_fail_required_int_value,
5434 : "event_dispatcher_exception: program_verify_message_fail.rprtr:9: message expected parameter \"version\" to be an integer set to \"200\" but found \"1\" instead.",
5435 : },
5436 : {
5437 : g_program_verify_message_fail_required_str_value,
5438 : "event_dispatcher_exception: program_verify_message_fail.rprtr:9: message expected parameter \"service\" to be a string set to \"not_this_one\" but found \"responder\" instead.",
5439 : },
5440 : {
5441 : g_program_verify_message_fail_required_long_str_value,
5442 : "event_dispatcher_exception: program_verify_message_fail.rprtr:9: message expected parameter \"service\" to be a string set to \"...responderresponderresponderresponderresponderresponderresponderresponderresponderresponderresponderresponderresponderresponder\" but found \"...\" instead.",
5443 : },
5444 : {
5445 : g_program_verify_message_fail_required_flt_value,
5446 : "event_dispatcher_exception: program_verify_message_fail.rprtr:9: message parameter type \"floating_point\" not supported yet.",
5447 : },
5448 : {
5449 : g_program_verify_message_fail_required_timestamp_value,
5450 : "event_dispatcher_exception: program_verify_message_fail.rprtr:9: message expected parameter \"version\", set to \"Thu Jan 1 00:00:01.000000000 1970\", to match timestamp \"Thu Jan 1 00:02:03.000000000 1970\".",
5451 : },
5452 : {
5453 : g_program_verify_message_fail_timestamp_command,
5454 : "event_dispatcher_exception: program_verify_message_fail.rprtr:9: message value \"command\" does not support type \"timestamp\".",
5455 : },
5456 : {
5457 : g_program_verify_message_fail_unexpected_command,
5458 : "event_dispatcher_exception: program_verify_message_fail.rprtr:9: message expected \"command\", set to \"REGISTER\", to match regex \"^NOT_THIS_ONE$\".",
5459 : },
5460 : };
5461 15 : for(auto const & bv : bad_verifications)
5462 : {
5463 14 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("program_verify_message_fail.rprtr", bv.f_program));
5464 14 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
5465 14 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
5466 14 : p->parse_program();
5467 :
5468 14 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
5469 14 : e->start();
5470 14 : addr::addr a;
5471 14 : sockaddr_in ip = {
5472 : .sin_family = AF_INET,
5473 14 : .sin_port = htons(20002),
5474 : .sin_addr = {
5475 14 : .s_addr = htonl(0x7f000001),
5476 : },
5477 : .sin_zero = {},
5478 14 : };
5479 14 : a.set_ipv4(ip);
5480 14 : messenger_responder::pointer_t messenger(std::make_shared<messenger_responder>(
5481 : a
5482 14 : , ed::mode_t::MODE_PLAIN
5483 28 : , messenger_responder::sequence_t::SEQUENCE_ONE_MESSAGE));
5484 14 : ed::communicator::instance()->add_connection(messenger);
5485 14 : messenger_timer::pointer_t timer(std::make_shared<messenger_timer>(messenger));
5486 14 : ed::communicator::instance()->add_connection(timer);
5487 14 : messenger->set_timer(timer);
5488 14 : e->set_thread_done_callback([messenger, timer]()
5489 : {
5490 14 : ed::communicator::instance()->remove_connection(messenger);
5491 14 : ed::communicator::instance()->remove_connection(timer);
5492 14 : });
5493 :
5494 14 : CATCH_REQUIRE(e->run());
5495 :
5496 : // the thread exception happens when e->stop() is called
5497 : //
5498 42 : CATCH_REQUIRE_THROWS_MATCHES(
5499 : e->stop()
5500 : , ed::runtime_error
5501 : , Catch::Matchers::ExceptionMessage(bv.f_error));
5502 :
5503 : // if we exited because of our timer, then the test did not pass
5504 : //
5505 14 : CATCH_REQUIRE_FALSE(timer->timed_out_prima());
5506 :
5507 14 : CATCH_REQUIRE(s->get_exit_code() == -1);
5508 14 : }
5509 : }
5510 3 : CATCH_END_SECTION()
5511 :
5512 3 : CATCH_START_SECTION("reporter_executor_error_message: wait for nothing (should time out)")
5513 : {
5514 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("program_wait_for_nothing.rprtr", g_program_wait_for_nothing));
5515 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
5516 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
5517 1 : p->parse_program();
5518 :
5519 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
5520 1 : e->start();
5521 1 : addr::addr a;
5522 1 : sockaddr_in ip = {
5523 : .sin_family = AF_INET,
5524 1 : .sin_port = htons(20002),
5525 : .sin_addr = {
5526 1 : .s_addr = htonl(0x7f000001),
5527 : },
5528 : .sin_zero = {},
5529 1 : };
5530 1 : a.set_ipv4(ip);
5531 1 : messenger_responder::pointer_t messenger(std::make_shared<messenger_responder>(
5532 : a
5533 1 : , ed::mode_t::MODE_PLAIN
5534 2 : , messenger_responder::sequence_t::SEQUENCE_ONE_MESSAGE));
5535 1 : ed::communicator::instance()->add_connection(messenger);
5536 1 : messenger_timer::pointer_t timer(std::make_shared<messenger_timer>(messenger));
5537 1 : ed::communicator::instance()->add_connection(timer);
5538 1 : messenger->set_timer(timer);
5539 1 : e->set_thread_done_callback([messenger, timer]()
5540 : {
5541 1 : ed::communicator::instance()->remove_connection(messenger);
5542 1 : ed::communicator::instance()->remove_connection(timer);
5543 1 : });
5544 1 : CATCH_REQUIRE(e->run());
5545 :
5546 3 : CATCH_REQUIRE_THROWS_MATCHES(
5547 : e->stop()
5548 : , ed::runtime_error
5549 : , Catch::Matchers::ExceptionMessage("event_dispatcher_exception: ppoll() timed out."));
5550 :
5551 : // if we exited because of our timer, then the test did not pass
5552 : //
5553 1 : CATCH_REQUIRE_FALSE(timer->timed_out_prima());
5554 :
5555 1 : CATCH_REQUIRE(s->get_exit_code() == -1);
5556 1 : }
5557 3 : CATCH_END_SECTION()
5558 :
5559 3 : CATCH_START_SECTION("reporter_executor_error_message: check parameter with incorrect regex fails")
5560 : {
5561 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("program_regex_parameter_no_match.rprtr", g_program_regex_parameter_no_match));
5562 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
5563 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
5564 1 : p->parse_program();
5565 :
5566 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
5567 1 : e->start();
5568 1 : addr::addr a;
5569 1 : sockaddr_in ip = {
5570 : .sin_family = AF_INET,
5571 1 : .sin_port = htons(20002),
5572 : .sin_addr = {
5573 1 : .s_addr = htonl(0x7f000001),
5574 : },
5575 : .sin_zero = {},
5576 1 : };
5577 1 : a.set_ipv4(ip);
5578 1 : messenger_responder::pointer_t messenger(std::make_shared<messenger_responder>(
5579 : a
5580 1 : , ed::mode_t::MODE_PLAIN
5581 2 : , messenger_responder::sequence_t::SEQUENCE_ONE_MESSAGE));
5582 1 : ed::communicator::instance()->add_connection(messenger);
5583 1 : messenger_timer::pointer_t timer(std::make_shared<messenger_timer>(messenger));
5584 1 : ed::communicator::instance()->add_connection(timer);
5585 1 : messenger->set_timer(timer);
5586 1 : e->set_thread_done_callback([messenger, timer]()
5587 : {
5588 1 : ed::communicator::instance()->remove_connection(messenger);
5589 1 : ed::communicator::instance()->remove_connection(timer);
5590 1 : });
5591 1 : CATCH_REQUIRE(e->run());
5592 :
5593 3 : CATCH_REQUIRE_THROWS_MATCHES(
5594 : e->stop()
5595 : , ed::runtime_error
5596 : , Catch::Matchers::ExceptionMessage("event_dispatcher_exception: program_regex_parameter_no_match.rprtr:9: message expected parameter \"version\", set to \"1\", to match regex \"_[a-z]+\"."));
5597 :
5598 : // if we exited because of our timer, then the test did not pass
5599 : //
5600 1 : CATCH_REQUIRE_FALSE(timer->timed_out_prima());
5601 :
5602 1 : CATCH_REQUIRE(s->get_exit_code() == -1);
5603 1 : }
5604 3 : CATCH_END_SECTION()
5605 3 : }
5606 :
5607 :
5608 6 : CATCH_TEST_CASE("reporter_executor_error_data", "[executor][reporter][error]")
5609 : {
5610 6 : CATCH_START_SECTION("reporter_executor_error_data: read too large")
5611 : {
5612 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("raw_tcp_connection.rprtr", g_program_raw_tcp_connection_read_too_large));
5613 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
5614 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
5615 1 : p->parse_program();
5616 :
5617 1 : CATCH_REQUIRE(s->get_statement_size() == 11);
5618 :
5619 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
5620 1 : e->start();
5621 1 : addr::addr a;
5622 1 : sockaddr_in ip = {
5623 : .sin_family = AF_INET,
5624 1 : .sin_port = htons(20002),
5625 : .sin_addr = {
5626 1 : .s_addr = htonl(0x7f000001),
5627 : },
5628 : .sin_zero = {},
5629 1 : };
5630 1 : a.set_ipv4(ip);
5631 1 : permanent_binary_responder::pointer_t binary_responder(std::make_shared<permanent_binary_responder>(
5632 : a
5633 1 : , ed::mode_t::MODE_PLAIN
5634 2 : , permanent_binary_responder::sequence_t::SEQUENCE_PING_PONG));
5635 1 : ed::communicator::instance()->add_connection(binary_responder);
5636 1 : binary_responder->mark_complete();
5637 :
5638 1 : e->set_thread_done_callback([binary_responder]()
5639 : {
5640 1 : ed::communicator::instance()->remove_connection(binary_responder);
5641 1 : });
5642 :
5643 1 : CATCH_REQUIRE(e->run());
5644 :
5645 3 : CATCH_REQUIRE_THROWS_MATCHES(
5646 : e->stop()
5647 : , ed::runtime_error
5648 : , Catch::Matchers::ExceptionMessage("event_dispatcher_exception: raw_tcp_connection.rprtr:10: could not read 5 bytes from the data buffer, got 4 instead."));
5649 1 : }
5650 6 : CATCH_END_SECTION()
5651 :
5652 6 : CATCH_START_SECTION("reporter_executor_error_data: verify fails")
5653 : {
5654 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("raw_tcp_connection.rprtr", g_program_raw_tcp_connection_verify_fails));
5655 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
5656 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
5657 1 : p->parse_program();
5658 :
5659 1 : CATCH_REQUIRE(s->get_statement_size() == 11);
5660 :
5661 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
5662 1 : e->start();
5663 1 : addr::addr a;
5664 1 : sockaddr_in ip = {
5665 : .sin_family = AF_INET,
5666 1 : .sin_port = htons(20002),
5667 : .sin_addr = {
5668 1 : .s_addr = htonl(0x7f000001),
5669 : },
5670 : .sin_zero = {},
5671 1 : };
5672 1 : a.set_ipv4(ip);
5673 1 : permanent_binary_responder::pointer_t binary_responder(std::make_shared<permanent_binary_responder>(
5674 : a
5675 1 : , ed::mode_t::MODE_PLAIN
5676 2 : , permanent_binary_responder::sequence_t::SEQUENCE_PING_PONG));
5677 1 : ed::communicator::instance()->add_connection(binary_responder);
5678 1 : binary_responder->mark_complete();
5679 :
5680 1 : e->set_thread_done_callback([binary_responder]()
5681 : {
5682 1 : ed::communicator::instance()->remove_connection(binary_responder);
5683 1 : });
5684 :
5685 1 : CATCH_REQUIRE(e->run());
5686 :
5687 3 : CATCH_REQUIRE_THROWS_MATCHES(
5688 : e->stop()
5689 : , ed::runtime_error
5690 : , Catch::Matchers::ExceptionMessage("event_dispatcher_exception: raw_tcp_connection.rprtr:10: values at offset 0 do not match (80 != 73)."));
5691 1 : }
5692 6 : CATCH_END_SECTION()
5693 :
5694 6 : CATCH_START_SECTION("reporter_executor_error_data: verify fails")
5695 : {
5696 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("raw_tcp_connection.rprtr", g_program_raw_tcp_connection_send_invalid_value_too_large));
5697 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
5698 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
5699 1 : p->parse_program();
5700 :
5701 1 : CATCH_REQUIRE(s->get_statement_size() == 15);
5702 :
5703 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
5704 1 : e->start();
5705 1 : addr::addr a;
5706 1 : sockaddr_in ip = {
5707 : .sin_family = AF_INET,
5708 1 : .sin_port = htons(20002),
5709 : .sin_addr = {
5710 1 : .s_addr = htonl(0x7f000001),
5711 : },
5712 : .sin_zero = {},
5713 1 : };
5714 1 : a.set_ipv4(ip);
5715 1 : permanent_binary_responder::pointer_t binary_responder(std::make_shared<permanent_binary_responder>(
5716 : a
5717 1 : , ed::mode_t::MODE_PLAIN
5718 2 : , permanent_binary_responder::sequence_t::SEQUENCE_PING_PONG));
5719 1 : ed::communicator::instance()->add_connection(binary_responder);
5720 1 : binary_responder->mark_complete();
5721 :
5722 1 : e->set_thread_done_callback([binary_responder]()
5723 : {
5724 1 : ed::communicator::instance()->remove_connection(binary_responder);
5725 1 : });
5726 :
5727 1 : CATCH_REQUIRE(e->run());
5728 :
5729 3 : CATCH_REQUIRE_THROWS_MATCHES(
5730 : e->stop()
5731 : , ed::runtime_error
5732 : , Catch::Matchers::ExceptionMessage("event_dispatcher_exception: raw_tcp_connection.rprtr:14: byte values must be between -128 and +255 (position 2 has out of range value 256)."));
5733 1 : }
5734 6 : CATCH_END_SECTION()
5735 :
5736 6 : CATCH_START_SECTION("reporter_executor_error_data: verify fails")
5737 : {
5738 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("raw_tcp_connection.rprtr", g_program_raw_tcp_connection_send_invalid_value_too_small));
5739 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
5740 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
5741 1 : p->parse_program();
5742 :
5743 1 : CATCH_REQUIRE(s->get_statement_size() == 15);
5744 :
5745 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
5746 1 : e->start();
5747 1 : addr::addr a;
5748 1 : sockaddr_in ip = {
5749 : .sin_family = AF_INET,
5750 1 : .sin_port = htons(20002),
5751 : .sin_addr = {
5752 1 : .s_addr = htonl(0x7f000001),
5753 : },
5754 : .sin_zero = {},
5755 1 : };
5756 1 : a.set_ipv4(ip);
5757 1 : permanent_binary_responder::pointer_t binary_responder(std::make_shared<permanent_binary_responder>(
5758 : a
5759 1 : , ed::mode_t::MODE_PLAIN
5760 2 : , permanent_binary_responder::sequence_t::SEQUENCE_PING_PONG));
5761 1 : ed::communicator::instance()->add_connection(binary_responder);
5762 1 : binary_responder->mark_complete();
5763 :
5764 1 : e->set_thread_done_callback([binary_responder]()
5765 : {
5766 1 : ed::communicator::instance()->remove_connection(binary_responder);
5767 1 : });
5768 :
5769 1 : CATCH_REQUIRE(e->run());
5770 :
5771 3 : CATCH_REQUIRE_THROWS_MATCHES(
5772 : e->stop()
5773 : , ed::runtime_error
5774 : , Catch::Matchers::ExceptionMessage("event_dispatcher_exception: raw_tcp_connection.rprtr:14: byte values must be between -128 and +255 (position 2 has out of range value -129)."));
5775 1 : }
5776 6 : CATCH_END_SECTION()
5777 :
5778 6 : CATCH_START_SECTION("reporter_executor_error_data: empty array sending data")
5779 : {
5780 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("raw_tcp_connection.rprtr", g_program_raw_tcp_connection_send_empty_array));
5781 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
5782 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
5783 1 : p->parse_program();
5784 :
5785 1 : CATCH_REQUIRE(s->get_statement_size() == 15);
5786 :
5787 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
5788 1 : e->start();
5789 1 : addr::addr a;
5790 1 : sockaddr_in ip = {
5791 : .sin_family = AF_INET,
5792 1 : .sin_port = htons(20002),
5793 : .sin_addr = {
5794 1 : .s_addr = htonl(0x7f000001),
5795 : },
5796 : .sin_zero = {},
5797 1 : };
5798 1 : a.set_ipv4(ip);
5799 1 : permanent_binary_responder::pointer_t binary_responder(std::make_shared<permanent_binary_responder>(
5800 : a
5801 1 : , ed::mode_t::MODE_PLAIN
5802 2 : , permanent_binary_responder::sequence_t::SEQUENCE_PING_PONG));
5803 1 : ed::communicator::instance()->add_connection(binary_responder);
5804 1 : binary_responder->mark_complete();
5805 :
5806 1 : e->set_thread_done_callback([binary_responder]()
5807 : {
5808 1 : ed::communicator::instance()->remove_connection(binary_responder);
5809 1 : });
5810 :
5811 1 : CATCH_REQUIRE(e->run());
5812 :
5813 3 : CATCH_REQUIRE_THROWS_MATCHES(
5814 : e->stop()
5815 : , ed::runtime_error
5816 : , Catch::Matchers::ExceptionMessage("event_dispatcher_exception: raw_tcp_connection.rprtr:14: array cannot be empty."));
5817 1 : }
5818 6 : CATCH_END_SECTION()
5819 :
5820 6 : CATCH_START_SECTION("reporter_executor_error_data: empty array verifying data")
5821 : {
5822 1 : SNAP_CATCH2_NAMESPACE::reporter::lexer::pointer_t l(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::lexer>("raw_tcp_connection.rprtr", g_program_raw_tcp_connection_verify_empty_array));
5823 1 : SNAP_CATCH2_NAMESPACE::reporter::state::pointer_t s(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::state>());
5824 1 : SNAP_CATCH2_NAMESPACE::reporter::parser::pointer_t p(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::parser>(l, s));
5825 1 : p->parse_program();
5826 :
5827 1 : CATCH_REQUIRE(s->get_statement_size() == 11);
5828 :
5829 1 : SNAP_CATCH2_NAMESPACE::reporter::executor::pointer_t e(std::make_shared<SNAP_CATCH2_NAMESPACE::reporter::executor>(s));
5830 1 : e->start();
5831 1 : addr::addr a;
5832 1 : sockaddr_in ip = {
5833 : .sin_family = AF_INET,
5834 1 : .sin_port = htons(20002),
5835 : .sin_addr = {
5836 1 : .s_addr = htonl(0x7f000001),
5837 : },
5838 : .sin_zero = {},
5839 1 : };
5840 1 : a.set_ipv4(ip);
5841 1 : permanent_binary_responder::pointer_t binary_responder(std::make_shared<permanent_binary_responder>(
5842 : a
5843 1 : , ed::mode_t::MODE_PLAIN
5844 2 : , permanent_binary_responder::sequence_t::SEQUENCE_PING_PONG));
5845 1 : ed::communicator::instance()->add_connection(binary_responder);
5846 1 : binary_responder->mark_complete();
5847 :
5848 1 : e->set_thread_done_callback([binary_responder]()
5849 : {
5850 1 : ed::communicator::instance()->remove_connection(binary_responder);
5851 1 : });
5852 :
5853 1 : CATCH_REQUIRE(e->run());
5854 :
5855 3 : CATCH_REQUIRE_THROWS_MATCHES(
5856 : e->stop()
5857 : , ed::runtime_error
5858 : , Catch::Matchers::ExceptionMessage("event_dispatcher_exception: raw_tcp_connection.rprtr:10: array cannot be empty."));
5859 1 : }
5860 6 : CATCH_END_SECTION()
5861 6 : }
5862 :
5863 :
5864 :
5865 : // vim: ts=4 sw=4 et
|