2
0

test.h 20 KB

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