From 31708d22cceeca508541c0d087e66053fd79bca0 Mon Sep 17 00:00:00 2001 From: Francesco Cozzuto Date: Sat, 24 Jan 2026 17:29:56 +0100 Subject: [PATCH] Add feature testing build --- .gitignore | 1 + build.sh | 7 +-- src/basic.c | 2 +- src/byte_queue.c | 2 +- src/chunk_server.c | 2 +- src/client.c | 2 +- src/file_system.c | 2 +- src/file_system.h | 2 +- src/file_tree.c | 2 +- src/hash_set.c | 2 +- src/main.c | 113 +++++++++++++++++++++++++++++++++++++++++- src/message.c | 2 +- src/message.h | 2 +- src/metadata_server.c | 2 +- src/tcp.c | 2 +- src/tcp.h | 2 +- src/test_client.c | 95 +++++++++++++++++++++++++++++++++++ src/test_client.h | 21 ++++++++ src/wal.c | 2 +- 19 files changed, 246 insertions(+), 19 deletions(-) create mode 100644 src/test_client.c create mode 100644 src/test_client.h diff --git a/.gitignore b/.gitignore index a526b72..4786cee 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ toasty_metadata_server toasty_chunk_server +toasty_test toasty_simulation toasty_simulation_coverage *.gcno diff --git a/build.sh b/build.sh index d082bce..872c0b9 100644 --- a/build.sh +++ b/build.sh @@ -1,3 +1,4 @@ -gcc src/sha256.c src/basic.c src/file_system.c src/byte_queue.c src/file_tree.c src/message.c src/tcp.c src/wal.c src/hash_set.c src/client.c src/metadata_server.c src/chunk_server.c src/random_client.c src/main.c quakey/src/mockfs.c quakey/src/quakey.c -o toasty_simulation -Iquakey/include -Iinclude -Wall -Wextra -ggdb -O0 -DMAIN_SIMULATION -DFAULT_INJECTION -gcc src/sha256.c src/basic.c src/file_system.c src/byte_queue.c src/file_tree.c src/message.c src/tcp.c src/wal.c src/hash_set.c src/client.c src/metadata_server.c src/chunk_server.c src/random_client.c src/main.c -o toasty_metadata_server -DMAIN_METADATA_SERVER -Wall -Wextra -ggdb -O0 -Iinclude -Iquakey/include -gcc src/sha256.c src/basic.c src/file_system.c src/byte_queue.c src/file_tree.c src/message.c src/tcp.c src/wal.c src/hash_set.c src/client.c src/metadata_server.c src/chunk_server.c src/random_client.c src/main.c -o toasty_chunk_server -DMAIN_CHUNK_SERVER -Wall -Wextra -ggdb -O0 -Iinclude -Iquakey/include +gcc src/sha256.c src/basic.c src/file_system.c src/byte_queue.c src/file_tree.c src/message.c src/tcp.c src/wal.c src/hash_set.c src/client.c src/metadata_server.c src/chunk_server.c src/random_client.c src/test_client.c src/main.c quakey/src/mockfs.c quakey/src/quakey.c -o toasty_simulation -Iquakey/include -Iinclude -Wall -Wextra -ggdb -O0 -DMAIN_SIMULATION -DFAULT_INJECTION +gcc src/sha256.c src/basic.c src/file_system.c src/byte_queue.c src/file_tree.c src/message.c src/tcp.c src/wal.c src/hash_set.c src/client.c src/metadata_server.c src/chunk_server.c src/random_client.c src/test_client.c src/main.c quakey/src/mockfs.c quakey/src/quakey.c -o toasty_test -Iquakey/include -Iinclude -Wall -Wextra -ggdb -O0 -DMAIN_TEST +gcc src/sha256.c src/basic.c src/file_system.c src/byte_queue.c src/file_tree.c src/message.c src/tcp.c src/wal.c src/hash_set.c src/client.c src/metadata_server.c src/chunk_server.c src/random_client.c src/test_client.c src/main.c -o toasty_metadata_server -DMAIN_METADATA_SERVER -Wall -Wextra -ggdb -O0 -Iinclude -Iquakey/include +gcc src/sha256.c src/basic.c src/file_system.c src/byte_queue.c src/file_tree.c src/message.c src/tcp.c src/wal.c src/hash_set.c src/client.c src/metadata_server.c src/chunk_server.c src/random_client.c src/test_client.c src/main.c -o toasty_chunk_server -DMAIN_CHUNK_SERVER -Wall -Wextra -ggdb -O0 -Iinclude -Iquakey/include diff --git a/src/basic.c b/src/basic.c index 364e46e..57f4abc 100644 --- a/src/basic.c +++ b/src/basic.c @@ -1,4 +1,4 @@ -#ifdef MAIN_SIMULATION +#if defined(MAIN_SIMULATION) || defined(MAIN_TEST) #define QUAKEY_ENABLE_MOCKS #endif #include diff --git a/src/byte_queue.c b/src/byte_queue.c index f382a23..bb807d6 100644 --- a/src/byte_queue.c +++ b/src/byte_queue.c @@ -1,4 +1,4 @@ -#ifdef MAIN_SIMULATION +#if defined(MAIN_SIMULATION) || defined(MAIN_TEST) #define QUAKEY_ENABLE_MOCKS #endif diff --git a/src/chunk_server.c b/src/chunk_server.c index 99a475c..7bef118 100644 --- a/src/chunk_server.c +++ b/src/chunk_server.c @@ -1,4 +1,4 @@ -#ifdef MAIN_SIMULATION +#if defined(MAIN_SIMULATION) || defined(MAIN_TEST) #define QUAKEY_ENABLE_MOCKS #endif diff --git a/src/client.c b/src/client.c index b1387cb..fca999c 100644 --- a/src/client.c +++ b/src/client.c @@ -1,4 +1,4 @@ -#ifdef MAIN_SIMULATION +#if defined(MAIN_SIMULATION) || defined(MAIN_TEST) #define QUAKEY_ENABLE_MOCKS #endif diff --git a/src/file_system.c b/src/file_system.c index 63bb836..4b2ff47 100644 --- a/src/file_system.c +++ b/src/file_system.c @@ -1,4 +1,4 @@ -#ifdef MAIN_SIMULATION +#if defined(MAIN_SIMULATION) || defined(MAIN_TEST) #define QUAKEY_ENABLE_MOCKS #endif #include diff --git a/src/file_system.h b/src/file_system.h index d12ce5e..298a32a 100644 --- a/src/file_system.h +++ b/src/file_system.h @@ -1,7 +1,7 @@ #ifndef FILE_SYSTEM_INCLUDED #define FILE_SYSTEM_INCLUDED -#ifdef MAIN_SIMULATION +#if defined(MAIN_SIMULATION) || defined(MAIN_TEST) #define QUAKEY_ENABLE_MOCKS #endif #include diff --git a/src/file_tree.c b/src/file_tree.c index 1abfb7a..4e5ea8b 100644 --- a/src/file_tree.c +++ b/src/file_tree.c @@ -1,4 +1,4 @@ -#ifdef MAIN_SIMULATION +#if defined(MAIN_SIMULATION) || defined(MAIN_TEST) #define QUAKEY_ENABLE_MOCKS #endif diff --git a/src/hash_set.c b/src/hash_set.c index 80b7ae2..f0ade33 100644 --- a/src/hash_set.c +++ b/src/hash_set.c @@ -1,4 +1,4 @@ -#ifdef MAIN_SIMULATION +#if defined(MAIN_SIMULATION) || defined(MAIN_TEST) #define QUAKEY_ENABLE_MOCKS #endif #include diff --git a/src/main.c b/src/main.c index 0230f44..c48d3a2 100644 --- a/src/main.c +++ b/src/main.c @@ -131,7 +131,7 @@ int main(void) // Client 1 { QuakeySpawn config = { - .name = "client 1", + .name = "cli1", .state_size = sizeof(RandomClient), .init_func = random_client_init, .tick_func = random_client_tick, @@ -147,7 +147,7 @@ int main(void) // Client 2 { QuakeySpawn config = { - .name = "client 2", + .name = "cli2", .state_size = sizeof(RandomClient), .init_func = random_client_init, .tick_func = random_client_tick, @@ -231,3 +231,112 @@ int main(void) return 0; } #endif // MAIN_SIMULATION + +#ifdef MAIN_TEST +#include +#include "test_client.h" + +static volatile int simulation_running = 1; + +static void sigint_handler(int sig) +{ + (void)sig; + simulation_running = 0; +} + +int main(void) +{ + signal(SIGINT, sigint_handler); + + Quakey *quakey; + int ret = quakey_init(&quakey, 1); + if (ret < 0) + return -1; + + // Client 1 + { + QuakeySpawn config = { + .name = "test_cli_1", + .state_size = sizeof(TestClient), + .init_func = test_client_init, + .tick_func = test_client_tick, + .free_func = test_client_free, + .addrs = (char*[]) { "127.0.0.2" }, + .num_addrs = 1, + .disk_size = 10<<20, + .platform = QUAKEY_LINUX, + }; + quakey_spawn(quakey, config, "cli --server 127.0.0.3 8080"); + } + + // Metadata Server + { + QuakeySpawn config = { + .name = "ms", + .state_size = sizeof(MetadataServer), + .init_func = metadata_server_init, + .tick_func = metadata_server_tick, + .free_func = metadata_server_free, + .addrs = (char*[]) { "127.0.0.3" }, + .num_addrs = 1, + .disk_size = 10<<20, + .platform = QUAKEY_LINUX, + }; + quakey_spawn(quakey, config, "ms --addr 127.0.0.3 --port 8080"); + } + + // Chunk Server 1 + { + QuakeySpawn config = { + .name = "cs1", + .state_size = sizeof(ChunkServer), + .init_func = chunk_server_init, + .tick_func = chunk_server_tick, + .free_func = chunk_server_free, + .addrs = (char*[]) { "127.0.0.4" }, + .num_addrs = 1, + .disk_size = 10<<20, + .platform = QUAKEY_LINUX, + }; + quakey_spawn(quakey, config, "cs --addr 127.0.0.4 --port 8081 --remote-addr 127.0.0.3 --remote-port 8080"); + } + + // Chunk Server 2 + { + QuakeySpawn config = { + .name = "cs2", + .state_size = sizeof(ChunkServer), + .init_func = chunk_server_init, + .tick_func = chunk_server_tick, + .free_func = chunk_server_free, + .addrs = (char*[]) { "127.0.0.5" }, + .num_addrs = 1, + .disk_size = 10<<20, + .platform = QUAKEY_LINUX, + }; + quakey_spawn(quakey, config, "cs --addr 127.0.0.5 --port 8082 --remote-addr 127.0.0.3 --remote-port 8080"); + } + + // Chunk Server 3 + { + QuakeySpawn config = { + .name = "cs3", + .state_size = sizeof(ChunkServer), + .init_func = chunk_server_init, + .tick_func = chunk_server_tick, + .free_func = chunk_server_free, + .addrs = (char*[]) { "127.0.0.6" }, + .num_addrs = 1, + .disk_size = 10<<20, + .platform = QUAKEY_LINUX, + }; + quakey_spawn(quakey, config, "cs --addr 127.0.0.6 --port 8083 --remote-addr 127.0.0.3 --remote-port 8080"); + } + + while (simulation_running) + quakey_schedule_one(quakey); + + quakey_free(quakey); + return 0; +} +#endif // MAIN_TEST diff --git a/src/message.c b/src/message.c index 67b7d1c..5b9391e 100644 --- a/src/message.c +++ b/src/message.c @@ -1,4 +1,4 @@ -#ifdef MAIN_SIMULATION +#if defined(MAIN_SIMULATION) || defined(MAIN_TEST) #define QUAKEY_ENABLE_MOCKS #endif #include diff --git a/src/message.h b/src/message.h index 9d1c220..71aacd8 100644 --- a/src/message.h +++ b/src/message.h @@ -1,7 +1,7 @@ #ifndef MESSAGE_INCLUDED #define MESSAGE_INCLUDED -#ifdef MAIN_SIMULATION +#if defined(MAIN_SIMULATION) || defined(MAIN_TEST) #define QUAKEY_ENABLE_MOCKS #endif #include diff --git a/src/metadata_server.c b/src/metadata_server.c index 7c8bb66..bbe3239 100644 --- a/src/metadata_server.c +++ b/src/metadata_server.c @@ -1,4 +1,4 @@ -#ifdef MAIN_SIMULATION +#if defined(MAIN_SIMULATION) || defined(MAIN_TEST) #define QUAKEY_ENABLE_MOCKS #endif diff --git a/src/tcp.c b/src/tcp.c index ec8de4f..765bc91 100644 --- a/src/tcp.c +++ b/src/tcp.c @@ -1,5 +1,5 @@ -#ifdef MAIN_SIMULATION +#if defined(MAIN_SIMULATION) || defined(MAIN_TEST) #define QUAKEY_ENABLE_MOCKS #endif diff --git a/src/tcp.h b/src/tcp.h index 02e6e8c..fa77297 100644 --- a/src/tcp.h +++ b/src/tcp.h @@ -1,7 +1,7 @@ #ifndef TCP_INCLUDED #define TCP_INCLUDED -#ifdef MAIN_SIMULATION +#if defined(MAIN_SIMULATION) || defined(MAIN_TEST) # define QUAKEY_ENABLE_MOCKS # include #else diff --git a/src/test_client.c b/src/test_client.c new file mode 100644 index 0000000..99f1e6f --- /dev/null +++ b/src/test_client.c @@ -0,0 +1,95 @@ +#ifdef MAIN_TEST + +#define QUAKEY_ENABLE_MOCKS +#include +#include + +#include "tcp.h" +#include "test_client.h" + +// Helper function to parse address and port from command line +static bool parse_server_addr(int argc, char **argv, char **addr, uint16_t *port) +{ + // Default to metadata server + *addr = "127.0.0.1"; + *port = 8080; + + for (int i = 0; i < argc - 1; i++) { + if (!strcmp(argv[i], "--server") || !strcmp(argv[i], "-s")) { + *addr = argv[i + 1]; + if (i + 2 < argc) { + + errno = 0; + char *end; + long val = strtol(argv[i+2], &end, 10); + + if (end == argv[i+2] || *end != '\0' || errno == ERANGE) + break; + + if (val < 0 || val > UINT16_MAX) + break; + + *port = (uint16_t) val; + return true; + } + } + } + return true; +} + +int test_client_init(void *state_, int argc, char **argv, + void **ctxs, struct pollfd *pdata, int pcap, int *pnum, + int *timeout) +{ + TestClient *client = state_; + + char *addr; + uint16_t port; + parse_server_addr(argc, argv, &addr, &port); + + client->toasty = toasty_connect((ToastyString) { addr, strlen(addr) }, port); + if (client->toasty == NULL) + return -1; + + printf("Client set up (remote=%s:%d)\n", addr, port); + + *timeout = 0; + if (pcap < TCP_POLL_CAPACITY) + return -1; + *pnum = toasty_process_events(client->toasty, ctxs, pdata, *pnum); + return 0; +} + +static int random_in_range(int min, int max) +{ + uint64_t n = quakey_random(); + return min + n % (max - min + 1); +} + +int test_client_tick(void *state_, void **ctxs, + struct pollfd *pdata, int pcap, int *pnum, + int *timeout) +{ + TestClient *client = state_; + + // Process any pending events from the network and get new poll descriptors + *pnum = toasty_process_events(client->toasty, ctxs, pdata, *pnum); + + assert(0); // TODO + + *timeout = -1; + if (pcap < TCP_POLL_CAPACITY) + return -1; + *pnum = toasty_process_events(client->toasty, ctxs, pdata, 0); + return 0; +} + +int test_client_free(void *state_) +{ + TestClient *client = state_; + + toasty_disconnect(client->toasty); + return 0; +} + +#endif // MAIN_TEST \ No newline at end of file diff --git a/src/test_client.h b/src/test_client.h new file mode 100644 index 0000000..ace4c01 --- /dev/null +++ b/src/test_client.h @@ -0,0 +1,21 @@ +#ifndef TEST_CLIENT_INCLUDED +#define TEST_CLIENT_INCLUDED + +#include "ToastyFS.h" + +typedef struct { + ToastyFS *toasty; +} TestClient; + +struct pollfd; + +int test_client_init(void *state, int argc, char **argv, + void **ctxs, struct pollfd *pdata, int pcap, int *pnum, + int *timeout); + +int test_client_tick(void *state, void **ctxs, + struct pollfd *pdata, int pcap, int *pnum, int *timeout); + +int test_client_free(void *state); + +#endif // TEST_CLIENT_INCLUDED \ No newline at end of file diff --git a/src/wal.c b/src/wal.c index a3f94a8..967b2c2 100644 --- a/src/wal.c +++ b/src/wal.c @@ -1,5 +1,5 @@ -#ifdef MAIN_SIMULATION +#if defined(MAIN_SIMULATION) || defined(MAIN_TEST) #define QUAKEY_ENABLE_MOCKS #endif