| check_ipc.c | check_ipc.c | |||
|---|---|---|---|---|
| skipping to change at line 27 | skipping to change at line 27 | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU Lesser General Public License for more details. | * GNU Lesser General Public License for more details. | |||
| * | * | |||
| * You should have received a copy of the GNU Lesser General Public License | * You should have received a copy of the GNU Lesser General Public License | |||
| * along with libqb. If not, see <http://www.gnu.org/licenses/>. | * along with libqb. If not, see <http://www.gnu.org/licenses/>. | |||
| */ | */ | |||
| #include <stdio.h> | #include <stdio.h> | |||
| #include <stdlib.h> | #include <stdlib.h> | |||
| #include <unistd.h> | #include <unistd.h> | |||
| #include <syslog.h> | ||||
| #include <sys/types.h> | #include <sys/types.h> | |||
| #include <sys/wait.h> | #include <sys/wait.h> | |||
| #include <errno.h> | #include <errno.h> | |||
| #include <signal.h> | #include <signal.h> | |||
| #include <check.h> | #include <check.h> | |||
| #include <qb/qbdefs.h> | #include <qb/qbdefs.h> | |||
| #include <qb/qbutil.h> | #include <qb/qblog.h> | |||
| #include <qb/qbipcc.h> | #include <qb/qbipcc.h> | |||
| #include <qb/qbipcs.h> | #include <qb/qbipcs.h> | |||
| #include <qb/qbloop.h> | #include <qb/qbloop.h> | |||
| #define IPC_NAME "ipc_test" | static const char *ipc_name = "ipc_test"; | |||
| #define MAX_MSG_SIZE (8192*16) | #define MAX_MSG_SIZE (8192*16) | |||
| static qb_ipcc_connection_t *conn; | static qb_ipcc_connection_t *conn; | |||
| static enum qb_ipc_type ipc_type; | static enum qb_ipc_type ipc_type; | |||
| enum my_msg_ids { | enum my_msg_ids { | |||
| IPC_MSG_REQ_TX_RX, | IPC_MSG_REQ_TX_RX, | |||
| IPC_MSG_RES_TX_RX, | IPC_MSG_RES_TX_RX, | |||
| IPC_MSG_REQ_DISPATCH, | IPC_MSG_REQ_DISPATCH, | |||
| IPC_MSG_RES_DISPATCH, | IPC_MSG_RES_DISPATCH, | |||
| IPC_MSG_REQ_SERVER_FAIL, | IPC_MSG_REQ_SERVER_FAIL, | |||
| skipping to change at line 79 | skipping to change at line 78 | |||
| * | * | |||
| * 8) multiple services | * 8) multiple services | |||
| */ | */ | |||
| static qb_loop_t *my_loop; | static qb_loop_t *my_loop; | |||
| static qb_ipcs_service_t* s1; | static qb_ipcs_service_t* s1; | |||
| static int32_t turn_on_fc = QB_FALSE; | static int32_t turn_on_fc = QB_FALSE; | |||
| static int32_t fc_enabled = 89; | static int32_t fc_enabled = 89; | |||
| static int32_t exit_handler(int32_t rsignal, void *data) | static int32_t exit_handler(int32_t rsignal, void *data) | |||
| { | { | |||
| qb_log(LOG_DEBUG, "caught signal %d", rsignal); | ||||
| qb_ipcs_destroy(s1); | qb_ipcs_destroy(s1); | |||
| qb_loop_stop(my_loop); | ||||
| exit(0); | ||||
| return -1; | return -1; | |||
| } | } | |||
| static int32_t s1_msg_process_fn(qb_ipcs_connection_t *c, | static int32_t s1_msg_process_fn(qb_ipcs_connection_t *c, | |||
| void *data, size_t size) | void *data, size_t size) | |||
| { | { | |||
| struct qb_ipc_request_header *req_pt = (struct qb_ipc_request_header *)data; | struct qb_ipc_request_header *req_pt = (struct qb_ipc_request_header *)data; | |||
| struct qb_ipc_response_header response; | struct qb_ipc_response_header response; | |||
| ssize_t res; | ssize_t res; | |||
| if (req_pt->id == IPC_MSG_REQ_TX_RX) { | if (req_pt->id == IPC_MSG_REQ_TX_RX) { | |||
| response.size = sizeof(struct qb_ipc_response_header); | response.size = sizeof(struct qb_ipc_response_header); | |||
| response.id = IPC_MSG_RES_TX_RX; | response.id = IPC_MSG_RES_TX_RX; | |||
| response.error = 0; | response.error = 0; | |||
| res = qb_ipcs_response_send(c, &response, | res = qb_ipcs_response_send(c, &response, response.size); | |||
| sizeof(response)); | ||||
| if (res < 0) { | if (res < 0) { | |||
| perror("qb_ipcs_response_send"); | qb_perror(LOG_INFO, "qb_ipcs_response_send"); | |||
| } else if (res != response.size) { | ||||
| qb_log(LOG_DEBUG, "qb_ipcs_response_send %zd != %d", | ||||
| res, response.size); | ||||
| } | } | |||
| if (turn_on_fc) { | if (turn_on_fc) { | |||
| qb_ipcs_request_rate_limit(s1, QB_IPCS_RATE_OFF); | qb_ipcs_request_rate_limit(s1, QB_IPCS_RATE_OFF); | |||
| } | } | |||
| } else if (req_pt->id == IPC_MSG_REQ_DISPATCH) { | } else if (req_pt->id == IPC_MSG_REQ_DISPATCH) { | |||
| response.size = sizeof(struct qb_ipc_response_header); | response.size = sizeof(struct qb_ipc_response_header); | |||
| response.id = IPC_MSG_RES_DISPATCH; | response.id = IPC_MSG_RES_DISPATCH; | |||
| response.error = 0; | response.error = 0; | |||
| res = qb_ipcs_event_send(c, &response, | res = qb_ipcs_event_send(c, &response, | |||
| sizeof(response)); | sizeof(response)); | |||
| if (res < 0) { | if (res < 0) { | |||
| perror("qb_ipcs_event_send"); | qb_perror(LOG_INFO, "qb_ipcs_event_send"); | |||
| } | } | |||
| } else if (req_pt->id == IPC_MSG_REQ_SERVER_FAIL) { | } else if (req_pt->id == IPC_MSG_REQ_SERVER_FAIL) { | |||
| qb_ipcs_destroy(s1); | qb_ipcs_destroy(s1); | |||
| exit(0); | exit(0); | |||
| } | } | |||
| return 0; | return 0; | |||
| } | } | |||
| static void ipc_log_fn(const char *file_name, | static int32_t my_job_add(enum qb_loop_priority p, | |||
| int32_t file_line, int32_t severity, const char *msg) | void *data, | |||
| qb_loop_job_dispatch_fn fn) | ||||
| { | { | |||
| if (severity < LOG_INFO) | return qb_loop_job_add(my_loop, p, data, fn); | |||
| fprintf(stderr, "%s:%d [%d] %s\n", file_name, file_line, sev | ||||
| erity, msg); | ||||
| } | } | |||
| static int32_t my_dispatch_add(enum qb_loop_priority p, int32_t fd, int32_t events, | static int32_t my_dispatch_add(enum qb_loop_priority p, int32_t fd, int32_t events, | |||
| void *data, qb_ipcs_dispatch_fn_t fn) | void *data, qb_ipcs_dispatch_fn_t fn) | |||
| { | { | |||
| return qb_loop_poll_add(my_loop, p, fd, events, data, fn); | return qb_loop_poll_add(my_loop, p, fd, events, data, fn); | |||
| } | } | |||
| static int32_t my_dispatch_mod(enum qb_loop_priority p, int32_t fd, int32_t events, | static int32_t my_dispatch_mod(enum qb_loop_priority p, int32_t fd, int32_t events, | |||
| void *data, qb_ipcs_dispatch_fn_t fn) | void *data, qb_ipcs_dispatch_fn_t fn) | |||
| { | { | |||
| return qb_loop_poll_mod(my_loop, p, fd, events, data, fn); | return qb_loop_poll_mod(my_loop, p, fd, events, data, fn); | |||
| } | } | |||
| static int32_t my_dispatch_del(int32_t fd) | static int32_t my_dispatch_del(int32_t fd) | |||
| { | { | |||
| return qb_loop_poll_del(my_loop, fd); | return qb_loop_poll_del(my_loop, fd); | |||
| } | } | |||
| static void s1_connection_destroyed(qb_ipcs_connection_t *c) | ||||
| { | ||||
| qb_enter(); | ||||
| qb_loop_stop(my_loop); | ||||
| } | ||||
| static void run_ipc_server(void) | static void run_ipc_server(void) | |||
| { | { | |||
| int32_t res; | int32_t res; | |||
| qb_loop_signal_handle handle; | qb_loop_signal_handle handle; | |||
| struct qb_ipcs_service_handlers sh = { | struct qb_ipcs_service_handlers sh = { | |||
| .connection_accept = NULL, | .connection_accept = NULL, | |||
| .connection_created = NULL, | .connection_created = NULL, | |||
| .msg_process = s1_msg_process_fn, | .msg_process = s1_msg_process_fn, | |||
| .connection_destroyed = NULL, | .connection_destroyed = s1_connection_destroyed, | |||
| .connection_closed = NULL, | .connection_closed = NULL, | |||
| }; | }; | |||
| struct qb_ipcs_poll_handlers ph = { | struct qb_ipcs_poll_handlers ph = { | |||
| .job_add = my_job_add, | ||||
| .dispatch_add = my_dispatch_add, | .dispatch_add = my_dispatch_add, | |||
| .dispatch_mod = my_dispatch_mod, | .dispatch_mod = my_dispatch_mod, | |||
| .dispatch_del = my_dispatch_del, | .dispatch_del = my_dispatch_del, | |||
| }; | }; | |||
| qb_loop_signal_add(my_loop, QB_LOOP_HIGH, SIGSTOP, | qb_loop_signal_add(my_loop, QB_LOOP_HIGH, SIGSTOP, | |||
| NULL, exit_handler, &handle); | NULL, exit_handler, &handle); | |||
| qb_loop_signal_add(my_loop, QB_LOOP_HIGH, SIGTERM, | qb_loop_signal_add(my_loop, QB_LOOP_HIGH, SIGTERM, | |||
| NULL, exit_handler, &handle); | NULL, exit_handler, &handle); | |||
| my_loop = qb_loop_create(); | my_loop = qb_loop_create(); | |||
| s1 = qb_ipcs_create(IPC_NAME, 4, ipc_type, &sh); | s1 = qb_ipcs_create(ipc_name, 4, ipc_type, &sh); | |||
| fail_if(s1 == 0); | fail_if(s1 == 0); | |||
| qb_ipcs_poll_handlers_set(s1, &ph); | qb_ipcs_poll_handlers_set(s1, &ph); | |||
| res = qb_ipcs_run(s1); | res = qb_ipcs_run(s1); | |||
| ck_assert_int_eq(res, 0); | ck_assert_int_eq(res, 0); | |||
| qb_loop_run(my_loop); | qb_loop_run(my_loop); | |||
| } | } | |||
| skipping to change at line 199 | skipping to change at line 206 | |||
| if (pid == 0) { | if (pid == 0) { | |||
| run_ipc_server_fn(); | run_ipc_server_fn(); | |||
| return 0; | return 0; | |||
| } | } | |||
| return pid; | return pid; | |||
| } | } | |||
| static int32_t stop_process(pid_t pid) | static int32_t stop_process(pid_t pid) | |||
| { | { | |||
| /* wait a bit for the server to shutdown by it's self */ | ||||
| usleep(100000); | ||||
| kill(pid, SIGTERM); | kill(pid, SIGTERM); | |||
| waitpid(pid, NULL, 0); | waitpid(pid, NULL, 0); | |||
| return 0; | return 0; | |||
| } | } | |||
| #define IPC_BUF_SIZE (1024 * 1024) | struct my_req { | |||
| static char buffer[IPC_BUF_SIZE]; | struct qb_ipc_request_header hdr; | |||
| char message[1024 * 1024]; | ||||
| }; | ||||
| static struct my_req request; | ||||
| static int32_t send_and_check(uint32_t size, int32_t ms_timeout) | static int32_t send_and_check(uint32_t size, int32_t ms_timeout) | |||
| { | { | |||
| struct qb_ipc_request_header *req_header = (struct qb_ipc_request_he ader *)buffer; | ||||
| struct qb_ipc_response_header res_header; | struct qb_ipc_response_header res_header; | |||
| int32_t res; | int32_t res; | |||
| int32_t try_times = 0; | int32_t try_times = 0; | |||
| req_header->id = IPC_MSG_REQ_TX_RX; | request.hdr.id = IPC_MSG_REQ_TX_RX; | |||
| req_header->size = sizeof(struct qb_ipc_request_header) + size; | request.hdr.size = sizeof(struct qb_ipc_request_header) + size; | |||
| repeat_send: | repeat_send: | |||
| res = qb_ipcc_send(conn, req_header, req_header->size); | res = qb_ipcc_send(conn, &request, request.hdr.size); | |||
| try_times++; | try_times++; | |||
| if (res < 0) { | if (res < 0) { | |||
| if (res == -EAGAIN && try_times < 10) { | if (res == -EAGAIN && try_times < 10) { | |||
| goto repeat_send; | goto repeat_send; | |||
| } else { | } else { | |||
| if (res == -EAGAIN && try_times >= 10) { | if (res == -EAGAIN && try_times >= 10) { | |||
| fc_enabled = QB_TRUE; | fc_enabled = QB_TRUE; | |||
| } | } | |||
| errno = -res; | errno = -res; | |||
| perror("qb_ipcc_send"); | qb_perror(LOG_INFO, "qb_ipcc_send"); | |||
| return res; | return res; | |||
| } | } | |||
| } | } | |||
| try_times = 0; | ||||
| repeat_recv: | repeat_recv: | |||
| res = qb_ipcc_recv(conn, &res_header, | res = qb_ipcc_recv(conn, &res_header, | |||
| sizeof(struct qb_ipc_response_header), ms_timeout); | sizeof(struct qb_ipc_response_header), ms_timeout); | |||
| try_times++; | ||||
| if (res == -EINTR) { | if (res == -EINTR) { | |||
| return -1; | return -1; | |||
| } | } | |||
| if (res == -EAGAIN || res == -ETIMEDOUT) { | if (res == -EAGAIN || res == -ETIMEDOUT) { | |||
| goto repeat_recv; | if (try_times < 10) { | |||
| goto repeat_recv; | ||||
| } else { | ||||
| fc_enabled = QB_TRUE; | ||||
| qb_perror(LOG_DEBUG, "qb_ipcc_recv"); | ||||
| return res; | ||||
| } | ||||
| } | } | |||
| ck_assert_int_eq(res, sizeof(struct qb_ipc_response_header)); | ck_assert_int_eq(res, sizeof(struct qb_ipc_response_header)); | |||
| ck_assert_int_eq(res_header.id, IPC_MSG_RES_TX_RX); | ck_assert_int_eq(res_header.id, IPC_MSG_RES_TX_RX); | |||
| ck_assert_int_eq(res_header.size, sizeof(struct qb_ipc_response_head er)); | ck_assert_int_eq(res_header.size, sizeof(struct qb_ipc_response_head er)); | |||
| return 0; | return 0; | |||
| } | } | |||
| static int32_t recv_timeout = -1; | static int32_t recv_timeout = -1; | |||
| static void test_ipc_txrx(void) | static void test_ipc_txrx(void) | |||
| { | { | |||
| int32_t j; | int32_t j; | |||
| int32_t c = 0; | int32_t c = 0; | |||
| size_t size; | size_t size; | |||
| pid_t pid; | pid_t pid; | |||
| pid = run_function_in_new_process(run_ipc_server); | pid = run_function_in_new_process(run_ipc_server); | |||
| fail_if(pid == -1); | fail_if(pid == -1); | |||
| sleep(1); | sleep(1); | |||
| do { | do { | |||
| conn = qb_ipcc_connect(IPC_NAME, MAX_MSG_SIZE); | conn = qb_ipcc_connect(ipc_name, MAX_MSG_SIZE); | |||
| if (conn == NULL) { | if (conn == NULL) { | |||
| j = waitpid(pid, NULL, WNOHANG); | j = waitpid(pid, NULL, WNOHANG); | |||
| ck_assert_int_eq(j, 0); | ck_assert_int_eq(j, 0); | |||
| sleep(1); | sleep(1); | |||
| c++; | c++; | |||
| } | } | |||
| } while (conn == NULL && c < 5); | } while (conn == NULL && c < 5); | |||
| fail_if(conn == NULL); | fail_if(conn == NULL); | |||
| size = QB_MIN(sizeof(struct qb_ipc_request_header), 64); | size = QB_MIN(sizeof(struct qb_ipc_request_header), 64); | |||
| skipping to change at line 288 | skipping to change at line 308 | |||
| } | } | |||
| if (turn_on_fc) { | if (turn_on_fc) { | |||
| ck_assert_int_eq(fc_enabled, QB_TRUE); | ck_assert_int_eq(fc_enabled, QB_TRUE); | |||
| } | } | |||
| qb_ipcc_disconnect(conn); | qb_ipcc_disconnect(conn); | |||
| stop_process(pid); | stop_process(pid); | |||
| } | } | |||
| START_TEST(test_ipc_txrx_shm_tmo) | START_TEST(test_ipc_txrx_shm_tmo) | |||
| { | { | |||
| turn_on_fc = QB_FALSE; | ||||
| ipc_type = QB_IPC_SHM; | ipc_type = QB_IPC_SHM; | |||
| ipc_name = __func__; | ||||
| recv_timeout = 1000; | recv_timeout = 1000; | |||
| test_ipc_txrx(); | test_ipc_txrx(); | |||
| } | } | |||
| END_TEST | END_TEST | |||
| START_TEST(test_ipc_txrx_shm_block) | START_TEST(test_ipc_txrx_shm_block) | |||
| { | { | |||
| turn_on_fc = QB_FALSE; | ||||
| ipc_type = QB_IPC_SHM; | ipc_type = QB_IPC_SHM; | |||
| ipc_name = __func__; | ||||
| recv_timeout = -1; | recv_timeout = -1; | |||
| test_ipc_txrx(); | test_ipc_txrx(); | |||
| } | } | |||
| END_TEST | END_TEST | |||
| START_TEST(test_ipc_txrx_us_block) | START_TEST(test_ipc_txrx_us_block) | |||
| { | { | |||
| turn_on_fc = QB_FALSE; | ||||
| ipc_type = QB_IPC_SOCKET; | ipc_type = QB_IPC_SOCKET; | |||
| ipc_name = __func__; | ||||
| recv_timeout = -1; | recv_timeout = -1; | |||
| test_ipc_txrx(); | test_ipc_txrx(); | |||
| } | } | |||
| END_TEST | END_TEST | |||
| START_TEST(test_ipc_txrx_us_tmo) | START_TEST(test_ipc_txrx_us_tmo) | |||
| { | { | |||
| turn_on_fc = QB_FALSE; | ||||
| ipc_type = QB_IPC_SOCKET; | ipc_type = QB_IPC_SOCKET; | |||
| ipc_name = __func__; | ||||
| recv_timeout = 1000; | recv_timeout = 1000; | |||
| test_ipc_txrx(); | test_ipc_txrx(); | |||
| } | } | |||
| END_TEST | END_TEST | |||
| START_TEST(test_ipc_fc_shm) | START_TEST(test_ipc_fc_shm) | |||
| { | { | |||
| turn_on_fc = QB_TRUE; | turn_on_fc = QB_TRUE; | |||
| ipc_type = QB_IPC_SHM; | ipc_type = QB_IPC_SHM; | |||
| recv_timeout = 500; | ||||
| ipc_name = __func__; | ||||
| test_ipc_txrx(); | test_ipc_txrx(); | |||
| } | } | |||
| END_TEST | END_TEST | |||
| START_TEST(test_ipc_fc_us) | START_TEST(test_ipc_fc_us) | |||
| { | { | |||
| turn_on_fc = QB_TRUE; | turn_on_fc = QB_TRUE; | |||
| ipc_type = QB_IPC_SOCKET; | ipc_type = QB_IPC_SOCKET; | |||
| recv_timeout = 500; | ||||
| ipc_name = __func__; | ||||
| test_ipc_txrx(); | test_ipc_txrx(); | |||
| } | } | |||
| END_TEST | END_TEST | |||
| START_TEST(test_ipc_txrx_pmq) | START_TEST(test_ipc_txrx_pmq) | |||
| { | { | |||
| turn_on_fc = QB_FALSE; | ||||
| ipc_type = QB_IPC_POSIX_MQ; | ipc_type = QB_IPC_POSIX_MQ; | |||
| ipc_name = __func__; | ||||
| test_ipc_txrx(); | test_ipc_txrx(); | |||
| } | } | |||
| END_TEST | END_TEST | |||
| START_TEST(test_ipc_txrx_smq) | START_TEST(test_ipc_txrx_smq) | |||
| { | { | |||
| turn_on_fc = QB_FALSE; | ||||
| ipc_type = QB_IPC_SYSV_MQ; | ipc_type = QB_IPC_SYSV_MQ; | |||
| ipc_name = __func__; | ||||
| test_ipc_txrx(); | test_ipc_txrx(); | |||
| } | } | |||
| END_TEST | END_TEST | |||
| struct my_res { | ||||
| struct qb_ipc_response_header hdr; | ||||
| char message[1024 * 1024]; | ||||
| }; | ||||
| static struct my_res response; | ||||
| static void test_ipc_dispatch(void) | static void test_ipc_dispatch(void) | |||
| { | { | |||
| int32_t res; | int32_t res; | |||
| int32_t j; | int32_t j; | |||
| int32_t c = 0; | int32_t c = 0; | |||
| pid_t pid; | pid_t pid; | |||
| struct qb_ipc_request_header req_header; | struct qb_ipc_request_header req_header; | |||
| struct qb_ipc_response_header *res_header = (struct qb_ipc_response_ header*)buffer; | ||||
| pid = run_function_in_new_process(run_ipc_server); | pid = run_function_in_new_process(run_ipc_server); | |||
| fail_if(pid == -1); | fail_if(pid == -1); | |||
| sleep(1); | sleep(1); | |||
| do { | do { | |||
| conn = qb_ipcc_connect(IPC_NAME, MAX_MSG_SIZE); | conn = qb_ipcc_connect(ipc_name, MAX_MSG_SIZE); | |||
| if (conn == NULL) { | if (conn == NULL) { | |||
| j = waitpid(pid, NULL, WNOHANG); | j = waitpid(pid, NULL, WNOHANG); | |||
| ck_assert_int_eq(j, 0); | ck_assert_int_eq(j, 0); | |||
| sleep(1); | sleep(1); | |||
| c++; | c++; | |||
| } | } | |||
| } while (conn == NULL && c < 5); | } while (conn == NULL && c < 5); | |||
| fail_if(conn == NULL); | fail_if(conn == NULL); | |||
| req_header.id = IPC_MSG_REQ_DISPATCH; | req_header.id = IPC_MSG_REQ_DISPATCH; | |||
| req_header.size = sizeof(struct qb_ipc_request_header); | req_header.size = sizeof(struct qb_ipc_request_header); | |||
| repeat_send: | repeat_send: | |||
| res = qb_ipcc_send(conn, &req_header, req_header.size); | res = qb_ipcc_send(conn, &req_header, req_header.size); | |||
| if (res < 0) { | if (res < 0) { | |||
| if (res == -EAGAIN) { | if (res == -EAGAIN) { | |||
| goto repeat_send; | goto repeat_send; | |||
| } else if (res == -EINVAL || res == -EINTR) { | } else if (res == -EINVAL || res == -EINTR) { | |||
| perror("qb_ipcc_send"); | qb_perror(LOG_INFO, "qb_ipcc_send"); | |||
| return; | return; | |||
| } else { | } else { | |||
| errno = -res; | errno = -res; | |||
| perror("qb_ipcc_send"); | qb_perror(LOG_INFO, "qb_ipcc_send"); | |||
| goto repeat_send; | goto repeat_send; | |||
| } | } | |||
| } | } | |||
| repeat_event_recv: | repeat_event_recv: | |||
| res = qb_ipcc_event_recv(conn, res_header, IPC_BUF_SIZE, 0); | res = qb_ipcc_event_recv(conn, &response, sizeof(struct my_res), 0); | |||
| if (res < 0) { | if (res < 0) { | |||
| if (res == -EAGAIN || res == -ETIMEDOUT) { | if (res == -EAGAIN || res == -ETIMEDOUT) { | |||
| goto repeat_event_recv; | goto repeat_event_recv; | |||
| } else { | } else { | |||
| errno = -res; | errno = -res; | |||
| perror("qb_ipcc_event_recv"); | qb_perror(LOG_INFO, "qb_ipcc_event_recv"); | |||
| goto repeat_send; | goto repeat_send; | |||
| } | } | |||
| } | } | |||
| ck_assert_int_eq(res, sizeof(struct qb_ipc_response_header)); | ck_assert_int_eq(res, sizeof(struct qb_ipc_response_header)); | |||
| ck_assert_int_eq(res_header->id, IPC_MSG_RES_DISPATCH); | ck_assert_int_eq(response.hdr.id, IPC_MSG_RES_DISPATCH); | |||
| qb_ipcc_disconnect(conn); | qb_ipcc_disconnect(conn); | |||
| stop_process(pid); | stop_process(pid); | |||
| } | } | |||
| START_TEST(test_ipc_disp_shm) | START_TEST(test_ipc_disp_shm) | |||
| { | { | |||
| ipc_type = QB_IPC_SHM; | ipc_type = QB_IPC_SHM; | |||
| ipc_name = __func__; | ||||
| test_ipc_dispatch(); | test_ipc_dispatch(); | |||
| } | } | |||
| END_TEST | END_TEST | |||
| START_TEST(test_ipc_disp_us) | START_TEST(test_ipc_disp_us) | |||
| { | { | |||
| ipc_type = QB_IPC_SOCKET; | ipc_type = QB_IPC_SOCKET; | |||
| ipc_name = __func__; | ||||
| test_ipc_dispatch(); | test_ipc_dispatch(); | |||
| } | } | |||
| END_TEST | END_TEST | |||
| #ifdef IPC_HANDLES_FAILED_SERVER | ||||
| static void test_ipc_server_fail(void) | static void test_ipc_server_fail(void) | |||
| { | { | |||
| struct qb_ipc_request_header req_header; | struct qb_ipc_request_header req_header; | |||
| struct qb_ipc_response_header res_header; | struct qb_ipc_response_header res_header; | |||
| int32_t res; | int32_t res; | |||
| int32_t try_times = 0; | int32_t try_times = 0; | |||
| int32_t j; | int32_t j; | |||
| int32_t c = 0; | int32_t c = 0; | |||
| pid_t pid; | pid_t pid; | |||
| pid = run_function_in_new_process(run_ipc_server); | pid = run_function_in_new_process(run_ipc_server); | |||
| fail_if(pid == -1); | fail_if(pid == -1); | |||
| sleep(1); | sleep(1); | |||
| do { | do { | |||
| conn = qb_ipcc_connect(IPC_NAME, MAX_MSG_SIZE); | conn = qb_ipcc_connect(ipc_name, MAX_MSG_SIZE); | |||
| if (conn == NULL) { | if (conn == NULL) { | |||
| j = waitpid(pid, NULL, WNOHANG); | j = waitpid(pid, NULL, WNOHANG); | |||
| ck_assert_int_eq(j, 0); | ck_assert_int_eq(j, 0); | |||
| sleep(1); | sleep(1); | |||
| c++; | c++; | |||
| } | } | |||
| } while (conn == NULL && c < 5); | } while (conn == NULL && c < 5); | |||
| fail_if(conn == NULL); | fail_if(conn == NULL); | |||
| /* | /* | |||
| skipping to change at line 483 | skipping to change at line 528 | |||
| */ | */ | |||
| ck_assert_int_eq(res, -ENOTCONN); | ck_assert_int_eq(res, -ENOTCONN); | |||
| qb_ipcc_disconnect(conn); | qb_ipcc_disconnect(conn); | |||
| stop_process(pid); | stop_process(pid); | |||
| } | } | |||
| START_TEST(test_ipc_server_fail_soc) | START_TEST(test_ipc_server_fail_soc) | |||
| { | { | |||
| ipc_type = QB_IPC_SOCKET; | ipc_type = QB_IPC_SOCKET; | |||
| ipc_name = __func__; | ||||
| test_ipc_server_fail(); | test_ipc_server_fail(); | |||
| } | } | |||
| END_TEST | END_TEST | |||
| START_TEST(test_ipc_server_fail_shm) | START_TEST(test_ipc_server_fail_shm) | |||
| { | { | |||
| ipc_type = QB_IPC_SHM; | ipc_type = QB_IPC_SHM; | |||
| ipc_name = __func__; | ||||
| test_ipc_server_fail(); | test_ipc_server_fail(); | |||
| } | } | |||
| END_TEST | END_TEST | |||
| #endif /* IPC_HANDLES_FAILED_SERVER */ | ||||
| static Suite *ipc_suite(void) | static Suite *ipc_suite(void) | |||
| { | { | |||
| TCase *tc; | TCase *tc; | |||
| uid_t uid; | uid_t uid; | |||
| Suite *s = suite_create("ipc"); | Suite *s = suite_create("ipc"); | |||
| #ifdef IPC_HANDLES_FAILED_SERVER | ||||
| tc = tcase_create("ipc_server_fail_shm"); | tc = tcase_create("ipc_server_fail_shm"); | |||
| tcase_add_test(tc, test_ipc_server_fail_shm); | tcase_add_test(tc, test_ipc_server_fail_shm); | |||
| tcase_set_timeout(tc, 6); | tcase_set_timeout(tc, 6); | |||
| suite_add_tcase(s, tc); | suite_add_tcase(s, tc); | |||
| tc = tcase_create("ipc_server_fail_soc"); | tc = tcase_create("ipc_server_fail_soc"); | |||
| tcase_add_test(tc, test_ipc_server_fail_soc); | tcase_add_test(tc, test_ipc_server_fail_soc); | |||
| tcase_set_timeout(tc, 6); | tcase_set_timeout(tc, 6); | |||
| suite_add_tcase(s, tc); | suite_add_tcase(s, tc); | |||
| #endif /* IPC_HANDLES_FAILED_SERVER */ | ||||
| tc = tcase_create("ipc_txrx_shm_block"); | tc = tcase_create("ipc_txrx_shm_block"); | |||
| tcase_add_test(tc, test_ipc_txrx_shm_block); | tcase_add_test(tc, test_ipc_txrx_shm_block); | |||
| tcase_set_timeout(tc, 6); | tcase_set_timeout(tc, 6); | |||
| suite_add_tcase(s, tc); | suite_add_tcase(s, tc); | |||
| tc = tcase_create("ipc_txrx_shm_tmo"); | tc = tcase_create("ipc_txrx_shm_tmo"); | |||
| tcase_add_test(tc, test_ipc_txrx_shm_tmo); | tcase_add_test(tc, test_ipc_txrx_shm_tmo); | |||
| tcase_set_timeout(tc, 6); | tcase_set_timeout(tc, 6); | |||
| suite_add_tcase(s, tc); | suite_add_tcase(s, tc); | |||
| skipping to change at line 572 | skipping to change at line 622 | |||
| return s; | return s; | |||
| } | } | |||
| int32_t main(void) | int32_t main(void) | |||
| { | { | |||
| int32_t number_failed; | int32_t number_failed; | |||
| Suite *s = ipc_suite(); | Suite *s = ipc_suite(); | |||
| SRunner *sr = srunner_create(s); | SRunner *sr = srunner_create(s); | |||
| qb_util_set_log_function(ipc_log_fn); | qb_log_init("check", LOG_USER, LOG_EMERG); | |||
| qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE); | ||||
| qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD, | ||||
| QB_LOG_FILTER_FILE, "*", LOG_INFO); | ||||
| qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_TRUE); | ||||
| srunner_run_all(sr, CK_VERBOSE); | srunner_run_all(sr, CK_VERBOSE); | |||
| number_failed = srunner_ntests_failed(sr); | number_failed = srunner_ntests_failed(sr); | |||
| srunner_free(sr); | srunner_free(sr); | |||
| return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; | return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; | |||
| } | } | |||
| End of changes. 56 change blocks. | ||||
| 34 lines changed or deleted | 87 lines changed or added | |||
This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ | ||||