src/test.c
changeset 74 11ec458d1cbf
parent 73 2780a73c71f3
child 75 ff6272398d2e
equal deleted inserted replaced
73:2780a73c71f3 74:11ec458d1cbf
   514 struct test_chan_ctx {
   514 struct test_chan_ctx {
   515     /** The channel we're supposed to be testing */
   515     /** The channel we're supposed to be testing */
   516     struct irc_chan *chan;
   516     struct irc_chan *chan;
   517     
   517     
   518     /** Flags for callbacks called*/
   518     /** Flags for callbacks called*/
   519     bool on_chan_self_join, on_chan_join;
   519     bool on_chan_self_join, on_chan_self_part, on_chan_join, on_chan_part;
   520 
   520 
   521 };
   521 };
   522 
   522 
   523 void _on_chan_self_join (struct irc_chan *chan, void *arg)
   523 void _on_chan_self_join (struct irc_chan *chan, void *arg)
   524 {
   524 {
   541 
   541 
   542     ctx->on_chan_join = true;
   542     ctx->on_chan_join = true;
   543 
   543 
   544     log_debug("on_join");
   544     log_debug("on_join");
   545 }
   545 }
       
   546 
       
   547 void _on_chan_part (struct irc_chan *chan, const struct irc_nm *source, const char *msg, void *arg)
       
   548 {
       
   549     struct test_chan_ctx *ctx = arg;
       
   550 
       
   551     assert(chan == ctx->chan);
       
   552 
       
   553     // XXX: verify source
       
   554     // XXX: verify msg
       
   555 
       
   556     ctx->on_chan_part = true;
       
   557 
       
   558     log_debug("on_part");
       
   559 }
       
   560 
   546 
   561 
   547 struct irc_chan_callbacks _chan_callbacks = {
   562 struct irc_chan_callbacks _chan_callbacks = {
   548     .on_self_join       = &_on_chan_self_join,
   563     .on_self_join       = &_on_chan_self_join,
   549     .on_join            = &_on_chan_join,
   564     .on_join            = &_on_chan_join,
       
   565     .on_part            = &_on_chan_part,
   550 };
   566 };
   551 
   567 
   552 /**
   568 /**
   553  * Setup an irc_net using the given socket, and consume the register request output, but do not push the RPL_WELCOME
   569  * Setup an irc_net using the given socket, and consume the register request output, but do not push the RPL_WELCOME
   554  */
   570  */
   622     // cleanup
   638     // cleanup
   623     irc_net_destroy(net);
   639     irc_net_destroy(net);
   624 }
   640 }
   625 
   641 
   626 /**
   642 /**
       
   643  * Ensure that an irc_chan_user exists/doesn't exist for the given channel/nickname, and return it
       
   644  */
       
   645 struct irc_chan_user* check_chan_user (struct irc_chan *chan, const char *nickname, bool exists)
       
   646 {
       
   647     struct irc_chan_user *chan_user = irc_chan_get_user(chan, nickname);
       
   648     
       
   649     if (exists && chan_user == NULL)
       
   650         FATAL("user %s not found in channel %s", dump_str(nickname), dump_str(irc_chan_name(chan)));
       
   651     
       
   652     if (!exists && chan_user)
       
   653         FATAL("user %s should not be on channel %s anymore", dump_str(nickname), dump_str(irc_chan_name(chan)));
       
   654 
       
   655     log_debug("%s, exists=%d -> %p: user=%p, nickname=%s", 
       
   656             nickname, exists, chan_user, chan_user ? chan_user->user : NULL, chan_user ? chan_user->user->nickname : NULL);
       
   657     
       
   658     if (chan_user)
       
   659         assert_strcmp(chan_user->user->nickname, nickname);
       
   660 
       
   661     return chan_user;
       
   662 }
       
   663 
       
   664 /**
   627  * Creates an irc_chan on the given irc_net, but does not check any output (useful for testing offline add).
   665  * Creates an irc_chan on the given irc_net, but does not check any output (useful for testing offline add).
   628  *
   666  *
   629  * You must pass a test_chan_ctx for use with later operations, this will be initialized for you.
   667  * You must pass a test_chan_ctx for use with later operations, this will be initialized for you.
   630  */
   668  */
   631 struct irc_chan* setup_irc_chan_raw (struct irc_net *net, struct test_chan_ctx *ctx)
   669 struct irc_chan* setup_irc_chan_raw (struct irc_net *net, struct test_chan_ctx *ctx)
   663     assert(!ctx->chan->joining && ctx->chan->joined);
   701     assert(!ctx->chan->joining && ctx->chan->joined);
   664     assert(ctx->on_chan_self_join);
   702     assert(ctx->on_chan_self_join);
   665 }
   703 }
   666 
   704 
   667 /**
   705 /**
       
   706  * Sends a short RPL_NAMREPLY/RPL_ENDOFNAMES reply and checks that the users list matches
       
   707  */
       
   708 void do_irc_chan_namreply (struct sock_test *sock, struct test_chan_ctx *ctx)
       
   709 {
       
   710     // RPL_NAMREPLY
       
   711     test_sock_push(sock, "353 mynick = #test :mynick userA +userB @userC\r\n");
       
   712     test_sock_push(sock, "366 mynick #test :End of NAMES\r\n");
       
   713     
       
   714     // XXX: this should be an exclusive test, i.e. these should be the only ones...
       
   715     check_chan_user(ctx->chan, "mynick", true);
       
   716     check_chan_user(ctx->chan, "userA", true);
       
   717     check_chan_user(ctx->chan, "userB", true);
       
   718     check_chan_user(ctx->chan, "userC", true);
       
   719 }
       
   720 
       
   721 /**
   668  * Creates an irc_chan on the given irc_net, and checks up to the JOIN reply
   722  * Creates an irc_chan on the given irc_net, and checks up to the JOIN reply
   669  */
   723  */
   670 struct irc_chan* setup_irc_chan (struct sock_test *sock, struct irc_net *net, struct test_chan_ctx *ctx)
   724 struct irc_chan* setup_irc_chan_join (struct sock_test *sock, struct irc_net *net, struct test_chan_ctx *ctx)
   671 {
   725 {
   672     setup_irc_chan_raw(net, ctx);
   726     setup_irc_chan_raw(net, ctx);
   673     do_irc_chan_join(sock, ctx);
   727     do_irc_chan_join(sock, ctx);
   674 
   728 
   675     // ok
   729     // ok
   676     return ctx->chan;
   730     return ctx->chan;
   677 }
   731 }
       
   732 
       
   733 /**
       
   734  * Creates an irc_chan on the given irc_net, sends the JOIN stuff plus RPL_NAMREPLY
       
   735  */
       
   736 struct irc_chan* setup_irc_chan (struct sock_test *sock, struct irc_net *net, struct test_chan_ctx *ctx)
       
   737 {
       
   738     setup_irc_chan_raw(net, ctx);
       
   739     do_irc_chan_join(sock, ctx);
       
   740     do_irc_chan_namreply(sock, ctx);
       
   741 
       
   742     // ok
       
   743     return ctx->chan;
       
   744 }
       
   745 
   678 
   746 
   679 /**
   747 /**
   680  * Call irc_net_add_chan while offline, and ensure that we send the JOIN request after RPL_WELCOME, and handle the join
   748  * Call irc_net_add_chan while offline, and ensure that we send the JOIN request after RPL_WELCOME, and handle the join
   681  * reply OK.
   749  * reply OK.
   682  */
   750  */
   704     
   772     
   705     // cleanup
   773     // cleanup
   706     irc_net_destroy(net);
   774     irc_net_destroy(net);
   707 }
   775 }
   708 
   776 
   709 /**
       
   710  * Ensure that an irc_chan_user exists for the given channel/nickname, and return it
       
   711  */
       
   712 struct irc_chan_user* check_chan_user (struct irc_chan *chan, const char *nickname)
       
   713 {
       
   714     struct irc_chan_user *chan_user;
       
   715 
       
   716     if ((chan_user = irc_chan_get_user(chan, nickname)) == NULL)
       
   717         FATAL("user %s not found in channel %s", dump_str(nickname), dump_str(irc_chan_name(chan)));
       
   718 
       
   719     log_debug("%s -> %p: user=%p, nickname=%s", nickname, chan_user, chan_user->user, chan_user->user->nickname);
       
   720 
       
   721     assert_strcmp(chan_user->user->nickname, nickname);
       
   722 
       
   723     return chan_user;
       
   724 }
       
   725 
       
   726 void test_irc_chan_namreply (void)
   777 void test_irc_chan_namreply (void)
       
   778 {
       
   779     struct test_chan_ctx ctx;
       
   780     struct sock_test *sock = setup_sock_test();
       
   781     struct irc_net *net = setup_irc_net(sock);
       
   782     setup_irc_chan_join(sock, net, &ctx);
       
   783 
       
   784     log_info("test irc_chan_on_RPL_NAMREPLY");
       
   785     do_irc_chan_namreply(sock, &ctx);
       
   786 
       
   787     // cleanup
       
   788     irc_net_destroy(net);
       
   789 }
       
   790 
       
   791 void test_irc_chan_user_join (void)
   727 {
   792 {
   728     struct test_chan_ctx ctx;
   793     struct test_chan_ctx ctx;
   729     struct sock_test *sock = setup_sock_test();
   794     struct sock_test *sock = setup_sock_test();
   730     struct irc_net *net = setup_irc_net(sock);
   795     struct irc_net *net = setup_irc_net(sock);
   731     struct irc_chan *chan = setup_irc_chan(sock, net, &ctx);
   796     struct irc_chan *chan = setup_irc_chan(sock, net, &ctx);
   732 
   797 
   733     // RPL_NAMREPLY
   798     // have a user join
   734     log_info("test irc_chan_on_RPL_NAMREPLY");
   799     log_info("test irc_chan_on_JOIN");
   735     test_sock_push(sock, "353 mynick = #test :mynick userA +userB @userC\r\n");
   800     test_sock_push(sock, ":newuser!someone@somewhere JOIN #test\r\n");
   736 
   801     assert(ctx.on_chan_join);
   737     check_chan_user(chan, "mynick");
   802     check_chan_user(chan, "newuser", true);
   738     check_chan_user(chan, "userA");
       
   739     check_chan_user(chan, "userB");
       
   740     check_chan_user(chan, "userC");
       
   741 
   803 
   742     // cleanup
   804     // cleanup
   743     irc_net_destroy(net);
   805     irc_net_destroy(net);
   744 }
   806 }
   745 
   807 
   746 void test_irc_chan_user_join (void)
   808 void test_irc_chan_user_part (void)
   747 {
   809 {
   748     struct test_chan_ctx ctx;
   810     struct test_chan_ctx ctx;
   749     struct sock_test *sock = setup_sock_test();
   811     struct sock_test *sock = setup_sock_test();
   750     struct irc_net *net = setup_irc_net(sock);
   812     struct irc_net *net = setup_irc_net(sock);
   751     struct irc_chan *chan = setup_irc_chan(sock, net, &ctx);
   813     struct irc_chan *chan = setup_irc_chan(sock, net, &ctx);
   752 
   814 
   753     // RPL_NAMREPLY
       
   754     test_sock_push(sock, "353 mynick = #test :mynick userA +userB @userC\r\n");
       
   755 
       
   756     check_chan_user(chan, "mynick");
       
   757     check_chan_user(chan, "userA");
       
   758     check_chan_user(chan, "userB");
       
   759     check_chan_user(chan, "userC");
       
   760 
       
   761     // have a user join
   815     // have a user join
   762     log_info("test irc_chan_on_JOIN");
   816     log_info("test irc_chan_on_PART");
   763     test_sock_push(sock, ":newuser!someone@somewhere JOIN #test\r\n");
   817     test_sock_push(sock, ":userA!someone@somewhere PART #test\r\n");
   764     assert(ctx.on_chan_join);
   818     assert(ctx.on_chan_part); ctx.on_chan_part = NULL;
   765     check_chan_user(chan, "newuser");
   819     check_chan_user(chan, "userA", false);
   766 
   820 
   767     // cleanup
   821     // cleanup
   768     irc_net_destroy(net);
   822     irc_net_destroy(net);
   769 }
   823 }
   770 
   824 
   785     {   "irc_conn",             &test_irc_conn              },
   839     {   "irc_conn",             &test_irc_conn              },
   786     {   "irc_net",              &test_irc_net               },
   840     {   "irc_net",              &test_irc_net               },
   787     {   "irc_chan_add_offline", &test_irc_chan_add_offline  },
   841     {   "irc_chan_add_offline", &test_irc_chan_add_offline  },
   788     {   "irc_chan_namreply",    &test_irc_chan_namreply     },
   842     {   "irc_chan_namreply",    &test_irc_chan_namreply     },
   789     {   "irc_chan_user_join",   &test_irc_chan_user_join    },
   843     {   "irc_chan_user_join",   &test_irc_chan_user_join    },
       
   844     {   "irc_chan_user_part",   &test_irc_chan_user_part    },
   790     {   NULL,                   NULL                        }
   845     {   NULL,                   NULL                        }
   791 };
   846 };
   792 
   847 
   793 /**
   848 /**
   794  * Command-line option codes
   849  * Command-line option codes