#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)
{
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;
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)
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;
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;
}