diff options
author | Johnny Richard <johnny@johnnyrichard.com> | 2022-04-10 04:53:29 +0200 |
---|---|---|
committer | Johnny Richard <johnny@johnnyrichard.com> | 2022-04-11 01:51:19 +0200 |
commit | 6108b3a1c10d66f8c446ee54acdbe52efcfdf4e8 (patch) | |
tree | c2b7c5bbe659ce2631f2d028ebca2ca0bfcb3097 | |
parent | cfd0f74bb8156a537a9482222be31723420b035e (diff) |
Add testing support
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | Makefile | 16 | ||||
-rw-r--r-- | server.c | 14 | ||||
-rw-r--r-- | test.py | 57 |
4 files changed, 83 insertions, 7 deletions
@@ -1,3 +1,6 @@ papo tags *.o +*.so +.exrc +__pycache__ @@ -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 @@ -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; } @@ -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() |