1
#ifndef TEST_UTIL_COMMON_H
2
#define TEST_UTIL_COMMON_H
8
#include <nih-dbus/test_dbus.h>
10
#define BUFFER_SIZE 1024
13
* TEST_QUIESCE_WAIT_PHASE:
15
* Maximum time we expect upstart to wait in the QUIESCE_PHASE_WAIT
18
#define TEST_EXIT_TIME 5
21
* TEST_QUIESCE_KILL_PHASE:
23
* Maximum time we expect upstart to wait in the QUIESCE_PHASE_KILL
26
#define TEST_QUIESCE_KILL_PHASE 5
28
#define TEST_QUIESCE_TOTAL_WAIT_TIME (TEST_EXIT_TIME + TEST_QUIESCE_KILL_PHASE)
30
/* A 'reasonable' path, but which also contains a marker at the end so
31
* we know when we're looking at a PATH these tests have set.
33
#define TEST_INITCTL_DEFAULT_PATH "/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/wibble"
35
/* Default value for TERM if not already set */
36
#define TEST_INITCTL_DEFAULT_TERM "linux"
39
/* TEST_ENSURE_CLEAN_ENV:
41
* Ensure the environment is as pristine as possible (to avoid follow-on
42
* errors caused by not freeing objects in a previous test, say)
44
#define TEST_ENSURE_CLEAN_ENV() \
46
setvbuf(stdout, NULL, _IONBF, 0); \
49
TEST_HASH_EMPTY (job_classes); \
53
TEST_LIST_EMPTY (conf_sources); \
56
if (nih_io_watches) { \
57
TEST_LIST_EMPTY (nih_io_watches); \
61
TEST_LIST_EMPTY (nih_timers); \
65
TEST_LIST_EMPTY (events); \
71
* @force: if TRUE, force an update,
72
* @timeout: struct timeval pointer, or NULL if no timeout required.
74
* Request NIH look for a file event relating to any NihIo objects,
75
* with an optional timeout. Behaviour can be forced via @force.
77
#define _TEST_WATCH_UPDATE(force, timeout) \
81
fd_set readfds, writefds, exceptfds; \
84
FD_ZERO (&writefds); \
85
FD_ZERO (&exceptfds); \
87
nih_io_select_fds (&nfds, &readfds, &writefds, &exceptfds); \
89
ret = select (nfds, &readfds, &writefds, \
90
&exceptfds, timeout); \
92
if (force || ret > 0) \
93
nih_io_handle_fds (&readfds, &writefds, &exceptfds); \
99
* Request NIH look for a file event relating to any NihIo objects,
101
#define TEST_WATCH_UPDATE() \
102
_TEST_WATCH_UPDATE (0, NULL)
105
* TEST_WATCH_UPDATE_TIMEOUT:
106
* @timeout: struct timeval pointer.
108
* Request NIH look for a file event relating to any NihIo objects
109
* within time period @timeout.
111
#define TEST_WATCH_UPDATE_TIMEOUT(timeout) \
112
_TEST_WATCH_UPDATE (0, timeout)
115
* TEST_WATCH_UPDATE_TIMEOUT_SECS:
116
* @secs: seconds to wait before timeout.
118
* Request NIH look for a file event relating to any NihIo objects
119
* within @secs timeout.
121
#define TEST_WATCH_UPDATE_TIMEOUT_SECS(secs) \
126
_TEST_WATCH_UPDATE (0, &_t); \
130
* TEST_FORCE_WATCH_UPDATE:
132
* Force NIH to look for a file event relating to any NihIo objects.
134
#define TEST_FORCE_WATCH_UPDATE() \
135
_TEST_WATCH_UPDATE (1, NULL)
138
* TEST_FORCE_WATCH_UPDATE_TIMEOUT:
139
* @timeout: struct timeval pointer.
141
* Force NIH to look for a file event relating to any NihIo objects
142
* within time period @timeout.
144
#define TEST_FORCE_WATCH_UPDATE_TIMEOUT(timeout) \
145
_TEST_WATCH_UPDATE (1, timeout)
148
* TEST_FORCE_WATCH_UPDATE_TIMEOUT_SECS:
149
* @timeout: struct timeval pointer.
151
* Force NIH to look for a file event relating to any NihIo objects
152
* within time period @timeout.
154
#define TEST_FORCE_WATCH_UPDATE_TIMEOUT_SECS(secs) \
159
_TEST_WATCH_UPDATE (1, &_t); \
163
* ENSURE_DIRECTORY_EMPTY:
164
* @path: Full path to a directory.
166
* Ensure specified directory is empty.
168
#define ENSURE_DIRECTORY_EMPTY(path) \
171
struct dirent *file = NULL; \
174
dp = opendir (path); \
175
TEST_NE_P (dp, NULL); \
177
while((file = readdir (dp))) { \
178
if (!strcmp (".", file->d_name) || \
179
!strcmp ("..", file->d_name)) \
186
TEST_EQ (count, 0); \
194
* @name: name of string element.
196
* Compare string element @name in objects @a and @b.
198
* Returns: 0 if strings are identical
199
* (or both NULL), else 1.
201
#define obj_string_check(a, b, name) \
202
string_check ((a)->name, (b)->name)
209
* @name: name of numeric element.
211
* Compare numeric element @name in objects @a and @b.
213
* Returns: 0 if @a and @b are identical, else 1.
215
#define obj_num_check(a, b, name) \
219
* TEST_CMP_INT_ARRAYS:
222
* @sizea: size of @a,
223
* @sizeb: size of @b.
225
* Compare integer arrays @a and @b for equivalence.
227
* Returns: 0 if arrays are identical, else -1.
229
#define TEST_CMP_INT_ARRAYS(a, b, sizea, sizeb) \
232
if (sizea == sizeb) { \
236
if ((a)[__i] != (b)[__i]) { \
246
* TEST_CMP_STR_ARRAYS:
247
* @a: first string array,
248
* @b: second string array,
249
* @sizea: length of @a,
250
* @sizeb: length of @b.
252
* Compare string arrays @a and @b for equivalence.
254
* Returns: 0 if arrays are identical, else -1.
256
#define TEST_CMP_STR_ARRAYS(a, b, sizea, sizeb) \
258
if (sizea == sizeb) { \
259
for (size_t __i = 0; \
262
if (strcmp (a[__i], b[__i])) { \
272
* TEST_TWO_LISTS_FOREACH:
273
* @list1: entry in the first list to iterate,
274
* @list2: entry in the second list to iterate,
275
* @iter1: name of iterator variable for @list1,
276
* @iter2: name of iterator variable for @list2.
278
* Dual version of NIH_LIST_FOREACH() which iterates
279
* two lists in tandem.
281
#define TEST_TWO_LISTS_FOREACH(list1, list2, iter1, iter2) \
282
for (NihList *iter1 = (list1)->next, \
283
*iter2 = (list2)->next; \
284
iter1 != (list1) && iter2 != (list2); \
285
iter1 = iter1->next, \
289
* TEST_TWO_HASHES_FOREACH:
290
* @hash1: entry in the first hash to iterate,
291
* @hash2: entry in the second hash to iterate,
292
* @iter1: name of iterator variable for @hash1,
293
* @iter2: name of iterator variable for @hash2.
295
* Dual version of NIH_HASH_FOREACH() which iterates
296
* two hashes in tandem.
298
#define TEST_TWO_HASHES_FOREACH(hash1, hash2, iter1, iter2) \
299
for (size_t _##iter##_i = 0; _##iter##_i < (hash1)->size; \
301
TEST_TWO_LISTS_FOREACH (&(hash1)->bins[_##iter##_i], \
302
&(hash2)->bins[_##iter##_i], \
306
* TEST_TWO_TREES_FOREACH:
307
* @tree1: root of the first tree to iterate,
308
* @tree2: root of the second tree to iterate,
309
* @iter1: name of iterator variable for @tree1,
310
* @iter2: name of iterator variable for @tree2.
312
* Dual version of NIH_TREE_FOREACH() which walks
313
* two trees in tandem.
315
#define TEST_TWO_TREES_FOREACH(tree1, tree2, iter1, iter2) \
316
for (NihTree *iter1 = nih_tree_next (tree1, NULL), \
317
*iter2 = nih_tree_next (tree2, NULL); \
318
iter1 != NULL && iter2 != NULL; \
319
iter1 = nih_tree_next (tree1, iter1), \
320
iter2 = nih_tree_next (tree2, iter2))
327
* Determine size of specified array.
329
* Returns: array size.
331
#define TEST_ARRAY_SIZE(array) \
332
(sizeof (array) / sizeof (array[0]))
337
* @pid: pid_t that will contain pid of running instance on success,
338
* @user_mode: TRUE for Session Init (or FALSE to use D-Bus
341
* Start an instance of Upstart and return PID in @pid.
343
#define START_UPSTART(pid, user_mode) \
344
start_upstart_common (&(pid), user_mode, NULL, NULL, NULL)
349
* @pid: pid of upstart to kill,
350
* @signo: signal number to send to @pid,
351
* @wait: TRUE to wait for @pid to die.
353
* Send specified signal to upstart process @pid.
355
#define KILL_UPSTART(pid, signo, wait) \
361
assert0 (kill (pid, signo)); \
363
TEST_EQ (waitpid (pid, &status, 0), pid); \
364
TEST_TRUE (WIFSIGNALED (status)); \
365
TEST_TRUE (WTERMSIG (status) == signo); \
367
/* reset since a subsequent start could specify a different \
370
test_user_mode = FALSE; \
376
* @pid: pid of upstart to kill.
378
* Stop upstart process @pid.
380
#define STOP_UPSTART(pid) \
381
KILL_UPSTART (pid, SIGKILL, TRUE)
386
* @pid: pid of upstart,
387
* @user: TRUE if @pid refers to a Session Init, else FALSE.
389
* Force upstart to perform a re-exec.
391
#define REEXEC_UPSTART(pid, user) \
392
KILL_UPSTART (pid, SIGTERM, FALSE); \
393
wait_for_upstart (user ? pid : FALSE)
398
* @parent: pointer to parent object,
399
* @cmd: string representing command to run,
400
* @result: "char ***" pointer which will contain an array of string
401
* values corresponding to lines of standard output generated by @cmd,
402
* @len: size_t pointer which will be set to length of @result.
404
* Run a command and return its standard output. It is the callers
405
* responsibility to free @result. Errors from running @cmd are fatal.
407
* Note: trailing '\n' characters are removed in returned command
410
#define RUN_COMMAND(parent, cmd, result, len) \
413
char buffer[BUFFER_SIZE]; \
418
*(result) = nih_str_array_new (parent); \
419
TEST_NE_P (*result, NULL); \
422
f = popen (cmd, "r"); \
423
TEST_NE_P (f, NULL); \
425
while (fgets (buffer, BUFFER_SIZE, f)) { \
426
size_t l = strlen (buffer)-1; \
428
if ( buffer[l] == '\n') \
430
ret = nih_str_array_add (result, parent, len, \
432
TEST_NE_P (ret, NULL); \
435
TEST_NE (pclose (f), -1); \
441
* @dirname: directory name (assumed to already exist),
442
* @name: name of file to create (no leading slash),
443
* @contents: string contents of @name.
445
* Create a file in the specified directory with the specified
448
* Notes: A newline character is added in the case where @contents does
451
#define CREATE_FILE(dirname, name, contents) \
454
char filename[PATH_MAX]; \
456
assert (dirname[0]); \
459
strcpy (filename, dirname); \
460
if ( name[0] != '/' ) \
461
strcat (filename, "/"); \
462
strcat (filename, name); \
463
f = fopen (filename, "w"); \
464
TEST_NE_P (f, NULL); \
465
fprintf (f, "%s", contents); \
466
if ( contents[strlen(contents)-1] != '\n') \
474
* @dirname: directory in which file to delete exists,
475
* @name: name of file in @dirname to delete.
477
* Delete specified file.
480
#define DELETE_FILE(dirname, name) \
482
char filename[PATH_MAX]; \
484
assert (dirname[0]); \
487
strcpy (filename, dirname); \
488
if ( name[0] != '/' ) \
489
strcat (filename, "/"); \
490
strcat (filename, name); \
492
TEST_EQ (unlink (filename), 0); \
498
* @path: full path to file to look for,
499
* @sleep_secs: number of seconds to sleep per loop,
500
* @loops: number of times to check for file.
502
* Wait for a reasonable period of time for @path to be created.
504
* Abort if file does not appear within (sleep_secs * loops) seconds.
506
* XXX:WARNING: this is intrinsically racy since although the file has
507
* been _created_, it has not necessarily been fully written at the
508
* point this macro signifies success. For that we need inotify or
511
#define _WAIT_FOR_FILE(path, sleep_secs, loops) \
514
struct stat statbuf; \
518
/* Wait for log to be created */ \
520
for (int i = 0; i < loops; i++) { \
521
sleep (sleep_secs); \
522
if (! stat (logfile, &statbuf)) { \
527
TEST_EQ (ok, TRUE); \
533
* @path: full path to file to look for.
535
* Wait for a "reasonable period of time" for @path to be created.
537
* Abort if file does not appear within.
539
#define WAIT_FOR_FILE(path) \
540
_WAIT_FOR_FILE (path, 1, 5)
544
* @_string: string to check,
545
* @_pattern: pattern to expect.
547
* Check that @_string matches the glob pattern @_pattern, which
548
* should include the terminating newline if one is expected.
550
* Notes: Analagous to TEST_FILE_MATCH().
552
#define TEST_STR_MATCH(_string, _pattern) \
554
if (fnmatch ((_pattern), _string, 0)) \
555
TEST_FAILED ("wrong string value, " \
556
"expected '%s' got '%s'", \
557
(_pattern), _string); \
561
* _TEST_STR_ARRAY_CONTAINS:
563
* @_array: string array,
564
* @_pattern: pattern to expect,
565
* @_invert: invert meaning.
567
* Check that atleast 1 element in @_array matches @_pattern.
569
* If @_invert is TRUE, ensure @_pattern is _NOT_ found in @_array.
571
#define _TEST_STR_ARRAY_CONTAINS(_array, _pattern, _invert) \
576
for (p = _array; p && *p; p++) { \
578
if (! fnmatch ((_pattern), *p, 0)) { \
586
TEST_FAILED ("wrong content in array " \
587
"%p (%s), '%s' found unexpectedly", \
588
(_array), #_array, (_pattern)); \
592
TEST_FAILED ("wrong content in array " \
593
"%p (%s), '%s' not found", \
594
(_array), #_array, (_pattern)); \
600
* _TEST_FILE_CONTAINS:
601
* @_file: FILE to read from,
602
* @_pattern: pattern to expect,
603
* @_invert: invert meaning.
605
* Check that any subsequent line in file @_file matches the glob pattern
606
* @_pattern, which should include the terminating newline if one is expected.
608
* If @_invert is TRUE, ensure @_pattern is _NOT_ found in @_file.
610
#define _TEST_FILE_CONTAINS(_file, _pattern, _invert) \
615
while (fgets (buffer, sizeof (buffer), _file)) { \
617
ret = fnmatch ((_pattern), buffer, 0); \
627
TEST_FAILED ("wrong content in file " \
628
"%p (%s), '%s' found unexpectedly", \
629
(_file), #_file, (_pattern)); \
633
TEST_FAILED ("wrong content in file " \
634
"%p (%s), '%s' not found", \
635
(_file), #_file, (_pattern)); \
642
* TEST_FILE_CONTAINS:
643
* @_file: FILE to read from,
644
* @_pattern: pattern to expect.
646
* Check that any subsequent line in file @_file matches the glob pattern
647
* @_pattern, which should include the terminating newline if one is expected.
650
#define TEST_FILE_CONTAINS(_file, _pattern) \
651
_TEST_FILE_CONTAINS(_file, _pattern, FALSE)
654
* TEST_FILE_NOT_CONTAINS:
655
* @_file: FILE to read from,
656
* @_pattern: pattern NOT to expect.
658
* Check that no subsequent line in file @_file does NOT match the glob pattern
659
* @_pattern, which should include the terminating newline if one is expected.
662
#define TEST_FILE_NOT_CONTAINS(_file, _pattern) \
663
_TEST_FILE_CONTAINS(_file, _pattern, TRUE)
666
* TEST_STR_ARRAY_CONTAINS:
668
* @_array: string array,
669
* @_pattern: pattern to expect.
671
* Check that atleast 1 element in @_array matches @_pattern.
673
#define TEST_STR_ARRAY_CONTAINS(_array, _pattern) \
674
_TEST_STR_ARRAY_CONTAINS (_array, _pattern, FALSE)
677
* TEST_STR_ARRAY_NOT_CONTAINS:
679
* @_array: string array,
680
* @_pattern: pattern to expect.
682
* Check that no element in @_array matches @_pattern.
684
#define TEST_STR_ARRAY_NOT_CONTAINS(_array, _pattern) \
685
_TEST_STR_ARRAY_CONTAINS (_array, _pattern, TRUE)
687
extern int test_user_mode;
690
int set_upstart_session (pid_t session_init_pid)
691
__attribute__ ((warn_unused_result));
693
void wait_for_upstart (int session_init_pid);
695
pid_t timed_waitpid (pid_t pid, time_t timeout)
696
__attribute__ ((warn_unused_result));
698
char * get_initctl (void)
699
__attribute__ ((warn_unused_result));
701
void _start_upstart (pid_t *pid, int user, char * const *args);
703
void start_upstart_common (pid_t *pid, int user, const char *confdir,
704
const char *logdir, char * const *extra);
706
void start_upstart (pid_t *pid);
708
pid_t job_to_pid (const char *job)
709
__attribute__ ((warn_unused_result));
711
int string_check (const char *a, const char *b)
712
__attribute__ ((warn_unused_result));
714
const char * get_upstart_binary (void)
715
__attribute__ ((warn_unused_result));
717
const char * get_initctl_binary (void)
718
__attribute__ ((warn_unused_result));
720
int strcmp_compar (const void *a, const void *b)
721
__attribute__ ((warn_unused_result));
723
char *get_session_file (const char *xdg_runtime_dir, pid_t pid)
724
__attribute__ ((warn_unused_result));
727
__attribute__ ((warn_unused_result));
729
int dbus_configured (void)
730
__attribute__ ((warn_unused_result));
732
char *search_and_replace (void *parent, const char *str,
733
const char *from, const char *to)
734
__attribute__ ((warn_unused_result));
736
#endif /* TEST_UTIL_COMMON_H */