1 /*
2 * librdkafka - Apache Kafka C library
3 *
4 * Copyright (c) 2012-2015, Magnus Edenhill
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28 #ifndef _TESTSHARED_H_
29 #define _TESTSHARED_H_
30
31 /**
32 * C variables and functions shared with C++ tests
33 */
34
35 typedef struct rd_kafka_s rd_kafka_t;
36
37 /* ANSI color codes */
38 #define _C_CLR "\033[0m"
39 #define _C_RED "\033[31m"
40 #define _C_GRN "\033[32m"
41 #define _C_YEL "\033[33m"
42 #define _C_BLU "\033[34m"
43 #define _C_MAG "\033[35m"
44 #define _C_CYA "\033[36m"
45
46
47 /** Test scenario */
48 extern char test_scenario[64];
49
50 /** @returns the \p msecs timeout multiplied by the test timeout multiplier */
51 extern int tmout_multip (int msecs);
52
53 /** @brief true if tests should run in quick-mode (faster, less data) */
54 extern int test_quick;
55
56 /** @brief Broker version to int */
57 #define TEST_BRKVER(A,B,C,D) \
58 (((A) << 24) | ((B) << 16) | ((C) << 8) | (D))
59 /** @brief return single version component from int */
60 #define TEST_BRKVER_X(V,I) \
61 (((V) >> (24-((I)*8))) & 0xff)
62
63 /** @brief Topic Admin API supported by this broker version and later */
64 #define TEST_BRKVER_TOPIC_ADMINAPI TEST_BRKVER(0,10,2,0)
65
66 extern int test_broker_version;
67 extern int test_on_ci;
68
69 const char *test_mk_topic_name (const char *suffix, int randomized);
70
71 void test_delete_topic (rd_kafka_t *use_rk, const char *topicname);
72
73 void test_create_topic (rd_kafka_t *use_rk, const char *topicname,
74 int partition_cnt, int replication_factor);
75
76 uint64_t
77 test_produce_msgs_easy_size (const char *topic, uint64_t testid,
78 int32_t partition, int msgcnt, size_t size);
79 #define test_produce_msgs_easy(topic,testid,partition,msgcnt) \
80 test_produce_msgs_easy_size(topic,testid,partition,msgcnt,0)
81
82
83 void test_fail0 (const char *file, int line, const char *function,
84 int do_lock, int fail_now, const char *fmt, ...)
85 RD_FORMAT(printf, 6, 7);
86
87
88
89 void test_fail0 (const char *file, int line, const char *function,
90 int do_lock, int fail_now, const char *fmt, ...)
91 RD_FORMAT(printf, 6, 7);
92
93 #define TEST_FAIL0(file,line,do_lock,fail_now,...) \
94 test_fail0(__FILE__, __LINE__, __FUNCTION__, \
95 do_lock, fail_now, __VA_ARGS__)
96
97 /* Whine and abort test */
98 #define TEST_FAIL(...) TEST_FAIL0(__FILE__,__LINE__,1,1,__VA_ARGS__)
99
100 /* Whine right away, mark the test as failed, but continue the test. */
101 #define TEST_FAIL_LATER(...) TEST_FAIL0(__FILE__,__LINE__,1,0,__VA_ARGS__)
102
103 /* Whine right away, maybe mark the test as failed, but continue the test. */
104 #define TEST_FAIL_LATER0(LATER,...) TEST_FAIL0(__FILE__,__LINE__,1,!(LATER),__VA_ARGS__)
105
106 #define TEST_FAILCNT() (test_curr->failcnt)
107
108 #define TEST_LATER_CHECK(...) do { \
109 if (test_curr->state == TEST_FAILED) \
110 TEST_FAIL("See previous errors. " __VA_ARGS__); \
111 } while (0)
112
113 #define TEST_PERROR(call) do { \
114 if (!(call)) \
115 TEST_FAIL(#call " failed: %s", rd_strerror(errno)); \
116 } while (0)
117
118 #define TEST_WARN(...) do { \
119 fprintf(stderr, "\033[33m[%-28s/%7.3fs] WARN: ", \
120 test_curr->name, \
121 test_curr->start ? \
122 ((float)(test_clock() - \
123 test_curr->start)/1000000.0f) : 0); \
124 fprintf(stderr, __VA_ARGS__); \
125 fprintf(stderr, "\033[0m"); \
126 } while (0)
127
128 /* "..." is a failure reason in printf format, include as much info as needed */
129 #define TEST_ASSERT(expr,...) do { \
130 if (!(expr)) { \
131 TEST_FAIL("Test assertion failed: \"" # expr "\": " \
132 __VA_ARGS__); \
133 } \
134 } while (0)
135
136
137 /* "..." is a failure reason in printf format, include as much info as needed */
138 #define TEST_ASSERT_LATER(expr,...) do { \
139 if (!(expr)) { \
140 TEST_FAIL0(__FILE__, __LINE__, 1, 0, \
141 "Test assertion failed: \"" # expr "\": " \
142 __VA_ARGS__); \
143 } \
144 } while (0)
145
146
147 void test_SAY (const char *file, int line, int level, const char *str);
148 void test_SKIP (const char *file, int line, const char *str);
149
150 void test_timeout_set (int timeout);
151 int test_set_special_conf (const char *name, const char *val, int *timeoutp);
152 const char *test_conf_get_path (void);
153 const char *test_getenv (const char *env, const char *def);
154
155 int test_needs_auth (void);
156
157 uint64_t test_id_generate (void);
158 char *test_str_id_generate (char *dest, size_t dest_size);
159 const char *test_str_id_generate_tmp (void);
160
161 void test_prepare_msg (uint64_t testid, int32_t partition, int msg_id,
162 char *val, size_t val_size,
163 char *key, size_t key_size);
164 /**
165 * Parse a message token
166 */
167 void test_msg_parse00 (const char *func, int line,
168 uint64_t testid, int32_t exp_partition, int *msgidp,
169 const char *topic, int32_t partition, int64_t offset,
170 const char *key, size_t key_size);
171
172
173 int test_check_builtin (const char *feature);
174
175 /**
176 * @returns the current test's name (thread-local)
177 */
178 extern const char *test_curr_name (void);
179
180 #ifndef _MSC_VER
181 #include <sys/time.h>
182 #ifndef RD_UNUSED
183 #define RD_UNUSED __attribute__((unused))
184 #endif
185
186 #else
187
188 #define WIN32_LEAN_AND_MEAN
189 #include <Windows.h>
190 #endif
191
192 #ifndef RD_UNUSED
193 #define RD_UNUSED
194 #endif
195
196
197 /**
198 * A microsecond monotonic clock
199 */
200 static RD_INLINE int64_t test_clock (void)
201 #ifndef _MSC_VER
202 __attribute__((unused))
203 #endif
204 ;
test_clock(void)205 static RD_INLINE int64_t test_clock (void) {
206 #ifdef __APPLE__
207 /* No monotonic clock on Darwin */
208 struct timeval tv;
209 gettimeofday(&tv, NULL);
210 return ((int64_t)tv.tv_sec * 1000000LLU) + (int64_t)tv.tv_usec;
211 #elif _MSC_VER
212 LARGE_INTEGER now;
213 static RD_TLS LARGE_INTEGER freq;
214 if (!freq.QuadPart)
215 QueryPerformanceFrequency(&freq);
216 QueryPerformanceCounter(&now);
217 return (now.QuadPart * 1000000) / freq.QuadPart;
218 #else
219 struct timespec ts;
220 clock_gettime(CLOCK_MONOTONIC, &ts);
221 return ((int64_t)ts.tv_sec * 1000000LLU) +
222 ((int64_t)ts.tv_nsec / 1000LLU);
223 #endif
224 }
225
226
227 typedef struct test_timing_s {
228 char name[256];
229 int64_t ts_start;
230 int64_t duration;
231 int64_t ts_every; /* Last every */
232 } test_timing_t;
233
234 /**
235 * @brief Start timing, Va-Argument is textual name (printf format)
236 */
237 #define TIMING_RESTART(TIMING) do { \
238 (TIMING)->ts_start = test_clock(); \
239 (TIMING)->duration = 0; \
240 } while (0)
241
242 #define TIMING_START(TIMING,...) do { \
243 rd_snprintf((TIMING)->name, sizeof((TIMING)->name), __VA_ARGS__); \
244 TIMING_RESTART(TIMING); \
245 (TIMING)->ts_every = (TIMING)->ts_start; \
246 } while (0)
247
248 #define TIMING_STOPPED(TIMING) ((TIMING)->duration != 0)
249
250 #ifndef __cplusplus
251 #define TIMING_STOP(TIMING) do { \
252 (TIMING)->duration = test_clock() - (TIMING)->ts_start; \
253 TEST_SAY("%s: duration %.3fms\n", \
254 (TIMING)->name, (float)(TIMING)->duration / 1000.0f); \
255 } while (0)
256 #define TIMING_REPORT(TIMING) \
257 TEST_SAY("%s: duration %.3fms\n", \
258 (TIMING)->name, (float)(TIMING)->duration / 1000.0f); \
259
260 #else
261 #define TIMING_STOP(TIMING) do { \
262 char _str[512]; \
263 (TIMING)->duration = test_clock() - (TIMING)->ts_start; \
264 rd_snprintf(_str, sizeof(_str), "%s: duration %.3fms\n", \
265 (TIMING)->name, (float)(TIMING)->duration / 1000.0f); \
266 Test::Say(_str); \
267 } while (0)
268
269 #endif
270
271 #define TIMING_DURATION(TIMING) ((TIMING)->duration ? (TIMING)->duration : \
272 (test_clock() - (TIMING)->ts_start))
273
274 #define TIMING_ASSERT0(TIMING,DO_FAIL_LATER,TMIN_MS,TMAX_MS) do { \
275 if (!TIMING_STOPPED(TIMING)) \
276 TIMING_STOP(TIMING); \
277 int _dur_ms = (int)TIMING_DURATION(TIMING) / 1000; \
278 if (TMIN_MS <= _dur_ms && _dur_ms <= TMAX_MS) \
279 break; \
280 if (test_on_ci || strcmp(test_mode, "bare")) \
281 TEST_WARN("%s: expected duration %d <= %d <= %d ms%s\n", \
282 (TIMING)->name, TMIN_MS, _dur_ms, TMAX_MS, \
283 ": not FAILING test on CI"); \
284 else \
285 TEST_FAIL_LATER0(DO_FAIL_LATER, \
286 "%s: expected duration %d <= %d <= %d ms", \
287 (TIMING)->name, TMIN_MS, _dur_ms, TMAX_MS); \
288 } while (0)
289
290 #define TIMING_ASSERT(TIMING,TMIN_MS,TMAX_MS) \
291 TIMING_ASSERT0(TIMING,0,TMIN_MS,TMAX_MS)
292 #define TIMING_ASSERT_LATER(TIMING,TMIN_MS,TMAX_MS) \
293 TIMING_ASSERT0(TIMING,1,TMIN_MS,TMAX_MS)
294
295 /* Trigger something every US microseconds. */
TIMING_EVERY(test_timing_t * timing,int us)296 static RD_UNUSED int TIMING_EVERY (test_timing_t *timing, int us) {
297 int64_t now = test_clock();
298 if (timing->ts_every + us <= now) {
299 timing->ts_every = now;
300 return 1;
301 }
302 return 0;
303 }
304
305
306 #ifndef _MSC_VER
307 #define rd_sleep(S) sleep(S)
308 #else
309 #define rd_sleep(S) Sleep((S)*1000)
310 #endif
311
312 /* Make sure __SANITIZE_ADDRESS__ (gcc) is defined if compiled with asan */
313 #if !defined(__SANITIZE_ADDRESS__) && defined(__has_feature)
314 #if __has_feature(address_sanitizer)
315 #define __SANITIZE_ADDRESS__ 1
316 #endif
317 #endif
318
319
320 int test_run_java (const char *cls, const char **argv);
321 int test_waitpid (int pid);
322 #endif /* _TESTSHARED_H_ */
323