test.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  1. #ifndef HEADER_CURL_TEST_H
  2. #define HEADER_CURL_TEST_H
  3. /***************************************************************************
  4. * _ _ ____ _
  5. * Project ___| | | | _ \| |
  6. * / __| | | | |_) | |
  7. * | (__| |_| | _ <| |___
  8. * \___|\___/|_| \_\_____|
  9. *
  10. * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
  11. *
  12. * This software is licensed as described in the file COPYING, which
  13. * you should have received as part of this distribution. The terms
  14. * are also available at https://curl.se/docs/copyright.html.
  15. *
  16. * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  17. * copies of the Software, and permit persons to whom the Software is
  18. * furnished to do so, under the terms of the COPYING file.
  19. *
  20. * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
  21. * KIND, either express or implied.
  22. *
  23. * SPDX-License-Identifier: curl
  24. *
  25. ***************************************************************************/
  26. /* Now include the curl_setup.h file from libcurl's private libdir (the source
  27. version, but that might include "curl_config.h" from the build dir so we
  28. need both of them in the include path), so that we get good in-depth
  29. knowledge about the system we're building this on */
  30. #define CURL_NO_OLDIES
  31. #include "curl_setup.h"
  32. #include <curl/curl.h>
  33. #ifdef HAVE_SYS_SELECT_H
  34. /* since so many tests use select(), we can just as well include it here */
  35. #include <sys/select.h>
  36. #elif defined(HAVE_UNISTD_H)
  37. #include <unistd.h>
  38. #endif
  39. #include "curl_printf.h"
  40. #ifdef _WIN32
  41. #define sleep(sec) Sleep ((sec)*1000)
  42. #endif
  43. #define test_setopt(A,B,C) \
  44. if((res = curl_easy_setopt((A), (B), (C))) != CURLE_OK) \
  45. goto test_cleanup
  46. #define test_multi_setopt(A,B,C) \
  47. if((res = curl_multi_setopt((A), (B), (C))) != CURLE_OK) \
  48. goto test_cleanup
  49. extern char *libtest_arg2; /* set by first.c to the argv[2] or NULL */
  50. extern char *libtest_arg3; /* set by first.c to the argv[3] or NULL */
  51. /* argc and argv as passed in to the main() function */
  52. extern int test_argc;
  53. extern char **test_argv;
  54. extern struct timeval tv_test_start; /* for test timing */
  55. extern int select_wrapper(int nfds, fd_set *rd, fd_set *wr, fd_set *exc,
  56. struct timeval *tv);
  57. extern void wait_ms(int ms); /* wait this many milliseconds */
  58. #ifndef CURLTESTS_BUNDLED_TEST_H
  59. extern CURLcode test(char *URL); /* the actual test function provided by each
  60. individual libXXX.c file */
  61. #endif
  62. extern char *hexdump(const unsigned char *buffer, size_t len);
  63. extern int unitfail;
  64. /*
  65. ** TEST_ERR_* values must be greater than CURL_LAST CURLcode in order
  66. ** to avoid confusion with any CURLcode or CURLMcode. These TEST_ERR_*
  67. ** codes are returned to signal test specific situations and should
  68. ** not get mixed with CURLcode or CURLMcode values.
  69. **
  70. ** For portability reasons TEST_ERR_* values should be less than 127.
  71. */
  72. #define TEST_ERR_MAJOR_BAD (CURLcode) 126
  73. #define TEST_ERR_RUNS_FOREVER (CURLcode) 125
  74. #define TEST_ERR_EASY_INIT (CURLcode) 124
  75. #define TEST_ERR_MULTI (CURLcode) 123
  76. #define TEST_ERR_NUM_HANDLES (CURLcode) 122
  77. #define TEST_ERR_SELECT (CURLcode) 121
  78. #define TEST_ERR_SUCCESS (CURLcode) 120
  79. #define TEST_ERR_FAILURE (CURLcode) 119
  80. #define TEST_ERR_USAGE (CURLcode) 118
  81. #define TEST_ERR_FOPEN (CURLcode) 117
  82. #define TEST_ERR_FSTAT (CURLcode) 116
  83. #define TEST_ERR_BAD_TIMEOUT (CURLcode) 115
  84. /*
  85. ** Macros for test source code readability/maintainability.
  86. **
  87. ** All of the following macros require that an int data type 'res' variable
  88. ** exists in scope where macro is used, and that it has been initialized to
  89. ** zero before the macro is used.
  90. **
  91. ** exe_* and chk_* macros are helper macros not intended to be used from
  92. ** outside of this header file. Arguments 'Y' and 'Z' of these represent
  93. ** source code file and line number, while Arguments 'A', 'B', etc, are
  94. ** the arguments used to actually call a libcurl function.
  95. **
  96. ** All easy_* and multi_* macros call a libcurl function and evaluate if
  97. ** the function has succeeded or failed. When the function succeeds 'res'
  98. ** variable is not set nor cleared and program continues normal flow. On
  99. ** the other hand if function fails 'res' variable is set and a jump to
  100. ** label 'test_cleanup' is performed.
  101. **
  102. ** Every easy_* and multi_* macros have a res_easy_* and res_multi_* macro
  103. ** counterpart that operates in the same way with the exception that no
  104. ** jump takes place in case of failure. res_easy_* and res_multi_* macros
  105. ** should be immediately followed by checking if 'res' variable has been
  106. ** set.
  107. **
  108. ** 'res' variable when set will hold a CURLcode, CURLMcode, or any of the
  109. ** TEST_ERR_* values defined above. It is advisable to return this value
  110. ** as test result.
  111. */
  112. /* ---------------------------------------------------------------- */
  113. #define exe_easy_init(A,Y,Z) do { \
  114. if(((A) = curl_easy_init()) == NULL) { \
  115. fprintf(stderr, "%s:%d curl_easy_init() failed\n", (Y), (Z)); \
  116. res = TEST_ERR_EASY_INIT; \
  117. } \
  118. } while(0)
  119. #define res_easy_init(A) \
  120. exe_easy_init((A), (__FILE__), (__LINE__))
  121. #define chk_easy_init(A,Y,Z) do { \
  122. exe_easy_init((A), (Y), (Z)); \
  123. if(res) \
  124. goto test_cleanup; \
  125. } while(0)
  126. #define easy_init(A) \
  127. chk_easy_init((A), (__FILE__), (__LINE__))
  128. /* ---------------------------------------------------------------- */
  129. #define exe_multi_init(A,Y,Z) do { \
  130. if(((A) = curl_multi_init()) == NULL) { \
  131. fprintf(stderr, "%s:%d curl_multi_init() failed\n", (Y), (Z)); \
  132. res = TEST_ERR_MULTI; \
  133. } \
  134. } while(0)
  135. #define res_multi_init(A) \
  136. exe_multi_init((A), (__FILE__), (__LINE__))
  137. #define chk_multi_init(A,Y,Z) do { \
  138. exe_multi_init((A), (Y), (Z)); \
  139. if(res) \
  140. goto test_cleanup; \
  141. } while(0)
  142. #define multi_init(A) \
  143. chk_multi_init((A), (__FILE__), (__LINE__))
  144. /* ---------------------------------------------------------------- */
  145. #define exe_easy_setopt(A,B,C,Y,Z) do { \
  146. CURLcode ec; \
  147. if((ec = curl_easy_setopt((A), (B), (C))) != CURLE_OK) { \
  148. fprintf(stderr, "%s:%d curl_easy_setopt() failed, " \
  149. "with code %d (%s)\n", \
  150. (Y), (Z), (int)ec, curl_easy_strerror(ec)); \
  151. res = ec; \
  152. } \
  153. } while(0)
  154. #define res_easy_setopt(A, B, C) \
  155. exe_easy_setopt((A), (B), (C), (__FILE__), (__LINE__))
  156. #define chk_easy_setopt(A, B, C, Y, Z) do { \
  157. exe_easy_setopt((A), (B), (C), (Y), (Z)); \
  158. if(res) \
  159. goto test_cleanup; \
  160. } while(0)
  161. #define easy_setopt(A, B, C) \
  162. chk_easy_setopt((A), (B), (C), (__FILE__), (__LINE__))
  163. /* ---------------------------------------------------------------- */
  164. #define exe_multi_setopt(A, B, C, Y, Z) do { \
  165. CURLMcode ec; \
  166. if((ec = curl_multi_setopt((A), (B), (C))) != CURLM_OK) { \
  167. fprintf(stderr, "%s:%d curl_multi_setopt() failed, " \
  168. "with code %d (%s)\n", \
  169. (Y), (Z), (int)ec, curl_multi_strerror(ec)); \
  170. res = TEST_ERR_MULTI; \
  171. } \
  172. } while(0)
  173. #define res_multi_setopt(A,B,C) \
  174. exe_multi_setopt((A), (B), (C), (__FILE__), (__LINE__))
  175. #define chk_multi_setopt(A,B,C,Y,Z) do { \
  176. exe_multi_setopt((A), (B), (C), (Y), (Z)); \
  177. if(res) \
  178. goto test_cleanup; \
  179. } while(0)
  180. #define multi_setopt(A,B,C) \
  181. chk_multi_setopt((A), (B), (C), (__FILE__), (__LINE__))
  182. /* ---------------------------------------------------------------- */
  183. #define exe_multi_add_handle(A,B,Y,Z) do { \
  184. CURLMcode ec; \
  185. if((ec = curl_multi_add_handle((A), (B))) != CURLM_OK) { \
  186. fprintf(stderr, "%s:%d curl_multi_add_handle() failed, " \
  187. "with code %d (%s)\n", \
  188. (Y), (Z), (int)ec, curl_multi_strerror(ec)); \
  189. res = TEST_ERR_MULTI; \
  190. } \
  191. } while(0)
  192. #define res_multi_add_handle(A, B) \
  193. exe_multi_add_handle((A), (B), (__FILE__), (__LINE__))
  194. #define chk_multi_add_handle(A, B, Y, Z) do { \
  195. exe_multi_add_handle((A), (B), (Y), (Z)); \
  196. if(res) \
  197. goto test_cleanup; \
  198. } while(0)
  199. #define multi_add_handle(A, B) \
  200. chk_multi_add_handle((A), (B), (__FILE__), (__LINE__))
  201. /* ---------------------------------------------------------------- */
  202. #define exe_multi_remove_handle(A,B,Y,Z) do { \
  203. CURLMcode ec; \
  204. if((ec = curl_multi_remove_handle((A), (B))) != CURLM_OK) { \
  205. fprintf(stderr, "%s:%d curl_multi_remove_handle() failed, " \
  206. "with code %d (%s)\n", \
  207. (Y), (Z), (int)ec, curl_multi_strerror(ec)); \
  208. res = TEST_ERR_MULTI; \
  209. } \
  210. } while(0)
  211. #define res_multi_remove_handle(A, B) \
  212. exe_multi_remove_handle((A), (B), (__FILE__), (__LINE__))
  213. #define chk_multi_remove_handle(A, B, Y, Z) do { \
  214. exe_multi_remove_handle((A), (B), (Y), (Z)); \
  215. if(res) \
  216. goto test_cleanup; \
  217. } while(0)
  218. #define multi_remove_handle(A, B) \
  219. chk_multi_remove_handle((A), (B), (__FILE__), (__LINE__))
  220. /* ---------------------------------------------------------------- */
  221. #define exe_multi_perform(A,B,Y,Z) do { \
  222. CURLMcode ec; \
  223. if((ec = curl_multi_perform((A), (B))) != CURLM_OK) { \
  224. fprintf(stderr, "%s:%d curl_multi_perform() failed, " \
  225. "with code %d (%s)\n", \
  226. (Y), (Z), (int)ec, curl_multi_strerror(ec)); \
  227. res = TEST_ERR_MULTI; \
  228. } \
  229. else if(*((B)) < 0) { \
  230. fprintf(stderr, "%s:%d curl_multi_perform() succeeded, " \
  231. "but returned invalid running_handles value (%d)\n", \
  232. (Y), (Z), (int)*((B))); \
  233. res = TEST_ERR_NUM_HANDLES; \
  234. } \
  235. } while(0)
  236. #define res_multi_perform(A, B) \
  237. exe_multi_perform((A), (B), (__FILE__), (__LINE__))
  238. #define chk_multi_perform(A, B, Y, Z) do { \
  239. exe_multi_perform((A), (B), (Y), (Z)); \
  240. if(res) \
  241. goto test_cleanup; \
  242. } while(0)
  243. #define multi_perform(A,B) \
  244. chk_multi_perform((A), (B), (__FILE__), (__LINE__))
  245. /* ---------------------------------------------------------------- */
  246. #define exe_multi_fdset(A, B, C, D, E, Y, Z) do { \
  247. CURLMcode ec; \
  248. if((ec = curl_multi_fdset((A), (B), (C), (D), (E))) != CURLM_OK) { \
  249. fprintf(stderr, "%s:%d curl_multi_fdset() failed, " \
  250. "with code %d (%s)\n", \
  251. (Y), (Z), (int)ec, curl_multi_strerror(ec)); \
  252. res = TEST_ERR_MULTI; \
  253. } \
  254. else if(*((E)) < -1) { \
  255. fprintf(stderr, "%s:%d curl_multi_fdset() succeeded, " \
  256. "but returned invalid max_fd value (%d)\n", \
  257. (Y), (Z), (int)*((E))); \
  258. res = TEST_ERR_NUM_HANDLES; \
  259. } \
  260. } while(0)
  261. #define res_multi_fdset(A, B, C, D, E) \
  262. exe_multi_fdset((A), (B), (C), (D), (E), (__FILE__), (__LINE__))
  263. #define chk_multi_fdset(A, B, C, D, E, Y, Z) do { \
  264. exe_multi_fdset((A), (B), (C), (D), (E), (Y), (Z)); \
  265. if(res) \
  266. goto test_cleanup; \
  267. } while(0)
  268. #define multi_fdset(A, B, C, D, E) \
  269. chk_multi_fdset((A), (B), (C), (D), (E), (__FILE__), (__LINE__))
  270. /* ---------------------------------------------------------------- */
  271. #define exe_multi_timeout(A,B,Y,Z) do { \
  272. CURLMcode ec; \
  273. if((ec = curl_multi_timeout((A), (B))) != CURLM_OK) { \
  274. fprintf(stderr, "%s:%d curl_multi_timeout() failed, " \
  275. "with code %d (%s)\n", \
  276. (Y), (Z), (int)ec, curl_multi_strerror(ec)); \
  277. res = TEST_ERR_BAD_TIMEOUT; \
  278. } \
  279. else if(*((B)) < -1L) { \
  280. fprintf(stderr, "%s:%d curl_multi_timeout() succeeded, " \
  281. "but returned invalid timeout value (%ld)\n", \
  282. (Y), (Z), (long)*((B))); \
  283. res = TEST_ERR_BAD_TIMEOUT; \
  284. } \
  285. } while(0)
  286. #define res_multi_timeout(A, B) \
  287. exe_multi_timeout((A), (B), (__FILE__), (__LINE__))
  288. #define chk_multi_timeout(A, B, Y, Z) do { \
  289. exe_multi_timeout((A), (B), (Y), (Z)); \
  290. if(res) \
  291. goto test_cleanup; \
  292. } while(0)
  293. #define multi_timeout(A, B) \
  294. chk_multi_timeout((A), (B), (__FILE__), (__LINE__))
  295. /* ---------------------------------------------------------------- */
  296. #define exe_multi_poll(A,B,C,D,E,Y,Z) do { \
  297. CURLMcode ec; \
  298. if((ec = curl_multi_poll((A), (B), (C), (D), (E))) != CURLM_OK) { \
  299. fprintf(stderr, "%s:%d curl_multi_poll() failed, " \
  300. "with code %d (%s)\n", \
  301. (Y), (Z), (int)ec, curl_multi_strerror(ec)); \
  302. res = TEST_ERR_MULTI; \
  303. } \
  304. else if(*((E)) < 0) { \
  305. fprintf(stderr, "%s:%d curl_multi_poll() succeeded, " \
  306. "but returned invalid numfds value (%d)\n", \
  307. (Y), (Z), (int)*((E))); \
  308. res = TEST_ERR_NUM_HANDLES; \
  309. } \
  310. } while(0)
  311. #define res_multi_poll(A, B, C, D, E) \
  312. exe_multi_poll((A), (B), (C), (D), (E), (__FILE__), (__LINE__))
  313. #define chk_multi_poll(A, B, C, D, E, Y, Z) do { \
  314. exe_multi_poll((A), (B), (C), (D), (E), (Y), (Z)); \
  315. if(res) \
  316. goto test_cleanup; \
  317. } while(0)
  318. #define multi_poll(A, B, C, D, E) \
  319. chk_multi_poll((A), (B), (C), (D), (E), (__FILE__), (__LINE__))
  320. /* ---------------------------------------------------------------- */
  321. #define exe_multi_wakeup(A,Y,Z) do { \
  322. CURLMcode ec; \
  323. if((ec = curl_multi_wakeup((A))) != CURLM_OK) { \
  324. fprintf(stderr, "%s:%d curl_multi_wakeup() failed, " \
  325. "with code %d (%s)\n", \
  326. (Y), (Z), (int)ec, curl_multi_strerror(ec)); \
  327. res = TEST_ERR_MULTI; \
  328. } \
  329. } while(0)
  330. #define res_multi_wakeup(A) \
  331. exe_multi_wakeup((A), (__FILE__), (__LINE__))
  332. #define chk_multi_wakeup(A, Y, Z) do { \
  333. exe_multi_wakeup((A), (Y), (Z)); \
  334. if(res) \
  335. goto test_cleanup; \
  336. } while(0)
  337. #define multi_wakeup(A) \
  338. chk_multi_wakeup((A), (__FILE__), (__LINE__))
  339. /* ---------------------------------------------------------------- */
  340. #define exe_select_test(A, B, C, D, E, Y, Z) do { \
  341. int ec; \
  342. if(select_wrapper((A), (B), (C), (D), (E)) == -1) { \
  343. ec = SOCKERRNO; \
  344. fprintf(stderr, "%s:%d select() failed, with " \
  345. "errno %d (%s)\n", \
  346. (Y), (Z), ec, strerror(ec)); \
  347. res = TEST_ERR_SELECT; \
  348. } \
  349. } while(0)
  350. #define res_select_test(A, B, C, D, E) \
  351. exe_select_test((A), (B), (C), (D), (E), (__FILE__), (__LINE__))
  352. #define chk_select_test(A, B, C, D, E, Y, Z) do { \
  353. exe_select_test((A), (B), (C), (D), (E), (Y), (Z)); \
  354. if(res) \
  355. goto test_cleanup; \
  356. } while(0)
  357. #define select_test(A, B, C, D, E) \
  358. chk_select_test((A), (B), (C), (D), (E), (__FILE__), (__LINE__))
  359. /* ---------------------------------------------------------------- */
  360. #define start_test_timing() do { \
  361. tv_test_start = tutil_tvnow(); \
  362. } while(0)
  363. #define exe_test_timedout(Y,Z) do { \
  364. long timediff = tutil_tvdiff(tutil_tvnow(), tv_test_start); \
  365. if(timediff > (TEST_HANG_TIMEOUT)) { \
  366. fprintf(stderr, "%s:%d ABORTING TEST, since it seems " \
  367. "that it would have run forever (%ld ms > %ld ms)\n", \
  368. (Y), (Z), timediff, (long) (TEST_HANG_TIMEOUT)); \
  369. res = TEST_ERR_RUNS_FOREVER; \
  370. } \
  371. } while(0)
  372. #define res_test_timedout() \
  373. exe_test_timedout((__FILE__), (__LINE__))
  374. #define chk_test_timedout(Y, Z) do { \
  375. exe_test_timedout(Y, Z); \
  376. if(res) \
  377. goto test_cleanup; \
  378. } while(0)
  379. #define abort_on_test_timeout() \
  380. chk_test_timedout((__FILE__), (__LINE__))
  381. /* ---------------------------------------------------------------- */
  382. #define exe_global_init(A,Y,Z) do { \
  383. CURLcode ec; \
  384. if((ec = curl_global_init((A))) != CURLE_OK) { \
  385. fprintf(stderr, "%s:%d curl_global_init() failed, " \
  386. "with code %d (%s)\n", \
  387. (Y), (Z), (int)ec, curl_easy_strerror(ec)); \
  388. res = ec; \
  389. } \
  390. } while(0)
  391. #define res_global_init(A) \
  392. exe_global_init((A), (__FILE__), (__LINE__))
  393. #define chk_global_init(A, Y, Z) do { \
  394. exe_global_init((A), (Y), (Z)); \
  395. if(res) \
  396. return res; \
  397. } while(0)
  398. /* global_init() is different than other macros. In case of
  399. failure it 'return's instead of going to 'test_cleanup'. */
  400. #define global_init(A) \
  401. chk_global_init((A), (__FILE__), (__LINE__))
  402. #ifndef CURLTESTS_BUNDLED_TEST_H
  403. #define NO_SUPPORT_BUILT_IN \
  404. CURLcode test(char *URL) \
  405. { \
  406. (void)URL; \
  407. fprintf(stderr, "Missing support\n"); \
  408. return (CURLcode)1; \
  409. }
  410. #endif
  411. /* ---------------------------------------------------------------- */
  412. #endif /* HEADER_CURL_TEST_H */
  413. #ifdef CURLTESTS_BUNDLED_TEST_H
  414. extern CURLcode test(char *URL); /* the actual test function provided by each
  415. individual libXXX.c file */
  416. #undef NO_SUPPORT_BUILT_IN
  417. #define NO_SUPPORT_BUILT_IN \
  418. CURLcode test(char *URL) \
  419. { \
  420. (void)URL; \
  421. fprintf(stderr, "Missing support\n"); \
  422. return (CURLcode)1; \
  423. }
  424. #endif