1/*
2 * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef _UNIT_TEST_UTILS_H
6#define _UNIT_TEST_UTILS_H
7
8static timespec*
9absolute_timeout(timespec& timeout, bigtime_t relativeTimeout)
10{
11	timeval tv;
12	gettimeofday(&tv, NULL);
13	timeout.tv_sec = tv.tv_sec + relativeTimeout / 1000000;
14	timeout.tv_nsec = (tv.tv_usec + relativeTimeout % 1000000) * 1000;
15	if (timeout.tv_nsec > 1000000000) {
16		timeout.tv_sec++;
17		timeout.tv_nsec -= 1000000000;
18	}
19
20	return &timeout;
21}
22
23
24template<typename Type>
25static void
26_assert_equals(const char* test, const Type& expected, const Type& actual,
27	int lineNumber)
28{
29	if (actual == expected)
30		return;
31
32	fprintf(stderr, "%s FAILED in line %d\n", test, lineNumber);
33	exit(1);
34}
35
36
37template<typename Type>
38static void
39_assert_equals_not(const char* test, const Type& unexpected, const Type& actual,
40	int lineNumber)
41{
42	if (actual != unexpected)
43		return;
44
45	fprintf(stderr, "%s FAILED in line %d\n", test, lineNumber);
46	exit(1);
47}
48
49
50static void
51_assert_time_equals(const char* test, bigtime_t expected,
52	bigtime_t actual, int lineNumber)
53{
54	// allow 5% deviation
55	bigtime_t diff = actual > expected ? actual - expected : expected - actual;
56	if (diff <= expected / 20)
57		return;
58
59	fprintf(stderr, "%s FAILED in line %d: expected time: %lld, actual: %lld\n",
60		test, lineNumber, (long long)expected, (long long)actual);
61	exit(1);
62}
63
64
65static void
66_assert_posix_bool_success(const char* test, bool success, int lineNumber)
67{
68	if (success)
69		return;
70
71	fprintf(stderr, "%s FAILED in line %d: %s\n", test, lineNumber,
72		strerror(errno));
73	exit(1);
74}
75
76
77static void
78_assert_posix_bool_error(const char* test, int expectedError, bool success,
79	int lineNumber)
80{
81	if (success) {
82		fprintf(stderr, "%s FAILED in line %d: call succeeded unexpectedly\n",
83			test, lineNumber);
84		exit(1);
85	}
86
87	if (errno != expectedError) {
88		fprintf(stderr, "%s FAILED in line %d: call set unexpected error "
89			"code \"%s\" (0x%x), expected: \"%s\" (0x%x)\n", test, lineNumber,
90			strerror(errno), errno, strerror(expectedError), expectedError);
91		exit(1);
92	}
93}
94
95
96static void
97test_set(const char* testSet)
98{
99	printf("\nTEST SET: %s\n", testSet);
100}
101
102
103static void
104test_ok(const char* test)
105{
106	if (test != NULL)
107		printf("%s OK\n", test);
108}
109
110
111static void
112_wait_for_child(const char* test, pid_t child, int lineNumber)
113{
114	int status;
115	pid_t result = wait(&status);
116	_assert_posix_bool_success(test, result >= 0, lineNumber);
117	_assert_equals(test, child, result, lineNumber);
118	_assert_equals(test, 0, status, lineNumber);
119}
120
121
122#define TEST_SET(testSet)	test_set(testSet)
123#define TEST(test)	test_ok(currentTest); currentTest = (test)
124
125#define assert_equals(expected, actual) \
126	_assert_equals(currentTest, (expected), (actual), __LINE__)
127
128#define assert_equals_not(expected, actual) \
129	_assert_equals_not(currentTest, (expected), (actual), __LINE__)
130
131#define assert_time_equals(expected, actual) \
132	_assert_time_equals(currentTest, (expected), (actual), __LINE__)
133
134#define assert_posix_bool_success(success) \
135	_assert_posix_bool_success(currentTest, (success), __LINE__)
136
137#define assert_posix_success(result) \
138	_assert_posix_bool_success(currentTest, (result) == 0, __LINE__)
139
140#define assert_posix_bool_error(expectedError, success) \
141	_assert_posix_bool_error(currentTest, (expectedError), (success), __LINE__)
142
143#define assert_posix_error(expectedError, result) \
144	_assert_posix_bool_error(currentTest, (expectedError), (result) == 0, \
145		__LINE__)
146
147#define wait_for_child(child) \
148	_wait_for_child(currentTest, (child), __LINE__)
149
150#endif // _UNIT_TEST_UTILS_H
151