/** * 受信 * * @param[in] sockfd ソケット * @param[in] rbuf 受信バッファ * @retval EX_NG エラー */ static int recv_client(int sockfd, uchar *rbuf) { size_t length = 0; /* バイト数 */ struct header hd; /* ヘッダ構造体 */ int retval = 0; /* 戻り値 */ dbglog("start"); /* ヘッダ受信 */ length = sizeof(struct header); (void)memset(&hd, 0, length); retval = recv_data(sockfd, &hd, &length); if (retval < 0) { cut_notify("recv_data: length=%zu(%d)", length, errno); return EX_NG; } length = (size_t)ntohl((uint32_t)hd.length); /* 受信 */ retval = recv_data(sockfd, rbuf, &length); if (retval < 0) { cut_notify("recv_data: length=%zu(%d)", length, errno); return EX_NG; } return EX_OK; }
/** * 送信 * * @param[in] sockfd ソケット * @param[in] sbuf 送信バッファ * @param[in] length バイト数 * @retval EX_NG エラー */ static int send_client(int sockfd, uchar *sbuf, size_t length) { struct client_data *cdata = NULL; /* 送信データ構造体 */ ssize_t slen = 0; /* 送信データバイト数 */ int retval = 0; /* 戻り値 */ dbglog("start"); /* データ設定 */ slen = set_client_data(&cdata, sbuf, length); if (slen < 0) { cut_notify("set_server_data=%zd(%d)", slen, errno); return EX_NG; } /* 送信 */ retval = send_data(sockfd, cdata, (size_t *)&slen); if (retval < 0) { cut_notify("send_data: slen=%zd(%d)", slen, errno); memfree((void **)&cdata, NULL); return EX_NG; } memfree((void **)&cdata, NULL); return EX_OK; }
/** * シグナル設定 * * @return なし */ static void set_sig_handler(void) { /* シグナル無視 */ if (signal(SIGTERM, SIG_IGN) < 0) cut_notify("SIGTERM"); if (signal(SIGQUIT, SIG_IGN) < 0) cut_notify("SIGQUIT"); if (signal(SIGHUP, SIG_IGN) < 0) cut_notify("SIGHUP"); if (signal(SIGALRM, SIG_IGN) < 0) cut_notify("SIGALRM"); }
/** * 初期化処理 * * @return なし */ void cut_startup(void) { set_sig_handler(); /* バッファリングしない */ if (setvbuf(stdin, NULL, _IONBF, 0)) cut_notify("setvbuf: stdin(%d)", errno); if (setvbuf(stdout, NULL, _IONBF, 0)) cut_notify("setvbuf: stdout(%d)", errno); (void)memset(&server, 0, sizeof(testserver)); test_init_server(&server); /* リダイレクト */ redirect(STDERR_FILENO, "/dev/null"); }
static void stub_notification_iterated_test (gconstpointer data) { cut_assert_true(TRUE, cut_message("always pass")); if (GPOINTER_TO_INT(data) == 2) MARK_FAIL(cut_notify("NOTIFICATION!")); cut_assert_true(TRUE, cut_message("always pass if come here")); }
/** * test_server_loop() 関数テスト * * @return なし */ void test_server_loop(void) { pid_t cpid = 0; /* 子プロセスID */ pid_t w = 0; /* wait戻り値 */ int status = 0; /* wait引数 */ int retval = 0; /* 戻り値 */ int count = 1; /* ループカウント */ if (set_port_string(port) < 0) cut_error("set_port_string"); ssock = server_sock(); cpid = fork(); if (cpid < 0) { cut_error("fork(%d)", errno); return; } if (cpid == 0) { dbglog("child"); count = 2; g_sig_handled = 1; while (count--) server_loop(ssock); exit(EXIT_SUCCESS); } else { dbglog("parent: cpid=%d", (int)cpid); csock = inet_sock_client(); if (csock < 0) return; /* 送信 */ retval = send_client(csock, expr, sizeof(expr)); if (retval < 0) { cut_error("send_client: csock=%d(%d)", csock, errno); return; } /* 受信 */ retval = recv_client(csock, readbuf); if (retval < 0) { cut_error("recv_client: csock=%d(%d)", csock, errno); return; } cut_assert_equal_string((char *)expected, (char *)readbuf); w = wait(&status); if (w < 0) cut_notify("wait(%d)", errno); dbglog("w=%d", (int)w); } }
static gboolean watch_func (GIOChannel *channel, GIOCondition condition, gpointer data) { MilterTestClient *client = data; gboolean keep_callback = TRUE; if (condition & G_IO_IN || condition & G_IO_PRI) { keep_callback = accept_server(client); } if (condition & G_IO_ERR || condition & G_IO_HUP || condition & G_IO_NVAL) { gchar *message; message = milter_utils_inspect_io_condition_error(condition); cut_notify("%s", message); g_free(message); return FALSE; } return keep_callback; }
/** * test_server_proc() 関数テスト * * @return なし */ void test_server_proc(void) { pid_t cpid = 0; /* 子プロセスID */ pid_t w = 0; /* wait戻り値 */ int status = 0; /* wait引数 */ int retval = 0; /* 戻り値 */ thread_data *dt = NULL; /* ソケット情報構造体 */ void *servret = NULL; /* テスト関数戻り値 */ if (set_port_string(port) < 0) cut_error("set_port_string"); ssock = server_sock(); cpid = fork(); if (cpid < 0) { cut_error("fork(%d)", errno); return; } if (cpid == 0) { dbglog("child"); dt = (thread_data *)malloc(sizeof(thread_data)); if (!dt) { outlog("malloc: size=%zu", sizeof(thread_data)); exit(EXIT_FAILURE); } (void)memset(dt, 0, sizeof(thread_data)); dt->len = (socklen_t)sizeof(dt->addr); dt->sock = accept(ssock, (struct sockaddr *)&dt->addr, &dt->len); if (dt->sock < 0) { outlog("accept: ssock=%d", ssock); memfree((void **)&dt, NULL); exit(EXIT_FAILURE); } g_sig_handled = 1; /* テスト関数実行 */ servret = server.server_proc(dt); if (servret) { outlog("server_proc"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); } else { dbglog("parent: cpid=%d", (int)cpid); csock = inet_sock_client(); if (csock < 0) return; /* 送信 */ retval = send_client(csock, expr, sizeof(expr)); if (retval < 0) { cut_error("send_client: csock=%d(%d)", csock, errno); return; } /* 受信 */ retval = recv_client(csock, readbuf); if (retval < 0) { cut_error("recv_client: csock=%d(%d)", csock, errno); return; } cut_assert_equal_string((char *)expected, (char *)readbuf); w = wait(&status); if (w < 0) cut_notify("wait(%d)", errno); dbglog("w=%d", (int)w); if (WEXITSTATUS(status)) cut_error("child failed"); } }
static void stub_notification_test (void) { MARK_FAIL(cut_notify("This test has been notifable ever!")); }
/** * readline() 実行 * * @param[in] data テストデータ * @param[in] length バイト数 * @return 結果文字列 */ static unsigned char * exec_readline(char *data, size_t length) { FILE *fp = NULL; /* ファイルポインタ */ int retval = 0; /* 戻り値 */ pid_t cpid = 0; /* プロセスID */ pid_t w = 0; /* wait戻り値 */ int status = 0; /* ステイタス */ ssize_t len = 0; /* writen 戻り値 */ retval = pipe(pfd); if (retval < 0) { cut_error("pipe=%d", retval); return NULL; } fp = fdopen(pfd[PIPE_R], "r"); if (!fp) { cut_error("fdopen=%p", fp); return NULL; } cpid = fork(); if (cpid < 0) { cut_error("fork(%d)", errno); return NULL; } if (cpid == 0) { /* 子プロセス */ dbglog("child"); close_fd(&pfd[PIPE_R], NULL); /* 送信 */ len = writen(pfd[PIPE_W], data, length); if (len < 0) { outlog("writen"); close_fd(&pfd[PIPE_W], NULL); exit(EXIT_FAILURE); } close_fd(&pfd[PIPE_W], NULL); exit(EXIT_SUCCESS); } else { /* 親プロセス */ dbglog("parent: cpid=%d", (int)cpid); close_fd(&pfd[PIPE_W], NULL); /* テスト関数の実行 */ /* 受信待ち */ result = _readline(fp); dbglog("result=%s", result); close_fd(&pfd[PIPE_R], NULL); w = waitpid(-1, &status, WNOHANG); if (w < 0) cut_notify("wait: status=%d(%d)", status, errno); dbglog("w=%d", (int)w); if (WEXITSTATUS(status)) { cut_notify("child error"); return NULL; } } return result; }