The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
pair_server_tests.c
Go to the documentation of this file.
1 /*
2  * This library is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU Lesser General Public
4  * License as published by the Free Software Foundation; either
5  * version 2.1 of the License, or (at your option) any later version.
6  *
7  * This library is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10  * Lesser General Public License for more details.
11  *
12  * You should have received a copy of the GNU Lesser General Public
13  * License along with this library; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15  */
16 
17 /** Tests for a AVP manipulation and search API.
18  *
19  * @file src/lib/server/pair_server_tests.c
20  * @author Jorge Pereira <jpereira@freeradius.org>
21  * @copyright 2020 Network RADIUS SAS (legal@networkradius.com)
22  */
23 
24 static void test_init(void);
25 static void test_free(void);
26 # define TEST_INIT test_init()
27 # define TEST_FINI test_free()
28 
29 #include <freeradius-devel/util/acutest.h>
30 #include <freeradius-devel/util/acutest_helpers.h>
31 #include <freeradius-devel/util/pair_test_helpers.h>
32 
33 #include <freeradius-devel/util/conf.h>
34 #include <freeradius-devel/util/dict.h>
35 #include <freeradius-devel/util/dict_test.h>
36 #include <freeradius-devel/util/pair.h>
37 #include <freeradius-devel/util/talloc.h>
38 
39 #include <freeradius-devel/server/pair.h>
40 #include <freeradius-devel/server/request.h>
41 
42 #ifdef HAVE_GPERFTOOLS_PROFILER_H
43 # include <gperftools/profiler.h>
44 #endif
45 
46 static TALLOC_CTX *autofree;
49 
50 
51 /** Global initialisation
52  */
53 static void test_init(void)
54 {
56  if (!autofree) {
57  error:
58  fr_perror("pair_tests");
59  fr_exit_now(EXIT_FAILURE);
60  }
61 
62  /*
63  * Mismatch between the binary and the libraries it depends on
64  */
65  if (fr_check_lib_magic(RADIUSD_MAGIC_NUMBER) < 0) goto error;
66 
67  if (fr_dict_test_init(autofree, &test_dict, NULL) < 0) goto error;
68 
69  /* Initialize the "test_pairs" list */
71 
72  if (fr_pair_test_list_alloc(autofree, &test_pairs, NULL) < 0) goto error;
73 
74  if (request_global_init() < 0) goto error;
75 }
76 
77 static void test_free(void)
78 {
80 }
81 
83 {
84  request_t *request;
85 
86  /*
87  * Create and initialize the new request.
88  */
89  request = request_local_alloc_external(autofree, NULL);
90 
91  request->packet = fr_packet_alloc(request, false);
92  TEST_CHECK(request->packet != NULL);
93 
94  request->reply = fr_packet_alloc(request, false);
95  TEST_CHECK(request->reply != NULL);
96 
97  return request;
98 }
99 
100 /*
101  * Tests functions
102  */
103 static void test_pair_append_request(void)
104 {
105  fr_pair_t *local_vp;
106  fr_pair_t *vp;
107  request_t *request = request_fake_alloc();
108 
109  TEST_CASE("Add 'Test-Integer' in 'request_pairs' using pair_append_request()");
111 
112  TEST_CASE("Validating PAIR_VERIFY()");
113  TEST_CHECK((vp = fr_pair_list_head(&request->request_pairs)) != NULL);
114  PAIR_VERIFY(vp);
115 
116  TEST_MSG("Set vp = 12345");
117  vp->vp_uint32 = 12345;
118  TEST_CHECK(vp->vp_uint32 == 12345);
119  TEST_MSG("Expected %s == 12345", fr_dict_attr_test_uint32->name);
120 
121  TEST_CHECK_RET(talloc_free(request), 0);
122 }
123 
124 static void test_pair_append_reply(void)
125 {
126  fr_pair_t *local_vp;
127  fr_pair_t *vp;
128  request_t *request = request_fake_alloc();
129 
130  TEST_CASE("Add 'Test-Integer' in 'reply_pairs' using pair_append_reply()");
132 
133  TEST_CASE("Validating PAIR_VERIFY()");
134  TEST_CHECK((vp = fr_pair_list_head(&request->reply_pairs)) != NULL);
135  PAIR_VERIFY(vp);
136 
137  TEST_MSG("Set vp = 12345");
138  vp->vp_uint32 = 12345;
139 
140  TEST_CHECK(vp->vp_uint32 == 12345);
141  TEST_MSG("Expected %s == 12345", fr_dict_attr_test_uint32->name);
142 
143  TEST_CHECK_RET(talloc_free(request), 0);
144 }
145 
146 static void test_pair_append_control(void)
147 {
148  fr_pair_t *local_vp;
149  fr_pair_t *vp;
150  request_t *request = request_fake_alloc();
151 
152  TEST_CASE("Add 'Test-Integer' in 'control_pairs' using pair_append_control()");
154 
155  TEST_CASE("Validating PAIR_VERIFY()");
156  TEST_CHECK((vp = fr_pair_list_head(&request->control_pairs)) != NULL);
157  PAIR_VERIFY(vp);
158 
159  TEST_MSG("Set vp = 12345");
160  vp->vp_uint32 = 12345;
161 
162  TEST_CHECK(vp->vp_uint32 == 12345);
163  TEST_MSG("Expected %s == 12345", fr_dict_attr_test_uint32->name);
164 
165  TEST_CHECK_RET(talloc_free(request), 0);
166 }
167 
169 {
170  fr_pair_t *local_vp;
171  fr_pair_t *vp;
172  request_t *request = request_fake_alloc();
173 
174  TEST_CASE("Add 'Test-Integer' in 'control_pairs' using pair_append_session_state()");
176 
177  TEST_CASE("Validating PAIR_VERIFY()");
178  TEST_CHECK((vp = fr_pair_list_head(&request->session_state_pairs)) != NULL);
179  PAIR_VERIFY(vp);
180 
181  TEST_MSG("Set vp = 12345");
182  vp->vp_uint32 = 12345;
183 
184  TEST_CHECK(vp->vp_uint32 == 12345);
185  TEST_MSG("Expected %s == 12345", fr_dict_attr_test_uint32->name);
186 
187  TEST_CHECK_RET(talloc_free(request), 0);
188 }
189 
190 static void test_pair_update_request(void)
191 {
192  fr_pair_t *vp;
193  request_t *request = request_fake_alloc();
194 
195  TEST_CASE("Update 'Test-Integer' in 'request_pairs' using pair_update_request()");
197 
198  TEST_CASE("Validating PAIR_VERIFY()");
199  PAIR_VERIFY(vp);
200 
201  TEST_MSG("Set vp = 112233");
202  vp->vp_uint32 = 112233;
203 
204  TEST_CASE("Expected fr_dict_attr_test_uint32 (vp->vp_uint32 == 112233)");
205  TEST_CHECK((vp = fr_pair_find_by_da(&request->request_pairs, NULL, fr_dict_attr_test_uint32)) != NULL);
206 
207  TEST_CASE("Validating PAIR_VERIFY()");
208  PAIR_VERIFY(vp);
209 
210  TEST_MSG("Checking if vp == 12345");
211  /*
212  * Such 'vp != NULL' just to mute clang "warning: Dereference of null pointer"
213  */
214  TEST_CHECK(vp && vp->vp_uint32 == 112233);
215 
216  TEST_CHECK_RET(talloc_free(request), 0);
217 }
218 
219 static void test_pair_update_reply(void)
220 {
221  fr_pair_t *vp;
222  request_t *request = request_fake_alloc();
223 
224  TEST_CASE("Update 'Test-Integer' in 'reply_pairs' using pair_update_request()");
226 
227  TEST_CASE("Validating PAIR_VERIFY()");
228  PAIR_VERIFY(vp);
229 
230  TEST_MSG("Set vp = 3333");
231  vp->vp_uint32 = 3333;
232 
233  TEST_CASE("Expected fr_dict_attr_test_uint32 (vp->vp_uint32 == 3333)");
234  TEST_CHECK((vp = fr_pair_find_by_da(&request->reply_pairs, NULL, fr_dict_attr_test_uint32)) != NULL);
235 
236  TEST_CASE("Validating PAIR_VERIFY()");
237  PAIR_VERIFY(vp);
238 
239  TEST_CHECK(vp && vp->vp_uint32 == 3333);
240 
241  TEST_CHECK_RET(talloc_free(request), 0);
242 }
243 
244 static void test_pair_update_control(void)
245 {
246  fr_pair_t *vp;
247  request_t *request = request_fake_alloc();
248 
249  TEST_CASE("Update 'Test-Integer' in 'control_pairs' using pair_update_control()");
251 
252  TEST_CASE("Validating PAIR_VERIFY()");
253  PAIR_VERIFY(vp);
254 
255  TEST_MSG("Set vp = 44444");
256  vp->vp_uint32 = 44444;
257 
258  TEST_CASE("Expected fr_dict_attr_test_uint32 (vp->vp_uint32 == 44444)");
259  TEST_CHECK((vp = fr_pair_find_by_da(&request->control_pairs, NULL, fr_dict_attr_test_uint32)) != NULL);
260 
261  TEST_CASE("Validating PAIR_VERIFY()");
262  PAIR_VERIFY(vp);
263 
264  TEST_CHECK(vp && vp->vp_uint32 == 44444);
265 
266  TEST_CHECK_RET(talloc_free(request), 0);
267 }
268 
270 {
271  fr_pair_t *vp;
272  request_t *request = request_fake_alloc();
273 
274  TEST_CASE("Update 'Test-Integer' in 'state' using pair_update_session_state()");
276 
277  TEST_CASE("Validating PAIR_VERIFY()");
278  PAIR_VERIFY(vp);
279 
280  TEST_MSG("Set vp = 7890");
281  vp->vp_uint32 = 7890;
282 
283  TEST_CASE("Expected fr_dict_attr_test_uint32 (vp->vp_uint32 == 7890)");
284  TEST_CHECK((vp = fr_pair_find_by_da(&request->session_state_pairs, NULL, fr_dict_attr_test_uint32)) != NULL);
285 
286  TEST_CASE("Validating PAIR_VERIFY()");
287  PAIR_VERIFY(vp);
288 
289  TEST_CHECK(vp && vp->vp_uint32 == 7890);
290 
291  TEST_CHECK_RET(talloc_free(request), 0);
292 }
293 
294 static void test_pair_delete_request(void)
295 {
296  request_t *request = request_fake_alloc();
297 
298  TEST_CASE("Copy 'test_pairs' into 'request->request_pairs'");
299  TEST_CHECK(fr_pair_list_copy(autofree, &request->request_pairs, &test_pairs) > 0);
300 
301  TEST_CASE("Delete 'Test-Integer' in 'request->request_pairs' using pair_delete_request()");
303 
304  TEST_CASE("The 'Test-Integer' shouldn't exist in 'request->request_pairs'");
305  TEST_CHECK(fr_pair_find_by_da(&request->request_pairs, NULL, fr_dict_attr_test_uint32) == NULL);
306 
307  TEST_CHECK_RET(talloc_free(request), 0);
308 }
309 
310 static void test_pair_delete_reply(void)
311 {
312  request_t *request = request_fake_alloc();
313 
314  TEST_CASE("Copy 'test_pairs' into 'request->reply_pairs'");
315  TEST_CHECK(fr_pair_list_copy(autofree, &request->reply_pairs, &test_pairs) > 0);
316 
317  TEST_CASE("Delete 'Test-Integer' in 'request->reply_pairs' using pair_delete_reply()");
319 
320  TEST_CASE("The 'Test-Integer' shouldn't exist in 'request->reply_pairs'");
321  TEST_CHECK(fr_pair_find_by_da(&request->reply_pairs, NULL, fr_dict_attr_test_uint32) == NULL);
322 
323  TEST_CHECK_RET(talloc_free(request), 0);
324 }
325 
326 static void test_pair_delete_control(void)
327 {
328  request_t *request = request_fake_alloc();
329 
330  TEST_CASE("Copy 'test_pairs' into 'request->control_pairs'");
331  TEST_CHECK(fr_pair_list_copy(autofree, &request->control_pairs, &test_pairs) > 0);
332 
333  TEST_CASE("Delete 'Test-Integer' in 'request->control_pairs' using pair_delete_control()");
335 
336  TEST_CASE("The 'Test-Integer' shouldn't exist in 'request->control_pairs'");
337  TEST_CHECK(fr_pair_find_by_da(&request->control_pairs, NULL, fr_dict_attr_test_uint32) == NULL);
338 
339  TEST_CHECK_RET(talloc_free(request), 0);
340 }
341 
343 {
344  request_t *request = request_fake_alloc();
345 
346  TEST_CASE("Copy 'test_pairs' into 'request->state'");
347  TEST_CHECK(fr_pair_list_copy(autofree, &request->session_state_pairs, &test_pairs) > 0);
348 
349  TEST_CASE("Delete 'Test-Integer' in 'request->state' using pair_delete_session_state()");
351 
352  TEST_CASE("The 'Test-Integer' shouldn't exist in 'request->state'");
353  TEST_CHECK(fr_pair_find_by_da(&request->session_state_pairs, NULL, fr_dict_attr_test_uint32) == NULL);
354 
355  TEST_CHECK_RET(talloc_free(request), 0);
356 }
357 
359  /*
360  * Add pairs
361  */
362  { "pair_append_request", test_pair_append_request },
363  { "pair_append_reply", test_pair_append_reply },
364  { "pair_append_control", test_pair_append_control },
365  { "pair_append_session_state", test_pair_append_session_state },
366 
367  /*
368  * Update pairs
369  */
370  { "pair_update_request", test_pair_update_request },
371  { "pair_update_reply", test_pair_update_reply },
372  { "pair_update_control", test_pair_update_control },
373  { "pair_update_session_state", test_pair_update_session_state },
374 
375  /*
376  * Delete pairs
377  */
378  { "pair_delete_request", test_pair_delete_request },
379  { "pair_delete_reply", test_pair_delete_reply },
380  { "pair_delete_control", test_pair_delete_control },
381  { "pair_delete_session_state", test_pair_delete_session_state },
382 
383  { NULL }
384 };
#define TEST_CHECK(cond)
Definition: acutest.h:85
#define TEST_CASE(name)
Definition: acutest.h:184
#define TEST_MSG(...)
Definition: acutest.h:215
#define fr_exit_now(_x)
Exit without calling atexit() handlers, producing a log message in debug builds.
Definition: debug.h:232
fr_dict_attr_t const * fr_dict_attr_test_uint32
Definition: dict_test.c:47
int fr_dict_test_init(TALLOC_CTX *ctx, fr_dict_t **dict_p, fr_dict_test_attr_t const *test_defs)
Initialise a test dictionary and add our test_defs to it.
Definition: dict_test.c:248
TEST_CHECK_RET((int) count,(int) 3)
talloc_free(reap)
fr_packet_t * fr_packet_alloc(TALLOC_CTX *ctx, bool new_vector)
Allocate a new fr_packet_t.
Definition: packet.c:38
fr_pair_t * fr_pair_find_by_da(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find the first pair with a matching da.
Definition: pair.c:688
int fr_pair_list_copy(TALLOC_CTX *ctx, fr_pair_list_t *to, fr_pair_list_t const *from)
Duplicate a list of pairs.
Definition: pair.c:2316
void fr_pair_list_init(fr_pair_list_t *list)
Initialise a pair list header.
Definition: pair.c:46
static void test_pair_update_control(void)
static void test_pair_append_request(void)
static void test_pair_append_session_state(void)
static void test_pair_delete_request(void)
static TALLOC_CTX * autofree
static void test_pair_append_control(void)
static void test_pair_delete_session_state(void)
static void test_pair_update_request(void)
static void test_pair_delete_control(void)
static fr_pair_list_t test_pairs
static void test_pair_append_reply(void)
static void test_pair_update_session_state(void)
static void test_pair_delete_reply(void)
static void test_free(void)
static fr_dict_t * test_dict
static void test_init(void)
Global initialisation.
static void test_pair_update_reply(void)
static request_t * request_fake_alloc(void)
static int fr_pair_test_list_alloc(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_test_attr_t const *test_defs)
#define pair_update_request(_attr, _da)
Definition: radclient-ng.c:60
void request_global_free(void)
Definition: request.c:713
int request_global_init(void)
Definition: request.c:698
#define request_local_alloc_external(_ctx, _args)
Allocate a new external request outside of the request pool.
Definition: request.h:315
#define pair_append_control(_attr, _da)
Allocate and append a fr_pair_t to the control list.
Definition: pair.h:57
#define pair_update_reply(_attr, _da)
Return or allocate a fr_pair_t in the reply list.
Definition: pair.h:129
#define pair_append_session_state(_attr, _da)
Allocate and append a fr_pair_t to session-state list.
Definition: pair.h:67
#define pair_delete_session_state(_pair_or_da)
Delete a fr_pair_t in the session_state list.
Definition: pair.h:199
#define pair_append_request(_attr, _da)
Allocate and append a fr_pair_t to the request list.
Definition: pair.h:37
#define pair_delete_request(_pair_or_da)
Delete a fr_pair_t in the request list.
Definition: pair.h:172
#define pair_update_session_state(_attr, _da)
Return or allocate a fr_pair_t in the session_state list.
Definition: pair.h:151
#define pair_delete_reply(_pair_or_da)
Delete a fr_pair_t in the reply list.
Definition: pair.h:181
#define pair_append_reply(_attr, _da)
Allocate and append a fr_pair_t to reply list.
Definition: pair.h:47
#define pair_delete_control(_pair_or_da)
Delete a fr_pair_t in the control list.
Definition: pair.h:190
#define pair_update_control(_attr, _da)
Return or allocate a fr_pair_t in the control list.
Definition: pair.h:140
fr_pair_t * vp
Stores an attribute, a value and various bits of other data.
Definition: pair.h:68
#define talloc_autofree_context
The original function is deprecated, so replace it with our version.
Definition: talloc.h:51
fr_pair_t * fr_pair_list_head(fr_pair_list_t const *list)
Get the head of a valuepair list.
Definition: pair_inline.c:43
#define PAIR_VERIFY(_x)
Definition: pair.h:190
void fr_perror(char const *fmt,...)
Print the current error to stderr with a prefix.
Definition: strerror.c:733
int fr_check_lib_magic(uint64_t magic)
Check if the application linking to the library has the correct magic number.
Definition: version.c:40
#define RADIUSD_MAGIC_NUMBER
Definition: version.h:81