/* Cesar project {{{ * * Copyright (C) 2007 Spidcom * * <<>> * * }}} */ /** * \file test_fcall.c * \brief Test all fcall functions. * \ingroup test */ #include #include #include #include #include #include #include "common/std.h" #include "host/inc/fcall.h" #include "lib/test.h" extern char dump_buffer[]; //void fcall_param_new_test_case(test_t t) //{ // fcall_param_t *param; // test_case_begin(t, "param_new"); // // test_begin(t, "id = NULL") // { // test_fail_unless( // (fcall_param_new(NULL) == NULL) // ); // } test_end; // // test_begin(t, "check new") // { // param = fcall_param_new("test_func"); // test_fail_unless( // (param != NULL) // && !strcmp(param->function_id, "test_func") // && (param->param_nb == 0) // ); // } test_end; // // fcall_param_free(param); // return; //} // //void fcall_param_free_test_case(test_t t) //{ // // noting to do ? // return; //} //void fcall_new_test_case(test_t t) //{ // fcall_ctx_t *fcall; // station_ctx_t *station; // // test_case_begin(t, "new"); // station = station_new(); // // test_begin(t, "station = NULL") // { // test_fail_unless( // (fcall_new(NULL) == NULL) // && (errno == EINVAL) // ); // } test_end; // // test_begin(t, "check new") // { // test_fail_unless( // ((fcall = fcall_new(station)) != NULL) // && (fcall->station == station) // ); // } test_end; // // fcall_free(fcall); // station_free(station); // return; //} // //void fcall_free_test_case(test_t t) //{ // // how to test it ? // return; //} void fcall_init_test_case(test_t t) { fcall_ctx_t fcall; sci_ctx_t sci; station_ctx_t station; sci_init(&sci, &station); test_case_begin(t, "init"); test_begin(t, "fcall = NULL") { test_fail_unless( (fcall_init(NULL, &sci) < 0) && (errno == EINVAL) ); } test_end; test_begin(t, "sci = NULL") { test_fail_unless( (fcall_init(&fcall, NULL) < 0) && (errno == EINVAL) ); } test_end; test_begin(t, "check init") { int i; test_fail_unless( (fcall_init(&fcall, &sci) >= 0) && (fcall.sci == &sci) && (fcall.function_nb == 0) && (fcall.sci->msg_callback[SCI_MSG_TYPE_FUNCTION_CALL].function == fcall_recv) && (fcall.sci->msg_callback[SCI_MSG_TYPE_FUNCTION_CALL].data == &fcall) ); for(i = 0; i < FUNCTION_CALL_FUNCTION_MAX_NB; i++) { test_fail_unless( (fcall.function_table[i].id[0] == '\0') ); } } test_end; return; } static int _test_register(fcall_param_t **param, sci_msg_t **msg, void *data) { return 0; } static int _test_data; void fcall_register_test_case(test_t t) { fcall_ctx_t fcall; sci_ctx_t sci; station_ctx_t station; test_case_begin(t, "register"); sci_init(&sci, &station); fcall_init(&fcall, &sci); test_begin(t, "fcall = NULL") { test_fail_unless( (fcall_register(NULL, "test_register", _test_register, &_test_data) < 0) && (errno == EINVAL) ); } test_end; test_begin(t, "id = NULL") { test_fail_unless( (fcall_register(&fcall, NULL, _test_register, &_test_data) < 0) && (errno == EINVAL) ); } test_end; test_begin(t, "function = NULL") { test_fail_unless( (fcall_register(&fcall, "test_register", NULL, &_test_data) < 0) && (errno == EINVAL) ); } test_end; test_begin(t, "check register") { test_fail_unless( (fcall_register(&fcall, "test_register", _test_register, &_test_data) >= 0) && (fcall.function_nb == 1) && !strcmp(fcall.function_table[0].id, "test_register") && (fcall.function_table[0].function == _test_register) && (fcall.function_table[0].data == &_test_data) ); } test_end; test_begin(t, "check already existing function") { test_fail_unless( (fcall_register(&fcall, "test_register", _test_register, &_test_data) < 0) && (errno == EEXIST) ); } test_end; test_begin(t, "check full table") { int i; fcall.function_nb = FUNCTION_CALL_FUNCTION_MAX_NB; test_fail_unless( (fcall_register(&fcall, "test_register", _test_register, &_test_data) < 0) && (errno == ENOSPC) ); fcall.function_nb = 1; for(i = 0; i < FUNCTION_CALL_FUNCTION_MAX_NB; i++) { sprintf(fcall.function_table[i].id, "test_%d", i); fcall.function_table[i].function = _test_register; } fcall.function_nb = FUNCTION_CALL_FUNCTION_MAX_NB; test_fail_unless( (fcall_register(&fcall, "test_register", _test_register, &_test_data) < 0) && (errno == ENOSPC) ); } test_end; return; } #define FCALL_DATA_STR "fill_hdr test" void fcall_fill_hdr_test_case(test_t t) { fcall_ctx_t fcall; station_ctx_t station; sci_ctx_t sci; sci_msg_t msg; fcall_param_t param; int data_int; unsigned char buffer[1024]; test_case_begin(t, "fill_hdr"); sci_init(&sci, &station); fcall_init(&fcall, &sci); sci_msg_init(&msg, buffer, 256); fcall_param_init(¶m, "test_function"); data_int = 12345; fcall_param_add(¶m, &msg, "data_int", sizeof(data_int), &data_int); fcall_param_add(¶m, &msg, "data_str", strlen(FCALL_DATA_STR), FCALL_DATA_STR); test_begin(t, "fcall = NULL") { test_fail_unless( (fcall_fill_hdr(NULL, &msg, ¶m, 0) < 0) && (errno == EINVAL) ); } test_end; test_begin(t, "msg = NULL") { test_fail_unless( (fcall_fill_hdr(&fcall, NULL, ¶m, 0) < 0) && (errno == EINVAL) ); } test_end; test_begin(t, "check fill_hdr") { test_fail_unless( (fcall_fill_hdr(&fcall, &msg, ¶m, 0xa5) >= 0) && ((unsigned char *)msg.hdr.fcall == msg.data_begin) && (msg.hdr.fcall->type == FUNCTION_CALL_TYPE_RSP) && (msg.hdr.fcall->param_nb == param.param_nb) && (msg.hdr.fcall->flags == 0xa5) ); } test_end; return; } #undef FCALL_DATA_STR //void fcall_fill_body_test_case(test_t t) //{ // fcall_ctx_t *fcall; // sci_msg_t *msg; // fcall_param_t *param; // int data_int; // char data_str[32]; // int body_length; // unsigned char *ptr; // // test_case_begin(t, "fill_body"); // fcall = fcall_new(); // msg = sci_msg_new(256); // param = fcall_param_new("test_function"); // data_int = 12345; // fcall_param_add(param, "data_int", &data_int, sizeof(data_int)); // fcall_param_add(param, "data_str", FCALL_DATA_STR, strlen(FCALL_DATA_STR)); // body_length = strlen("test_function") + 1 // + strlen("data_int") + 1 + sizeof(short) + sizeof(int) // + strlen("data_str") + 1 + sizeof(short) + strlen(FCALL_DATA_STR); // // test_begin(t, "fcall = NULL") // { // test_fail_unless( // (fcall_fill_body(NULL, msg, param) < 0) // && (errno == EINVAL) // ); // } test_end; // // test_begin(t, "msg = NULL") // { // test_fail_unless( // (fcall_fill_body(fcall, NULL, param) < 0) // && (errno == EINVAL) // ); // } test_end; // // test_begin(t, "param = NULL") // { // test_fail_unless( // (fcall_fill_body(fcall, msg, NULL) < 0) // && (errno == EINVAL) // ); // } test_end; // // test_begin(t, "check fill_body") // { // test_fail_unless( // (fcall_fill_body(fcall, msg, param) >= 0) // && (msg->length == body_length) // && !strcmp(msg->data_begin, "test_function") // ); // ptr = msg->data_begin + strlen((char *)msg->data_begin) + 1; // test_fail_unless( // !strcmp((char *)ptr, "data_int") // && (ntohs((unsigned short)*(ptr + strlen("data_int") + 1)) == sizeof(int)) // && !memcmp(ptr + strlen("data_int") + 1 + sizeof(short), &data_int, sizeof(int)) // ); // ptr += strlen("data_int") + 1 + sizeof(short) + sizeof(int); // test_fail_unless( // !strcmp((char *)ptr, "data_str") // && (ntohs((unsigned short)*(ptr + strlen("data_str") + 1)) == strlen(FCALL_DATA_STG)) // && !memcmp(ptr + strlen("data_str") + 1 + sizeof(short), FCALL_DATA_STR, strlen(FCALL_DATA_STR)) // ); // } test_end; // // fcall_param_free(param); // fcall_free(fcall); // sci_msg_free(msg); // return; //} // #define FCALL_REQ_STR "this is a request test" #define FCALL_RES_STR "this is a response test" int _test_recv_result; static int _test_recv(fcall_param_t **param, sci_msg_t **msg, void *data) { int data_int; int int_len; char data_str[32]; int str_len; int *private_data; //static fcall_param_t my_param; private_data = (int *)data; _test_recv_result = -1; if(((*param)->param_nb != 2) || (private_data == NULL) || (*private_data != 0x12345678)) goto failed; if((fcall_param_bind(*param, *msg, "data_int", &int_len, &data_int) < 0) || (data_int != 12345) || (int_len != sizeof(int))) goto failed; if((fcall_param_bind(*param, *msg, "data_str", &str_len, data_str) < 0) || memcmp(data_str, FCALL_REQ_STR, strlen(FCALL_REQ_STR)) || (str_len != strlen(FCALL_REQ_STR))) goto failed; /* now modify parameters */ // fcall_param_init(&my_param, (*param)->id); fcall_param_init(*param, NULL); data_int = 54321; fcall_param_add(*param, *msg, "data_int", sizeof(data_int), &data_int); // fcall_param_add(&my_param, *msg, "data_int", sizeof(data_int), &data_int); // *param = &my_param; _test_recv_result = 0; return 0; failed: return -1; } void fcall_recv_test_case(test_t t) { station_ctx_t station; fcall_ctx_t fcall; fcall_param_t param; sci_ctx_t sci; sci_msg_t msg; sci_msg_hdr_t *hdr; struct fcall_msg_hdr *fcall_hdr; int data_int; int private_data; int fd_in; int len; unsigned char buffer[256], *ptr; test_case_begin(t, "recv"); station_init(&station); sci_init(&sci, &station); fcall_init(&fcall, &sci); fcall_register(&fcall, "test_function", _test_recv, &private_data); sci_msg_init(&msg, buffer, 256); fcall_param_init(¶m, "test_function"); private_data = 0x12345678; data_int = 12345; fcall_param_add(¶m, &msg, "data_int", sizeof(data_int), &data_int); fcall_param_add(¶m, &msg, "data_str", strlen(FCALL_REQ_STR), FCALL_REQ_STR); fcall_fill_hdr(&fcall, &msg, ¶m, 0); msg.hdr.fcall->type = FUNCTION_CALL_TYPE_REQ; test_begin(t, "msg = NULL") { test_fail_unless( (fcall_recv(NULL, &fcall) < 0) && (errno == EINVAL) ); } test_end; test_begin(t, "fcall = NULL") { test_fail_unless( (fcall_recv(&msg, NULL) < 0) && (errno == EINVAL) ); } test_end; fd_in = open(station.pipe_out_name, O_RDONLY); test_begin(t, "check recv") { test_fail_unless( (fcall_recv(&msg, &fcall) >= 0) && (_test_recv_result >= 0) ); test_fail_if( (len = read(fd_in, buffer, sizeof(sci_msg_hdr_t))) != sizeof(sci_msg_hdr_t) ); hdr = (sci_msg_hdr_t *)buffer; test_fail_unless( (hdr->type == SCI_MSG_TYPE_FUNCTION_CALL) && (ntohs(hdr->station_id) == station.id) && (ntohs(hdr->msg_id) == (station.sci->current_msg_id | SCI_MSG_ID_STATION)) && (htons(hdr->length) == sizeof(struct fcall_msg_hdr) + strlen("test_function") + 1 + strlen("data_int") + 1 + sizeof(unsigned short) + sizeof(int)) ); test_fail_unless( ((len = read(fd_in, buffer + sizeof(sci_msg_hdr_t), htons(hdr->length))) == htons(hdr->length)) ); fcall_hdr = (struct fcall_msg_hdr *)(buffer + sizeof(sci_msg_hdr_t)); test_fail_unless( (fcall_hdr->type == FUNCTION_CALL_TYPE_RSP) && (fcall_hdr->param_nb == 1) && !strcmp((char *)fcall_hdr + sizeof(struct fcall_msg_hdr), "test_function") ); ptr = (unsigned char *)fcall_hdr + sizeof(struct fcall_msg_hdr) + strlen("test_function") + 1; // test_fail_unless( // !strcmp((char *)ptr, "data_str") // && (ptr += (strlen("data_str") + 1)) // && (ntohs(*(unsigned short *)(ptr)) == strlen(FCALL_RES_STR)) // && !memcmp(ptr + 2, FCALL_RES_STR, strlen(FCALL_RES_STR)) // ); // ptr += (2 + strlen(FCALL_RES_STR)); test_fail_unless( !strcmp((char *)ptr, "data_int") && (ptr += (strlen("data_int") + 1)) && (ntohs(*(unsigned short *)(ptr)) == sizeof(int)) && (*(int *)(ptr + 2) == 54321) ); } test_end; station_down(&station); return; } void fcall_test_suite(test_t t) { test_suite_begin(t, "fcall"); fcall_init_test_case(t); fcall_register_test_case(t); fcall_fill_hdr_test_case(t); fcall_recv_test_case(t); }