src/test.c
changeset 52 97604efda1ce
parent 51 cc61eaa841ef
child 72 43084f103c2a
equal deleted inserted replaced
51:cc61eaa841ef 52:97604efda1ce
    26 }
    26 }
    27 
    27 
    28 /**
    28 /**
    29  * This re-formats the given string to escape values, and returns a pointer to an internal static buffer.
    29  * This re-formats the given string to escape values, and returns a pointer to an internal static buffer.
    30  *
    30  *
    31  * If len is given as >= 0, only the given number of chars will be dumped from str
    31  * If len is given as >= 0, only the given number of chars will be dumped from str.
    32  *
    32  *
    33  * The buffer cycles a bit, so you pointers remain valid across DUMP_STR_COUNT calls.
    33  * The buffer cycles a bit, so the returned pointers remain valid across DUMP_STR_COUNT calls.
    34  *
    34  *
    35  * The resulting strings are truncated to (DUMP_STR_BUF - DUMP_STR_TAIL) bytes, not including the ending "...'\0"
    35  * The resulting string is truncated to (DUMP_STR_BUF - DUMP_STR_TAIL) bytes, not including the ending "...'\0".
       
    36  *
       
    37  * @param str the string to dump, should be NUL-terminated unless len is given
       
    38  * @param len if negative, ignored, otherwise, only this many bytes are dumped from str
       
    39  * @param return a pointer to a static buffer that remains valid across DUMP_STR_COUNT calls to this function
    36  */
    40  */
    37 const char *dump_strn (const char *str, ssize_t len)
    41 const char *dump_strn (const char *str, ssize_t len)
    38 {
    42 {
    39     static char dump_buf[DUMP_STR_COUNT][DUMP_STR_BUF];
    43     static char dump_buf[DUMP_STR_COUNT][DUMP_STR_BUF];
    40     static size_t dump_idx = 0;
    44     static size_t dump_idx = 0;
    79             buf = dump_str_append(buf, "\\\\");
    83             buf = dump_str_append(buf, "\\\\");
    80 
    84 
    81         } else if (isprint(*str)) {
    85         } else if (isprint(*str)) {
    82             // normal char
    86             // normal char
    83             *buf++ = *str;
    87             *buf++ = *str;
    84 
    88         
    85         } else {
    89         } else {
    86             // something more special
    90             // something more special
    87             switch (*str) {
    91             switch (*str) {
    88                 case '\r':
    92                 case '\r':
    89                     buf = dump_str_append(buf, "\\r"); break;
    93                     buf = dump_str_append(buf, "\\r"); break;
   118     return dump_strn(str, -1);
   122     return dump_strn(str, -1);
   119 }
   123 }
   120 
   124 
   121 void assert_strcmp (const char *is, const char *should_be)
   125 void assert_strcmp (const char *is, const char *should_be)
   122 {
   126 {
   123     if (strcmp(is, should_be))
   127     if (!is || strcmp(is, should_be))
   124         FATAL("%s != %s", dump_str(is), dump_str(should_be));
   128         FATAL("%s != %s", dump_str(is), dump_str(should_be));
   125 }
   129 }
   126 
   130 
   127 void assert_strncmp (const char *is, const char *should_be, size_t n)
   131 void assert_strncmp (const char *is, const char *should_be, size_t n)
   128 {   
   132 {   
   129     if (strncmp(is, should_be, n))
   133     if (!is || strncmp(is, should_be, n))
   130         FATAL("%s:%u != %s", dump_strn(is, n), (unsigned) n, dump_strn(should_be, n));
   134         FATAL("%s:%u != %s", dump_strn(is, n), (unsigned) n, dump_strn(should_be, n));
   131 }
   135 }
   132 
   136 
   133 void assert_strlen (const char *str, size_t n)
   137 void assert_strlen (const char *str, size_t n)
   134 {
   138 {
   135     if (strlen(str) != n)
   139     if (!str || strlen(str) != n)
   136         FATAL("strlen(%s) != %u", dump_str(str), (unsigned) n);
   140         FATAL("strlen(%s) != %u", dump_str(str), (unsigned) n);
   137 }
   141 }
   138 
   142 
   139 void assert_strnull (const char *str)
   143 void assert_strnull (const char *str)
   140 {
   144 {
   144 
   148 
   145 void assert_success (err_t err)
   149 void assert_success (err_t err)
   146 {
   150 {
   147     if (err != SUCCESS)
   151     if (err != SUCCESS)
   148         FATAL("error: %s", error_name(err));
   152         FATAL("error: %s", error_name(err));
   149 
       
   150 }
   153 }
   151 
   154 
   152 void assert_err (err_t err, err_t target)
   155 void assert_err (err_t err, err_t target)
   153 {
   156 {
   154     if (err != target)
   157     if (err != target)
   205     assert_strncmp(buf, data, len);
   208     assert_strncmp(buf, data, len);
   206     assert_strlen(data, len);
   209     assert_strlen(data, len);
   207 
   210 
   208     // cleanup
   211     // cleanup
   209     free(buf);
   212     free(buf);
       
   213 }
       
   214 
       
   215 /**
       
   216  * Nicer name for test_sock_add_recv_str
       
   217  */
       
   218 void test_sock_push (struct sock_test *sock, const char *str)
       
   219 {
       
   220     return sock_test_add_recv_str(sock, str);
   210 }
   221 }
   211 
   222 
   212 void test_dump_str (void)
   223 void test_dump_str (void)
   213 {
   224 {
   214     log_info("dumping example strings on stdout:");
   225     log_info("dumping example strings on stdout:");
   265     log_debug("expect: %s", dump_str(line_str));
   276     log_debug("expect: %s", dump_str(line_str));
   266 
   277 
   267     assert_success(line_proto_recv(lp, &line_buf));
   278     assert_success(line_proto_recv(lp, &line_buf));
   268 
   279 
   269     if (line_str) {
   280     if (line_str) {
   270         assert(line_buf != NULL);
       
   271         assert_strcmp(line_buf, line_str);
   281         assert_strcmp(line_buf, line_str);
   272 
   282 
   273     } else {
   283     } else {
   274         assert_strnull(line_buf);
   284         assert_strnull(line_buf);
   275 
   285 
   437     assert_success(irc_conn_register(conn, &register_info));
   447     assert_success(irc_conn_register(conn, &register_info));
   438     assert_sock_data(sock, "NICK nick\r\nUSER user 0 * realname\r\n");
   448     assert_sock_data(sock, "NICK nick\r\nUSER user 0 * realname\r\n");
   439  
   449  
   440     // test on_register callback    
   450     // test on_register callback    
   441     if (noisy) log_info("test irc_conn_callbacks.on_register");
   451     if (noisy) log_info("test irc_conn_callbacks.on_register");
   442     sock_test_add_recv_str(sock, "001 mynick :Blaa blaa blaa\r\n");
   452     test_sock_push(sock, "001 mynick :Blaa blaa blaa\r\n");
   443     if (ctx) assert(ctx->on_registered);
   453     if (ctx) assert(ctx->on_registered);
   444     assert_strcmp(conn->nickname, "mynick");
   454     assert_strcmp(conn->nickname, "mynick");
   445    
   455    
   446     // ok
   456     // ok
   447     return conn;
   457     return conn;
   462     // add our test handlers
   472     // add our test handlers
   463     assert_success(irc_conn_add_cmd_handlers(conn, _conn_handlers, &ctx));
   473     assert_success(irc_conn_add_cmd_handlers(conn, _conn_handlers, &ctx));
   464 
   474 
   465     // test on_TEST handler
   475     // test on_TEST handler
   466     log_info("test irc_conn.handlers");
   476     log_info("test irc_conn.handlers");
   467     sock_test_add_recv_str(sock, ":foobar-prefix TEST arg0\r\n");
   477     test_sock_push(sock, ":foobar-prefix TEST arg0\r\n");
   468     assert(ctx.on_TEST);
   478     assert(ctx.on_TEST);
   469 
   479 
   470     // test PING/PONG
   480     // test PING/PONG
   471     log_info("test PING/PONG");
   481     log_info("test PING/PONG");
   472     sock_test_add_recv_str(sock, "PING foo\r\n");
   482     test_sock_push(sock, "PING foo\r\n");
   473     assert_sock_data(sock, "PONG foo\r\n");
   483     assert_sock_data(sock, "PONG foo\r\n");
   474 
   484 
   475     // quit nicely
   485     // quit nicely
   476     log_info("test QUIT");
   486     log_info("test QUIT");
   477     assert_success(irc_conn_QUIT(conn, "bye now"));
   487     assert_success(irc_conn_QUIT(conn, "bye now"));
   478     assert_sock_data(sock, "QUIT :bye now\r\n");
   488     assert_sock_data(sock, "QUIT :bye now\r\n");
   479     assert(conn->quitting);
   489     assert(conn->quitting);
   480 
   490 
   481     sock_test_add_recv_str(sock, "ERROR :Closing Link: Quit\r\n");
   491     test_sock_push(sock, "ERROR :Closing Link: Quit\r\n");
   482     sock_test_set_recv_eof(sock);
   492     sock_test_set_recv_eof(sock);
   483     assert(conn->quit && !conn->quitting && !conn->registered);
   493     assert(conn->quit && !conn->quitting && !conn->registered);
   484     assert(ctx.on_quit);
   494     assert(ctx.on_quit);
   485     assert(!ctx.on_error);
   495     assert(!ctx.on_error);
   486 
   496 
   542     // test register output
   552     // test register output
   543     assert_sock_data(sock, "NICK nick\r\nUSER user 0 * realname\r\n");
   553     assert_sock_data(sock, "NICK nick\r\nUSER user 0 * realname\r\n");
   544     
   554     
   545     // registration reply
   555     // registration reply
   546     log_info("test irc_conn_on_RPL_WELCOME");
   556     log_info("test irc_conn_on_RPL_WELCOME");
   547     sock_test_add_recv_str(sock, "001 mynick :Blaa blaa blaa\r\n");
   557     test_sock_push(sock, "001 mynick :Blaa blaa blaa\r\n");
   548     assert(net->conn->registered);
   558     assert(net->conn->registered);
   549     assert_strcmp(net->conn->nickname, "mynick");
   559     assert_strcmp(net->conn->nickname, "mynick");
   550     
   560     
   551     // JOIN request
   561     // JOIN request
   552     log_info("test irc_net_conn_registered -> irc_chan_join");
   562     log_info("test irc_net_conn_registered -> irc_chan_join");
   553     assert(chan->joining);
   563     assert(chan->joining);
   554     assert_sock_data(sock, "JOIN #test\r\n");
   564     assert_sock_data(sock, "JOIN #test\r\n");
   555 
   565 
   556     // JOIN reply
   566     // JOIN reply
   557     log_info("test irc_chan_on_JOIN");
   567     log_info("test irc_chan_on_JOIN");
   558     sock_test_add_recv_str(sock, ":mynick!user@host JOIN #test\r\n");
   568     test_sock_push(sock, ":mynick!user@host JOIN #test\r\n");
   559     assert(!chan->joining && chan->joined);
   569     assert(!chan->joining && chan->joined);
   560     assert(ctx.on_chan_self_join);
   570     assert(ctx.on_chan_self_join);
   561 
   571 
   562     // test errors by setting EOF
   572     // test errors by setting EOF
   563     log_info("test irc_net_error");
   573     log_info("test irc_net_error");
   587     {   NULL,           NULL                }
   597     {   NULL,           NULL                }
   588 };
   598 };
   589 
   599 
   590 int main (int argc, char **argv)
   600 int main (int argc, char **argv)
   591 {
   601 {
       
   602     const char *filter;
   592     struct test *test;
   603     struct test *test;
   593 
   604     
   594     (void) argv;
   605     if (argc == 1) {
   595     
   606         // no arguments
   596     // no arguments
   607         filter = NULL;
   597     assert(argc == 1);
   608 
       
   609     } else if (argc == 2) {
       
   610         // filter
       
   611         filter = argv[1];
       
   612         
       
   613         log_info("only running tests: %s", filter);
       
   614 
       
   615     } else {
       
   616         FATAL("too many arguments");
       
   617     }
   598 
   618 
   599     // run tests
   619     // run tests
   600     for (test = _tests; test->name; test++) {
   620     for (test = _tests; test->name; test++) {
       
   621         if (filter && strcmp(test->name, filter))
       
   622             continue;
       
   623 
   601         log_info("Running test: %s", test->name);
   624         log_info("Running test: %s", test->name);
   602 
   625 
   603         test->func();
   626         test->func();
   604     }
   627     }
   605 
   628