Line data Source code
1 : /*
2 : Authors:
3 : Jakub Hrozek <jhrozek@redhat.com>
4 :
5 : Copyright (C) 2014 Red Hat
6 :
7 : SSSD tests: Data Provider Option Tests
8 :
9 : This program is free software; you can redistribute it and/or modify
10 : it under the terms of the GNU General Public License as published by
11 : the Free Software Foundation; either version 3 of the License, or
12 : (at your option) any later version.
13 :
14 : This program is distributed in the hope that it will be useful,
15 : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : GNU General Public License for more details.
18 :
19 : You should have received a copy of the GNU General Public License
20 : along with this program. If not, see <http://www.gnu.org/licenses/>.
21 : */
22 :
23 : #include <popt.h>
24 :
25 : #include "providers/data_provider.h"
26 :
27 : #include "tests/cmocka/common_mock.h"
28 :
29 : #define STRING_DEFAULT "stringval"
30 : #define BLOB_DEFAULT "blobval"
31 : #define INT_DEFAULT 123
32 :
33 : #define TESTS_PATH "tp_" BASE_FILE_STEM
34 : #define TEST_CONF_DB "test_opt_conf.ldb"
35 : #define TEST_DOM_NAME "opt_test"
36 : #define TEST_ID_PROVIDER "ldap"
37 :
38 : enum test_opts {
39 : OPT_STRING_NODEFAULT,
40 : OPT_STRING_DEFAULT,
41 : OPT_BLOB_NODEFAULT,
42 : OPT_BLOB_DEFAULT,
43 : OPT_INT_NODEFAULT,
44 : OPT_INT_DEFAULT,
45 : OPT_BOOL_TRUE,
46 : OPT_BOOL_FALSE,
47 :
48 : OPT_NUM_OPTS
49 : };
50 :
51 : struct dp_option test_def_opts[] = {
52 : { "string_nodefault", DP_OPT_STRING, NULL_STRING, NULL_STRING },
53 : { "string_default", DP_OPT_STRING, { STRING_DEFAULT }, NULL_STRING},
54 : { "blob_nodefault", DP_OPT_BLOB, NULL_BLOB, NULL_BLOB },
55 : { "blob_default", DP_OPT_BLOB,
56 : { .blob = { discard_const(BLOB_DEFAULT),
57 : sizeof(BLOB_DEFAULT) - 1 } },
58 : NULL_BLOB },
59 : { "int_nodefault", DP_OPT_NUMBER, NULL_NUMBER, NULL_NUMBER },
60 : { "int_default", DP_OPT_NUMBER, { .number = INT_DEFAULT }, NULL_NUMBER },
61 : { "bool_true", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE },
62 : { "bool_false", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
63 : DP_OPTION_TERMINATOR
64 : };
65 :
66 8 : static void assert_defaults(struct dp_option *opts)
67 : {
68 : char *s;
69 : struct dp_opt_blob b;
70 : int i;
71 : bool bo;
72 :
73 8 : s = dp_opt_get_string(opts, OPT_STRING_NODEFAULT);
74 8 : assert_null(s);
75 :
76 8 : s = dp_opt_get_string(opts, OPT_STRING_DEFAULT);
77 8 : assert_non_null(s);
78 8 : assert_string_equal(s, STRING_DEFAULT);
79 :
80 8 : b = dp_opt_get_blob(opts, OPT_BLOB_NODEFAULT);
81 8 : assert_null(b.data);
82 8 : assert_int_equal(b.length, 0);
83 :
84 8 : b = dp_opt_get_blob(opts, OPT_BLOB_DEFAULT);
85 8 : assert_non_null(b.data);
86 8 : assert_int_equal(b.length, strlen(BLOB_DEFAULT));
87 8 : assert_memory_equal(b.data, BLOB_DEFAULT, strlen(BLOB_DEFAULT));
88 :
89 8 : i = dp_opt_get_int(opts, OPT_INT_NODEFAULT);
90 8 : assert_int_equal(i, 0);
91 :
92 8 : i = dp_opt_get_int(opts, OPT_INT_DEFAULT);
93 8 : assert_int_equal(i, INT_DEFAULT);
94 :
95 8 : bo = dp_opt_get_bool(opts, OPT_BOOL_TRUE);
96 8 : assert_true(bo == true);
97 :
98 8 : bo = dp_opt_get_bool(opts, OPT_BOOL_FALSE);
99 8 : assert_true(bo == false);
100 8 : }
101 :
102 1 : void opt_test_copy_default(void **state)
103 : {
104 : int ret;
105 : TALLOC_CTX *mem_ctx;
106 : struct dp_option *opts;
107 : struct dp_opt_blob b;
108 :
109 1 : mem_ctx = talloc_new(global_talloc_context);
110 1 : assert_non_null(mem_ctx);
111 :
112 1 : ret = dp_copy_defaults(mem_ctx, test_def_opts, OPT_NUM_OPTS, &opts);
113 1 : assert_int_equal(ret, EOK);
114 1 : assert_defaults(opts);
115 :
116 : /* Test that copy_defaults would still copy defaults even if we
117 : * change the values
118 : */
119 1 : ret = dp_opt_set_string(opts, OPT_STRING_NODEFAULT, "str1");
120 1 : assert_int_equal(ret, EOK);
121 1 : ret = dp_opt_set_string(opts, OPT_STRING_DEFAULT, "str2");
122 1 : assert_int_equal(ret, EOK);
123 :
124 1 : b.data = discard_const_p(uint8_t, "blob1");
125 1 : b.length = strlen("blob1");
126 1 : ret = dp_opt_set_blob(opts, OPT_BLOB_NODEFAULT, b);
127 1 : assert_int_equal(ret, EOK);
128 :
129 1 : ret = dp_opt_set_blob(opts, OPT_BLOB_DEFAULT, b);
130 1 : b.data = discard_const_p(uint8_t, "blob2");
131 1 : b.length = strlen("blob2");
132 1 : assert_int_equal(ret, EOK);
133 :
134 1 : ret = dp_opt_set_int(opts, OPT_INT_NODEFAULT, 456);
135 1 : assert_int_equal(ret, EOK);
136 1 : ret = dp_opt_set_int(opts, OPT_INT_DEFAULT, 789);
137 1 : assert_int_equal(ret, EOK);
138 :
139 1 : ret = dp_opt_set_bool(opts, OPT_BOOL_TRUE, false);
140 1 : assert_int_equal(ret, EOK);
141 1 : ret = dp_opt_set_bool(opts, OPT_BOOL_FALSE, true);
142 1 : assert_int_equal(ret, EOK);
143 :
144 1 : talloc_free(opts);
145 1 : ret = dp_copy_defaults(mem_ctx, test_def_opts, OPT_NUM_OPTS, &opts);
146 1 : assert_int_equal(ret, EOK);
147 1 : assert_defaults(opts);
148 1 : }
149 :
150 1 : void opt_test_copy_options(void **state)
151 : {
152 : int ret;
153 : TALLOC_CTX *mem_ctx;
154 : struct dp_option *opts;
155 : char *s;
156 : struct dp_opt_blob b;
157 : int i;
158 : bool bo;
159 :
160 1 : mem_ctx = talloc_new(global_talloc_context);
161 1 : assert_non_null(mem_ctx);
162 :
163 1 : ret = dp_copy_options(mem_ctx, test_def_opts, OPT_NUM_OPTS, &opts);
164 1 : assert_int_equal(ret, EOK);
165 1 : assert_int_equal(ret, EOK);
166 :
167 1 : ret = dp_opt_set_string(opts, OPT_STRING_NODEFAULT, "str1");
168 1 : assert_int_equal(ret, EOK);
169 :
170 1 : b.data = discard_const_p(uint8_t, "blob1");
171 1 : b.length = strlen("blob1");
172 1 : ret = dp_opt_set_blob(opts, OPT_BLOB_NODEFAULT, b);
173 1 : assert_int_equal(ret, EOK);
174 :
175 1 : ret = dp_opt_set_int(opts, OPT_INT_NODEFAULT, 456);
176 1 : assert_int_equal(ret, EOK);
177 :
178 1 : ret = dp_opt_set_bool(opts, OPT_BOOL_TRUE, false);
179 1 : assert_int_equal(ret, EOK);
180 :
181 : /* Test that options set to an explicit value retain
182 : * the value and even options with default value
183 : * do not return the default unless explicitly set
184 : */
185 1 : s = dp_opt_get_string(opts, OPT_STRING_NODEFAULT);
186 1 : assert_string_equal(s, "str1");
187 1 : s = dp_opt_get_string(opts, OPT_STRING_DEFAULT);
188 1 : assert_null(s);
189 :
190 1 : b = dp_opt_get_blob(opts, OPT_BLOB_NODEFAULT);
191 1 : assert_non_null(b.data);
192 1 : assert_int_equal(b.length, strlen("blob1"));
193 1 : assert_memory_equal(b.data, "blob1", strlen("blob1"));
194 1 : b = dp_opt_get_blob(opts, OPT_BLOB_DEFAULT);
195 1 : assert_null(b.data);
196 1 : assert_int_equal(b.length, 0);
197 :
198 1 : i = dp_opt_get_int(opts, OPT_INT_NODEFAULT);
199 1 : assert_int_equal(i, 456);
200 1 : i = dp_opt_get_int(opts, OPT_INT_DEFAULT);
201 1 : assert_int_equal(i, 0);
202 :
203 1 : bo = dp_opt_get_bool(opts, OPT_BOOL_TRUE);
204 1 : assert_false(bo == true);
205 1 : }
206 :
207 1 : void opt_test_get(void **state)
208 : {
209 : int ret;
210 : struct sss_test_ctx *tctx;
211 : struct dp_option *opts;
212 1 : struct sss_test_conf_param params[] = {
213 : { "string_nodefault", "stringval2" },
214 : { "blob_nodefault", "blobval2" },
215 : { "int_nodefault", "456" },
216 : { "bool_true", "false" },
217 : { NULL, NULL }, /* Sentinel */
218 : };
219 : char *s;
220 : struct dp_opt_blob b;
221 : int i;
222 : bool bo;
223 :
224 1 : tctx = create_dom_test_ctx(global_talloc_context, TESTS_PATH, TEST_CONF_DB,
225 : TEST_DOM_NAME, TEST_ID_PROVIDER, params);
226 1 : assert_non_null(tctx);
227 :
228 1 : ret = dp_get_options(global_talloc_context, tctx->confdb, tctx->conf_dom_path,
229 : test_def_opts, OPT_NUM_OPTS, &opts);
230 1 : assert_int_equal(ret, EOK);
231 :
232 : /* Options that were not specified explicitly should only have the default
233 : * value, those that have been specified explicitly should carry that
234 : * value
235 : */
236 1 : s = dp_opt_get_string(opts, OPT_STRING_NODEFAULT);
237 1 : assert_non_null(s);
238 1 : assert_string_equal(s, "stringval2");
239 :
240 1 : s = dp_opt_get_string(opts, OPT_STRING_DEFAULT);
241 1 : assert_non_null(s);
242 1 : assert_string_equal(s, STRING_DEFAULT);
243 :
244 1 : b = dp_opt_get_blob(opts, OPT_BLOB_NODEFAULT);
245 1 : assert_non_null(b.data);
246 1 : assert_int_equal(b.length, strlen("blobval2"));
247 1 : assert_memory_equal(b.data, "blobval2", strlen("blobval2"));
248 :
249 1 : b = dp_opt_get_blob(opts, OPT_BLOB_DEFAULT);
250 1 : assert_non_null(b.data);
251 1 : assert_int_equal(b.length, strlen(BLOB_DEFAULT));
252 1 : assert_memory_equal(b.data, BLOB_DEFAULT, strlen(BLOB_DEFAULT));
253 :
254 1 : i = dp_opt_get_int(opts, OPT_INT_NODEFAULT);
255 1 : assert_int_equal(i, 456);
256 :
257 1 : i = dp_opt_get_int(opts, OPT_INT_DEFAULT);
258 1 : assert_int_equal(i, INT_DEFAULT);
259 :
260 1 : bo = dp_opt_get_bool(opts, OPT_BOOL_TRUE);
261 1 : assert_true(bo == false);
262 :
263 1 : bo = dp_opt_get_bool(opts, OPT_BOOL_FALSE);
264 1 : assert_true(bo == false);
265 1 : }
266 :
267 5 : static int opt_test_getset_setup(void **state)
268 : {
269 : int ret;
270 : struct dp_option *opts;
271 :
272 5 : ret = dp_copy_defaults(global_talloc_context,
273 : test_def_opts, OPT_NUM_OPTS, &opts);
274 5 : assert_int_equal(ret, EOK);
275 5 : assert_defaults(opts);
276 :
277 5 : *state = opts;
278 5 : return 0;
279 : }
280 :
281 5 : static int opt_test_getset_teardown(void **state)
282 : {
283 5 : struct dp_option *opts = talloc_get_type(*state, struct dp_option);
284 5 : talloc_free(opts);
285 5 : return 0;
286 : }
287 :
288 2 : static void assert_nondefault_string_empty(struct dp_option *opts)
289 : {
290 : char *s;
291 :
292 2 : s = dp_opt_get_string(opts, OPT_STRING_NODEFAULT);
293 2 : assert_null(s);
294 2 : }
295 :
296 2 : static void set_nondefault_string(struct dp_option *opts)
297 : {
298 : int ret;
299 :
300 2 : ret = dp_opt_set_string(opts, OPT_STRING_NODEFAULT, "str1");
301 2 : assert_int_equal(ret, EOK);
302 2 : }
303 :
304 2 : static void check_nondefault_string(struct dp_option *opts)
305 : {
306 : char *s;
307 :
308 2 : s = dp_opt_get_string(opts, OPT_STRING_NODEFAULT);
309 2 : assert_non_null(s);
310 2 : assert_string_equal(s, "str1");
311 2 : }
312 :
313 1 : void opt_test_getset_string(void **state)
314 : {
315 1 : struct dp_option *opts = talloc_get_type(*state, struct dp_option);
316 :
317 1 : assert_nondefault_string_empty(opts);
318 1 : set_nondefault_string(opts);
319 1 : check_nondefault_string(opts);
320 1 : }
321 :
322 2 : static void assert_nondefault_blob_empty(struct dp_option *opts)
323 : {
324 : struct dp_opt_blob b;
325 :
326 2 : b = dp_opt_get_blob(opts, OPT_BLOB_NODEFAULT);
327 2 : assert_null(b.data);
328 2 : assert_int_equal(b.length, 0);
329 2 : }
330 :
331 2 : static void set_nondefault_blob(struct dp_option *opts)
332 : {
333 : struct dp_opt_blob b;
334 : int ret;
335 :
336 2 : b.data = discard_const_p(uint8_t, "blob2");
337 2 : b.length = strlen("blob2");
338 2 : ret = dp_opt_set_blob(opts, OPT_BLOB_NODEFAULT, b);
339 2 : assert_int_equal(ret, EOK);
340 2 : }
341 :
342 2 : static void check_nondefault_blob(struct dp_option *opts)
343 : {
344 : struct dp_opt_blob b;
345 :
346 2 : b = dp_opt_get_blob(opts, OPT_BLOB_NODEFAULT);
347 2 : assert_non_null(b.data);
348 2 : assert_int_equal(b.length, strlen("blob2"));
349 2 : assert_memory_equal(b.data, "blob2", strlen("blob2"));
350 2 : }
351 :
352 1 : void opt_test_getset_blob(void **state)
353 : {
354 1 : struct dp_option *opts = talloc_get_type(*state, struct dp_option);
355 :
356 1 : assert_nondefault_blob_empty(opts);
357 1 : set_nondefault_blob(opts);
358 1 : check_nondefault_blob(opts);
359 1 : }
360 :
361 2 : static void assert_nondefault_int_notset(struct dp_option *opts)
362 : {
363 : int i;
364 2 : i = dp_opt_get_int(opts, OPT_INT_NODEFAULT);
365 2 : assert_int_equal(i, 0);
366 2 : }
367 :
368 2 : static void set_nondefault_int(struct dp_option *opts)
369 : {
370 : int ret;
371 2 : ret = dp_opt_set_int(opts, OPT_INT_NODEFAULT, 456);
372 2 : assert_int_equal(ret, EOK);
373 2 : }
374 :
375 2 : static void assert_nondefault_int_set(struct dp_option *opts)
376 : {
377 : int i;
378 2 : i = dp_opt_get_int(opts, OPT_INT_NODEFAULT);
379 2 : assert_int_equal(i, 456);
380 2 : }
381 :
382 1 : void opt_test_getset_int(void **state)
383 : {
384 1 : struct dp_option *opts = talloc_get_type(*state, struct dp_option);
385 :
386 1 : assert_nondefault_int_notset(opts);
387 1 : set_nondefault_int(opts);
388 1 : assert_nondefault_int_set(opts);
389 1 : }
390 :
391 1 : void opt_test_getset_bool(void **state)
392 : {
393 1 : struct dp_option *opts = talloc_get_type(*state, struct dp_option);
394 : int ret;
395 : bool b;
396 :
397 1 : b = dp_opt_get_bool(opts, OPT_BOOL_TRUE);
398 1 : assert_true(b == true);
399 :
400 1 : ret = dp_opt_set_bool(opts, OPT_BOOL_TRUE, false);
401 1 : assert_int_equal(ret, EOK);
402 :
403 1 : b = dp_opt_get_bool(opts, OPT_BOOL_TRUE);
404 1 : assert_false(b == true);
405 1 : }
406 :
407 1 : void opt_test_inherit(void **state)
408 : {
409 1 : struct dp_option *opts = talloc_get_type(*state, struct dp_option);
410 : int ret;
411 : struct dp_option *opts_copy;
412 : const char *s;
413 1 : const char *sd_inherit_match[] = { "string_nodefault",
414 : "blob_nodefault",
415 : "int_nodefault",
416 : "bool_true",
417 : NULL };
418 :
419 1 : ret = dp_copy_defaults(opts, test_def_opts,
420 : OPT_NUM_OPTS, &opts_copy);
421 1 : assert_int_equal(ret, EOK);
422 1 : assert_defaults(opts);
423 :
424 1 : dp_option_inherit(NULL, OPT_STRING_NODEFAULT,
425 : opts, opts_copy);
426 1 : s = dp_opt_get_string(opts_copy, OPT_STRING_NODEFAULT);
427 1 : assert_null(s);
428 :
429 : /* string */
430 1 : assert_nondefault_string_empty(opts_copy);
431 1 : set_nondefault_string(opts);
432 1 : dp_option_inherit(discard_const(sd_inherit_match),
433 : OPT_STRING_NODEFAULT,
434 : opts, opts_copy);
435 1 : check_nondefault_string(opts_copy);
436 :
437 : /* blob */
438 1 : assert_nondefault_blob_empty(opts_copy);
439 1 : set_nondefault_blob(opts);
440 1 : dp_option_inherit(discard_const(sd_inherit_match),
441 : OPT_BLOB_NODEFAULT,
442 : opts, opts_copy);
443 1 : check_nondefault_blob(opts_copy);
444 :
445 : /* number */
446 1 : assert_nondefault_int_notset(opts_copy);
447 1 : set_nondefault_int(opts);
448 1 : dp_option_inherit(discard_const(sd_inherit_match),
449 : OPT_INT_NODEFAULT,
450 : opts, opts_copy);
451 1 : assert_nondefault_int_set(opts_copy);
452 :
453 : /* bool */
454 1 : assert_true(dp_opt_get_bool(opts_copy, OPT_BOOL_TRUE));
455 :
456 1 : ret = dp_opt_set_bool(opts, OPT_BOOL_TRUE, false);
457 1 : assert_int_equal(ret, EOK);
458 :
459 1 : dp_option_inherit(discard_const(sd_inherit_match),
460 : OPT_BOOL_TRUE,
461 : opts, opts_copy);
462 :
463 1 : assert_false(dp_opt_get_bool(opts_copy, OPT_BOOL_TRUE));
464 1 : }
465 :
466 1 : int main(int argc, const char *argv[])
467 : {
468 1 : int no_cleanup = 0;
469 : poptContext pc;
470 : int opt;
471 : int ret;
472 7 : struct poptOption long_options[] = {
473 : POPT_AUTOHELP
474 5 : SSSD_DEBUG_OPTS
475 : {"no-cleanup", 'n', POPT_ARG_NONE, &no_cleanup, 0,
476 1 : _("Do not delete the test database after a test run"), NULL },
477 : POPT_TABLEEND
478 : };
479 1 : const struct CMUnitTest tests[] = {
480 : cmocka_unit_test_setup_teardown(opt_test_getset_string,
481 : opt_test_getset_setup,
482 : opt_test_getset_teardown),
483 : cmocka_unit_test_setup_teardown(opt_test_getset_int,
484 : opt_test_getset_setup,
485 : opt_test_getset_teardown),
486 : cmocka_unit_test_setup_teardown(opt_test_getset_bool,
487 : opt_test_getset_setup,
488 : opt_test_getset_teardown),
489 : cmocka_unit_test_setup_teardown(opt_test_getset_blob,
490 : opt_test_getset_setup,
491 : opt_test_getset_teardown),
492 : cmocka_unit_test_setup_teardown(opt_test_inherit,
493 : opt_test_getset_setup,
494 : opt_test_getset_teardown),
495 : cmocka_unit_test(opt_test_copy_default),
496 : cmocka_unit_test(opt_test_copy_options),
497 : cmocka_unit_test(opt_test_get)
498 : };
499 :
500 : /* Set debug level to invalid value so we can deside if -d 0 was used. */
501 1 : debug_level = SSSDBG_INVALID;
502 :
503 1 : pc = poptGetContext(argv[0], argc, argv, long_options, 0);
504 1 : while((opt = poptGetNextOpt(pc)) != -1) {
505 : switch(opt) {
506 : default:
507 0 : fprintf(stderr, "\nInvalid option %s: %s\n\n",
508 : poptBadOption(pc, 0), poptStrerror(opt));
509 0 : poptPrintUsage(pc, stderr, 0);
510 0 : return 1;
511 : }
512 : }
513 1 : poptFreeContext(pc);
514 :
515 1 : DEBUG_CLI_INIT(debug_level);
516 :
517 : /* Even though normally the tests should clean up after themselves
518 : * they might not after a failed run. Remove the old db to be sure */
519 1 : tests_set_cwd();
520 1 : test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME);
521 1 : test_dom_suite_setup(TESTS_PATH);
522 :
523 1 : ret = cmocka_run_group_tests(tests, NULL, NULL);
524 1 : if (ret == 0 && !no_cleanup) {
525 1 : test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME);
526 : }
527 1 : return ret;
528 : }
|