testing: server_main_loop [init]
This commit is contained in:
@@ -23,6 +23,8 @@
|
|||||||
volatile sig_atomic_t shutdown_requested = 0;
|
volatile sig_atomic_t shutdown_requested = 0;
|
||||||
volatile sig_atomic_t signal_received = 0;
|
volatile sig_atomic_t signal_received = 0;
|
||||||
|
|
||||||
|
void set_signals(sigset_t *orig_mask);
|
||||||
|
|
||||||
void term_int_handler(int s) {
|
void term_int_handler(int s) {
|
||||||
shutdown_requested = 1;
|
shutdown_requested = 1;
|
||||||
signal_received = s;
|
signal_received = s;
|
||||||
@@ -31,14 +33,9 @@ void term_int_handler(int s) {
|
|||||||
void server_main_loop(server_data_t *s_d) {
|
void server_main_loop(server_data_t *s_d) {
|
||||||
fd_set readfds;
|
fd_set readfds;
|
||||||
int i, sr;
|
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];
|
session *connections[MAX_CONNECTIONS];
|
||||||
|
|
||||||
for (i = 0; i < MAX_CONNECTIONS; i++) {
|
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);
|
sr = pselect(maxfd + 1, &readfds, NULL, NULL, NULL, &orig_mask);
|
||||||
|
|
||||||
if (shutdown_requested != 0) {
|
if (shutdown_requested != 0) {
|
||||||
@@ -193,4 +189,15 @@ void prepare_start(int argc, char *argv[]) {
|
|||||||
exit(8);
|
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);
|
||||||
}
|
}
|
||||||
@@ -51,8 +51,7 @@ session *make_new_session(int fd, struct sockaddr_in *from, char *wm) {
|
|||||||
sess->file = NULL;
|
sess->file = NULL;
|
||||||
sess->fl_start = NULL;
|
sess->fl_start = NULL;
|
||||||
sess->fl_current = NULL;
|
sess->fl_current = NULL;
|
||||||
session_send_string(sess, wm);
|
session_send_string(sess, "%slogin> ", wm);
|
||||||
session_send_string(sess, "login> ");
|
|
||||||
return sess;
|
return sess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
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
|
add_executable(file_receive_prepare
|
||||||
file_receive_prepare.c
|
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)
|
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
|
add_executable(clear_file_from_sess
|
||||||
clear_file_from_sess.c
|
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)
|
add_test(NAME file_p_clear_file_from_sess_test_1 COMMAND clear_file_from_sess)
|
||||||
|
|
||||||
# ---/ file_download /-------------------------------------------
|
# ---/ file_download /-----------------------------------------------
|
||||||
|
|
||||||
add_executable(file_download
|
add_executable(file_download
|
||||||
file_download.c
|
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)
|
add_test(NAME file_p_file_download_test_1 COMMAND file_download)
|
||||||
|
|
||||||
# ---/ file_upload /-------------------------------------------
|
# ---/ file_upload /-------------------------------------------------
|
||||||
|
|
||||||
add_executable(file_upload
|
add_executable(file_upload
|
||||||
file_upload.c
|
file_upload.c
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# ---/ start_server /--------------------------------------------------
|
# ---/ start_server /------------------------------------------------
|
||||||
|
|
||||||
add_executable(start_server
|
add_executable(start_server
|
||||||
start_server.c
|
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)
|
add_test(NAME client_start_server_test_1 COMMAND start_server)
|
||||||
|
|
||||||
# ---/ prepare_start /--------------------------------------------------
|
# ---/ prepare_start /-----------------------------------------------
|
||||||
|
|
||||||
add_executable(prepare_start
|
add_executable(prepare_start
|
||||||
prepare_start.c
|
prepare_start.c
|
||||||
@@ -36,6 +36,27 @@ target_link_libraries(prepare_start
|
|||||||
test_utils
|
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)
|
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)
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <cmocka.h>
|
||||||
|
#include <main.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <server.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user