]> git.saurik.com Git - apple/libdispatch.git/blob - testing/dispatch_test.c
libdispatch-84.5.3.tar.gz
[apple/libdispatch.git] / testing / dispatch_test.c
1 #include <stdarg.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <unistd.h>
5 #include <errno.h>
6 #include <sys/errno.h>
7 #include <string.h>
8
9 #include "dispatch_test.h"
10
11 #define _test_print(_file, _line, _desc, \
12 _expr, _fmt1, _val1, _fmt2, _val2) do { \
13 const char* _exprstr = _expr ? "PASS" : "FAIL"; \
14 char _linestr[BUFSIZ]; \
15 if (!_expr) { \
16 snprintf(_linestr, sizeof(_linestr), \
17 " (%s:%ld)", _file, _line); \
18 } else { \
19 _linestr[0] = 0; \
20 } \
21 if (_fmt2 == 0) { \
22 printf("\tValue: " _fmt1 "\n" \
23 "[%s] %s%s\n", \
24 _val1, \
25 _exprstr, \
26 _desc, \
27 _linestr); \
28 } else { \
29 printf("\tActual: " _fmt1 "\n" \
30 "\tExpected: " _fmt2 "\n" \
31 "[%s] %s%s\n", \
32 _val1, \
33 _val2, \
34 _exprstr, \
35 _desc, \
36 _linestr); \
37 } \
38 if (!_expr) { \
39 printf("\t%s:%ld\n", _file, _line); \
40 } \
41 fflush(stdout); \
42 } while (0);
43
44 void
45 test_start(const char* desc) {
46 printf("\n==================================================\n");
47 printf("[TEST] %s\n", desc);
48 printf("[PID] %d\n", getpid());
49 printf("==================================================\n\n");
50 usleep(100000); // give 'gdb --waitfor=' a chance to find this proc
51 }
52
53 #define test_ptr_null(a,b) _test_ptr_null(__FILE__, __LINE__, a, b)
54 void
55 _test_ptr_null(const char* file, long line, const char* desc, const void* ptr) {
56 _test_print(file, line, desc,
57 (ptr == NULL), "%p", ptr, "%p", (void*)0);
58 }
59
60 #define test_ptr_notnull(a,b) _test_ptr_notnull(__FILE__, __LINE__, a, b)
61 void
62 _test_ptr_notnull(const char* file, long line, const char* desc, const void* ptr) {
63 _test_print(file, line, desc,
64 (ptr != NULL), "%p", ptr, "%p", ptr ?: (void*)~0);
65 }
66
67 #define test_ptr(a,b,c) _test_ptr(__FILE__, __LINE__, a, b, c)
68 void
69 _test_ptr(const char* file, long line, const char* desc, const void* actual, const void* expected) {
70 _test_print(file, line, desc,
71 (actual == expected), "%p", actual, "%p", expected);
72 }
73
74 #define test_long(a,b,c) _test_long(__FILE__, __LINE__, a, b, c)
75 void
76 _test_long(const char* file, long line, const char* desc, long actual, long expected) {
77 _test_print(file, line, desc,
78 (actual == expected), "%ld", actual, "%ld", expected);
79 }
80
81 #define test_long_less_than(a, b, c) _test_long_less_than(__FILE__, __LINE__, a, b, c)
82 void
83 _test_long_less_than(const char* file, long line, const char* desc, long actual, long expected_max) {
84 _test_print(file, line, desc, (actual < expected_max), "%ld", actual, "<%ld", expected_max);
85 }
86
87 #define test_double_less_than(d, v, m) _test_double_less_than(__FILE__, __LINE__, d, v, m)
88 void
89 _test_double_less_than(const char* file, long line, const char* desc, double val, double max_expected) {
90 _test_print(file, line, desc, (val < max_expected), "%f", val, "<%f", max_expected);
91 }
92
93 #define test_double_less_than_or_equal(d, v, m) _test_double_less_than(__FILE__, __LINE__, d, v, m)
94 void
95 _test_double_less_than_or_equal(const char* file, long line, const char* desc, double val, double max_expected) {
96 _test_print(file, line, desc, (val <= max_expected), "%f", val, "<%f", max_expected);
97 }
98
99 #define test_errno(a,b,c) _test_errno(__FILE__, __LINE__, a, b, c)
100 void
101 _test_errno(const char* file, long line, const char* desc, long actual, long expected) {
102 char* actual_str;
103 char* expected_str;
104 asprintf(&actual_str, "%ld\t%s", actual, actual ? strerror(actual) : "");
105 asprintf(&expected_str, "%ld\t%s", expected, expected ? strerror(expected) : "");
106 _test_print(file, line, desc,
107 (actual == expected), "%s", actual_str, "%s", expected_str);
108 free(actual_str);
109 free(expected_str);
110 }
111
112 #include <spawn.h>
113
114 extern char **environ;
115
116 void
117 test_stop(void) {
118 test_stop_after_delay((void *)(intptr_t)0);
119 }
120
121 void
122 test_stop_after_delay(void *delay) {
123 int res;
124 pid_t pid;
125 char pidstr[10];
126
127 if (delay != NULL) {
128 sleep((int)(intptr_t)delay);
129 }
130
131 if (getenv("NOLEAKS")) _exit(EXIT_SUCCESS);
132
133 /* leaks doesn't work against debug variant malloc */
134 if (getenv("DYLD_IMAGE_SUFFIX")) _exit(EXIT_SUCCESS);
135
136 snprintf(pidstr, sizeof(pidstr), "%d", getpid());
137 char* args[] = { "./leaks-wrapper", pidstr, NULL };
138 res = posix_spawnp(&pid, args[0], NULL, NULL, args, environ);
139 if (res == 0 && pid > 0) {
140 int status;
141 waitpid(pid, &status, 0);
142 test_long("Leaks", status, 0);
143 } else {
144 perror(args[0]);
145 }
146
147 _exit(EXIT_SUCCESS);
148 }