test_nua.c 11.2 KB
Newer Older
Pekka Pessi's avatar
Pekka Pessi committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
/*
 * This file is part of the Sofia-SIP package
 *
 * Copyright (C) 2005 Nokia Corporation.
 *
 * Contact: Pekka Pessi <pekka.pessi@nokia.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

/**@CFILE test_nua.c
 * @brief High-level tester for Sofia SIP User Agent Engine
 *
 * @author Pekka Pessi <Pekka.Pessi@nokia.com>
29
 * @author Martti Mela <Martti Mela@nokia.com>
Pekka Pessi's avatar
Pekka Pessi committed
30 31 32 33 34 35
 *
 * @date Created: Wed Aug 17 12:12:12 EEST 2005 ppessi
 */

#include "config.h"

36
#include "test_nua.h"
37 38 39 40 41

#if HAVE_ALARM
#include <signal.h>
#endif

42 43 44 45
#if defined(_WIN32)
#include <fcntl.h>
#endif

46 47 48 49 50 51
SOFIAPUBVAR su_log_t nua_log[];
SOFIAPUBVAR su_log_t soa_log[];
SOFIAPUBVAR su_log_t nea_log[];
SOFIAPUBVAR su_log_t nta_log[];
SOFIAPUBVAR su_log_t tport_log[];
SOFIAPUBVAR su_log_t su_log_default[];
Pekka Pessi's avatar
Pekka Pessi committed
52 53

char const name[] = "test_nua";
54
int print_headings = 1;
Pekka Pessi's avatar
Pekka Pessi committed
55 56 57 58 59 60 61 62 63 64 65 66 67
int tstflags = 0;

#if HAVE_FUNC
#elif HAVE_FUNCTION
#define __func__ __FUNCTION__
#else
#define __func__ name
#endif

#if HAVE_ALARM
static RETSIGTYPE sig_alarm(int s)
{
  fprintf(stderr, "%s: FAIL! test timeout!\n", name);
68 69
  if (tstflags & tst_abort)
    abort();
Pekka Pessi's avatar
Pekka Pessi committed
70 71 72 73
  exit(1);
}
#endif

74
static char const options_usage[] =
75 76
  "   -v | --verbose    be verbose\n"
  "   -q | --quiet      be quiet\n"
77
  "   -a | --abort      abort on error\n"
Pekka Pessi's avatar
Pekka Pessi committed
78
  "   -s                use only single thread\n"
79 80 81 82
  "   -l level          set logging level (0 by default)\n"
  "   -e | --events     print nua events\n"
  "   -A                print nua events for A\n"
  "   -B                print nua events for B\n"
83
  "   -C                print nua events for C\n"
84 85 86 87
  "   --log=a           log messages for A\n"
  "   --log=b           log messages for B\n"
  "   --log=c           log messages for C\n"
  "   --log=proxy       log messages for proxy\n"
88
  "   --attach          print pid, wait for a debugger to be attached\n"
89
  "   --no-proxy        do not use internal proxy\n"
90
  "   --no-nat          do not use internal \"nat\"\n"
Pekka Pessi's avatar
Pekka Pessi committed
91 92
  "   --symmetric       run internal \"nat\" in symmetric mode\n"
  "   -N                print events from internal \"nat\"\n"
93
  "   --loop            loop main tests for ever\n"
94
  "   --no-alarm        don't ask for guard ALARM\n"
95
  "   -p uri            specify uri of outbound proxy (implies --no-proxy)\n"
96
  "   --proxy-tests     run tests involving proxy, too\n"
97 98 99
#if SU_HAVE_OSX_CF_API /* If compiled with CoreFoundation events */
  "   --osx-runloop     use OSX CoreFoundation runloop instead of poll() loop\n"
#endif
100
  "   -k                do not exit after first error\n"
101 102
  ;

103
static void usage(int exitcode)
Pekka Pessi's avatar
Pekka Pessi committed
104
{
105
  fprintf(stderr, "usage: %s OPTIONS\n   where OPTIONS are\n%s",
106
	    name, options_usage);
107
  exit(exitcode);
Pekka Pessi's avatar
Pekka Pessi committed
108 109 110 111
}

