Line data Source code
1 : /**
2 : * @file
3 : *
4 : * @brief Tests for internalnotification plugin
5 : *
6 : * @copyright BSD License (see doc/COPYING or http://www.libelektra.org)
7 : *
8 : */
9 :
10 : #include <math.h>
11 : #include <stdlib.h>
12 : #include <string.h>
13 :
14 : #include <kdbconfig.h>
15 : #include <kdbmacros.h>
16 : #include <kdbnotificationinternal.h>
17 : #include <kdbtypes.h>
18 :
19 : #include <tests.h>
20 : #include <tests_plugin.h>
21 :
22 : #include "internalnotification.h"
23 :
24 : int callback_called;
25 : char * callback_keyValue;
26 : char * callback_keyName;
27 :
28 : int doUpdate_callback_called;
29 :
30 : #define CALLBACK_CONTEXT_MAGIC_NUMBER ((void *) 1234)
31 :
32 : #define TEST_CASE_UPDATE_NAME(TYPE_NAME) test_update##TYPE_NAME
33 : #define TEST_CASE_NO_UPDATE_NAME(TYPE_NAME) test_noUpdate##TYPE_NAME
34 :
35 : #define RUN_TYPE_TESTS(TYPE_NAME) \
36 : printf ("\n" #TYPE_NAME "\n----------------\n"); \
37 : TEST_CASE_UPDATE_NAME (TYPE_NAME) (); \
38 : TEST_CASE_NO_UPDATE_NAME (TYPE_NAME) ();
39 :
40 6 : static void test_callback (Key * key, void * context)
41 : {
42 6 : succeed_if (context == CALLBACK_CONTEXT_MAGIC_NUMBER, "callback context was not passed");
43 6 : callback_called = 1;
44 6 : callback_keyValue = (char *) keyValue (key);
45 6 : callback_keyName = (char *) keyName (key);
46 6 : }
47 :
48 18 : static int internalnotificationRegisterInt (Plugin * plugin, Key * key, int * variable)
49 : {
50 18 : size_t address = elektraPluginGetFunction (plugin, "registerInt");
51 18 : if (!address) yield_error ("function not exported");
52 :
53 : // Register key with plugin
54 : ELEKTRA_NOTIFICATION_REGISTERFUNC_TYPEDEF (RegisterFuncType, int)
55 18 : return ((RegisterFuncType) address) (plugin, key, variable);
56 : }
57 :
58 2 : static int internalnotificationSetConversionErrorCallback (Plugin * plugin, ElektraNotificationConversionErrorCallback callback,
59 : void * context)
60 : {
61 2 : size_t address = elektraPluginGetFunction (plugin, "setConversionErrorCallback");
62 2 : if (!address) yield_error ("function not exported");
63 :
64 : // Register key with plugin
65 2 : ((ElektraNotificationSetConversionErrorCallback) address) (plugin, callback, context);
66 2 : return 1;
67 : }
68 :
69 10 : static int internalnotificationRegisterCallback (Plugin * plugin, Key * key, ElektraNotificationChangeCallback callback, void * context)
70 : {
71 10 : size_t address = elektraPluginGetFunction (plugin, "registerCallback");
72 10 : if (!address) yield_error ("function not exported");
73 :
74 : // Register key with plugin
75 10 : return ((ElektraNotificationPluginRegisterCallback) address) (plugin, key, callback, context);
76 : }
77 :
78 2 : static int internalnotificationRegisterCallbackSameOrBelow (Plugin * plugin, Key * key, ElektraNotificationChangeCallback callback,
79 : void * context)
80 : {
81 2 : size_t address = elektraPluginGetFunction (plugin, "registerCallbackSameOrBelow");
82 2 : if (!address) yield_error ("function not exported");
83 :
84 : // Register key with plugin
85 2 : return ((ElektraNotificationPluginRegisterCallbackSameOrBelow) address) (plugin, key, callback, context);
86 : }
87 :
88 : static int digits (long long number)
89 : {
90 8 : int digits = 0;
91 88 : while (number)
92 : {
93 80 : number /= 10;
94 80 : digits++;
95 : }
96 : return digits;
97 : }
98 :
99 8 : static char * convertLongLongToString (long long number)
100 : {
101 8 : int correction = 1; // Allocate space for '\0'
102 8 : int invert = 1;
103 8 : if (number < 0)
104 : {
105 4 : invert = -1; // Invert negative numbers
106 4 : correction += 1; // Allocate extra space for sign ('-')
107 : }
108 16 : int size = digits (number * invert) + correction;
109 :
110 8 : char * buffer = elektraMalloc (size);
111 8 : exit_if_fail (buffer != NULL, "elektraMalloc failed!");
112 :
113 8 : sprintf (buffer, "%lli", number);
114 8 : succeed_if (buffer[0] != '0', "number conversion failed!");
115 :
116 8 : return buffer;
117 : }
118 :
119 2 : static void test_basics (void)
120 : {
121 2 : printf ("test basics\n");
122 :
123 2 : Key * parentKey = keyNew ("user/tests/internalnotification", KEY_END);
124 2 : KeySet * conf = ksNew (0, KS_END);
125 2 : PLUGIN_OPEN ("internalnotification");
126 :
127 2 : KeySet * ks = ksNew (0, KS_END);
128 :
129 2 : succeed_if (plugin->kdbOpen (plugin, parentKey) == 1, "call to kdbOpen was not successful");
130 :
131 2 : succeed_if (plugin->kdbGet (plugin, ks, parentKey) == 1, "call to kdbGet was not successful");
132 :
133 2 : succeed_if (plugin->kdbSet (plugin, ks, parentKey) == 1, "call to kdbSet was not successful");
134 :
135 2 : succeed_if (plugin->kdbClose (plugin, parentKey) == 1, "call to kdbClose was not successful");
136 :
137 2 : keyDel (parentKey);
138 2 : ksDel (ks);
139 2 : PLUGIN_CLOSE ();
140 2 : }
141 :
142 2 : static void test_updateOnKdbGet (void)
143 : {
144 2 : printf ("test update on kdbGet\n");
145 :
146 2 : Key * parentKey = keyNew ("user/tests/internalnotification", KEY_END);
147 2 : KeySet * conf = ksNew (0, KS_END);
148 2 : PLUGIN_OPEN ("internalnotification");
149 :
150 2 : Key * valueKey = keyNew ("user/test/internalnotification/value", KEY_VALUE, "42", KEY_END);
151 2 : KeySet * ks = ksNew (1, valueKey, KS_END);
152 :
153 2 : int value = 0;
154 2 : succeed_if (internalnotificationRegisterInt (plugin, valueKey, &value) == 1,
155 : "call to elektraInternalnotificationRegisterInt was not successful");
156 :
157 2 : plugin->kdbGet (plugin, ks, parentKey);
158 :
159 2 : succeed_if (value == 42, "registered value was not updated");
160 :
161 2 : keyDel (parentKey);
162 2 : ksDel (ks);
163 2 : PLUGIN_CLOSE ();
164 2 : }
165 :
166 2 : static void test_updateOnKdbSet (void)
167 : {
168 2 : printf ("test update on kdbSet\n");
169 :
170 2 : Key * parentKey = keyNew ("user/tests/internalnotification", KEY_END);
171 2 : KeySet * conf = ksNew (0, KS_END);
172 2 : PLUGIN_OPEN ("internalnotification");
173 :
174 2 : Key * valueKey = keyNew ("user/test/internalnotification/value", KEY_VALUE, "42", KEY_END);
175 2 : KeySet * ks = ksNew (1, valueKey, KS_END);
176 :
177 2 : int value = 0;
178 2 : succeed_if (internalnotificationRegisterInt (plugin, valueKey, &value) == 1,
179 : "call to elektraInternalnotificationRegisterInt was not successful");
180 :
181 2 : plugin->kdbSet (plugin, ks, parentKey);
182 :
183 2 : succeed_if (value == 42, "registered value was not updated");
184 :
185 2 : keyDel (parentKey);
186 2 : ksDel (ks);
187 2 : PLUGIN_CLOSE ();
188 2 : }
189 :
190 2 : static void test_intUpdateWithCascadingKey (void)
191 : {
192 2 : printf ("test update with cascading key registered\n");
193 :
194 2 : KeySet * conf = ksNew (0, KS_END);
195 2 : PLUGIN_OPEN ("internalnotification");
196 :
197 2 : Key * registeredKey = keyNew ("/test/internalnotification/value", KEY_END);
198 2 : int value = 0;
199 2 : succeed_if (internalnotificationRegisterInt (plugin, registeredKey, &value) == 1,
200 : "call to elektraInternalnotificationRegisterInt was not successful");
201 :
202 2 : Key * valueKey = keyNew ("user/test/internalnotification/value", KEY_VALUE, "42", KEY_END);
203 2 : KeySet * ks = ksNew (1, valueKey, KS_END);
204 :
205 2 : elektraInternalnotificationUpdateRegisteredKeys (plugin, ks);
206 :
207 2 : succeed_if (value == 42, "registered value was not updated");
208 :
209 2 : keyDel (registeredKey);
210 2 : ksDel (ks);
211 2 : PLUGIN_CLOSE ();
212 2 : }
213 :
214 2 : static void test_intNoUpdateWithInvalidValue (void)
215 : {
216 2 : printf ("test no update with invalid value\n");
217 :
218 2 : KeySet * conf = ksNew (0, KS_END);
219 2 : PLUGIN_OPEN ("internalnotification");
220 :
221 2 : Key * valueKey = keyNew ("user/test/internalnotification/value", KEY_END);
222 2 : KeySet * ks = ksNew (1, valueKey, KS_END);
223 :
224 2 : int value = 123;
225 2 : succeed_if (internalnotificationRegisterInt (plugin, valueKey, &value) == 1,
226 : "call to elektraInternalnotificationRegisterInt was not successful");
227 :
228 2 : keySetString (valueKey, "42abcd");
229 :
230 :
231 2 : elektraInternalnotificationUpdateRegisteredKeys (plugin, ks);
232 :
233 2 : succeed_if (value == 123, "registered value was updated");
234 :
235 2 : ksDel (ks);
236 2 : PLUGIN_CLOSE ();
237 2 : }
238 :
239 2 : static void test_conversionError (void)
240 : {
241 2 : printf ("test conversion error callback is called on invalid value\n");
242 :
243 2 : KeySet * conf = ksNew (0, KS_END);
244 2 : PLUGIN_OPEN ("internalnotification");
245 :
246 2 : Key * valueKey = keyNew ("user/test/internalnotification/value", KEY_END);
247 2 : KeySet * ks = ksNew (1, valueKey, KS_END);
248 :
249 2 : succeed_if (internalnotificationSetConversionErrorCallback (plugin, test_callback, CALLBACK_CONTEXT_MAGIC_NUMBER) == 1,
250 : "call to elektraInternalnotificationSetConversionErrorCallback was not successful");
251 :
252 2 : int value = 123;
253 2 : succeed_if (internalnotificationRegisterInt (plugin, valueKey, &value) == 1,
254 : "call to elektraInternalnotificationRegisterInt was not successful");
255 :
256 2 : keySetString (valueKey, "42abcd");
257 :
258 2 : callback_called = 0;
259 2 : callback_keyName = NULL;
260 2 : callback_keyValue = NULL;
261 2 : elektraInternalnotificationUpdateRegisteredKeys (plugin, ks);
262 :
263 2 : succeed_if (value == 123, "registered value was updated");
264 2 : succeed_if (callback_called, "conversion error callback was not called");
265 2 : succeed_if_same_string (keyName (valueKey), callback_keyName) succeed_if_same_string (keyString (valueKey), callback_keyValue)
266 :
267 2 : ksDel (ks);
268 2 : PLUGIN_CLOSE ();
269 2 : }
270 :
271 2 : static void test_intUpdateWithValueNotYetExceedingIntMax (void)
272 : {
273 2 : printf ("test update with value = INT_MAX\n");
274 :
275 2 : KeySet * conf = ksNew (0, KS_END);
276 2 : PLUGIN_OPEN ("internalnotification");
277 :
278 2 : Key * valueKey = keyNew ("user/test/internalnotification/value", KEY_END);
279 2 : KeySet * ks = ksNew (1, valueKey, KS_END);
280 :
281 2 : int value = 123;
282 2 : succeed_if (internalnotificationRegisterInt (plugin, valueKey, &value) == 1,
283 : "call to elektraInternalnotificationRegisterInt was not successful");
284 :
285 2 : int exceedsInt = INT_MAX;
286 2 : char * stringValue = convertLongLongToString ((long long) exceedsInt);
287 2 : keySetString (valueKey, stringValue);
288 :
289 :
290 2 : elektraInternalnotificationUpdateRegisteredKeys (plugin, ks);
291 :
292 2 : succeed_if (value == INT_MAX, "registered value was not updated");
293 :
294 2 : elektraFree (stringValue);
295 2 : ksDel (ks);
296 2 : PLUGIN_CLOSE ();
297 2 : }
298 :
299 2 : static void test_intNoUpdateWithValueExceedingIntMax (void)
300 : {
301 2 : printf ("test no update with value that exceeds INT_MAX\n");
302 :
303 2 : KeySet * conf = ksNew (0, KS_END);
304 2 : PLUGIN_OPEN ("internalnotification");
305 :
306 2 : Key * valueKey = keyNew ("user/test/internalnotification/value", KEY_END);
307 2 : KeySet * ks = ksNew (1, valueKey, KS_END);
308 :
309 2 : int value = 123;
310 2 : succeed_if (internalnotificationRegisterInt (plugin, valueKey, &value) == 1,
311 : "call to elektraInternalnotificationRegisterInt was not successful");
312 :
313 2 : long long exceedsInt = (long long) INT_MAX + 1;
314 2 : char * stringValue = convertLongLongToString (exceedsInt);
315 2 : keySetString (valueKey, stringValue);
316 :
317 :
318 2 : elektraInternalnotificationUpdateRegisteredKeys (plugin, ks);
319 :
320 2 : succeed_if (value == 123, "registered value was updated");
321 :
322 2 : elektraFree (stringValue);
323 2 : ksDel (ks);
324 2 : PLUGIN_CLOSE ();
325 2 : }
326 :
327 :
328 2 : static void test_intUpdateWithValueNotYetExceedingIntMin (void)
329 : {
330 2 : printf ("test update with value = INT_MIN\n");
331 :
332 2 : KeySet * conf = ksNew (0, KS_END);
333 2 : PLUGIN_OPEN ("internalnotification");
334 :
335 2 : Key * valueKey = keyNew ("user/test/internalnotification/value", KEY_END);
336 2 : KeySet * ks = ksNew (1, valueKey, KS_END);
337 :
338 2 : int value = 123;
339 2 : succeed_if (internalnotificationRegisterInt (plugin, valueKey, &value) == 1,
340 : "call to elektraInternalnotificationRegisterInt was not successful");
341 :
342 2 : int exceedsInt = INT_MIN;
343 2 : char * stringValue = convertLongLongToString ((long long) exceedsInt);
344 2 : keySetString (valueKey, stringValue);
345 :
346 :
347 2 : elektraInternalnotificationUpdateRegisteredKeys (plugin, ks);
348 :
349 2 : succeed_if (value == INT_MIN, "registered value was not updated");
350 :
351 2 : elektraFree (stringValue);
352 2 : ksDel (ks);
353 2 : PLUGIN_CLOSE ();
354 2 : }
355 :
356 2 : static void test_intNoUpdateWithValueExceedingIntMin (void)
357 : {
358 2 : printf ("test no update with value that exceeds INT_MIN\n");
359 :
360 2 : KeySet * conf = ksNew (0, KS_END);
361 2 : PLUGIN_OPEN ("internalnotification");
362 :
363 2 : Key * valueKey = keyNew ("user/test/internalnotification/value", KEY_END);
364 2 : KeySet * ks = ksNew (1, valueKey, KS_END);
365 :
366 2 : int value = 123;
367 2 : succeed_if (internalnotificationRegisterInt (plugin, valueKey, &value) == 1,
368 : "call to elektraInternalnotificationRegisterInt was not successful");
369 :
370 2 : long long exceedsInt = (long long) INT_MIN - 1;
371 2 : char * stringValue = convertLongLongToString (exceedsInt);
372 2 : keySetString (valueKey, stringValue);
373 :
374 2 : elektraInternalnotificationUpdateRegisteredKeys (plugin, ks);
375 :
376 2 : succeed_if (value == 123, "registered value was updated");
377 :
378 2 : elektraFree (stringValue);
379 2 : ksDel (ks);
380 2 : PLUGIN_CLOSE ();
381 2 : }
382 :
383 2 : static void test_callbackCalledWithKey (void)
384 : {
385 2 : printf ("test callback is called with changed key\n");
386 :
387 2 : KeySet * conf = ksNew (0, KS_END);
388 2 : PLUGIN_OPEN ("internalnotification");
389 :
390 2 : char * value = "foobaroo!";
391 2 : Key * valueKey = keyNew ("user/test/internalnotification/value", KEY_VALUE, value, KEY_END);
392 2 : KeySet * ks = ksNew (1, valueKey, KS_END);
393 :
394 2 : succeed_if (internalnotificationRegisterCallback (plugin, valueKey, test_callback, CALLBACK_CONTEXT_MAGIC_NUMBER) == 1,
395 : "call to elektraInternalnotificationRegisterCallback was not successful");
396 :
397 2 : elektraInternalnotificationUpdateRegisteredKeys (plugin, ks);
398 :
399 2 : succeed_if (callback_called, "registered value was not updated");
400 2 : succeed_if_same_string (callback_keyName, keyName (valueKey));
401 2 : succeed_if_same_string (callback_keyValue, value);
402 :
403 2 : ksDel (ks);
404 2 : PLUGIN_CLOSE ();
405 2 : }
406 :
407 2 : static void test_callbackCalledWithChangeDetection (void)
408 : {
409 2 : printf ("test callback is not called when key has not changed\n");
410 :
411 2 : KeySet * conf = ksNew (0, KS_END);
412 2 : PLUGIN_OPEN ("internalnotification");
413 :
414 2 : char * value = "foobaroo!";
415 2 : Key * valueKey = keyNew ("user/test/internalnotification/value", KEY_VALUE, value, KEY_END);
416 2 : KeySet * ks = ksNew (1, valueKey, KS_END);
417 :
418 2 : succeed_if (internalnotificationRegisterCallback (plugin, valueKey, test_callback, CALLBACK_CONTEXT_MAGIC_NUMBER) == 1,
419 : "call to elektraInternalnotificationRegisterCallback was not successful");
420 :
421 2 : elektraInternalnotificationUpdateRegisteredKeys (plugin, ks);
422 :
423 2 : succeed_if (callback_called, "registered value was not updated");
424 :
425 2 : callback_called = 0;
426 2 : elektraInternalnotificationUpdateRegisteredKeys (plugin, ks);
427 2 : succeed_if (callback_called == 0, "registered value was updated but value has not changed");
428 :
429 2 : ksDel (ks);
430 2 : PLUGIN_CLOSE ();
431 2 : }
432 :
433 6 : static void test_doUpdate_callback (KDB * kdb ELEKTRA_UNUSED, Key * changedKey ELEKTRA_UNUSED)
434 : {
435 6 : doUpdate_callback_called = 1;
436 6 : }
437 :
438 2 : static void test_doUpdateShouldUpdateKey (void)
439 : {
440 2 : printf ("test doUpdate should update same key\n");
441 :
442 2 : KeySet * conf = ksNew (0, KS_END);
443 2 : PLUGIN_OPEN ("internalnotification");
444 :
445 2 : Key * changedKey = keyNew ("user/test/internalnotification/value", KEY_END);
446 :
447 2 : succeed_if (internalnotificationRegisterCallback (plugin, changedKey, test_callback, NULL) == 1,
448 : "call to elektraInternalnotificationRegisterCallback was not successful");
449 :
450 2 : ElektraNotificationCallbackContext * context = elektraMalloc (sizeof *context);
451 : context->kdbUpdate = NULL;
452 2 : context->kdbUpdate = test_doUpdate_callback;
453 2 : context->notificationPlugin = plugin;
454 :
455 2 : doUpdate_callback_called = 0;
456 2 : elektraInternalnotificationDoUpdate (changedKey, context);
457 :
458 2 : succeed_if (doUpdate_callback_called, "did not call callback for registered key");
459 :
460 2 : elektraFree (context);
461 2 : PLUGIN_CLOSE ();
462 2 : }
463 :
464 2 : static void test_doUpdateShouldUpdateKeyBelow (void)
465 : {
466 2 : printf ("test doUpdate should update key below changed key\n");
467 :
468 2 : KeySet * conf = ksNew (0, KS_END);
469 2 : PLUGIN_OPEN ("internalnotification");
470 :
471 2 : Key * changedKey = keyNew ("user/test/internalnotification", KEY_END);
472 :
473 2 : Key * registeredKey = keyNew ("user/test/internalnotification/value", KEY_END);
474 2 : succeed_if (internalnotificationRegisterCallback (plugin, registeredKey, test_callback, NULL) == 1,
475 : "call to elektraInternalnotificationRegisterCallback was not successful");
476 :
477 2 : ElektraNotificationCallbackContext * context = elektraMalloc (sizeof *context);
478 : context->kdbUpdate = NULL;
479 2 : context->kdbUpdate = test_doUpdate_callback;
480 2 : context->notificationPlugin = plugin;
481 :
482 2 : doUpdate_callback_called = 0;
483 2 : elektraInternalnotificationDoUpdate (changedKey, context);
484 :
485 2 : succeed_if (doUpdate_callback_called, "did not call callback for registered key");
486 :
487 2 : elektraFree (context);
488 2 : keyDel (registeredKey);
489 2 : PLUGIN_CLOSE ();
490 2 : }
491 :
492 2 : static void test_doUpdateShouldNotUpdateKeyAbove (void)
493 : {
494 2 : printf ("test doUpdate should not update key above changed key\n");
495 :
496 2 : KeySet * conf = ksNew (0, KS_END);
497 2 : PLUGIN_OPEN ("internalnotification");
498 :
499 2 : Key * changedKey = keyNew ("user/test/internalnotification/value", KEY_END);
500 :
501 2 : Key * registeredKey = keyNew ("user/test/internalnotification", KEY_END);
502 2 : succeed_if (internalnotificationRegisterCallback (plugin, registeredKey, test_callback, NULL) == 1,
503 : "call to elektraInternalnotificationRegisterCallback was not successful");
504 :
505 2 : ElektraNotificationCallbackContext * context = elektraMalloc (sizeof *context);
506 : context->kdbUpdate = NULL;
507 2 : context->kdbUpdate = test_doUpdate_callback;
508 2 : context->notificationPlugin = plugin;
509 :
510 2 : doUpdate_callback_called = 0;
511 2 : elektraInternalnotificationDoUpdate (changedKey, context);
512 :
513 2 : succeed_if (doUpdate_callback_called == 0, "did call callback for key above");
514 :
515 2 : elektraFree (context);
516 2 : keyDel (registeredKey);
517 2 : PLUGIN_CLOSE ();
518 2 : }
519 :
520 2 : static void test_doUpdateShouldUpdateKeyAbove (void)
521 : {
522 2 : printf ("test doUpdate should update key above changed key for sameOrBelow callbacks\n");
523 :
524 2 : KeySet * conf = ksNew (0, KS_END);
525 2 : PLUGIN_OPEN ("internalnotification");
526 :
527 2 : Key * changedKey = keyNew ("user/test/internalnotification/value", KEY_END);
528 :
529 2 : Key * registeredKey = keyNew ("user/test/internalnotification", KEY_END);
530 2 : succeed_if (internalnotificationRegisterCallbackSameOrBelow (plugin, registeredKey, test_callback, NULL) == 1,
531 : "call to internalnotificationRegisterCallbackSameOrBelow was not successful");
532 :
533 2 : ElektraNotificationCallbackContext * context = elektraMalloc (sizeof *context);
534 : context->kdbUpdate = NULL;
535 2 : context->kdbUpdate = test_doUpdate_callback;
536 2 : context->notificationPlugin = plugin;
537 :
538 2 : doUpdate_callback_called = 0;
539 2 : elektraInternalnotificationDoUpdate (changedKey, context);
540 :
541 2 : succeed_if (doUpdate_callback_called, "did not call callback for key above");
542 :
543 2 : elektraFree (context);
544 2 : keyDel (registeredKey);
545 2 : PLUGIN_CLOSE ();
546 2 : }
547 :
548 2 : static void test_doUpdateShouldNotUpdateUnregisteredKey (void)
549 : {
550 2 : printf ("test doUpdate should not update unregistered key\n");
551 :
552 2 : KeySet * conf = ksNew (0, KS_END);
553 2 : PLUGIN_OPEN ("internalnotification");
554 :
555 2 : Key * changedKey = keyNew ("user/test/internalnotification/value", KEY_END);
556 :
557 : // No key registration made
558 :
559 2 : ElektraNotificationCallbackContext * context = elektraMalloc (sizeof *context);
560 : context->kdbUpdate = NULL;
561 2 : context->kdbUpdate = test_doUpdate_callback;
562 2 : context->notificationPlugin = plugin;
563 :
564 2 : doUpdate_callback_called = 0;
565 2 : elektraInternalnotificationDoUpdate (changedKey, context);
566 :
567 2 : succeed_if (doUpdate_callback_called == 0, "did call callback for unregistered key");
568 :
569 2 : elektraFree (context);
570 2 : PLUGIN_CLOSE ();
571 2 : }
572 :
573 : // Generate test cases for C built-in types
574 : #define TYPE unsigned int
575 : #define TYPE_NAME UnsignedInt
576 : #define FORMAT_STRING "%u"
577 : #define TEST_VALUE UINT_MAX
578 : #define INVALID_VALUE "-1"
579 : #include "macros/create_type_tests.h"
580 :
581 : #define TYPE long
582 : #define TYPE_NAME Long
583 : #define FORMAT_STRING "%ld"
584 : #define TEST_VALUE LONG_MAX
585 : #define INVALID_VALUE "5000abc000"
586 : #include "macros/create_type_tests.h"
587 :
588 : #define TYPE unsigned long
589 : #define TYPE_NAME UnsignedLong
590 : #define FORMAT_STRING "%lu"
591 : #define TEST_VALUE ULONG_MAX
592 : #define INVALID_VALUE "-446744073715"
593 : #include "macros/create_type_tests.h"
594 :
595 : #define TYPE long long
596 : #define TYPE_NAME LongLong
597 : #define FORMAT_STRING "%lld"
598 : #define TEST_VALUE LLONG_MAX
599 : #define INVALID_VALUE "322337abc6854775807"
600 : #include "macros/create_type_tests.h"
601 :
602 : #define TYPE unsigned long long
603 : #define TYPE_NAME UnsignedLongLong
604 : #define FORMAT_STRING "%llu"
605 : #define TEST_VALUE ULLONG_MAX
606 : #define INVALID_VALUE "-3223372036854775807"
607 : #include "macros/create_type_tests.h"
608 :
609 : #define TYPE float
610 : #define TYPE_NAME Float
611 : #define FORMAT_STRING "%f"
612 : #define TEST_VALUE 2.3
613 : #define CHECK_VALUE (value >= 2.295 && value <= 2.305)
614 : #define INVALID_VALUE "4.a"
615 : #define CHECK_INVALID ((int) value == 0)
616 : #include "macros/create_type_tests.h"
617 :
618 : #define TYPE double
619 : #define TYPE_NAME Double
620 : #define FORMAT_STRING "%1.8f"
621 : #define TEST_VALUE 1.00000001
622 : #define CHECK_VALUE (value >= 1 + 1e-9 && value <= 1 + 1e-7)
623 : #define INVALID_VALUE "4.a"
624 : #define CHECK_INVALID ((int) value == 0)
625 : #include "macros/create_type_tests.h"
626 :
627 : // for kdb_*_t types
628 : #define TYPE kdb_boolean_t
629 : #define TYPE_NAME KdbBoolean
630 : #define FORMAT_STRING "%d"
631 : #define TEST_VALUE 1
632 : #define CHECK_VALUE (value)
633 : #include "macros/create_type_tests.h"
634 :
635 : #define TYPE kdb_char_t
636 : #define TYPE_NAME KdbChar
637 : #define FORMAT_STRING "abc%d"
638 : #define TEST_VALUE 1
639 : #define CHECK_VALUE (value == 'a')
640 : #include "macros/create_type_tests.h"
641 :
642 : #define TYPE kdb_octet_t
643 : #define TYPE_NAME KdbOctet
644 : #define FORMAT_STRING "%d"
645 : #define TEST_VALUE 255
646 : #define INVALID_VALUE "4a"
647 : #include "macros/create_type_tests.h"
648 :
649 : #define TYPE kdb_short_t
650 : #define TYPE_NAME KdbShort
651 : #define FORMAT_STRING "%d"
652 : #define TEST_VALUE SHRT_MIN
653 : #define INVALID_VALUE "-55ABC"
654 : #include "macros/create_type_tests.h"
655 :
656 : #define TYPE kdb_unsigned_short_t
657 : #define TYPE_NAME KdbUnsignedShort
658 : #define FORMAT_STRING "%d"
659 : #define TEST_VALUE USHRT_MAX
660 : #define INVALID_VALUE "-55"
661 : #include "macros/create_type_tests.h"
662 :
663 : #define TYPE kdb_long_t
664 : #define TYPE_NAME KdbLong
665 : #define FORMAT_STRING "%d"
666 : #define TEST_VALUE INT_MIN
667 : #define INVALID_VALUE "B5C"
668 : #include "macros/create_type_tests.h"
669 :
670 : #define TYPE kdb_unsigned_long_t
671 : #define TYPE_NAME KdbUnsignedLong
672 : #define FORMAT_STRING "%u"
673 : #define TEST_VALUE UINT_MAX
674 : #define INVALID_VALUE "-523255"
675 : #include "macros/create_type_tests.h"
676 :
677 : #define TYPE kdb_long_long_t
678 : #define TYPE_NAME KdbLongLong
679 : #define FORMAT_STRING ELEKTRA_LONG_LONG_F
680 : #define TEST_VALUE (kdb_long_long_t) LONG_MAX
681 : #define INVALID_VALUE "50000asasd"
682 : #include "macros/create_type_tests.h"
683 :
684 : #define TYPE kdb_unsigned_long_long_t
685 : #define TYPE_NAME KdbUnsignedLongLong
686 : #define FORMAT_STRING ELEKTRA_UNSIGNED_LONG_LONG_F
687 : #define TEST_VALUE (kdb_unsigned_long_long_t) ULONG_MAX
688 : #define INVALID_VALUE "-5326523652"
689 : #include "macros/create_type_tests.h"
690 :
691 : #define TYPE kdb_float_t
692 : #define TYPE_NAME KdbFloat
693 : #define FORMAT_STRING "%f"
694 : #define TEST_VALUE 2.3
695 : #define CHECK_VALUE (value >= 2.295 && value <= 2.305)
696 : #define INVALID_VALUE "4.a"
697 : #define CHECK_INVALID ((int) value == 0)
698 : #include "macros/create_type_tests.h"
699 :
700 : #define TYPE kdb_double_t
701 : #define TYPE_NAME KdbDouble
702 : #define FORMAT_STRING "%1.8f"
703 : #define TEST_VALUE 1.00000001
704 : #define CHECK_VALUE (value >= 1 + 1e-9 && value <= 1 + 1e-7)
705 : #define INVALID_VALUE "4.a"
706 : #define CHECK_INVALID ((int) value == 0)
707 : #include "macros/create_type_tests.h"
708 :
709 : #define TYPE kdb_long_double_t
710 : #define TYPE_NAME KdbLongDouble
711 : #define FORMAT_STRING "%1.8f"
712 : #define TEST_VALUE 1.00000001
713 : #define CHECK_VALUE (value >= 1 + 1e-9 && value <= 1 + 1e-7)
714 : #define INVALID_VALUE "4.a"
715 : #define CHECK_INVALID ((int) value == 0)
716 : #include "macros/create_type_tests.h"
717 :
718 2 : int main (int argc, char ** argv)
719 : {
720 2 : printf ("INTERNALNOTIFICATION TESTS\n");
721 2 : printf ("==============================\n\n");
722 :
723 2 : init (argc, argv);
724 :
725 2 : test_basics ();
726 2 : test_updateOnKdbGet ();
727 2 : test_updateOnKdbSet ();
728 2 : test_conversionError ();
729 :
730 2 : printf ("\nregisterInt\n-----------\n");
731 2 : test_intUpdateWithCascadingKey ();
732 2 : test_intNoUpdateWithInvalidValue ();
733 2 : test_intUpdateWithValueNotYetExceedingIntMax ();
734 2 : test_intNoUpdateWithValueExceedingIntMax ();
735 2 : test_intUpdateWithValueNotYetExceedingIntMin ();
736 2 : test_intNoUpdateWithValueExceedingIntMin ();
737 :
738 2 : printf ("\nregisterCallback\n----------------\n");
739 2 : test_callbackCalledWithKey ();
740 2 : test_callbackCalledWithChangeDetection ();
741 :
742 2 : RUN_TYPE_TESTS (UnsignedInt)
743 2 : RUN_TYPE_TESTS (Long)
744 2 : RUN_TYPE_TESTS (UnsignedLong)
745 2 : RUN_TYPE_TESTS (LongLong)
746 2 : RUN_TYPE_TESTS (UnsignedLongLong)
747 :
748 2 : RUN_TYPE_TESTS (Float)
749 2 : RUN_TYPE_TESTS (Double)
750 :
751 2 : printf ("\nKdbBoolean\n----------------\n");
752 2 : TEST_CASE_UPDATE_NAME (KdbBoolean) ();
753 :
754 2 : printf ("\nKdbChar\n----------------\n");
755 2 : TEST_CASE_UPDATE_NAME (KdbChar) ();
756 :
757 2 : RUN_TYPE_TESTS (KdbOctet)
758 2 : RUN_TYPE_TESTS (KdbShort)
759 2 : RUN_TYPE_TESTS (KdbUnsignedShort)
760 2 : RUN_TYPE_TESTS (KdbLong)
761 2 : RUN_TYPE_TESTS (KdbUnsignedLong)
762 2 : RUN_TYPE_TESTS (KdbLongLong)
763 2 : RUN_TYPE_TESTS (KdbUnsignedLongLong)
764 2 : RUN_TYPE_TESTS (KdbFloat)
765 2 : RUN_TYPE_TESTS (KdbDouble)
766 2 : RUN_TYPE_TESTS (KdbLongDouble)
767 :
768 2 : printf ("\nelektraInternalnotificationDoUpdate\n-----------------------------------\n");
769 2 : test_doUpdateShouldUpdateKey ();
770 2 : test_doUpdateShouldUpdateKeyBelow ();
771 2 : test_doUpdateShouldNotUpdateKeyAbove ();
772 2 : test_doUpdateShouldNotUpdateUnregisteredKey ();
773 2 : test_doUpdateShouldUpdateKeyAbove ();
774 :
775 2 : print_result ("testmod_internalnotification");
776 :
777 2 : return nbError;
778 : }
|