]> jfr.im git - irc/charybdis-ircd/charybdis.git/commitdiff
tests: add sendto_* test framework
authorSimon Arlott <sa.me.uk>
Sat, 5 Aug 2017 13:09:01 +0000 (14:09 +0100)
committerSimon Arlott <sa.me.uk>
Sat, 5 Aug 2017 13:09:01 +0000 (14:09 +0100)
16 files changed:
.gitignore
ircd/ircd.c
tests/Makefile.am
tests/TESTS
tests/client_util.c [new file with mode: 0644]
tests/client_util.h [new file with mode: 0644]
tests/ircd_util.c [new file with mode: 0644]
tests/ircd_util.h [new file with mode: 0644]
tests/runtime/bin/authd [new symlink]
tests/runtime/bin/bandb [new symlink]
tests/runtime/bin/ssld [new symlink]
tests/runtime/bin/wsockd [new symlink]
tests/runtime/help [new symlink]
tests/runtime/motd [new file with mode: 0644]
tests/send1.c [new file with mode: 0644]
tests/send1.conf [new file with mode: 0644]

index d1d39a8f5b164fd7004e9a165ebf2994b0adea57..014dd13a3b1c1c81c2f0481d9624baab02f79b92 100644 (file)
@@ -56,13 +56,19 @@ ircd/version.c
 ircd/version.c.last
 ssld/ssld
 wsockd/wsockd
+tests/core
 tests/msgbuf_parse1
 tests/msgbuf_unparse1
 tests/rb_linebuf_put1
 tests/rb_snprintf_append1
 tests/rb_snprintf_try_append1
+tests/send1
 tests/substitution1
 tests/runtests
+tests/*.c.ban.db
+tests/*.c.ban.db-journal
+tests/*.c.log
+tests/*.c.pid
 testsuite/ircd.pid.*
 tools/charybdis-mkpasswd
 tools/charybdis-mkfingerprint
index d68430720be145440e2d1430a89fb99d4cc29b6d..c224d40e15157f6fad70d585ae2dc51ca93c4d2d 100644 (file)
@@ -823,13 +823,6 @@ charybdis_main(int argc, char * const argv[])
                        ircd_ssl_ok = true;
        }
 
-       if (testing_conf)
-       {
-               fprintf(stderr, "\nConfig testing complete.\n");
-               fflush(stderr);
-               return 0;       /* Why? We want the launcher to exit out. */
-       }
-
        me.from = &me;
        me.servptr = &me;
        SetMe(&me);
@@ -843,6 +836,13 @@ charybdis_main(int argc, char * const argv[])
 
        construct_umodebuf();
 
+       if (testing_conf)
+       {
+               fprintf(stderr, "\nConfig testing complete.\n");
+               fflush(stderr);
+               return 0;       /* Why? We want the launcher to exit out. */
+       }
+
        check_class();
        write_pidfile(pidFileName);
        load_help();
index c57b876a262eb95ce3efb2fc43ec20cf7ce6d85e..20da4da9b7d954830f947daed6d94ef33339e209 100644 (file)
@@ -4,6 +4,7 @@ check_PROGRAMS = runtests \
        rb_linebuf_put1 \
        rb_snprintf_append1 \
        rb_snprintf_try_append1 \
+       send1 \
        substitution1
 AM_CFLAGS=$(WARNFLAGS)
 AM_CPPFLAGS = $(DEFAULT_INCLUDES) -I../librb/include -I..
@@ -24,7 +25,16 @@ msgbuf_unparse1_SOURCES = msgbuf_unparse1.c
 rb_linebuf_put1_SOURCES = rb_linebuf_put1.c
 rb_snprintf_append1_SOURCES = rb_snprintf_append1.c
 rb_snprintf_try_append1_SOURCES = rb_snprintf_try_append1.c
+send1_SOURCES = send1.c ircd_util.c client_util.c
 substitution1_SOURCES = substitution1.c
 