int main(int argc, char *argv[])
{
112
  int retval = 0;
113
  int i, o_quiet = 0, o_attach = 0, o_alarm = 1, o_loop = 0;
114 115
  int o_events_init = 0, o_events_a = 0, o_events_b = 0, o_events_c = 0;
  int o_iproxy = 1, o_inat = 1;
116
  int o_inat_symmetric = 0, o_inat_logging = 0, o_expensive = 0;
117
  url_t const *o_proxy = NULL;
118
  int level = 0;
Pekka Pessi's avatar
Pekka Pessi committed
119 120 121

  struct context ctx[1] = {{{ SU_HOME_INIT(ctx) }}};

122 123 124
#if HAVE_OPEN_C
  dup2(1, 2);
#endif
125

126 127 128
  if (getenv("EXPENSIVE_CHECKS"))
    o_expensive = 1;

Pekka Pessi's avatar
Pekka Pessi committed
129
  ctx->threading = 1;
130
  ctx->quit_on_single_failure = 1;
Pekka Pessi's avatar
Pekka Pessi committed
131

132 133 134
  endpoint_init(ctx, &ctx->a, 'a');
  endpoint_init(ctx, &ctx->b, 'b');
  endpoint_init(ctx, &ctx->c, 'c');
Pekka Pessi's avatar
Pekka Pessi committed
135

Pekka Pessi's avatar
Pekka Pessi committed
136
  for (i = 1; argv[i]; i++) {
137
    if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbose") == 0)
Pekka Pessi's avatar
Pekka Pessi committed
138
      tstflags |= tst_verbatim;
Pekka Pessi's avatar
Pekka Pessi committed
139 140
    else if (strcmp(argv[i], "-a") == 0 || strcmp(argv[i], "--abort") == 0)
      tstflags |= tst_abort;
141 142
    else if (strcmp(argv[i], "-q") == 0 || strcmp(argv[i], "--quiet") == 0)
      tstflags &= ~tst_verbatim, o_quiet = 1;
143
    else if (strcmp(argv[i], "-k") == 0)
144
      ctx->quit_on_single_failure = 0;
Pekka Pessi's avatar
Pekka Pessi committed
145 146 147 148 149 150 151 152 153 154 155
    else if (strncmp(argv[i], "-l", 2) == 0) {
      char *rest = NULL;

      if (argv[i][2])
	level = strtol(argv[i] + 2, &rest, 10);
      else if (argv[i + 1])
	level = strtol(argv[i + 1], &rest, 10), i++;
      else
	level = 3, rest = "";

      if (rest == NULL || *rest)
156
	usage(1);
157

Pekka Pessi's avatar
Pekka Pessi committed
158
      su_log_set_level(nua_log, level);
159
      su_log_soft_set_level(soa_log, level);
160
      su_log_soft_set_level(nea_log, level);
161 162 163 164
      su_log_soft_set_level(nta_log, level);
      su_log_soft_set_level(tport_log, level);
    }
    else if (strcmp(argv[i], "-e") == 0 || strcmp(argv[i], "--events") == 0) {
165 166 167 168
      o_events_init = o_events_a = o_events_b = o_events_c = 1;
    }
    else if (strcmp(argv[i], "-I") == 0) {
      o_events_init = 1;
169 170 171 172 173 174 175
    }
    else if (strcmp(argv[i], "-A") == 0) {
      o_events_a = 1;
    }
    else if (strcmp(argv[i], "-B") == 0) {
      o_events_b = 1;
    }
176 177 178
    else if (strcmp(argv[i], "-C") == 0) {
      o_events_c = 1;
    }
Pekka Pessi's avatar
Pekka Pessi committed
179 180 181
    else if (strcmp(argv[i], "-s") == 0) {
      ctx->threading = 0;
    }
182 183 184
    else if (strcmp(argv[i], "--attach") == 0) {
      o_attach = 1;
    }
185 186
    else if (strncmp(argv[i], "-p", 2) == 0) {
      if (argv[i][2])
187 188
	o_proxy = URL_STRING_MAKE(argv[i] + 2)->us_url;
      else if (!argv[++i] || argv[i][0] == '-')
189
	usage(1);
190
      else
191
	o_proxy = URL_STRING_MAKE(argv[i])->us_url;
Pekka Pessi's avatar
Pekka Pessi committed
192
    }
193 194 195
    else if (strcmp(argv[i], "--proxy-tests") == 0) {
      ctx->proxy_tests = 1;
    }
196 197
    else if (strcmp(argv[i], "--no-proxy") == 0) {
      o_iproxy = 0;
Pekka Pessi's avatar
Pekka Pessi committed
198
    }
199 200 201 202 203 204
    else if (strcmp(argv[i], "--no-nat") == 0) {
      o_inat = 0;
    }
    else if (strcmp(argv[i], "--nat") == 0) {
      o_inat = 1;
    }
Pekka Pessi's avatar
Pekka Pessi committed
205 206 207 208 209 210
    else if (strcmp(argv[i], "--symmetric") == 0) {
      o_inat_symmetric = 1;
    }
    else if (strcmp(argv[i], "-N") == 0) {
      o_inat_logging = 1;
    }
211 212 213
    else if (strcmp(argv[i], "--expensive") == 0) {
      o_expensive = 1;
    }
Pekka Pessi's avatar
Pekka Pessi committed
214 215 216
    else if (strcmp(argv[i], "--no-alarm") == 0) {
      o_alarm = 0;
    }
217 218 219
    else if (strcmp(argv[i], "--loop") == 0) {
      o_alarm = 0, o_loop = 1;
    }
220 221 222 223 224 225 226 227 228 229 230 231
    else if (strcmp(argv[i], "--print-tags") == 0) {
      ctx->print_tags = 1;
    }
    else if (strcmp(argv[i], "--tags=a") == 0) {
      ctx->a.print_tags = 1;
    }
    else if (strcmp(argv[i], "--tags=b") == 0) {
      ctx->b.print_tags = 1;
    }
    else if (strcmp(argv[i], "--tags=c") == 0) {
      ctx->c.print_tags = 1;
    }
232 233 234 235 236 237 238 239 240 241 242 243
    else if (strcmp(argv[i], "--log=a") == 0) {
      ctx->a.logging = 1;
    }
    else if (strcmp(argv[i], "--log=b") == 0) {
      ctx->b.logging = 1;
    }
    else if (strcmp(argv[i], "--log=c") == 0) {
      ctx->c.logging = 1;
    }
    else if (strcmp(argv[i], "--log=proxy") == 0) {
      ctx->proxy_logging = 1;
    }
244 245 246 247 248
#if SU_HAVE_OSX_CF_API /* If compiled with CoreFoundation events */
    else if (strcmp(argv[i], "--osx-runloop") == 0) {
      ctx->osx_runloop = 1;
    }
#endif
Pekka Pessi's avatar
Pekka Pessi committed
249 250 251 252 253 254
    else if (strcmp(argv[i], "-") == 0) {
      i++; break;
    }
    else if (argv[i][0] != '-') {
      break;
    }
255 256
    else {
      fprintf(stderr, "test_nua: unknown argument \"%s\"\n\n", argv[i]);
257
      usage(1);
258
    }
Pekka Pessi's avatar
Pekka Pessi committed
259 260 261
  }

  if (o_attach) {
262
    char line[10], *l;
263
    printf("%s: pid %lu\n", name, (unsigned long)getpid());
Pekka Pessi's avatar
Pekka Pessi committed
264
    printf("<Press RETURN to continue>\n");
265
    l = fgets(line, sizeof line, stdin);
Pekka Pessi's avatar
Pekka Pessi committed
266 267 268 269
  }
#if HAVE_ALARM
  else if (o_alarm) {
    signal(SIGALRM, sig_alarm);
270 271 272 273 274 275 276 277
    if (o_expensive) {
      printf("%s: extending timeout to %u because expensive tests\n",
	     name, 240);
      alarm(240);
    }
    else {
      alarm(120);
    }
Pekka Pessi's avatar
Pekka Pessi committed
278 279 280
  }
#endif

281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299
#if HAVE_OPEN_C
  tstflags |= tst_verbatim;
  level = 9;
  o_inat = 1; /* No NATs */
  ctx->threading = 1;
  ctx->quit_on_single_failure = 1;
  su_log_soft_set_level(nua_log, level);
  su_log_soft_set_level(soa_log, level);
  su_log_soft_set_level(su_log_default, level);
  su_log_soft_set_level(nea_log, level);
  su_log_soft_set_level(nta_log, level);
  su_log_soft_set_level(tport_log, level);
  setenv("SU_DEBUG", "9", 1);
  setenv("NUA_DEBUG", "9", 1);
  setenv("NTA_DEBUG", "9", 1);
  setenv("TPORT_DEBUG", "9", 1);
  o_events_a = o_events_b = 1;
#endif

Pekka Pessi's avatar
Pekka Pessi committed
300 301 302
  su_init();

  if (!(TSTFLAGS & tst_verbatim)) {
Pekka Pessi's avatar
Pekka Pessi committed
303 304
    if (level == 0 && !o_quiet)
      level = 1;
305 306
    su_log_soft_set_level(nua_log, level);
    su_log_soft_set_level(soa_log, level);
307
    su_log_soft_set_level(su_log_default, level);
308
    su_log_soft_set_level(nea_log, level);
309 310
    su_log_soft_set_level(nta_log, level);
    su_log_soft_set_level(tport_log, level);
Pekka Pessi's avatar
Pekka Pessi committed
311 312
  }

Pekka Pessi's avatar
Pekka Pessi committed
313
  if (!o_quiet || (TSTFLAGS & tst_verbatim)
314
      || o_events_a || o_events_b || o_events_c)
315 316
    print_headings = 1;

317
#if !HAVE_OPEN_C
Pekka Pessi's avatar
Pekka Pessi committed
318 319
#define SINGLE_FAILURE_CHECK()						\
  do { fflush(stdout);							\
320 321
    if (retval && ctx->quit_on_single_failure) {			\
      su_deinit(); return retval; }					\
Pekka Pessi's avatar
Pekka Pessi committed
322
  } while(0)
323 324 325 326 327 328 329
#else
#define SINGLE_FAILURE_CHECK()						\
  do { fflush(stdout);							\
    if (retval && ctx->quit_on_single_failure) {			\
      su_deinit(); sleep(10); return retval; }					\
  } while(0)
#endif
Pekka Pessi's avatar
Pekka Pessi committed
330

331 332
  ctx->a.printer = o_events_init ? print_event : NULL;

Pekka Pessi's avatar
Pekka Pessi committed
333
  retval |= test_nua_api_errors(ctx); SINGLE_FAILURE_CHECK();
334

335
  retval |= test_tag_filter(); SINGLE_FAILURE_CHECK();
336

Pekka Pessi's avatar
Pekka Pessi committed
337
  retval |= test_nua_params(ctx); SINGLE_FAILURE_CHECK();
338

339 340
  retval |= test_nua_destroy(ctx); SINGLE_FAILURE_CHECK();

341 342
  retval |= test_stack_errors(ctx); SINGLE_FAILURE_CHECK();

Pekka Pessi's avatar
Pekka Pessi committed
343 344 345 346
  retval |= test_nua_init(ctx, o_iproxy, o_proxy, o_inat,
			  TESTNATTAG_SYMMETRIC(o_inat_symmetric),
			  TESTNATTAG_LOGGING(o_inat_logging),
			  TAG_END());
347

348 349
  ctx->expensive = o_expensive;

Pekka Pessi's avatar
Pekka Pessi committed
350
  if (retval == 0) {
351
    ctx->a.printer = o_events_a ? print_event : NULL;
352 353
    if (o_events_b)
      ctx->b.printer = print_event;
354 355
    if (o_events_c)
      ctx->c.printer = print_event;
356

357
    retval |= test_register(ctx);
358 359 360 361

    if (retval == 0)
      retval |= test_connectivity(ctx);

362 363 364
    if (retval == 0 && o_inat)
      retval |= test_nat_timeout(ctx);

365
    while (retval == 0) {
366
      retval |= test_basic_call(ctx); SINGLE_FAILURE_CHECK();
367
      retval |= test_rejects(ctx); SINGLE_FAILURE_CHECK();
368
      retval |= test_call_cancel(ctx); SINGLE_FAILURE_CHECK();
369
      retval |= test_call_destroy(ctx); SINGLE_FAILURE_CHECK();
370
      retval |= test_early_bye(ctx); SINGLE_FAILURE_CHECK();
371
      retval |= test_offer_answer(ctx); SINGLE_FAILURE_CHECK();
372
      retval |= test_reinvites(ctx); SINGLE_FAILURE_CHECK();
373 374
      retval |= test_session_timer(ctx); SINGLE_FAILURE_CHECK();
      retval |= test_refer(ctx); SINGLE_FAILURE_CHECK();
375
      retval |= test_100rel(ctx); SINGLE_FAILURE_CHECK();
376
      retval |= test_simple(ctx); SINGLE_FAILURE_CHECK();
377
      retval |= test_events(ctx); SINGLE_FAILURE_CHECK();
378
      retval |= test_extension(ctx); SINGLE_FAILURE_CHECK();
379 380
      if (!o_loop)
	break;
381 382
    }

383
    if (ctx->proxy_tests && (retval == 0 || !ctx->p))
384
      retval |= test_unregister(ctx); SINGLE_FAILURE_CHECK();
Pekka Pessi's avatar
Pekka Pessi committed
385
  }
386
  retval |= test_deinit(ctx);
Pekka Pessi's avatar
Pekka Pessi committed
387

388 389
  su_home_deinit(ctx->home);

Pekka Pessi's avatar
Pekka Pessi committed
390 391
  su_deinit();

392 393 394 395
#if HAVE_OPEN_C
  sleep(7);
#endif

Pekka Pessi's avatar
Pekka Pessi committed
396 397
  return retval;
}