test_nua.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. /*
  2. * This file is part of the Sofia-SIP package
  3. *
  4. * Copyright (C) 2005 Nokia Corporation.
  5. *
  6. * Contact: Pekka Pessi <pekka.pessi@nokia.com>
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public License
  10. * as published by the Free Software Foundation; either version 2.1 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This library is distributed in the hope that it will be useful, but
  14. * WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with this library; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  21. * 02110-1301 USA
  22. *
  23. */
  24. /**@CFILE test_nua.c
  25. * @brief High-level tester for Sofia SIP User Agent Engine
  26. *
  27. * @author Pekka Pessi <Pekka.Pessi@nokia.com>
  28. * @author Martti Mela <Martti Mela@nokia.com>
  29. *
  30. * @date Created: Wed Aug 17 12:12:12 EEST 2005 ppessi
  31. */
  32. #include "config.h"
  33. #include "test_nua.h"
  34. #if HAVE_ALARM
  35. #include <signal.h>
  36. #endif
  37. #if defined(_WIN32)
  38. #include <fcntl.h>
  39. #endif
  40. SOFIAPUBVAR su_log_t nua_log[];
  41. SOFIAPUBVAR su_log_t soa_log[];
  42. SOFIAPUBVAR su_log_t nea_log[];
  43. SOFIAPUBVAR su_log_t nta_log[];
  44. SOFIAPUBVAR su_log_t tport_log[];
  45. SOFIAPUBVAR su_log_t su_log_default[];
  46. char const name[] = "test_nua";
  47. int print_headings = 1;
  48. int tstflags = 0;
  49. #if HAVE_FUNC
  50. #elif HAVE_FUNCTION
  51. #define __func__ __FUNCTION__
  52. #else
  53. #define __func__ name
  54. #endif
  55. #if HAVE_ALARM
  56. static RETSIGTYPE sig_alarm(int s)
  57. {
  58. fprintf(stderr, "%s: FAIL! test timeout!\n", name);
  59. if (tstflags & tst_abort)
  60. abort();
  61. exit(1);
  62. }
  63. #endif
  64. static char const options_usage[] =
  65. " -v | --verbose be verbose\n"
  66. " -q | --quiet be quiet\n"
  67. " -a | --abort abort on error\n"
  68. " -s use only single thread\n"
  69. " -l level set logging level (0 by default)\n"
  70. " -e | --events print nua events\n"
  71. " -A print nua events for A\n"
  72. " -B print nua events for B\n"
  73. " -C print nua events for C\n"
  74. " --log=a log messages for A\n"
  75. " --log=b log messages for B\n"
  76. " --log=c log messages for C\n"
  77. " --log=proxy log messages for proxy\n"
  78. " --attach print pid, wait for a debugger to be attached\n"
  79. " --no-proxy do not use internal proxy\n"
  80. " --no-nat do not use internal \"nat\"\n"
  81. " --symmetric run internal \"nat\" in symmetric mode\n"
  82. " -N print events from internal \"nat\"\n"
  83. " --loop loop main tests for ever\n"
  84. " --no-alarm don't ask for guard ALARM\n"
  85. " -p uri specify uri of outbound proxy (implies --no-proxy)\n"
  86. " --proxy-tests run tests involving proxy, too\n"
  87. #if SU_HAVE_OSX_CF_API /* If compiled with CoreFoundation events */
  88. " --osx-runloop use OSX CoreFoundation runloop instead of poll() loop\n"
  89. #endif
  90. " -k do not exit after first error\n"
  91. ;
  92. static void usage(int exitcode)
  93. {
  94. fprintf(stderr, "usage: %s OPTIONS\n where OPTIONS are\n%s",
  95. name, options_usage);
  96. exit(exitcode);
  97. }
  98. int main(int argc, char *argv[])
  99. {
  100. int retval = 0;
  101. int i, o_quiet = 0, o_attach = 0, o_alarm = 1, o_loop = 0;
  102. int o_events_init = 0, o_events_a = 0, o_events_b = 0, o_events_c = 0;
  103. int o_iproxy = 1, o_inat = 1;
  104. int o_inat_symmetric = 0, o_inat_logging = 0, o_expensive = 0;
  105. url_t const *o_proxy = NULL;
  106. int level = 0;
  107. struct context ctx[1] = {{{ SU_HOME_INIT(ctx) }}};
  108. #if HAVE_OPEN_C
  109. dup2(1, 2);
  110. #endif
  111. if (getenv("EXPENSIVE_CHECKS"))
  112. o_expensive = 1;
  113. ctx->threading = 1;
  114. ctx->quit_on_single_failure = 1;
  115. endpoint_init(ctx, &ctx->a, 'a');
  116. endpoint_init(ctx, &ctx->b, 'b');
  117. endpoint_init(ctx, &ctx->c, 'c');
  118. for (i = 1; argv[i]; i++) {
  119. if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbose") == 0)
  120. tstflags |= tst_verbatim;
  121. else if (strcmp(argv[i], "-a") == 0 || strcmp(argv[i], "--abort") == 0)
  122. tstflags |= tst_abort;
  123. else if (strcmp(argv[i], "-q") == 0 || strcmp(argv[i], "--quiet") == 0)
  124. tstflags &= ~tst_verbatim, o_quiet = 1;
  125. else if (strcmp(argv[i], "-k") == 0)
  126. ctx->quit_on_single_failure = 0;
  127. else if (strncmp(argv[i], "-l", 2) == 0) {
  128. char *rest = NULL;
  129. if (argv[i][2])
  130. level = strtol(argv[i] + 2, &rest, 10);
  131. else if (argv[i + 1])
  132. level = strtol(argv[i + 1], &rest, 10), i++;
  133. else
  134. level = 3, rest = "";
  135. if (rest == NULL || *rest)
  136. usage(1);
  137. su_log_set_level(nua_log, level);
  138. su_log_soft_set_level(soa_log, level);
  139. su_log_soft_set_level(nea_log, level);
  140. su_log_soft_set_level(nta_log, level);
  141. su_log_soft_set_level(tport_log, level);
  142. }
  143. else if (strcmp(argv[i], "-e") == 0 || strcmp(argv[i], "--events") == 0) {
  144. o_events_init = o_events_a = o_events_b = o_events_c = 1;
  145. }
  146. else if (strcmp(argv[i], "-I") == 0) {
  147. o_events_init = 1;
  148. }
  149. else if (strcmp(argv[i], "-A") == 0) {
  150. o_events_a = 1;
  151. }
  152. else if (strcmp(argv[i], "-B") == 0) {
  153. o_events_b = 1;
  154. }
  155. else if (strcmp(argv[i], "-C") == 0) {
  156. o_events_c = 1;
  157. }
  158. else if (strcmp(argv[i], "-s") == 0) {
  159. ctx->threading = 0;
  160. }
  161. else if (strcmp(argv[i], "--attach") == 0) {
  162. o_attach = 1;
  163. }
  164. else if (strncmp(argv[i], "-p", 2) == 0) {
  165. if (argv[i][2])
  166. o_proxy = URL_STRING_MAKE(argv[i] + 2)->us_url;
  167. else if (!argv[++i] || argv[i][0] == '-')
  168. usage(1);
  169. else
  170. o_proxy = URL_STRING_MAKE(argv[i])->us_url;
  171. }
  172. else if (strcmp(argv[i], "--proxy-tests") == 0) {
  173. ctx->proxy_tests = 1;
  174. }
  175. else if (strcmp(argv[i], "--no-proxy") == 0) {
  176. o_iproxy = 0;
  177. }
  178. else if (strcmp(argv[i], "--no-nat") == 0) {
  179. o_inat = 0;
  180. }
  181. else if (strcmp(argv[i], "--nat") == 0) {
  182. o_inat = 1;
  183. }
  184. else if (strcmp(argv[i], "--symmetric") == 0) {
  185. o_inat_symmetric = 1;
  186. }
  187. else if (strcmp(argv[i], "-N") == 0) {
  188. o_inat_logging = 1;
  189. }
  190. else if (strcmp(argv[i], "--expensive") == 0) {
  191. o_expensive = 1;
  192. }
  193. else if (strcmp(argv[i], "--no-alarm") == 0) {
  194. o_alarm = 0;
  195. }
  196. else if (strcmp(argv[i], "--loop") == 0) {
  197. o_alarm = 0, o_loop = 1;
  198. }
  199. else if (strcmp(argv[i], "--print-tags") == 0) {
  200. ctx->print_tags = 1;
  201. }
  202. else if (strcmp(argv[i], "--tags=a") == 0) {
  203. ctx->a.print_tags = 1;
  204. }
  205. else if (strcmp(argv[i], "--tags=b") == 0) {
  206. ctx->b.print_tags = 1;
  207. }
  208. else if (strcmp(argv[i], "--tags=c") == 0) {
  209. ctx->c.print_tags = 1;
  210. }
  211. else if (strcmp(argv[i], "--log=a") == 0) {
  212. ctx->a.logging = 1;
  213. }
  214. else if (strcmp(argv[i], "--log=b") == 0) {
  215. ctx->b.logging = 1;
  216. }
  217. else if (strcmp(argv[i], "--log=c") == 0) {
  218. ctx->c.logging = 1;
  219. }
  220. else if (strcmp(argv[i], "--log=proxy") == 0) {
  221. ctx->proxy_logging = 1;
  222. }
  223. #if SU_HAVE_OSX_CF_API /* If compiled with CoreFoundation events */
  224. else if (strcmp(argv[i], "--osx-runloop") == 0) {
  225. ctx->osx_runloop = 1;
  226. }
  227. #endif
  228. else if (strcmp(argv[i], "-") == 0) {
  229. i++; break;
  230. }
  231. else if (argv[i][0] != '-') {
  232. break;
  233. }
  234. else {
  235. fprintf(stderr, "test_nua: unknown argument \"%s\"\n\n", argv[i]);
  236. usage(1);
  237. }
  238. }
  239. if (o_attach) {
  240. char line[10], *l;
  241. printf("%s: pid %lu\n", name, (unsigned long)getpid());
  242. printf("<Press RETURN to continue>\n");
  243. l = fgets(line, sizeof line, stdin);
  244. }
  245. #if HAVE_ALARM
  246. else if (o_alarm) {
  247. signal(SIGALRM, sig_alarm);
  248. if (o_expensive) {
  249. printf("%s: extending timeout to %u because expensive tests\n",
  250. name, 240);
  251. alarm(240);
  252. }
  253. else {
  254. alarm(120);
  255. }
  256. }
  257. #endif
  258. #if HAVE_OPEN_C
  259. tstflags |= tst_verbatim;
  260. level = 9;
  261. o_inat = 1; /* No NATs */
  262. ctx->threading = 1;
  263. ctx->quit_on_single_failure = 1;
  264. su_log_soft_set_level(nua_log, level);
  265. su_log_soft_set_level(soa_log, level);
  266. su_log_soft_set_level(su_log_default, level);
  267. su_log_soft_set_level(nea_log, level);
  268. su_log_soft_set_level(nta_log, level);
  269. su_log_soft_set_level(tport_log, level);
  270. setenv("SU_DEBUG", "9", 1);
  271. setenv("NUA_DEBUG", "9", 1);
  272. setenv("NTA_DEBUG", "9", 1);
  273. setenv("TPORT_DEBUG", "9", 1);
  274. o_events_a = o_events_b = 1;
  275. #endif
  276. su_init();
  277. if (!(TSTFLAGS & tst_verbatim)) {
  278. if (level == 0 && !o_quiet)
  279. level = 1;
  280. su_log_soft_set_level(nua_log, level);
  281. su_log_soft_set_level(soa_log, level);
  282. su_log_soft_set_level(su_log_default, level);
  283. su_log_soft_set_level(nea_log, level);
  284. su_log_soft_set_level(nta_log, level);
  285. su_log_soft_set_level(tport_log, level);
  286. }
  287. if (!o_quiet || (TSTFLAGS & tst_verbatim)
  288. || o_events_a || o_events_b || o_events_c)
  289. print_headings = 1;
  290. #if !HAVE_OPEN_C
  291. #define SINGLE_FAILURE_CHECK() \
  292. do { fflush(stdout); \
  293. if (retval && ctx->quit_on_single_failure) { \
  294. su_deinit(); return retval; } \
  295. } while(0)
  296. #else
  297. #define SINGLE_FAILURE_CHECK() \
  298. do { fflush(stdout); \
  299. if (retval && ctx->quit_on_single_failure) { \
  300. su_deinit(); sleep(10); return retval; } \
  301. } while(0)
  302. #endif
  303. ctx->a.printer = o_events_init ? print_event : NULL;
  304. retval |= test_nua_api_errors(ctx); SINGLE_FAILURE_CHECK();
  305. retval |= test_tag_filter(); SINGLE_FAILURE_CHECK();
  306. retval |= test_nua_params(ctx); SINGLE_FAILURE_CHECK();
  307. retval |= test_nua_destroy(ctx); SINGLE_FAILURE_CHECK();
  308. retval |= test_stack_errors(ctx); SINGLE_FAILURE_CHECK();
  309. retval |= test_nua_init(ctx, o_iproxy, o_proxy, o_inat,
  310. TESTNATTAG_SYMMETRIC(o_inat_symmetric),
  311. TESTNATTAG_LOGGING(o_inat_logging),
  312. TAG_END());
  313. ctx->expensive = o_expensive;
  314. if (retval == 0) {
  315. ctx->a.printer = o_events_a ? print_event : NULL;
  316. if (o_events_b)
  317. ctx->b.printer = print_event;
  318. if (o_events_c)
  319. ctx->c.printer = print_event;
  320. retval |= test_register(ctx);
  321. if (retval == 0)
  322. retval |= test_connectivity(ctx);
  323. if (retval == 0 && o_inat)
  324. retval |= test_nat_timeout(ctx);
  325. while (retval == 0) {
  326. retval |= test_basic_call(ctx); SINGLE_FAILURE_CHECK();
  327. retval |= test_rejects(ctx); SINGLE_FAILURE_CHECK();
  328. retval |= test_call_cancel(ctx); SINGLE_FAILURE_CHECK();
  329. retval |= test_call_destroy(ctx); SINGLE_FAILURE_CHECK();
  330. retval |= test_early_bye(ctx); SINGLE_FAILURE_CHECK();
  331. retval |= test_offer_answer(ctx); SINGLE_FAILURE_CHECK();
  332. retval |= test_reinvites(ctx); SINGLE_FAILURE_CHECK();
  333. retval |= test_session_timer(ctx); SINGLE_FAILURE_CHECK();
  334. retval |= test_refer(ctx); SINGLE_FAILURE_CHECK();
  335. retval |= test_100rel(ctx); SINGLE_FAILURE_CHECK();
  336. retval |= test_simple(ctx); SINGLE_FAILURE_CHECK();
  337. retval |= test_events(ctx); SINGLE_FAILURE_CHECK();
  338. retval |= test_extension(ctx); SINGLE_FAILURE_CHECK();
  339. if (!o_loop)
  340. break;
  341. }
  342. if (ctx->proxy_tests && (retval == 0 || !ctx->p))
  343. retval |= test_unregister(ctx); SINGLE_FAILURE_CHECK();
  344. }
  345. retval |= test_deinit(ctx);
  346. su_home_deinit(ctx->home);
  347. su_deinit();
  348. #if HAVE_OPEN_C
  349. sleep(7);
  350. #endif
  351. return retval;
  352. }