-check-local: $(check_PROGRAMS)
+check-local: $(check_PROGRAMS) \
+       ../authd/authd \
+       ../bandb/bandb \
+       ../ssld/ssld \
+       ../wsockd/wsockd \
+       $(patsubst ../modules/%.c,../modules/.libs/%.so,$(wildcard ../modules/*.c)) \
+       $(patsubst ../modules/core/%.c,../modules/core/.libs/%.so,$(wildcard ../modules/core/*.c)) \
+       $(patsubst ../extensions/%.c,../extensions/.libs/%.so,$(wildcard ../extensions/*.c))
+
        ./runtests -l $(abs_top_srcdir)/tests/TESTS
index e5849befe467b5049cc6fa85d482086fd8021504..e4a4acb5e1f26e8dd121015922ae500cb8654315 100644 (file)
@@ -3,4 +3,5 @@ msgbuf_unparse1
 rb_linebuf_put1
 rb_snprintf_append1
 rb_snprintf_try_append1
+send1
 substitution1
diff --git a/tests/client_util.c b/tests/client_util.c
new file mode 100644 (file)
index 0000000..9a6468e
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ *  client_util.c: Utility functions for making test clients
+ *  Copyright 2017 Simon Arlott
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
+ *  USA
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "tap/basic.h"
+
+#include "stdinc.h"
+#include "ircd_defs.h"
+#include "client_util.h"
+
+#define MSG "%s:%d (%s)", __FILE__, __LINE__, __FUNCTION__
+
+struct Client *make_local_person(void)
+{
+       return make_local_person_nick(TEST_NICK);
+}
+
+struct Client *make_local_person_nick(const char *nick)
+{
+       return make_local_person_full(nick, TEST_USERNAME, TEST_HOSTNAME, TEST_IP, TEST_REALNAME);
+}
+
+struct Client *make_local_person_full(const char *nick, const char *username, const char *hostname, const char *ip, const char *realname)
+{
+       struct Client *client;
+
+       client = make_client(NULL);
+       rb_dlinkMoveNode(&client->localClient->tnode, &unknown_list, &lclient_list);
+       client->servptr = &me;
+       rb_dlinkAdd(client, &client->lnode, &client->servptr->serv->users);
+       SetClient(client);
+       make_user(client);
+
+       rb_inet_pton_sock(ip, (struct sockaddr *)&client->localClient->ip);
+       rb_strlcpy(client->name, nick, sizeof(client->name));
+       rb_strlcpy(client->username, username, sizeof(client->username));
+       rb_strlcpy(client->host, hostname, sizeof(client->host));
+       rb_inet_ntop_sock((struct sockaddr *)&client->localClient->ip, client->sockhost, sizeof(client->sockhost));
+       rb_strlcpy(client->info, realname, sizeof(client->info));
+
+       return client;
+}
+
+void remove_local_person(struct Client *client)
+{
+       exit_client(NULL, client, &me, "Test client removed");
+}
+
+char *get_client_sendq(const struct Client *client)
+{
+       static char buf[EXT_BUFSIZE + sizeof(CRLF)];
+
+       if (rb_linebuf_len(&client->localClient->buf_sendq)) {
+               int ret;
+
+               memset(buf, 0, sizeof(buf));
+               ret = rb_linebuf_get(&client->localClient->buf_sendq, buf, sizeof(buf), 0, 1);
+
+               if (is_bool(ret > 0, true, MSG)) {
+                       return buf;
+               } else {
+                       return "<get_client_sendq error>";
+               }
+       }
+
+       return "";
+}
+
+void client_util_init(void)
+{
+}
+
+void client_util_free(void)
+{
+}
diff --git a/tests/client_util.h b/tests/client_util.h
new file mode 100644 (file)
index 0000000..5bacac0
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ *  client_util.c: Utility functions for making test clients
+ *  Copyright 2017 Simon Arlott
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
+ *  USA
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "stdinc.h"
+#include "ircd_defs.h"
+#include "msg.h"
+#include "client.h"
+
+#define TEST_NICK "test"
+#define TEST_USERNAME "username"
+#define TEST_HOSTNAME "example.test"
+#define TEST_IP "2001:db8::1:5ee:bad:c0de"
+#define TEST_REALNAME "Test user"
+
+#define CRLF "\r\n"
+
+void client_util_init(void);
+void client_util_free(void);
+
+struct Client *make_local_person(void);
+struct Client *make_local_person_nick(const char *nick);
+struct Client *make_local_person_full(const char *nick, const char *username, const char *hostname, const char *ip, const char *realname);
+void remove_local_person(struct Client *client);
+
+char *get_client_sendq(const struct Client *client);
+
+#define is_client_sendq_empty(client, message, ...) do { \
+               is_string("", get_client_sendq(client), message, ##__VA_ARGS__); \
+       } while (0)
+
+#define is_client_sendq(queue, client, message, ...) do { \
+               is_string(queue, get_client_sendq(client), message, ##__VA_ARGS__); \
+               is_client_sendq_empty(client, message, ##__VA_ARGS__); \
+       } while (0)
diff --git a/tests/ircd_util.c b/tests/ircd_util.c
new file mode 100644 (file)
index 0000000..b6e895d
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ *  ircd_util.c: Utility functions for making test ircds
+ *  Copyright 2017 Simon Arlott
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
+ *  USA
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "tap/basic.h"
+
+#include "stdinc.h"
+#include "ircd_defs.h"
+#include "defaults.h"
+#include "client.h"
+#include "ircd_util.h"
+
+#define MSG "%s:%d (%s)", __FILE__, __LINE__, __FUNCTION__
+
+extern int charybdis_main(int argc, const char *argv[]);
+
+static char argv0[BUFSIZE];
+static char configfile[BUFSIZE];
+static char logfile[BUFSIZE];
+static char pidfile[BUFSIZE];
+
+static const char *argv[] = {
+       argv0,
+       "-configfile", configfile,
+       "-logfile", logfile,
+       "-pidfile", pidfile,
+       "-conftest",
+       NULL,
+};
+
+void ircd_util_init(const char *name)
+{
+       rb_strlcpy(argv0, name, sizeof(argv0));
+       snprintf(configfile, sizeof(configfile), "%sonf", name);
+       snprintf(logfile, sizeof(logfile), "%s.log", name);
+       snprintf(pidfile, sizeof(pidfile), "%s.pid", name);
+       unlink(logfile);
+       unlink(pidfile);
+
+       rb_lib_init(NULL, NULL, NULL, 0, 1024, DNODE_HEAP_SIZE, FD_HEAP_SIZE);
+       rb_linebuf_init(LINEBUF_HEAP_SIZE);
+
+       char buf[BUFSIZE];
+       ircd_paths[IRCD_PATH_IRCD_EXEC] = argv0;
+       ircd_paths[IRCD_PATH_PREFIX] = ".";
+
+       snprintf(buf, sizeof(buf), "runtime%cmodules", RB_PATH_SEPARATOR);
+       ircd_paths[IRCD_PATH_MODULES] = rb_strdup(buf);
+
+       snprintf(buf, sizeof(buf), "runtime%1$cmodules%1$cautoload", RB_PATH_SEPARATOR);
+       ircd_paths[IRCD_PATH_AUTOLOAD_MODULES] = rb_strdup(buf);
+
+       ircd_paths[IRCD_PATH_ETC] = "runtime";
+       ircd_paths[IRCD_PATH_LOG] = "runtime";
+
+       snprintf(buf, sizeof(buf), "runtime%1$chelp%1$cusers", RB_PATH_SEPARATOR);
+       ircd_paths[IRCD_PATH_USERHELP] = rb_strdup(buf);
+
+       snprintf(buf, sizeof(buf), "runtime%1$chelp%1$copers", RB_PATH_SEPARATOR);
+       ircd_paths[IRCD_PATH_OPERHELP] = rb_strdup(buf);
+
+       snprintf(buf, sizeof(buf), "runtime%cmotd", RB_PATH_SEPARATOR);
+       ircd_paths[IRCD_PATH_IRCD_MOTD] = rb_strdup(buf);
+       ircd_paths[IRCD_PATH_IRCD_OMOTD] = rb_strdup(buf);
+
+       snprintf(buf, sizeof(buf), "%s.ban.db", name);
+       ircd_paths[IRCD_PATH_BANDB] = rb_strdup(buf);
+       snprintf(buf, sizeof(buf), "%s.ban.db-journal", name);
+       unlink(buf);
+
+       ircd_paths[IRCD_PATH_IRCD_PID] = rb_strdup(pidfile);
+       ircd_paths[IRCD_PATH_IRCD_LOG] = rb_strdup(logfile);
+
+       snprintf(buf, sizeof(buf), "runtime%cbin", RB_PATH_SEPARATOR);
+       ircd_paths[IRCD_PATH_BIN] = rb_strdup(buf);
+       ircd_paths[IRCD_PATH_LIBEXEC] = rb_strdup(buf);
+
+       is_int(0, charybdis_main(ARRAY_SIZE(argv) - 1, argv), MSG);
+}
+
+void ircd_util_free(void)
+{
+}
diff --git a/tests/ircd_util.h b/tests/ircd_util.h
new file mode 100644 (file)
index 0000000..cde5adb
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ *  ircd_util.c: Utility functions for making test ircds
+ *  Copyright 2017 Simon Arlott
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
+ *  USA
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "stdinc.h"
+#include "ircd_defs.h"
+
+#define TEST_ME_NAME "me.test"
+
+void ircd_util_init(const char *name);
+void ircd_util_free(void);
diff --git a/tests/runtime/bin/authd b/tests/runtime/bin/authd
new file mode 120000 (symlink)
index 0000000..e4c0453
--- /dev/null
@@ -0,0 +1 @@
+../../../authd/authd
\ No newline at end of file
diff --git a/tests/runtime/bin/bandb b/tests/runtime/bin/bandb
new file mode 120000 (symlink)
index 0000000..3543deb
--- /dev/null
@@ -0,0 +1 @@
+../../../bandb/bandb
\ No newline at end of file
diff --git a/tests/runtime/bin/ssld b/tests/runtime/bin/ssld
new file mode 120000 (symlink)
index 0000000..0f55f62
--- /dev/null
@@ -0,0 +1 @@
+../../../ssld/ssld
\ No newline at end of file
diff --git a/tests/runtime/bin/wsockd b/tests/runtime/bin/wsockd
new file mode 120000 (symlink)
index 0000000..0331b16
--- /dev/null
@@ -0,0 +1 @@
+../../../wsockd/wsockd
\ No newline at end of file
diff --git a/tests/runtime/help b/tests/runtime/help
new file mode 120000 (symlink)
index 0000000..92f6500
--- /dev/null
@@ -0,0 +1 @@
+../../help
\ No newline at end of file
diff --git a/tests/runtime/motd b/tests/runtime/motd
new file mode 100644 (file)
index 0000000..980a0d5
--- /dev/null
@@ -0,0 +1 @@
+Hello World!
diff --git a/tests/send1.c b/tests/send1.c
new file mode 100644 (file)
index 0000000..2ed74ab
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ *  send1.c: Test sendto_* under various conditions
+ *  Copyright 2017 Simon Arlott
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
+ *  USA
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "tap/basic.h"
+
+#include "ircd_util.h"
+#include "client_util.h"
+
+#include "send.h"
+
+#define MSG "%s:%d (%s)", __FILE__, __LINE__, __FUNCTION__
+
+static void sendto_one_numeric1(void)
+{
+       struct Client *user = make_local_person();
+
+       sendto_one_numeric(user, 1, "Hello %s!", "World");
+       is_client_sendq(":" TEST_ME_NAME " 001 " TEST_NICK " Hello World!" CRLF, user, MSG);
+
+       remove_local_person(user);
+}
+
+static void sendto_wallops_flags1(void)
+{
+       struct Client *user1 = make_local_person_nick("user1");
+       struct Client *user2 = make_local_person_nick("user2");
+       struct Client *oper1 = make_local_person_nick("oper1");
+       struct Client *oper2 = make_local_person_nick("oper2");
+       struct Client *oper3 = make_local_person_nick("oper3");
+       struct Client *oper4 = make_local_person_nick("oper4");
+
+       rb_dlinkAddAlloc(oper1, &local_oper_list);
+       rb_dlinkAddAlloc(oper1, &oper_list);
+       SetOper(oper1);
+
+       rb_dlinkAddAlloc(oper2, &local_oper_list);
+       rb_dlinkAddAlloc(oper2, &oper_list);
+       SetOper(oper2);
+
+       rb_dlinkAddAlloc(oper3, &local_oper_list);
+       rb_dlinkAddAlloc(oper3, &oper_list);
+       SetOper(oper3);
+
+       rb_dlinkAddAlloc(oper4, &local_oper_list);
+       rb_dlinkAddAlloc(oper4, &oper_list);
+       SetOper(oper4);
+
+       user1->umodes |= UMODE_WALLOP;
+       oper1->umodes |= UMODE_WALLOP | UMODE_OPERWALL;
+       oper2->umodes |= UMODE_WALLOP | UMODE_OPERWALL | UMODE_ADMIN;
+       oper3->umodes |= UMODE_WALLOP;
+       oper4->umodes |= UMODE_OPERWALL;
+
+       sendto_wallops_flags(UMODE_WALLOP, oper1, "Test to users");
+       is_client_sendq(":oper1!" TEST_USERNAME "@" TEST_HOSTNAME " WALLOPS :Test to users" CRLF, user1, "User is +w; " MSG);
+       is_client_sendq_empty(user2, "User is -w; " MSG);
+       is_client_sendq(":oper1!" TEST_USERNAME "@" TEST_HOSTNAME " WALLOPS :Test to users" CRLF, oper1, "User is +w; " MSG);
+       is_client_sendq(":oper1!" TEST_USERNAME "@" TEST_HOSTNAME " WALLOPS :Test to users" CRLF, oper2, "User is +w; " MSG);
+       is_client_sendq(":oper1!" TEST_USERNAME "@" TEST_HOSTNAME " WALLOPS :Test to users" CRLF, oper3, "User is +w; " MSG);
+       is_client_sendq_empty(oper4, "User is -w; " MSG);
+
+       sendto_wallops_flags(UMODE_OPERWALL, oper2, "Test to opers");
+       is_client_sendq_empty(user1, "Not an oper; " MSG);
+       is_client_sendq_empty(user2, "Not an oper; " MSG);
+       is_client_sendq(":oper2!" TEST_USERNAME "@" TEST_HOSTNAME " WALLOPS :Test to opers" CRLF, oper1, "Oper is +z; " MSG);
+       is_client_sendq(":oper2!" TEST_USERNAME "@" TEST_HOSTNAME " WALLOPS :Test to opers" CRLF, oper2, "Oper is +z; " MSG);
+       is_client_sendq_empty(oper3, "Oper is -z; " MSG);
+       is_client_sendq(":oper2!" TEST_USERNAME "@" TEST_HOSTNAME " WALLOPS :Test to opers" CRLF, oper4, "Oper is +z; " MSG);
+
+       sendto_wallops_flags(UMODE_ADMIN, &me, "Test to admins");
+       is_client_sendq_empty(user1, "Not an admin; " MSG);
+       is_client_sendq_empty(user2, "Not an admin; " MSG);
+       is_client_sendq_empty(oper1, "Not an admin; " MSG);
+       is_client_sendq(":" TEST_ME_NAME " WALLOPS :Test to admins" CRLF, oper2, MSG);
+       is_client_sendq_empty(oper3, "Not an admin; " MSG);
+       is_client_sendq_empty(oper4, "Not an admin; " MSG);
+
+       remove_local_person(user1);
+       remove_local_person(user2);
+       remove_local_person(oper1);
+       remove_local_person(oper2);
+       remove_local_person(oper3);
+       remove_local_person(oper4);
+}
+
+int main(int argc, char *argv[])
+{
+       plan_lazy();
+
+       ircd_util_init(__FILE__);
+       client_util_init();
+
+       sendto_one_numeric1();
+       sendto_wallops_flags1();
+
+       client_util_free();
+       ircd_util_free();
+       return 0;
+}
diff --git a/tests/send1.conf b/tests/send1.conf
new file mode 100644 (file)
index 0000000..3c198e2
--- /dev/null
@@ -0,0 +1,7 @@
+serverinfo {
+       sid = "0AA";
+       name = "me.test";
+       description = "Test server";
+       network_name = "Test network";
+};
+