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 # define TEST_INIT test_init()
26 
27 #include <freeradius-devel/util/acutest.h>
28 #include <freeradius-devel/util/acutest_helpers.h>
29 #include <freeradius-devel/util/pair_test_helpers.h>
30 
31 #include <freeradius-devel/util/conf.h>
32 #include <freeradius-devel/util/dict.h>
33 #include <freeradius-devel/util/dict_test.h>
34 #include <freeradius-devel/util/pair.h>
35 #include <freeradius-devel/util/talloc.h>
36 
37 #include <freeradius-devel/server/pair.h>
38 #include <freeradius-devel/server/request.h>
39 
40 #ifdef HAVE_GPERFTOOLS_PROFILER_H
41 # include <gperftools/profiler.h>
42 #endif
43 
44 static TALLOC_CTX *autofree;
47 
48 
49 /** Global initialisation
50  */
51 static void test_init(void)
52 {
54  if (!autofree) {
55  error:
56  fr_perror("pair_tests");
57  fr_exit_now(EXIT_FAILURE);
58  }
59 
60  /*
61  * Mismatch between the binary and the libraries it depends on
62  */
63  if (fr_check_lib_magic(RADIUSD_MAGIC_NUMBER) < 0) goto error;
64 
65  if (fr_dict_test_init(autofree, &test_dict, NULL) < 0) goto error;
66 
67  /* Initialize the "test_pairs" list */
69 
70  if (fr_pair_test_list_alloc(autofree, &test_pairs, NULL) < 0) goto error;
71 
72  if (request_global_init() < 0) goto error;
73 }
74 
76 {
77  request_t *request;
78 
79  /*
80  * Create and initialize the new request.
81  */
82  request = request_local_alloc_external(autofree, NULL);
83 
84  request->packet = fr_packet_alloc(request, false);
85  TEST_CHECK(request->packet != NULL);
86 
87  request->reply = fr_packet_alloc(request, false);
88  TEST_CHECK(request->reply != NULL);
89 
90  return request;
91 }
92 
93 /*
94  * Tests functions
95  */
96 static void test_pair_append_request(void)
97 {
98  fr_pair_t *local_vp;
99  fr_pair_t *vp;
100  request_t *request = request_fake_alloc();
101 
102  TEST_CASE("Add 'Test-Integer' in 'request_pairs' using pair_append_request()");
104 
105  TEST_CASE("Validating PAIR_VERIFY()");
106  TEST_CHECK((vp = fr_pair_list_head(&request->request_pairs)) != NULL);
107  PAIR_VERIFY(vp);
108 
109  TEST_MSG("Set vp = 12345");
110  vp->vp_uint32 = 12345;
111  TEST_CHECK(vp->vp_uint32 == 12345);
112  TEST_MSG("Expected %s == 12345", fr_dict_attr_test_uint32->name);
113 
114  TEST_CHECK_RET(talloc_free(request), 0);
115 }
116 
117 static void test_pair_append_reply(void)
118 {
119  fr_pair_t *local_vp;
120  fr_pair_t *vp;
121  request_t *request = request_fake_alloc();
122 
123  TEST_CASE("Add 'Test-Integer' in 'reply_pairs' using pair_append_reply()");
125 
126  TEST_CASE("Validating PAIR_VERIFY()");
127  TEST_CHECK((vp = fr_pair_list_head(&request->reply_pairs)) != NULL);
128  PAIR_VERIFY(vp);
129 
130  TEST_MSG("Set vp = 12345");
131  vp->vp_uint32 = 12345;
132 
133  TEST_CHECK(vp->vp_uint32 == 12345);
134  TEST_MSG("Expected %s == 12345", fr_dict_attr_test_uint32->name);
135 
136  TEST_CHECK_RET(talloc_free(request), 0);
137 }
138 
139 static void test_pair_append_control(void)
140 {
141  fr_pair_t *local_vp;
142  fr_pair_t *vp;
143  request_t *request = request_fake_alloc();
144 
145  TEST_CASE("Add 'Test-Integer' in 'control_pairs' using pair_append_control()");
147 
148  TEST_CASE("Validating PAIR_VERIFY()");
149  TEST_CHECK((vp = fr_pair_list_head(&request->control_pairs)) != NULL);
150  PAIR_VERIFY(vp);
151 
152  TEST_MSG("Set vp = 12345");
153  vp->vp_uint32 = 12345;
154 
155  TEST_CHECK(vp->vp_uint32 == 12345);
156  TEST_MSG("Expected %s == 12345", fr_dict_attr_test_uint32->name);
157 
158  TEST_CHECK_RET(talloc_free(request), 0);
159 }
160 
162 {
163  fr_pair_t *local_vp;
164  fr_pair_t *vp;
165  request_t *request = request_fake_alloc();
166 
167  TEST_CASE("Add 'Test-Integer' in 'control_pairs' using pair_append_session_state()");
169 
170  TEST_CASE("Validating PAIR_VERIFY()");
171  TEST_CHECK((vp = fr_pair_list_head(&request->session_state_pairs)) != NULL);
172  PAIR_VERIFY(vp);
173 
174  TEST_MSG("Set vp = 12345");
175  vp->vp_uint32 = 12345;
176 
177  TEST_CHECK(vp->vp_uint32 == 12345);
178  TEST_MSG("Expected %s == 12345", fr_dict_attr_test_uint32->name);
179 
180  TEST_CHECK_RET(talloc_free(request), 0);
181 }
182 
183 static void test_pair_update_request(void)
184 {
185  fr_pair_t *vp;
186  request_t *request = request_fake_alloc();
187 
188  TEST_CASE("Update 'Test-Integer' in 'request_pairs' using pair_update_request()");
190 
191  TEST_CASE("Validating PAIR_VERIFY()");
192  PAIR_VERIFY(vp);
193 
194  TEST_MSG("Set vp = 112233");
195  vp->vp_uint32 = 112233;
196 
197  TEST_CASE("Expected fr_dict_attr_test_uint32 (vp->vp_uint32 == 112233)");
198  TEST_CHECK((vp = fr_pair_find_by_da(&request->request_pairs, NULL, fr_dict_attr_test_uint32)) != NULL);
199 
200  TEST_CASE("Validating PAIR_VERIFY()");
201  PAIR_VERIFY(vp);
202 
203  TEST_MSG("Checking if vp == 12345");
204  /*
205  * Such 'vp != NULL' just to mute clang "warning: Dereference of null pointer"
206  */
207  TEST_CHECK(vp && vp->vp_uint32 == 112233);
208 
209  TEST_CHECK_RET(talloc_free(request), 0);
210 }
211 
212 static void test_pair_update_reply(void)
213 {
214  fr_pair_t *vp;
215  request_t *request = request_fake_alloc();
216 
217  TEST_CASE("Update 'Test-Integer' in 'reply_pairs' using pair_update_request()");
219 
220  TEST_CASE("Validating PAIR_VERIFY()");
221  PAIR_VERIFY(vp);
222 
223  TEST_MSG("Set vp = 3333");
224  vp->vp_uint32 = 3333;
225 
226  TEST_CASE("Expected fr_dict_attr_test_uint32 (vp->vp_uint32 == 3333)");
227  TEST_CHECK((vp = fr_pair_find_by_da(&request->reply_pairs, NULL, fr_dict_attr_test_uint32)) != NULL);
228 
229  TEST_CASE("Validating PAIR_VERIFY()");
230  PAIR_VERIFY(vp);
231 
232  TEST_CHECK(vp && vp->vp_uint32 == 3333);
233 
234  TEST_CHECK_RET(talloc_free(request), 0);
235 }
236 
237 static void test_pair_update_control(void)
238 {
239  fr_pair_t *vp;
240  request_t *request = request_fake_alloc();
241 
242  TEST_CASE("Update 'Test-Integer' in 'control_pairs' using pair_update_control()");
244 
245  TEST_CASE("Validating PAIR_VERIFY()");
246  PAIR_VERIFY(vp);
247 
248  TEST_MSG("Set vp = 44444");
249  vp->vp_uint32 = 44444;
250 
251  TEST_CASE("Expected fr_dict_attr_test_uint32 (vp->vp_uint32 == 44444)");
252  TEST_CHECK((vp = fr_pair_find_by_da(&request->control_pairs, NULL, fr_dict_attr_test_uint32)) != NULL);
253 
254  TEST_CASE("Validating PAIR_VERIFY()");
255  PAIR_VERIFY(vp);
256 
257  TEST_CHECK(vp && vp->vp_uint32 == 44444);
258 
259  TEST_CHECK_RET(talloc_free(request), 0);
260 }
261 
263 {
264  fr_pair_t *vp;
265  request_t *request = request_fake_alloc();
266 
267  TEST_CASE("Update 'Test-Integer' in 'state' using pair_update_session_state()");
269 
270  TEST_CASE("Validating PAIR_VERIFY()");
271  PAIR_VERIFY(vp);
272 
273  TEST_MSG("Set vp = 7890");
274  vp->vp_uint32 = 7890;
275 
276  TEST_CASE("Expected fr_dict_attr_test_uint32 (vp->vp_uint32 == 7890)");
277  TEST_CHECK((vp = fr_pair_find_by_da(&request->session_state_pairs, NULL, fr_dict_attr_test_uint32)) != NULL);
278 
279  TEST_CASE("Validating PAIR_VERIFY()");
280  PAIR_VERIFY(vp);
281 
282  TEST_CHECK(vp && vp->vp_uint32 == 7890);
283 
284  TEST_CHECK_RET(talloc_free(request), 0);
285 }
286 
287 static void test_pair_delete_request(void)
288 {
289  request_t *request = request_fake_alloc();
290 
291  TEST_CASE("Copy 'test_pairs' into 'request->request_pairs'");
292  TEST_CHECK(fr_pair_list_copy(autofree, &request->request_pairs, &test_pairs) > 0);
293 
294  TEST_CASE("Delete 'Test-Integer' in 'request->request_pairs' using pair_delete_request()");
296 
297  TEST_CASE("The 'Test-Integer' shouldn't exist in 'request->request_pairs'");
298  TEST_CHECK(fr_pair_find_by_da(&request->request_pairs, NULL, fr_dict_attr_test_uint32) == NULL);
299 
300  TEST_CHECK_RET(talloc_free(request), 0);
301 }
302 
303 static void test_pair_delete_reply(void)
304 {
305  request_t *request = request_fake_alloc();
306 
307  TEST_CASE("Copy 'test_pairs' into 'request->reply_pairs'");
308  TEST_CHECK(fr_pair_list_copy(autofree, &request->reply_pairs, &test_pairs) > 0);
309 
310  TEST_CASE("Delete 'Test-Integer' in 'request->reply_pairs' using pair_delete_reply()");
312 
313  TEST_CASE("The 'Test-Integer' shouldn't exist in 'request->reply_pairs'");
314  TEST_CHECK(fr_pair_find_by_da(&request->reply_pairs, NULL, fr_dict_attr_test_uint32) == NULL);
315 
316  TEST_CHECK_RET(talloc_free(request), 0);
317 }
318 
319 static void test_pair_delete_control(void)
320 {
321  request_t *request = request_fake_alloc();
322 
323  TEST_CASE("Copy 'test_pairs' into 'request->control_pairs'");
324  TEST_CHECK(fr_pair_list_copy(autofree, &request->control_pairs, &test_pairs) > 0);
325 
326  TEST_CASE("Delete 'Test-Integer' in 'request->control_pairs' using pair_delete_control()");
328 
329  TEST_CASE("The 'Test-Integer' shouldn't exist in 'request->control_pairs'");
330  TEST_CHECK(fr_pair_find_by_da(&request->control_pairs, NULL, fr_dict_attr_test_uint32) == NULL);
331 
332  TEST_CHECK_RET(talloc_free(request), 0);
333 }
334 
336 {
337  request_t *request = request_fake_alloc();
338 
339  TEST_CASE("Copy 'test_pairs' into 'request->state'");
340  TEST_CHECK(fr_pair_list_copy(autofree, &request->session_state_pairs, &test_pairs) > 0);
341 
342  TEST_CASE("Delete 'Test-Integer' in 'request->state' using pair_delete_session_state()");
344 
345  TEST_CASE("The 'Test-Integer' shouldn't exist in 'request->state'");
346  TEST_CHECK(fr_pair_find_by_da(&request->session_state_pairs, NULL, fr_dict_attr_test_uint32) == NULL);
347 
348  TEST_CHECK_RET(talloc_free(request), 0);
349 }
350 
352  /*
353  * Add pairs
354  */
355  { "pair_append_request", test_pair_append_request },
356  { "pair_append_reply", test_pair_append_reply },
357  { "pair_append_control", test_pair_append_control },
358  { "pair_append_session_state", test_pair_append_session_state },
359 
360  /*
361  * Update pairs
362  */
363  { "pair_update_request", test_pair_update_request },
364  { "pair_update_reply", test_pair_update_reply },
365  { "pair_update_control", test_pair_update_control },
366  { "pair_update_session_state", test_pair_update_session_state },
367 
368  /*
369  * Delete pairs
370  */
371  { "pair_delete_request", test_pair_delete_request },
372  { "pair_delete_reply", test_pair_delete_reply },
373  { "pair_delete_control", test_pair_delete_control },
374  { "pair_delete_session_state", test_pair_delete_session_state },
375 
376  { NULL }
377 };
#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:234
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:693
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:2319
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 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
int request_global_init(void)
Definition: request.c:722
#define request_local_alloc_external(_ctx, _args)
Allocate a new external request outside of the request pool.
Definition: request.h:316
#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:191
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