test.h 20 KB

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