From 22283ef54b66495e2c88e0dbac9856c4a34434a6 Mon Sep 17 00:00:00 2001 From: Johnny Richard Date: Tue, 12 Apr 2022 03:33:59 +0200 Subject: Add munit testing framework support --- .gitignore | 1 + .gitmodules | 3 ++ Makefile | 21 ++++++++----- README | 28 ----------------- README.md | 36 ++++++++++++++++++++++ ftest.py | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++ hash_table.c | 34 +++++++++++++++++++++ hash_table.h | 36 ++++++++++++++++++++++ server.c | 6 ++-- server.h | 6 ++-- test.py | 66 ---------------------------------------- test/Makefile | 13 ++++++++ test/hash_table_test.c | 49 ++++++++++++++++++++++++++++++ test/munit | 1 + 14 files changed, 274 insertions(+), 108 deletions(-) create mode 100644 .gitmodules delete mode 100644 README create mode 100644 README.md create mode 100644 ftest.py create mode 100644 hash_table.c create mode 100644 hash_table.h delete mode 100644 test.py create mode 100644 test/Makefile create mode 100644 test/hash_table_test.c create mode 160000 test/munit diff --git a/.gitignore b/.gitignore index 616a87a..ee92416 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ papo +test/*_test tags *.o *.so diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..a9cc99c --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "test/munit"] + path = test/munit + url = https://github.com/nemequ/munit/ diff --git a/Makefile b/Makefile index d9a3929..22d10a7 100644 --- a/Makefile +++ b/Makefile @@ -1,20 +1,25 @@ -CFLAGS=-DLOG_USE_COLOR CC=gcc .PHONY: all -all: main.c server.c log.c - $(CC) $(CFLAGS) -g -o papo main.c server.c log.c +all: main.c server.o log.o hash_table.o + $(CC) -g -o papo main.c server.o log.o hash_table.o .PHONY: test -test: libpapo.so - @python test.py -v --locals +test: all + @make -C test + +.PHONY: ftest +ftest: libpapo.so + @python ftest.py -v --locals libpapo.so: server.o log.o - $(CC) $(CFLAGS) -shared -o libpapo.so server.o log.o + $(CC) -shared -o libpapo.so server.o log.o log.o: log.c - $(CC) $(CFLAGS) -fPIC -c log.c + $(CC) -DLOG_USE_COLOR -fPIC -c log.c .PHONY: clean clean: - rm *.o *.so + @$(RM) *.o + @$(RM) *.so + @$(RM) papo diff --git a/README b/README deleted file mode 100644 index 7365cc9..0000000 --- a/README +++ /dev/null @@ -1,28 +0,0 @@ -PAPO -==== - -Minimal IRC Server implementation. - -DEVELOPMENT ------------ - -Requirements: - - 1) gcc - -Compiling instructions: - - $ make - -CONTRIBUTE ----------- - -We accept patches on our mailing list[1] (use git-send-email to avoid issues -with your patches). We recommend you to follow the mailing etiquette[2] before -send/reply emails to our mailing list. - ---- - -Links: -[1]: ~johnnyrichard/papo-devel@lists.sr.ht -[2]: https://man.sr.ht/lists.sr.ht/etiquette.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..6e267ae --- /dev/null +++ b/README.md @@ -0,0 +1,36 @@ +PAPO IRC Server +=============== + +Minimal IRC Server implementation. + +DEVELOPMENT +----------- + +Requirements + + 1. gcc + 2. python3 + +### Compiling + + $ make + +### Testing + +Make sure you have unit submodule cloned before run tests. You can run `git +submodule update --init` to get the submodules cloned. + + $ make test + +CONTRIBUTE +---------- + +We accept patches on our mailing list[^1] (use git-send-email to avoid issues +with your patches). We recommend you to follow the mailing etiquette[^2] before +send/reply emails to our mailing list. + +--- + +Links: +[^1]: ~johnnyrichard/papo-devel@lists.sr.ht +[^2]: https://man.sr.ht/lists.sr.ht/etiquette.md diff --git a/ftest.py b/ftest.py new file mode 100644 index 0000000..f8c3195 --- /dev/null +++ b/ftest.py @@ -0,0 +1,82 @@ +# Papo IRC Server +# Copyright (C) 2021 Johnny Richard +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +import ctypes +import socket +import threading +import time +import unittest + + +libpapo = ctypes.CDLL('./libpapo.so') +unittest.util._MAX_LENGTH=2000 + + +class PapoServerTest(unittest.TestCase): + + + @classmethod + def setUpClass(cls): + server = papo_server(); + thread = threading.Thread(target=cls.run_papo_server, args=(server,)) + thread.start() + time.sleep(2) + + + @classmethod + def tearDownClass(cls): + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.connect(('localhost', 6667)) + s.sendall(b'exit') + + + @classmethod + def run_papo_server(cls, server): + libpapo.server_init(ctypes.byref(server), 6667) + libpapo.server_run(ctypes.byref(server)) + + + def test_server_run(self): + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.connect(('localhost', 6667)) + s.sendall(b'USER username 0 * :User Name\r\n') + data = s.recv(1024) + self.assertIn(b'001 username :Welcome!\r\n', data) + + +class epoll_data(ctypes.Union): + _fields_ = [('ptr', ctypes.c_void_p), + ('fd', ctypes.c_int), + ('u32', ctypes.c_uint), + ('u64', ctypes.c_ulong)] + + +class epoll_event(ctypes.Structure): + _fields_ = [('events', ctypes.c_uint), + ('epoll_data_t', epoll_data)] + + +class papo_server(ctypes.Structure): + _MAXEVENTS=64 + _fields_ = [('fd', ctypes.c_int), + ('epoll_fd', ctypes.c_int), + ('events', epoll_event * _MAXEVENTS), + ('connected_clients', ctypes.c_int * _MAXEVENTS), + ('running', ctypes.c_bool)] + + +if __name__ == '__main__': + unittest.main() diff --git a/hash_table.c b/hash_table.c new file mode 100644 index 0000000..0fc28c7 --- /dev/null +++ b/hash_table.c @@ -0,0 +1,34 @@ +/* + * Papo IRC Server + * Copyright (C) 2021 Johnny Richard + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +#include "hash_table.h" + +#include +#include + +#define INITAL_CAPACITY 16 + +hash_table_t* +hash_table_new(void) +{ + hash_table_t* ht = malloc(sizeof(hash_table_t)); + if (ht == NULL) { + fprintf(stderr, "could not create hash_table: out of memory\n"); + return NULL; + } + return ht; +} diff --git a/hash_table.h b/hash_table.h new file mode 100644 index 0000000..5ac3cfd --- /dev/null +++ b/hash_table.h @@ -0,0 +1,36 @@ +/* + * Papo IRC Server + * Copyright (C) 2021 Johnny Richard + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +#ifndef HASH_TABLE_H +#define HASH_TABLE + +#include + +typedef struct hash_entry { + const char* key; + void* value; +} hash_entry_t; + +typedef struct hash_table { + hash_entry_t* entries; + size_t capacity; + size_t length; +} hash_table_t; + +hash_table_t* hash_table_new(); + +#endif /* HASH_TABLE_H */ diff --git a/server.c b/server.c index 16b3354..cb8b28d 100644 --- a/server.c +++ b/server.c @@ -1,17 +1,17 @@ /* * Papo IRC Server * Copyright (C) 2021 Johnny Richard - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 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 Affero General Public License for more details. - * + * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ diff --git a/server.h b/server.h index 4cc1ab2..fb37b6f 100644 --- a/server.h +++ b/server.h @@ -1,17 +1,17 @@ /* * Papo IRC Server * Copyright (C) 2021 Johnny Richard - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 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 Affero General Public License for more details. - * + * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ diff --git a/test.py b/test.py deleted file mode 100644 index 9f6421e..0000000 --- a/test.py +++ /dev/null @@ -1,66 +0,0 @@ -import ctypes -import socket -import threading -import time -import unittest - - -libpapo = ctypes.CDLL('./libpapo.so') -unittest.util._MAX_LENGTH=2000 - - -class PapoServerTest(unittest.TestCase): - - - @classmethod - def setUpClass(cls): - server = papo_server(); - thread = threading.Thread(target=cls.run_papo_server, args=(server,)) - thread.start() - time.sleep(2) - - - @classmethod - def tearDownClass(cls): - with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: - s.connect(('localhost', 6667)) - s.sendall(b'exit') - - - @classmethod - def run_papo_server(cls, server): - libpapo.server_init(ctypes.byref(server), 6667) - libpapo.server_run(ctypes.byref(server)) - - - def test_server_run(self): - with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: - s.connect(('localhost', 6667)) - s.sendall(b'USER username 0 * :User Name\r\n') - data = s.recv(1024) - self.assertIn(b'001 username :Welcome!\r\n', data) - - -class epoll_data(ctypes.Union): - _fields_ = [('ptr', ctypes.c_void_p), - ('fd', ctypes.c_int), - ('u32', ctypes.c_uint), - ('u64', ctypes.c_ulong)] - - -class epoll_event(ctypes.Structure): - _fields_ = [('events', ctypes.c_uint), - ('epoll_data_t', epoll_data)] - - -class papo_server(ctypes.Structure): - _MAXEVENTS=64 - _fields_ = [('fd', ctypes.c_int), - ('epoll_fd', ctypes.c_int), - ('events', epoll_event * _MAXEVENTS), - ('connected_clients', ctypes.c_int * _MAXEVENTS), - ('running', ctypes.c_bool)] - - -if __name__ == '__main__': - unittest.main() diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..3d86f0e --- /dev/null +++ b/test/Makefile @@ -0,0 +1,13 @@ +CC=gcc + +.PHONY: all +all: hash_table_test + +.PHONY: hash_table_test +hash_table_test: ../hash_table.o hash_table_test.c + $(CC) -o hash_table_test ../hash_table.o hash_table_test.c + ./hash_table_test + +.PHONY: clean +clean: + @$(RM) hash_table_test diff --git a/test/hash_table_test.c b/test/hash_table_test.c new file mode 100644 index 0000000..075c9d2 --- /dev/null +++ b/test/hash_table_test.c @@ -0,0 +1,49 @@ +/* + * Papo IRC Server + * Copyright (C) 2021 Johnny Richard + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +#define MUNIT_ENABLE_ASSERT_ALIASES +#include "munit/munit.c" +#include "../hash_table.h" + +#include + +static MunitResult +test_create_new(const MunitParameter params[], + void *user_data_or_fixture) +{ + hash_table_t* table = hash_table_new(); + + assert_not_null(table); + + return MUNIT_OK; +} + +static MunitTest tests[] = { + { "/test_create_new", test_create_new, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }, + { NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL } +}; + +static const MunitSuite suite = { + "/hash_table", tests, NULL, 1, MUNIT_SUITE_OPTION_NONE +}; + +int +main(int argc, char *argv[]) +{ + return munit_suite_main(&suite, NULL, argc, argv); + return EXIT_SUCCESS; +} diff --git a/test/munit b/test/munit new file mode 160000 index 0000000..fbbdf14 --- /dev/null +++ b/test/munit @@ -0,0 +1 @@ +Subproject commit fbbdf1467eb0d04a6ee465def2e529e4c87f2118 -- cgit v1.2.3