summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohnny Richard <johnny@johnnyrichard.com>2022-04-10 04:53:29 +0200
committerJohnny Richard <johnny@johnnyrichard.com>2022-04-11 01:51:19 +0200
commit6108b3a1c10d66f8c446ee54acdbe52efcfdf4e8 (patch)
treec2b7c5bbe659ce2631f2d028ebca2ca0bfcb3097
parentcfd0f74bb8156a537a9482222be31723420b035e (diff)
Add testing support
-rw-r--r--.gitignore3
-rw-r--r--Makefile16
-rw-r--r--server.c14
-rw-r--r--test.py57
4 files changed, 83 insertions, 7 deletions
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()