From 6108b3a1c10d66f8c446ee54acdbe52efcfdf4e8 Mon Sep 17 00:00:00 2001 From: Johnny Richard Date: Sun, 10 Apr 2022 04:53:29 +0200 Subject: Add testing support --- .gitignore | 3 +++ Makefile | 16 ++++++++++++++++ server.c | 14 +++++++------- test.py | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 83 insertions(+), 7 deletions(-) create mode 100644 test.py diff --git a/.gitignore b/.gitignore index d6ee6fc..616a87a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ papo tags *.o +*.so +.exrc +__pycache__ diff --git a/Makefile b/Makefile index c9b5be6..58bf569 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,20 @@ 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 + +.PHONY: test +test: libpapo.so + @python test.py + +libpapo.so: server.o log.o + $(CC) $(CFLAGS) -shared -o libpapo.so server.o log.o + +log.o: log.c + $(CC) $(CFLAGS) -fPIC -c log.c + +.PHONY: clean +clean: + rm *.o *.so diff --git a/server.c b/server.c index 25d9c45..9a74222 100644 --- a/server.c +++ b/server.c @@ -43,7 +43,7 @@ server_init(server_t *server, uint32_t port) int server_fd = socket(AF_INET, SOCK_STREAM, 0); if (server_fd == -1) { - log_error("unable to create a socket: %s", strerror(errno)); + log_fatal("unable to create a socket: %s", strerror(errno)); exit(EXIT_FAILURE); } server->fd = server_fd; @@ -57,13 +57,13 @@ server_init(server_t *server, uint32_t port) setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt_val, sizeof(opt_val)); if (bind(server_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)) == -1) { - log_error("could not bind: %s", strerror(errno)); + log_fatal("could not bind: %s", strerror(errno)); close(server_fd); exit(EXIT_FAILURE); } if (listen(server_fd, SOMAXCONN) == -1) { - log_error("could not listen: %s", strerror(errno)); + log_fatal("could not listen: %s", strerror(errno)); close(server_fd); exit(EXIT_FAILURE); } @@ -72,7 +72,7 @@ server_init(server_t *server, uint32_t port) server->epoll_fd = epoll_create1(0); if (server->epoll_fd == -1) { - log_error("faild to create epoll: %s", strerror(errno)); + log_fatal("faild to create epoll: %s", strerror(errno)); exit(EXIT_FAILURE); } @@ -81,11 +81,11 @@ server_init(server_t *server, uint32_t port) event.data.fd = server->fd; if (epoll_ctl(server->epoll_fd, EPOLL_CTL_ADD, server->fd, &event) == -1) { - log_error("could not add server to epoll: %s", strerror(errno)); + log_fatal("could not add server to epoll: %s", strerror(errno)); exit(EXIT_FAILURE); } - log_info("server listening at port (%d)", port); + log_debug("server listening on port (%d)", port); } void @@ -176,7 +176,7 @@ server_handle_client_data(server_t *server, struct epoll_event *event) } if (!strncasecmp(client_buf, EXIT_COMMAND, strlen(EXIT_COMMAND) - 1)) { - log_info("exiting program. bye bye!"); + log_debug("exiting program. bye bye!"); server->running = false; } diff --git a/test.py b/test.py new file mode 100644 index 0000000..e1e3028 --- /dev/null +++ b/test.py @@ -0,0 +1,57 @@ +import ctypes +import socket +import threading +import time +import unittest + +libpapo = ctypes.CDLL('./libpapo.so') + +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'A msg from client') + data = s.recv(1024) + self.assertIn(b':A msg from client', 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() -- cgit v1.2.3