Release 3.0.3.
[jelmer/ctrlproxy.git] / testsuite / test-linestack.c
index d424ebd4f683530b416e57b550227f50ce840869..93c7929850d5ba2750ac6dd0dc4df8414d6516c2 100644 (file)
@@ -21,6 +21,7 @@
 #include <string.h>
 #include <check.h>
 #include "ctrlproxy.h"
+#include "torture.h"
 
 void stack_process(struct linestack_context *ctx, struct network_state *ns, const char *line)
 {
@@ -39,48 +40,6 @@ void stack_process(struct linestack_context *ctx, struct network_state *ns, cons
        return FALSE; \
 }
 
-struct hash_data {
-       GEqualFunc fn;
-       GHashTable *hash2;
-       gboolean success;
-};
-
-static void hash_traverse_equal(void *key, void *val1, void *userdata)
-{
-       struct hash_data *hash = userdata;
-       void *val2;
-
-       val2 = g_hash_table_lookup(hash->hash2, key);
-
-       hash->success &= hash->fn(val1, val2);
-}
-
-static gboolean hash_equal(GHashTable *hash1, GHashTable *hash2, GEqualFunc eqval)
-{
-       struct hash_data userdata;
-
-       null_equal(hash1, hash2);
-       
-       /* Traverse over all keys in hash1 and make sure they exist
-        * with the same value in hash1 and hash2 */
-
-       userdata.fn = eqval;
-       userdata.hash2 = hash2;
-       userdata.success = TRUE;
-       g_hash_table_foreach(hash1, hash_traverse_equal, &userdata);
-       if (!userdata.success)
-               return FALSE;
-       
-       /* Traverse over all keys in hash2 and make sure 
-        * they exist in hash1 */
-
-       userdata.fn = eqval;
-       userdata.hash2 = hash1;
-       g_hash_table_foreach(hash2, hash_traverse_equal, &userdata);
-
-       return userdata.success;
-}
-
 static gboolean list_equal(GList *list1, GList *list2, GEqualFunc eq)
 {
        GList *gl1, *gl2;
@@ -148,12 +107,44 @@ static gboolean network_info_equal(const struct network_info *info1, const struc
 
        return str_equal(info1->name, info2->name) &&
                   str_equal(info1->server, info2->server) &&
-                  hash_equal(info1->features, info2->features, (GEqualFunc)str_equal) &&
                   str_equal(info1->supported_user_modes, info2->supported_user_modes) &&
                   str_equal(info1->supported_channel_modes, info2->supported_channel_modes) &&
-                  info1->casemapping == info2->casemapping &&
+                  str_equal(info1->prefix, info2->prefix) &&
+                  str_equal(info1->chantypes, info2->chantypes) &&
+                  str_equal(info1->charset, info2->charset) &&
+                  ((info1->chanmodes == NULL && info2->chanmodes == NULL) ||
+                  (str_equal(info1->chanmodes[0], info2->chanmodes[0]) &&
+                  str_equal(info1->chanmodes[1], info2->chanmodes[1]) &&
+                  str_equal(info1->chanmodes[2], info2->chanmodes[2]) &&
+                  str_equal(info1->chanmodes[3], info2->chanmodes[3]))) &&
+                  info1->keylen == info2->keylen &&
+                  info1->silence == info2->silence &&
                   info1->channellen == info2->channellen &&
-                  info1->topiclen == info2->topiclen;
+                  info1->awaylen == info2->awaylen &&
+                  info1->maxtargets == info2->maxtargets &&
+                  info1->nicklen == info2->nicklen &&
+                  info1->userlen == info2->userlen &&
+                  info1->hostlen == info2->hostlen &&
+                  info1->maxchannels == info2->maxchannels &&
+                  info1->topiclen == info2->topiclen &&
+                  info1->maxbans == info2->maxbans &&
+                  info1->maxmodes == info2->maxmodes &&
+                  info1->wallchops == info2->wallchops &&
+                  info1->wallvoices == info2->wallvoices &&
+                  info1->rfc2812 == info2->rfc2812 &&
+                  info1->penalty == info2->penalty &&
+                  info1->forced_nick_changes == info2->forced_nick_changes &&
+                  info1->safelist == info2->safelist &&
+                  info1->userip == info2->userip &&
+                  info1->cprivmsg == info2->cprivmsg &&
+                  info1->cnotice == info2->cnotice &&
+                  info1->knock == info2->knock &&
+                  info1->vchannels == info2->vchannels &&
+                  info1->whox == info2->whox &&
+                  info1->callerid == info2->callerid &&
+                  info1->accept == info2->accept &&
+                  info1->capab == info2->capab &&
+                  info1->casemapping == info2->casemapping;
 }
 
 static gboolean network_nick_equal(const struct network_nick *nick1, const struct network_nick *nick2)
@@ -166,17 +157,21 @@ static gboolean network_nick_equal(const struct network_nick *nick1, const struc
                   str_equal(nick1->username, nick2->username) &&
                   str_equal(nick1->hostname, nick2->hostname) &&
                   !memcmp(nick1->modes, nick2->modes, 255) &&
-                  list_equal(nick1->channel_nicks, nick2->channel_nicks, (GEqualFunc)channel_nick_equal);
+                  list_equal(nick1->channel_nicks, nick2->channel_nicks, 
+                                         (GEqualFunc)channel_nick_equal);
 }
 
-static gboolean network_state_equal(const struct network_state *state1, const struct network_state *state2)
+static gboolean network_state_equal(const struct network_state *state1, 
+                                                                       const struct network_state *state2)
 {
        null_equal(state1, state2);
 
        return network_nick_equal(&state1->me, &state2->me) &&
-                  network_info_equal(state1->info, state2->info) &&
-                  list_equal(state1->channels, state2->channels, (GEqualFunc)channel_state_equal) &&
-                  list_equal(state1->nicks, state2->nicks, (GEqualFunc)network_nick_equal);
+                  network_info_equal(&state1->info, &state2->info) &&
+                  list_equal(state1->channels, state2->channels, 
+                                         (GEqualFunc)channel_state_equal) &&
+                  list_equal(state1->nicks, state2->nicks, 
+                                         (GEqualFunc)network_nick_equal);
 }
 
 static struct ctrlproxy_config *my_config;
@@ -187,36 +182,224 @@ START_TEST(test_empty)
        struct network_state *ns1, *ns2;
        struct linestack_context *ctx;
        
-       ns1 = network_state_init(NULL, "bla", "Gebruikersnaam", "Computernaam");
+       ns1 = network_state_init("bla", "Gebruikersnaam", "Computernaam");
        ctx = create_linestack(&linestack_file, "test", my_config, ns1);
 
        ns2 = linestack_get_state(ctx, NULL);
 
-       fail_unless (network_state_equal(ns1, ns2), "Network state returned not equal");
+       fail_unless (network_state_equal(ns1, ns2), 
+                                "Network state returned not equal");
+END_TEST
+
+START_TEST(test_msg)
+       struct network_state *ns1;
+       struct linestack_context *ctx;
+       struct linestack_marker *lm;
+       struct client *cl;
+
+       GIOChannel *ch1, *ch2;
+       char *raw;
+       
+       ns1 = network_state_init("bla", "Gebruikersnaam", "Computernaam");
+       ctx = create_linestack(&linestack_file, "test", my_config, ns1);
+
+       lm = linestack_get_marker(ctx);
+
+       stack_process(ctx, ns1, ":bla!Gebruikersnaam@Computernaam JOIN #bla");
+       stack_process(ctx, ns1, ":bloe!Gebruikersnaam@Computernaam PRIVMSG #bla :hihi");
+
+       g_io_channel_pair(&ch1, &ch2);
+       g_io_channel_set_flags(ch1, G_IO_FLAG_NONBLOCK, NULL);
+       g_io_channel_set_flags(ch2, G_IO_FLAG_NONBLOCK, NULL);
+       cl = client_init(NULL, ch1, "test");
+       g_io_channel_unref(ch1);
+
+       linestack_send(ctx, lm, NULL, cl, FALSE, FALSE);
+       disconnect_client(cl, "foo");
+
+       g_io_channel_read_to_end(ch2, &raw, NULL, NULL);
+
+       fail_unless(!strcmp(raw, ":bla!Gebruikersnaam@Computernaam JOIN #bla\r\n"
+                                                    ":bloe!Gebruikersnaam@Computernaam PRIVMSG #bla :hihi\r\n"
+                                                        "ERROR :foo\r\n"));
+END_TEST
+
+START_TEST(test_join_part)
+       struct network_state *ns1;
+       struct linestack_context *ctx;
+       struct linestack_marker *lm;
+       struct client *cl;
+
+       GIOChannel *ch1, *ch2;
+       char *raw;
+       
+       ns1 = network_state_init("bla", "Gebruikersnaam", "Computernaam");
+       ctx = create_linestack(&linestack_file, "test", my_config, ns1);
+
+       lm = linestack_get_marker(ctx);
+
+       stack_process(ctx, ns1, ":bla!Gebruikersnaam@Computernaam JOIN #bla");
+       stack_process(ctx, ns1, ":bla!Gebruikersnaam@Computernaam PART #bla :hihi");
+
+       g_io_channel_pair(&ch1, &ch2);
+       g_io_channel_set_flags(ch1, G_IO_FLAG_NONBLOCK, NULL);
+       g_io_channel_set_flags(ch2, G_IO_FLAG_NONBLOCK, NULL);
+       cl = client_init(NULL, ch1, "test");
+       g_io_channel_unref(ch1);
+
+       linestack_send(ctx, lm, NULL, cl, FALSE, FALSE);
+       disconnect_client(cl, "foo");
+
+       g_io_channel_read_to_end(ch2, &raw, NULL, NULL);
+
+       fail_unless(!strcmp(raw, ":bla!Gebruikersnaam@Computernaam JOIN #bla\r\n"
+                                                    ":bla!Gebruikersnaam@Computernaam PART #bla :hihi\r\n"
+                                                        "ERROR :foo\r\n"));
+END_TEST
+
+
+
+START_TEST(test_skip_msg)
+       struct network_state *ns1;
+       struct linestack_context *ctx;
+       struct linestack_marker *lm;
+       struct client *cl;
+
+       GIOChannel *ch1, *ch2;
+       char *raw;
+       
+       ns1 = network_state_init("bla", "Gebruikersnaam", "Computernaam");
+       ctx = create_linestack(&linestack_file, "test", my_config, ns1);
+
+       stack_process(ctx, ns1, ":bloe!Gebruikersnaam@Computernaam PRIVMSG #bla :haha");
+
+       lm = linestack_get_marker(ctx);
+
+       stack_process(ctx, ns1, ":bla!Gebruikersnaam@Computernaam JOIN #bla");
+       stack_process(ctx, ns1, ":bloe!Gebruikersnaam@Computernaam PRIVMSG #bla :hihi");
+
+       g_io_channel_pair(&ch1, &ch2);
+       g_io_channel_set_flags(ch1, G_IO_FLAG_NONBLOCK, NULL);
+       g_io_channel_set_flags(ch2, G_IO_FLAG_NONBLOCK, NULL);
+       cl = client_init(NULL, ch1, "test");
+       g_io_channel_unref(ch1);
+
+       linestack_send(ctx, lm, NULL, cl, FALSE, FALSE);
+       disconnect_client(cl, "foo");
+
+       g_io_channel_read_to_end(ch2, &raw, NULL, NULL);
+
+       fail_unless(!strcmp(raw, ":bla!Gebruikersnaam@Computernaam JOIN #bla\r\n"
+                                                    ":bloe!Gebruikersnaam@Computernaam PRIVMSG #bla :hihi\r\n"
+                                                        "ERROR :foo\r\n"));
+END_TEST
+
+START_TEST(test_object_msg)
+       struct network_state *ns1;
+       struct linestack_context *ctx;
+       struct linestack_marker *lm;
+       struct client *cl;
+
+       GIOChannel *ch1, *ch2;
+       char *raw;
+       
+       ns1 = network_state_init("bla", "Gebruikersnaam", "Computernaam");
+       ctx = create_linestack(&linestack_file, "test", my_config, ns1);
+
+       lm = linestack_get_marker(ctx);
+
+       stack_process(ctx, ns1, ":bla!Gebruikersnaam@Computernaam JOIN #foo");
+       stack_process(ctx, ns1, ":bla!Gebruikersnaam@Computernaam JOIN #bla");
+       stack_process(ctx, ns1, ":bloe!Gebruikersnaam@Computernaam PRIVMSG #foo :hihi");
+       stack_process(ctx, ns1, ":bloe!Gebruikersnaam@Computernaam PRIVMSG #bar :hihi");
+       stack_process(ctx, ns1, ":bloe!Gebruikersnaam@Computernaam PRIVMSG #blablie :hihi");
+       stack_process(ctx, ns1, ":bloe!Gebruikersnaam@Computernaam PRIVMSG #bla :hihi");
+
+       g_io_channel_pair(&ch1, &ch2);
+       g_io_channel_set_flags(ch1, G_IO_FLAG_NONBLOCK, NULL);
+       g_io_channel_set_flags(ch2, G_IO_FLAG_NONBLOCK, NULL);
+       cl = client_init(NULL, ch1, "test");
+       g_io_channel_unref(ch1);
+
+       linestack_send_object(ctx, "#bla", lm, NULL, cl, FALSE, FALSE);
+       disconnect_client(cl, "foo");
+
+       g_io_channel_read_to_end(ch2, &raw, NULL, NULL);
+
+       fail_unless(!strcmp(raw, ":bla!Gebruikersnaam@Computernaam JOIN #bla\r\n"
+                                                    ":bloe!Gebruikersnaam@Computernaam PRIVMSG #bla :hihi\r\n"
+                                                        "ERROR :foo\r\n"));
+END_TEST
+
+
+START_TEST(test_object_open)
+       struct network_state *ns1;
+       struct linestack_context *ctx;
+       struct linestack_marker *lm;
+       struct client *cl;
+
+       GIOChannel *ch1, *ch2;
+       char *raw;
+
+       int j;
+       
+       ns1 = network_state_init("bla", "Gebruikersnaam", "Computernaam");
+       ctx = create_linestack(&linestack_file, "test", my_config, ns1);
+
+       lm = linestack_get_marker(ctx);
+
+       stack_process(ctx, ns1, ":bla!Gebruikersnaam@Computernaam JOIN #foo");
+       stack_process(ctx, ns1, ":bla!Gebruikersnaam@Computernaam JOIN #bla");
+       stack_process(ctx, ns1, ":bloe!Gebruikersnaam@Computernaam PRIVMSG #foo :hihi");
+       stack_process(ctx, ns1, ":bloe!Gebruikersnaam@Computernaam PRIVMSG #bar :hihi");
+       stack_process(ctx, ns1, ":bloe!Gebruikersnaam@Computernaam PRIVMSG #blablie :hihi");
+       stack_process(ctx, ns1, ":bloe!Gebruikersnaam@Computernaam PRIVMSG #bla :hihi");
+
+       for (j = 0; j < 4; j++) {
+               g_io_channel_pair(&ch1, &ch2);
+               g_io_channel_set_flags(ch1, G_IO_FLAG_NONBLOCK, NULL);
+               g_io_channel_set_flags(ch2, G_IO_FLAG_NONBLOCK, NULL);
+               cl = client_init(NULL, ch1, "test");
+               g_io_channel_unref(ch1);
+
+               linestack_send_object(ctx, "#bla", NULL, NULL, cl, FALSE, FALSE);
+               disconnect_client(cl, "foo");
+
+               g_io_channel_read_to_end(ch2, &raw, NULL, NULL);
+
+               fail_unless(!strcmp(raw, ":bla!Gebruikersnaam@Computernaam JOIN #bla\r\n"
+                                               ":bloe!Gebruikersnaam@Computernaam PRIVMSG #bla :hihi\r\n"
+                                               "ERROR :foo\r\n"));
+       }
 END_TEST
 
 START_TEST(test_join)
        struct network_state *ns1, *ns2;
        struct linestack_context *ctx;
        
-       ns1 = network_state_init(NULL, "bla", "Gebruikersnaam", "Computernaam");
+       ns1 = network_state_init("bla", "Gebruikersnaam", "Computernaam");
        ctx = create_linestack(&linestack_file, "test", my_config, ns1);
 
        stack_process(ctx, ns1, ":bla!Gebruikersnaam@Computernaam JOIN #bla");
 
-       ns2 = linestack_get_state(ctx, NULL);
+       ns2 = linestack_get_state(ctx, linestack_get_marker(ctx));
 
        fail_unless (network_state_equal(ns1, ns2), "Network state returned not equal");
 END_TEST
 
 Suite *linestack_suite()
 {
-       Suite *s = suite_create("cmp");
+       Suite *s = suite_create("linestack");
        TCase *tc_core = tcase_create("core");
        my_config = g_new0(struct ctrlproxy_config, 1);
        my_config->config_dir = "/tmp";
        suite_add_tcase(s, tc_core);
        tcase_add_test(tc_core, test_empty);
        tcase_add_test(tc_core, test_join);
+       tcase_add_test(tc_core, test_msg);
+       tcase_add_test(tc_core, test_skip_msg);
+       tcase_add_test(tc_core, test_object_msg);
+       tcase_add_test(tc_core, test_object_open);
+       tcase_add_test(tc_core, test_join_part);
        return s;
 }