test.h 20 KB

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