diff --git a/src/components/server/server.c b/src/components/server/server.c index 5f36f64..f1f3536 100644 --- a/src/components/server/server.c +++ b/src/components/server/server.c @@ -23,6 +23,8 @@ volatile sig_atomic_t shutdown_requested = 0; volatile sig_atomic_t signal_received = 0; +void set_signals(sigset_t *orig_mask); + void term_int_handler(int s) { shutdown_requested = 1; signal_received = s; @@ -31,14 +33,9 @@ void term_int_handler(int s) { void server_main_loop(server_data_t *s_d) { fd_set readfds; int i, sr; - sigset_t mask, orig_mask; + sigset_t orig_mask; + set_signals(&orig_mask); - signal(SIGINT, term_int_handler); - signal(SIGTERM, term_int_handler); - sigemptyset(&mask); - sigaddset(&mask, SIGINT); - sigaddset(&mask, SIGTERM); - sigprocmask(SIG_BLOCK, &mask, &orig_mask); session *connections[MAX_CONNECTIONS]; for (i = 0; i < MAX_CONNECTIONS; i++) { @@ -69,7 +66,6 @@ void server_main_loop(server_data_t *s_d) { } } } - sr = pselect(maxfd + 1, &readfds, NULL, NULL, NULL, &orig_mask); if (shutdown_requested != 0) { @@ -193,4 +189,15 @@ void prepare_start(int argc, char *argv[]) { exit(8); } } +} + +void set_signals(sigset_t *orig_mask) { + sigset_t mask; + + signal(SIGINT, term_int_handler); + signal(SIGTERM, term_int_handler); + sigemptyset(&mask); + sigaddset(&mask, SIGINT); + sigaddset(&mask, SIGTERM); + sigprocmask(SIG_BLOCK, &mask, orig_mask); } \ No newline at end of file diff --git a/src/components/session/session.c b/src/components/session/session.c index e24720e..35211bc 100644 --- a/src/components/session/session.c +++ b/src/components/session/session.c @@ -51,8 +51,7 @@ session *make_new_session(int fd, struct sockaddr_in *from, char *wm) { sess->file = NULL; sess->fl_start = NULL; sess->fl_current = NULL; - session_send_string(sess, wm); - session_send_string(sess, "login> "); + session_send_string(sess, "%slogin> ", wm); return sess; } diff --git a/test/file_p/CMakeLists.txt b/test/file_p/CMakeLists.txt index d246b76..01b9650 100644 --- a/test/file_p/CMakeLists.txt +++ b/test/file_p/CMakeLists.txt @@ -65,7 +65,7 @@ target_link_options(file_send_prepare PRIVATE -Wl,--wrap=write,--wrap=print_log, add_test(NAME file_p_file_send_prepare_test_1 COMMAND file_send_prepare) -# ---/ file_receive_prepare /------------------------------------------- +# ---/ file_receive_prepare /---------------------------------------- add_executable(file_receive_prepare file_receive_prepare.c @@ -83,7 +83,7 @@ target_link_options(file_receive_prepare PRIVATE -Wl,--wrap=statvfs,--wrap=stat, add_test(NAME file_p_file_receive_prepare_test_1 COMMAND file_receive_prepare) -# ---/ clear_file_from_sess /------------------------------------------- +# ---/ clear_file_from_sess /---------------------------------------- add_executable(clear_file_from_sess clear_file_from_sess.c @@ -101,7 +101,7 @@ target_link_options(clear_file_from_sess PRIVATE -Wl,--wrap=free) add_test(NAME file_p_clear_file_from_sess_test_1 COMMAND clear_file_from_sess) -# ---/ file_download /------------------------------------------- +# ---/ file_download /----------------------------------------------- add_executable(file_download file_download.c @@ -120,7 +120,7 @@ target_link_options(file_download PRIVATE -Wl,--wrap=print_log,--wrap=read,--wra add_test(NAME file_p_file_download_test_1 COMMAND file_download) -# ---/ file_upload /------------------------------------------- +# ---/ file_upload /------------------------------------------------- add_executable(file_upload file_upload.c diff --git a/test/server/CMakeLists.txt b/test/server/CMakeLists.txt index f854c23..3d54a7d 100644 --- a/test/server/CMakeLists.txt +++ b/test/server/CMakeLists.txt @@ -1,4 +1,4 @@ -# ---/ start_server /-------------------------------------------------- +# ---/ start_server /------------------------------------------------ add_executable(start_server start_server.c @@ -19,7 +19,7 @@ target_link_options(start_server PRIVATE -Wl,--wrap=socket,--wrap=setsockopt,--w add_test(NAME client_start_server_test_1 COMMAND start_server) -# ---/ prepare_start /-------------------------------------------------- +# ---/ prepare_start /----------------------------------------------- add_executable(prepare_start prepare_start.c @@ -36,6 +36,27 @@ target_link_libraries(prepare_start test_utils ) -target_link_options(prepare_start PRIVATE -Wl,--wrap=print_log,--wrap=print_log,--wrap=chdir,--wrap=mkdir,--wrap=exit,--wrap=directory_exists) +target_link_options(prepare_start PRIVATE -Wl,--wrap=print_log,--wrap=chdir,--wrap=mkdir,--wrap=exit,--wrap=directory_exists) -add_test(NAME client_prepare_start_test_1 COMMAND prepare_start) \ No newline at end of file +add_test(NAME client_prepare_start_test_1 COMMAND prepare_start) + +# ---/ server_main_loop /-------------------------------------------- + +add_executable(server_main_loop + server_main_loop.c +) + +target_link_libraries(server_main_loop + cmocka + client + file_p + session + utils + main + server + test_utils +) + +target_link_options(server_main_loop PRIVATE -Wl,--wrap=print_log) + +add_test(NAME client_server_main_loop_test_1 COMMAND server_main_loop) \ No newline at end of file diff --git a/test/server/server_main_loop.c b/test/server/server_main_loop.c new file mode 100644 index 0000000..056a0e2 --- /dev/null +++ b/test/server/server_main_loop.c @@ -0,0 +1,123 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CLIENT_PORT PORT + 1 + +int sd = -1; +int lpid = -1; +int _addr; +volatile sig_atomic_t child_ready = 0; +#define WELCOME_MES "Hello everyworld!\n" + +int init_client(void); +bool connect_to_server(int sd, int addr, short int port); +void _server_loop(); +void usr1hdl(int n) { child_ready = true; } +int setup(void **state); +int tear_down(void **state); + +/* === TESTS === */ + +/* TODO: better solution than sleep() */ +void test__welcome(void **state) { + char str[] = WELCOME_MES "login> "; + char buf[256]; + int rlen = read(sd, buf, 128); + buf[rlen] = 0; + assert_string_equal(str, buf); +} + +/* === MAIN === */ +int main(int argc, char **argv) { + const struct CMUnitTest tests[] = {cmocka_unit_test(test__welcome)}; + return cmocka_run_group_tests(tests, setup, tear_down); +} + +/* === ADDITIONAL === */ +bool connect_to_server(int sd, int addr, short int port) { + struct sockaddr_in server; + server.sin_family = AF_INET; + server.sin_addr.s_addr = addr; + server.sin_port = port; + + if (-1 == connect(sd, (struct sockaddr *)&server, sizeof(server))) { + return false; + } + + return true; +} + +int init_client(void) { + int res; + int cs = socket(AF_INET, SOCK_STREAM, 0); + struct sockaddr_in client; + + client.sin_family = AF_INET; + client.sin_port = htons(CLIENT_PORT); + client.sin_addr.s_addr = htonl(INADDR_ANY); + + int opt = 1; + setsockopt(cs, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); + + res = bind(cs, (struct sockaddr *)&client, sizeof(client)); + if (res == -1) { + exit(1); + } + return cs; +} + +void _server_loop() { + server_data_t s_d = {.ls = start_server(), + .welcome_message = WELCOME_MES}; + if (s_d.ls == -1) { + kill(getppid(), SIGTERM); + exit(1); + } + kill(getppid(), SIGUSR1); + server_main_loop(&s_d); + exit(0); +} + +int setup(void **state) { + sigset_t mask_usr1, mask_empty; + sigemptyset(&mask_usr1); + sigaddset(&mask_usr1, SIGUSR1); + sigemptyset(&mask_empty); + sigprocmask(SIG_SETMASK, &mask_usr1, NULL); + signal(SIGUSR1, usr1hdl); + + lpid = fork(); + + if (lpid == 0) { + _server_loop(); + } + + while (!child_ready) + sigsuspend(&mask_empty); + struct sockaddr_in addr; + inet_aton("127.0.0.1", &(addr.sin_addr)); + _addr = addr.sin_addr.s_addr; + + sd = init_client(); + int res = connect_to_server(sd, _addr, htons(PORT)); + if (!res) { + perror("connect failed"); + kill(lpid, SIGTERM); + exit(1); + } + return 0; +} + +int tear_down(void **state) { + kill(lpid, SIGTERM); + return 0; +}