]> git.ipfire.org Git - thirdparty/strongswan.git/blame - src/libcharon/tests/utils/exchange_test_asserts.h
Spelling fixes
[thirdparty/strongswan.git] / src / libcharon / tests / utils / exchange_test_asserts.h
CommitLineData
632ba2a2 1/*
72655fe4 2 * Copyright (C) 2016-2017 Tobias Brunner
632ba2a2
TB
3 * HSR Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16/**
72655fe4 17 * Special assertions using listener_t etc.
632ba2a2
TB
18 *
19 * @defgroup exchange_test_asserts exchange_test_asserts
20 * @{ @ingroup test_utils_c
21 */
22
23#ifndef EXCHANGE_TEST_ASSERTS_H_
24#define EXCHANGE_TEST_ASSERTS_H_
25
26#include <bus/listeners/listener.h>
27
28typedef struct listener_hook_assert_t listener_hook_assert_t;
29typedef struct listener_message_assert_t listener_message_assert_t;
fbb0b3cb 30typedef struct listener_message_rule_t listener_message_rule_t;
72655fe4 31typedef struct ipsec_sas_assert_t ipsec_sas_assert_t;
632ba2a2
TB
32
33struct listener_hook_assert_t {
34
35 /**
36 * Implemented interface
37 */
38 listener_t listener;
39
40 /**
41 * Original source file
42 */
43 const char *file;
44
45 /**
46 * Source line
47 */
48 int line;
49
50 /**
51 * Name of the hook
52 */
53 const char *name;
54
55 /**
56 * Expected number of calls (-1 to ignore)
57 */
58 int expected;
59
60 /**
61 * Number of times the hook was called
62 */
63 int count;
64
65 /**
66 * Expected updown result
67 */
68 bool up;
14588d99
TB
69
70 /**
71 * Initiator/Inbound SPIs to expect in rekey event
72 */
73 uint64_t spi_old, spi_new;
632ba2a2
TB
74};
75
76/**
77 * Basic callback for methods on listener_t, counting the number of calls.
78 */
79bool exchange_test_asserts_hook(listener_t *this);
80
81/**
82 * Implementation of listener_t::ike_updown.
83 */
84bool exchange_test_asserts_ike_updown(listener_t *this, ike_sa_t *ike_sa,
85 bool up);
86
87/**
88 * Implementation of listener_t::child_updown.
89 */
90bool exchange_test_asserts_child_updown(listener_t *this, ike_sa_t *ike_sa,
91 child_sa_t *child_sa, bool up);
92
14588d99
TB
93/**
94 * Implementation of listener_t::ike_rekey.
95 */
96bool exchange_test_asserts_ike_rekey(listener_t *this, ike_sa_t *old,
97 ike_sa_t *new);
98
99/**
100 * Implementation of listener_t::child_rekey.
101 */
102bool exchange_test_asserts_child_rekey(listener_t *this, ike_sa_t *ike_sa,
103 child_sa_t *old, child_sa_t *new);
104
632ba2a2
TB
105/**
106 * Check if a statement evaluates to TRUE, use original source file and line
107 * in the error message if not.
108 *
109 * @param x statement to evaluate
110 * @param l listener providing original source file and line
111 * @param fmt printf format string
112 * @param ... arguments for fmt
113 */
114#define assert_listener_msg(x, l, fmt, ...) ({ \
115 test_fail_if_worker_failed(); \
116 if (!(x)) \
117 { \
118 test_fail_msg((l)->file, (l)->line, "%s: " fmt, #x, ##__VA_ARGS__); \
119 } \
120})
121
122/**
123 * Initialize an assertion that enforces that the given hook was called.
124 * Must be matched by a call to assert_hook().
125 *
126 * @param name name of the hook
127 */
128#define assert_hook_called(name) \
129 _assert_hook_init(name, exchange_test_asserts_hook, .expected = 1)
130
131/**
132 * Initialize an assertion that enforces that the given hook was not called.
133 * Must be matched by a call to assert_hook().
134 *
135 * @param name name of the hook
136 */
137#define assert_hook_not_called(name) \
138 _assert_hook_init(name, exchange_test_asserts_hook, .expected = 0)
139
140/**
141 * Initialize an assertion that enforces that the given updown hook was called
142 * with the expected result.
143 * Must be matched by a call to assert_hook().
144 *
145 * @param name name of the hook
146 * @param e whether to expect up in the hook to be TRUE or not
147 */
148#define assert_hook_updown(name, e) \
149 _assert_hook_init(name, \
150 streq(#name, "ike_updown") ? (void*)exchange_test_asserts_ike_updown \
151 : (void*)exchange_test_asserts_child_updown, \
152 .expected = 1, \
153 .up = e, \
154 )
155
14588d99
TB
156/**
157 * Initialize an assertion that enforces that the given rekey hook was called
158 * with the SAs with the matching initiator/inbound SPIs.
159 * Must be matched by a call to assert_hook().
160 *
161 * @param name name of the hook
162 * @param old SPI of the old SA
163 * @param new SPI of the new SA
164 */
165#define assert_hook_rekey(name, old, new) \
166 _assert_hook_init(name, \
167 streq(#name, "ike_rekey") ? (void*)exchange_test_asserts_ike_rekey \
168 : (void*)exchange_test_asserts_child_rekey, \
169 .expected = 1, \
170 .spi_old = old, \
171 .spi_new = new, \
172 )
173
632ba2a2
TB
174/**
175 * Initialize assertions against invocations of listener_t hooks. Each call
176 * must be matched by a call to assert_hook().
177 */
178#define _assert_hook_init(n, callback, ...) \
179do { \
180 listener_hook_assert_t _hook_listener = { \
181 .listener = { .n = (void*)callback, }, \
182 .file = __FILE__, \
183 .line = __LINE__, \
184 .name = #n, \
185 ##__VA_ARGS__ \
186 }; \
7c6e0c29 187 exchange_test_helper->add_listener(exchange_test_helper, &_hook_listener.listener)
632ba2a2
TB
188
189/**
190 * Enforce the most recently initialized hook assertion.
191 */
192#define assert_hook() \
193 charon->bus->remove_listener(charon->bus, &_hook_listener.listener); \
194 if (_hook_listener.expected > 0) { \
195 if (_hook_listener.count > 0) { \
196 assert_listener_msg(_hook_listener.expected == _hook_listener.count, \
197 &_hook_listener, "hook '%s' was called %d times " \
198 "instead of %d", _hook_listener.name, \
199 _hook_listener.count, _hook_listener.expected); \
200 } else { \
201 assert_listener_msg(_hook_listener.count, &_hook_listener, \
202 "hook '%s' was not called (expected %d)", _hook_listener.name, \
203 _hook_listener.expected); \
204 } \
205 } else if (_hook_listener.expected == 0) { \
206 assert_listener_msg(_hook_listener.count == 0, &_hook_listener, \
207 "hook '%s' was called unexpectedly", _hook_listener.name); \
208 } \
209} while(FALSE)
210
fbb0b3cb
TB
211/**
212 * Rules regarding payloads/notifies to expect/not expect in a message
213 */
214struct listener_message_rule_t {
215
216 /**
217 * Whether the payload/notify is expected in the message, FALSE to fail if
218 * it is found
219 */
220 bool expected;
221
222 /**
223 * Payload type to expect/not expect
224 */
225 payload_type_t payload;
226
227 /**
b3ab7a48 228 * Notify type to expect/not expect (payload type does not have to be
fbb0b3cb
TB
229 * specified)
230 */
231 notify_type_t notify;
232};
233
632ba2a2
TB
234/**
235 * Data used to check plaintext messages via listener_t
236 */
237struct listener_message_assert_t {
238
239 /**
240 * Implemented interface
241 */
242 listener_t listener;
243
244 /**
245 * Original source file
246 */
247 const char *file;
248
249 /**
250 * Source line
251 */
252 int line;
253
254 /**
255 * Whether to check the next inbound or outbound message
256 */
257 bool incoming;
258
259 /**
fbb0b3cb 260 * Payload count to expect (-1 to ignore the count)
632ba2a2
TB
261 */
262 int count;
263
264 /**
fbb0b3cb 265 * Payloads to expect or not expect in a message
632ba2a2 266 */
fbb0b3cb 267 listener_message_rule_t *rules;
632ba2a2
TB
268
269 /**
fbb0b3cb 270 * Number of rules
632ba2a2 271 */
fbb0b3cb 272 int num_rules;
632ba2a2
TB
273};
274
275/**
276 * Implementation of listener_t::message collecting data and asserting
277 * certain things.
278 */
279bool exchange_test_asserts_message(listener_t *this, ike_sa_t *ike_sa,
280 message_t *message, bool incoming, bool plain);
281
282/**
283 * Assert that the next in- or outbound plaintext message is empty.
284 *
285 * @param dir IN or OUT to check the next in- or outbound message
286 */
fbb0b3cb 287#define assert_message_empty(dir) \
67ad553a 288 _assert_payload(#dir, 0)
632ba2a2
TB
289
290/**
291 * Assert that the next in- or outbound plaintext message contains exactly
292 * one payload of the given type.
293 *
294 * @param dir IN or OUT to check the next in- or outbound message
295 * @param expected expected payload type
296 */
fbb0b3cb 297#define assert_single_payload(dir, expected) \
67ad553a 298 _assert_payload(#dir, 1, { TRUE, expected, 0 })
632ba2a2 299
202fb101
TB
300/**
301 * Assert that the next in- or outbound plaintext message contains a payload
302 * of the given type.
303 *
304 * @param dir IN or OUT to check the next in- or outbound message
305 * @param expected expected payload type
306 */
307#define assert_payload(dir, expected) \
308 _assert_payload(#dir, -1, { TRUE, expected, 0 })
309
310/**
311 * Assert that the next in- or outbound plaintext message contains no payload
312 * of the given type.
313 *
314 * @param dir IN or OUT to check the next in- or outbound message
315 * @param unexpected not expected payload type
316 */
317#define assert_no_payload(dir, unexpected) \
318 _assert_payload(#dir, -1, { FALSE, unexpected, 0 })
319
632ba2a2
TB
320/**
321 * Assert that the next in- or outbound plaintext message contains exactly
322 * one notify of the given type.
323 *
324 * @param dir IN or OUT to check the next in- or outbound message
325 * @param expected expected notify type
326 */
fbb0b3cb 327#define assert_single_notify(dir, expected) \
67ad553a 328 _assert_payload(#dir, 1, { TRUE, 0, expected })
fbb0b3cb
TB
329
330/**
331 * Assert that the next in- or outbound plaintext message contains a notify
332 * of the given type.
333 *
334 * @param dir IN or OUT to check the next in- or outbound message
335 * @param expected expected notify type
336 */
337#define assert_notify(dir, expected) \
67ad553a 338 _assert_payload(#dir, -1, { TRUE, 0, expected })
fbb0b3cb
TB
339
340/**
341 * Assert that the next in- or outbound plaintext message does not contain a
342 * notify of the given type.
343 *
344 * @param dir IN or OUT to check the next in- or outbound message
345 * @param unexpected not expected notify type
346 */
347#define assert_no_notify(dir, unexpected) \
67ad553a 348 _assert_payload(#dir, -1, { FALSE, 0, unexpected })
632ba2a2 349
fbb0b3cb
TB
350#define _assert_payload(dir, c, ...) ({ \
351 listener_message_rule_t _rules[] = { __VA_ARGS__ }; \
632ba2a2
TB
352 listener_message_assert_t _listener = { \
353 .listener = { .message = exchange_test_asserts_message, }, \
354 .file = __FILE__, \
355 .line = __LINE__, \
67ad553a 356 .incoming = streq(dir, "IN") ? TRUE : FALSE, \
632ba2a2 357 .count = c, \
fbb0b3cb
TB
358 .rules = _rules, \
359 .num_rules = countof(_rules), \
632ba2a2 360 }; \
7c6e0c29 361 exchange_test_helper->add_listener(exchange_test_helper, &_listener.listener); \
632ba2a2
TB
362})
363
72655fe4
TB
364/**
365 * Data used to check IPsec SAs
366 */
367struct ipsec_sas_assert_t {
368
369 /**
370 * Original source file
371 */
372 const char *file;
373
374 /**
375 * Source line
376 */
377 int line;
378
379 /**
380 * IKE_SA that installed the IPsec SAs
381 */
382 ike_sa_t *ike_sa;
383
384 /**
385 * SPIs to check
386 */
387 uint32_t *spis;
388
389 /**
390 * Number of SPIs for IPsec SAs to check
391 */
392 int count;
393};
394
395/**
396 * Assert that all given IPsec SAs (and only these) are installed for the given
397 * IKE_SA.
398 */
399void exchange_test_asserts_ipsec_sas(ipsec_sas_assert_t *sas);
400
401/**
402 * Assert that the IPsec SAs with the given SPIs (and none other) are currently
403 * installed by the given IKE_SA.
404 *
405 * @param sa IKE_SA
406 * @param ... list of SPIs
407 */
408#define assert_ipsec_sas_installed(sa, ...) ({ \
409 uint32_t _spis[] = { __VA_ARGS__ }; \
410 ipsec_sas_assert_t _sas_assert = { \
411 .file = __FILE__, \
412 .line = __LINE__, \
413 .ike_sa = sa, \
414 .spis = _spis, \
415 .count = countof(_spis), \
416 }; \
417 exchange_test_asserts_ipsec_sas(&_sas_assert); \
418})
419
632ba2a2 420#endif /** EXCHANGE_TEST_ASSERTS_H_ @}*/