diff options
author | Nanang Izzuddin <nanang@teluu.com> | 2009-04-06 17:13:33 +0000 |
---|---|---|
committer | Nanang Izzuddin <nanang@teluu.com> | 2009-04-06 17:13:33 +0000 |
commit | 350d6756668b62617ac3169ee10148199fab4037 (patch) | |
tree | 64636d97e48c218eee07c4122db17312bfdcf012 /pjmedia/src/test/jbuf_test.c | |
parent | bbdeaae143a7707d8dcf8a5ff77f06d342ea1393 (diff) |
Ticket #762: Updated JB test:
- Added support for more scenarios, e.g: frame loss, late, sequence restart, etc.
- Added automatic test result checks based on specified condition.
- Updated test data.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@2579 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjmedia/src/test/jbuf_test.c')
-rw-r--r-- | pjmedia/src/test/jbuf_test.c | 310 |
1 files changed, 243 insertions, 67 deletions
diff --git a/pjmedia/src/test/jbuf_test.c b/pjmedia/src/test/jbuf_test.c index c8a5681f..eac92db5 100644 --- a/pjmedia/src/test/jbuf_test.c +++ b/pjmedia/src/test/jbuf_test.c @@ -26,107 +26,283 @@ #define JB_MIN_PREFETCH 0 #define JB_MAX_PREFETCH 10 #define JB_PTIME 20 -#define JB_BUF_SIZE 20 +#define JB_BUF_SIZE 50 #define REPORT //#define PRINT_COMMENT +typedef struct test_param_t { + pj_bool_t adaptive; + unsigned init_prefetch; + unsigned min_prefetch; + unsigned max_prefetch; +} test_param_t; + +typedef struct test_cond_t { + int burst; + int discard; + int lost; + int empty; + int delay; /**< Maximum delay, in frames. */ +} test_cond_t; + +static pj_bool_t parse_test_headers(char *line, test_param_t *param, + test_cond_t *cond) +{ + char *p = line; + + if (*p == '%') { + /* Test params. */ + char mode_st[16]; + + sscanf(p+1, "%s %u %u %u", mode_st, ¶m->init_prefetch, + ¶m->min_prefetch, ¶m->max_prefetch); + param->adaptive = (stricmp(mode_st, "adaptive") == 0); + + } else if (*p == '!') { + /* Success condition. */ + char cond_st[16]; + unsigned cond_val; + + sscanf(p+1, "%s %u", cond_st, &cond_val); + if (stricmp(cond_st, "burst") == 0) + cond->burst = cond_val; + else if (stricmp(cond_st, "delay") == 0) + cond->delay = cond_val; + else if (stricmp(cond_st, "discard") == 0) + cond->discard = cond_val; + else if (stricmp(cond_st, "empty") == 0) + cond->empty = cond_val; + else if (stricmp(cond_st, "lost") == 0) + cond->lost = cond_val; + + } else if (*p == '=') { + /* Test title. */ + ++p; + while (*p && isspace(*p)) ++p; + printf("%s", p); + } else { + /* Unknown header, perhaps this is the test data */ + + /* Skip spaces */ + while (*p && isspace(*p)) ++p; + + /* Test data started.*/ + if (*p != 0) + return PJ_FALSE; + } + + return PJ_TRUE; +} + +static pj_bool_t process_test_data(char data, pjmedia_jbuf *jb, + pj_uint16_t *seq, pj_uint16_t *last_seq) +{ + char frame[1]; + char f_type; + pj_bool_t print_state = PJ_TRUE; + pj_bool_t data_eos = PJ_FALSE; + + switch (toupper(data)) { + case 'G': /* Get */ + pjmedia_jbuf_get_frame(jb, frame, &f_type); + break; + case 'P': /* Put */ + pjmedia_jbuf_put_frame(jb, (void*)frame, 1, *seq); + *last_seq = *seq; + ++*seq; + break; + case 'L': /* Lost */ + *last_seq = *seq; + ++*seq; + printf("Lost\n"); + break; + case 'R': /* Sequence restarts */ + *seq = 1; + printf("Sequence restarting, from %u to %u\n", *last_seq, *seq); + break; + case 'J': /* Sequence jumps */ + (*seq) += 5000; + printf("Sequence jumping, from %u to %u\n", *last_seq, *seq); + break; + case 'D': /* Frame duplicated */ + pjmedia_jbuf_put_frame(jb, (void*)frame, 1, *seq - 1); + break; + case 'O': /* Old/late frame */ + pjmedia_jbuf_put_frame(jb, (void*)frame, 1, *seq - 10 - pj_rand()%40); + break; + case '.': /* End of test session. */ + data_eos = PJ_TRUE; + break; + default: + print_state = PJ_FALSE; + printf("Unknown test data '%c'\n", data); + break; + } + + if (data_eos) + return PJ_FALSE; + +#ifdef REPORT + if (print_state) { + pjmedia_jb_state state; + + pjmedia_jbuf_get_state(jb, &state); + printf("seq=%d\t%c\tsize=%d\tprefetch=%d\n", + *last_seq, toupper(data), state.size, state.prefetch); + } +#endif + + return PJ_TRUE; +} + int jbuf_main(void) { - pjmedia_jbuf *jb; FILE *input = fopen("JBTEST.DAT", "rt"); - unsigned seq; - char line[1024 * 10], *p; - pj_pool_t *pool; - pjmedia_jb_state state; - pj_str_t jb_name = {"JBTEST", 6}; + pj_bool_t data_eof = PJ_FALSE; + int old_log_level; + int rc = 0; - pj_init(); - pool = pj_pool_create(mem, "JBPOOL", 256*16, 256*16, NULL); + old_log_level = pj_log_get_level(); + pj_log_set_level(5); - pjmedia_jbuf_create(pool, &jb_name, 1, JB_PTIME, JB_BUF_SIZE, &jb); - pjmedia_jbuf_set_adaptive(jb, JB_INIT_PREFETCH, JB_MIN_PREFETCH, - JB_MAX_PREFETCH); + while (rc == 0 && !data_eof) { + pj_str_t jb_name = {"JBTEST", 6}; + pjmedia_jbuf *jb; + pj_pool_t *pool; + pjmedia_jb_state state; + pj_uint16_t last_seq = 0; + pj_uint16_t seq = 1; + char line[1024], *p = NULL; - while ((p=fgets(line, sizeof(line), input)) != NULL) { + test_param_t param; + test_cond_t cond; - while (*p && isspace(*p)) - ++p; + param.adaptive = PJ_TRUE; + param.init_prefetch = JB_INIT_PREFETCH; + param.min_prefetch = JB_MIN_PREFETCH; + param.max_prefetch = JB_MAX_PREFETCH; - if (!*p) - continue; + cond.burst = -1; + cond.delay = -1; + cond.discard = -1; + cond.empty = -1; + cond.lost = -1; - if (*p == '#') { -#ifdef PRINT_COMMENT - printf("%s", p); -#endif - continue; - } + printf("\n\n"); + + /* Parse test session title, param, and conditions */ + do { + p = fgets(line, sizeof(line), input); + } while (p && parse_test_headers(line, ¶m, &cond)); + + /* EOF test data */ + if (p == NULL) + break; + //printf("======================================================\n"); + + /* Initialize test session */ + pool = pj_pool_create(mem, "JBPOOL", 256*16, 256*16, NULL); + pjmedia_jbuf_create(pool, &jb_name, 1, JB_PTIME, JB_BUF_SIZE, &jb); pjmedia_jbuf_reset(jb); - seq = 1; + + if (param.adaptive) { + pjmedia_jbuf_set_adaptive(jb, + param.init_prefetch, + param.min_prefetch, + param.max_prefetch); + } else { + pjmedia_jbuf_set_fixed(jb, param.init_prefetch); + } #ifdef REPORT pjmedia_jbuf_get_state(jb, &state); printf("Initial\tsize=%d\tprefetch=%d\tmin.pftch=%d\tmax.pftch=%d\n", - state.size, state.prefetch, state.min_prefetch, state.max_prefetch); + state.size, state.prefetch, state.min_prefetch, + state.max_prefetch); #endif - while (*p) { + + /* Test session start */ + while (1) { int c; - char frame[1]; - char f_type; + /* Get next line of test data */ + if (!p || *p == 0) { + p = fgets(line, sizeof(line), input); + if (p == NULL) { + data_eof = PJ_TRUE; + break; + } + } + + /* Get next char of test data */ c = *p++; + + /* Skip spaces */ if (isspace(c)) continue; - - if (c == '/') { - putchar('\n'); - - while (*++p && *p != '/') - putchar(*p); - - putchar('\n'); - - if (*++p == 0) - break; + /* Print comment line */ + if (c == '#') { +#ifdef PRINT_COMMENT + while (*p && isspace(*p)) ++p; + if (*p) printf("..%s", p); +#endif + *p = 0; continue; } - switch (toupper(c)) { - case 'G': - pjmedia_jbuf_get_frame(jb, frame, &f_type); - break; - case 'P': - pjmedia_jbuf_put_frame(jb, (void*)frame, 1, seq); - seq++; + /* Process test data */ + if (!process_test_data(c, jb, &seq, &last_seq)) break; - case 'L': - seq++; - printf("Lost\n"); - break; - default: - printf("Unknown character '%c'\n", c); - break; - } + } -#ifdef REPORT - if (toupper(c) != 'L') { - pjmedia_jbuf_get_state(jb, &state); - printf("seq=%d\t%c\tsize=%d\tprefetch=%d\n", - seq, toupper(c), state.size, state.prefetch); - } -#endif + /* Print JB states */ + pjmedia_jbuf_get_state(jb, &state); + printf("------------------------------------------------------\n"); + printf("Summary:\n"); + printf(" size=%d prefetch=%d\n", state.size, state.prefetch); + printf(" delay (min/max/avg/dev)=%d/%d/%d/%d ms\n", + state.min_delay, state.max_delay, state.avg_delay, + state.dev_delay); + printf(" lost=%d discard=%d empty=%d burst(avg)=%d\n", + state.lost, state.discard, state.empty, state.avg_burst); + + /* Evaluate test session */ + if (cond.burst >= 0 && (int)state.avg_burst > cond.burst) { + printf("! 'Burst' should be %d, it is %d\n", + cond.burst, state.avg_burst); + rc |= 1; + } + if (cond.delay >= 0 && (int)state.avg_delay/JB_PTIME > cond.delay) { + printf("! 'Delay' should be %d, it is %d\n", + cond.delay, state.avg_delay/JB_PTIME); + rc |= 2; + } + if (cond.discard >= 0 && (int)state.discard > cond.discard) { + printf("! 'Discard' should be %d, it is %d\n", + cond.discard, state.discard); + rc |= 4; + } + if (cond.empty >= 0 && (int)state.empty > cond.empty) { + printf("! 'Empty' should be %d, it is %d\n", + cond.empty, state.empty); + rc |= 8; + } + if (cond.lost >= 0 && (int)state.lost > cond.lost) { + printf("! 'Lost' should be %d, it is %d\n", + cond.lost, state.lost); + rc |= 16; } - } - pjmedia_jbuf_destroy(jb); + pjmedia_jbuf_destroy(jb); + pj_pool_release(pool); + } - if (input != stdin) - fclose(input); + fclose(input); + pj_log_set_level(old_log_level); - pj_pool_release(pool); - return 0; + return rc; } |