test.h 20 KB

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