diff --git a/src/tests/dump_domo.h b/src/tests/dump_domo.h new file mode 100644 index 0000000..4ae8dd1 --- /dev/null +++ b/src/tests/dump_domo.h @@ -0,0 +1,16 @@ +#define k_device_list_empty "{\n\ + \"capabilities\": [\n\ + {\n\ + \"name\": \"outlets\",\n\ + \"speech_name\": \"lumière\"\n\ + },\n\ + {\n\ + \"name\": \"shutters\",\n\ + \"speech_name\": \"volet\"\n\ + },\n\ + {\n\ + \"name\": \"sprinklers\",\n\ + \"speech_name\": \"station\"\n\ + }\n\ + ]\n\ +}" diff --git a/src/tests/test_domo.c b/src/tests/test_domo.c index 95edb2a..c5188a4 100644 --- a/src/tests/test_domo.c +++ b/src/tests/test_domo.c @@ -46,29 +46,12 @@ char *load_capabilities(devices_manager_t *dm) /*--------------------------------------------------------------------------*/ -TEST("Domo - Server - Create Free\t") +restd_server_t *setup_server(devices_manager_t *dm) { - restd_server_t *rest_server; - - rest_server = restd_server_new(); - ASSERT_NOT_NULL(rest_server); - - restd_server_free(rest_server); -} - -/*--------------------------------------------------------------------------*/ - -TEST("Domo - Test API correct access\t") -{ - struct event_base *ev_base; - restd_server_t *rest_server; - devices_manager_t *dm; - char *config_path, *capabilities_path; int ret; - char *capabilities; - - dm = devices_manager_new(); - ASSERT_NOT_NULL(dm); + struct event_base *ev_base; + char *config_path, *capabilities_path; + restd_server_t *rest_server = NULL; ev_base = event_base_new(); ASSERT_NOT_NULL(ev_base); @@ -92,21 +75,103 @@ TEST("Domo - Test API correct access\t") restd_server_set_option(rest_server, "server.thread", "1"); + free(config_path); + ret = restd_server_start(rest_server); ASSERT_EQUAL_INT(ret, 0); + return rest_server; +} + +/*--------------------------------------------------------------------------*/ + +TEST("Domo - Server - Create Free\t") +{ + restd_server_t *rest_server; + + rest_server = restd_server_new(); + ASSERT_NOT_NULL(rest_server); + + restd_server_free(rest_server); +} + +/*--------------------------------------------------------------------------*/ + +TEST("Domo - Test API /api/v1/capabilities - correct access\t") +{ + restd_server_t *rest_server; + devices_manager_t *dm; + int ret; + char *capabilities; + + dm = devices_manager_new(); + ASSERT_NOT_NULL(dm); + + rest_server = setup_server(dm); + ASSERT_NOT_NULL(rest_server); + sleep(1); + // Capabilites capabilities = load_capabilities(dm); ASSERT_NOT_NULL(capabilities); ret = exec_request(kget_method, "http://localhost:" kserver_port "/api/v1/capabilities", 200, "", capabilities, false); ASSERT_EQUAL_INT(ret, 0); free(capabilities); - // TODO + restd_server_free(rest_server); + devices_manager_free(dm); +} + +/*--------------------------------------------------------------------------*/ + +TEST("Domo - Test API /api/v1/outlets - correct access\t") +{ + restd_server_t *rest_server; + devices_manager_t *dm; + int ret; + + dm = devices_manager_new(); + ASSERT_NOT_NULL(dm); + + rest_server = setup_server(dm); + ASSERT_NOT_NULL(rest_server); + + sleep(1); + + // Outlets + + // Get All Devices. Should be empty. + ret = exec_request(kget_method, "http://localhost:" kserver_port "/api/v1/capabilities", 200, "", k_device_list_empty, false); + ASSERT_EQUAL_INT(ret, 0); + + // Create An Outlet. Should be empty. + + + // Get All Devices. Should Contain One Device. + + + // Create A second Outlet. Should Contain two Device. + + + // Update the second Outlet. Device should contain. + + // Get Device 2 only. Should Contain Device two updated. + + // Delete Device 2. + + + // Get All Devices. Should Contain One Device. restd_server_free(rest_server); devices_manager_free(dm); - free(config_path); } +#if 0 + // Outlets + restd_server_register_hook_on_path(rest_server, EVHTTP_REQ_POST, "/api/v1/outlets", outlet_create_handler, dm); + restd_server_register_hook_on_path(rest_server, EVHTTP_REQ_GET, "/api/v1/outlets", outlet_list_handler, dm); + restd_server_register_hook_on_path(rest_server, EVHTTP_REQ_GET, "/api/v1/outlets/:id", outlet_get_handler, dm); + restd_server_register_hook_on_path(rest_server, EVHTTP_REQ_PUT, "/api/v1/outlets/:id", outlet_update_handler, dm); + restd_server_register_hook_on_path(rest_server, EVHTTP_REQ_DELETE, "/api/v1/outlets/:id", outlet_remove_handler, dm); +#endif \ No newline at end of file diff --git a/src/tests/test_main.c b/src/tests/test_main.c index 5c6981d..b57f5e2 100644 --- a/src/tests/test_main.c +++ b/src/tests/test_main.c @@ -28,6 +28,7 @@ /*------------------------------- INCLUDES ----------------------------------*/ +#include #include #include #include @@ -47,6 +48,8 @@ #include "devices/devices_manager.h" #include "rest/rest_server.h" +#include "dump_domo.h" + /*--------------------------------------------------------------------------*/ #define k_max_path_len 200 /* make this larger if you need to. */ @@ -112,6 +115,7 @@ TEST("devices_manager create and free\t") devices_manager_free(dm); } +#include "test_utils.c" #include "test_devices.c" #include "test_sprinkler.c" #include "test_shutter.c" diff --git a/src/tests/test_rest.c b/src/tests/test_rest.c index 1e45e26..916d420 100644 --- a/src/tests/test_rest.c +++ b/src/tests/test_rest.c @@ -43,11 +43,6 @@ #define kapi_test_put_id2 "/api/v1/test_put/:year/todo" #define kapi_test_put_id2_body "/api/v1/test_put/1977/todo" -#define kpost_method "POST" -#define kget_method "GET" -#define kput_method "PUT" -#define kdelete_method "DELETE" - #define kserver_port "7777" /*--------------------------------------------------------------------------*/ @@ -137,130 +132,6 @@ int my_success_rest_post_handler(restd_resp_t *response, void *arg) /*--------------------------------------------------------------------------*/ -size_t write_callback(void *ptr, size_t size, size_t nmemb, void *stream) -{ - size_t body_size = 0; - size_t curent_size = size * nmemb; - - char *body = *((char **)stream); - char *new_body; - - if (body != 0) - { - body_size = strlen(body); - } - - new_body = (char *)realloc(body, curent_size + body_size + 1); - if (new_body == NULL) - { - free(body); - return 0; - } - - memcpy(new_body + body_size, ptr, curent_size); - new_body[curent_size + body_size] = 0; - - *((char **)stream) = new_body; - - return curent_size; -} - -/*--------------------------------------------------------------------------*/ - -int exec_request(const char *request, const char *path, int expected_code, const char *body, const char *expected_body, bool debug) -{ - int ret = 0; - CURL *curl_handle; - CURLcode res; - char *resp_body = NULL; - long http_result_code; - - /* init libcurl */ - curl_global_init(CURL_GLOBAL_ALL); - - /* init the curl session */ - curl_handle = curl_easy_init(); - - /* specify URL and method */ - curl_easy_setopt(curl_handle, CURLOPT_URL, path); - - if (strcmp(request, kget_method) == 0) - { - curl_easy_setopt(curl_handle, CURLOPT_HTTPGET, 1); - } - else if (strcmp(request, kdelete_method) == 0) - { - curl_easy_setopt(curl_handle, CURLOPT_HTTPGET, 0); - curl_easy_setopt(curl_handle, CURLOPT_CUSTOMREQUEST, kdelete_method); - } - else if (strcmp(request, kput_method) == 0) - { - curl_easy_setopt(curl_handle, CURLOPT_HTTPGET, 0); - curl_easy_setopt(curl_handle, CURLOPT_CUSTOMREQUEST, kput_method); - curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDSIZE, strlen(body)); - curl_easy_setopt(curl_handle, CURLOPT_COPYPOSTFIELDS, body); - } - else if (strcmp(request, kpost_method) == 0) - { - curl_easy_setopt(curl_handle, CURLOPT_POST, 0); - curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDSIZE, strlen(body)); - curl_easy_setopt(curl_handle, CURLOPT_COPYPOSTFIELDS, body); - } - - curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, 2); - - if (debug) - curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1); - - /* send all data to this function */ - curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_callback); - curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, &resp_body); - curl_easy_setopt(curl_handle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); - - /* get it! */ - res = curl_easy_perform(curl_handle); - if (res != CURLE_OK) - { - printf("Error: %d\n", res); - } - ASSERT_EQUAL_INT(res, CURLE_OK); - - curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &http_result_code); - ASSERT_EQUAL_INT(http_result_code, expected_code); - - if (resp_body == NULL) - { - res = 1; - } - else - { - res = strcmp(expected_body, resp_body); - } - - if (debug) - printf ("body: %s != expected_body: %s\n", resp_body, expected_body); - - if (res != 0) - { - ret = 2; - goto exit; - } - ASSERT_EQUAL_INT(res, 0); - -exit: - free(resp_body); - - /* cleanup curl stuff */ - curl_easy_cleanup(curl_handle); - - /* we're done with libcurl, so clean it up */ - curl_global_cleanup(); - - return ret; -} - -/*--------------------------------------------------------------------------*/ - bool found_route(restd_server_t *server, enum evhttp_cmd_type method, const char *path) { qlist_t *hooks = server->hooks; diff --git a/src/tests/test_utils.c b/src/tests/test_utils.c new file mode 100644 index 0000000..22ff7a1 --- /dev/null +++ b/src/tests/test_utils.c @@ -0,0 +1,277 @@ +/*! + * test_utils.c + * + * Copyright (c) 2015-2020, NADAL Jean-Baptiste. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + * + * @Author: NADAL Jean-Baptiste + * @Date: 24/02/2020 + * + */ + +/*--------------------------------------------------------------------------*/ + +#define kpost_method "POST" +#define kget_method "GET" +#define kput_method "PUT" +#define kdelete_method "DELETE" + +/*--------------------------------------------------------------------------*/ + +int rows_eq(int *a, int *b) +{ + int i; + + for (i = 0; i < 16; i++) + { + if (a[i] != b[i]) + { + return 0; + } + } + + return 1; +} + +/*--------------------------------------------------------------------------*/ + +void dump_row(long a_count, int a_numinrow, int *a_chs) +{ + int i; + + printf("%08lX:", a_count - a_numinrow); + + if (a_numinrow > 0) + { + for (i = 0; i < a_numinrow; i++) + { + if (i == 8) + { + printf(" :"); + } + printf(" %02X", a_chs[i]); + } + + for (i = a_numinrow; i < 16; i++) + { + if (i == 8) + { + printf(" :"); + } + printf(" "); + } + printf(" "); + for (i = 0; i < a_numinrow; i++) + { + if (isprint(a_chs[i])) + { + printf("%c", a_chs[i]); + } + else + { + printf("."); + } + } + } + printf("\n"); +} + +/*--------------------------------------------------------------------------*/ + +void dump_memory(void const *a_buffer, size_t a_len) +{ + unsigned char *the_buf = (unsigned char *)a_buffer; + long the_count = 0; + int the_numinrow = 0; + int the_chs[16]; + int the_oldchs[16] = {0}; + int the_showed_dots = 0; + size_t i; + + for (i = 0; i < a_len; i++) + { + int the_ch = the_buf[i]; + + if (the_numinrow == 16) + { + int j; + + if (rows_eq(the_oldchs, the_chs)) + { + if (!the_showed_dots) + { + the_showed_dots = 1; + printf(" .. .. .. .. .. .. .. .. : .. .. .. .. .. .. .. ..\n"); + } + } + else + { + the_showed_dots = 0; + dump_row(the_count, the_numinrow, the_chs); + } + + for (j = 0; j < 16; j++) + { + the_oldchs[j] = the_chs[j]; + } + + the_numinrow = 0; + } + + the_count++; + the_chs[the_numinrow++] = the_ch; + } + + dump_row(the_count, the_numinrow, the_chs); + + if (the_numinrow != 0) + { + printf("%08lX:\n", the_count); + } +} + +/*--------------------------------------------------------------------------*/ + +size_t write_callback(void *ptr, size_t size, size_t nmemb, void *stream) +{ + size_t body_size = 0; + size_t curent_size = size * nmemb; + + char *body = *((char **)stream); + char *new_body; + + if (body != 0) + { + body_size = strlen(body); + } + + new_body = (char *)realloc(body, curent_size + body_size + 1); + if (new_body == NULL) + { + free(body); + return 0; + } + + memcpy(new_body + body_size, ptr, curent_size); + new_body[curent_size + body_size] = 0; + + *((char **)stream) = new_body; + + return curent_size; +} + +/*--------------------------------------------------------------------------*/ + +int exec_request(const char *request, const char *path, int expected_code, const char *body, const char *expected_body, bool debug) +{ + int ret = 0; + CURL *curl_handle; + CURLcode res; + char *resp_body = NULL; + long http_result_code; + + /* init libcurl */ + curl_global_init(CURL_GLOBAL_ALL); + + /* init the curl session */ + curl_handle = curl_easy_init(); + + /* specify URL and method */ + curl_easy_setopt(curl_handle, CURLOPT_URL, path); + + if (strcmp(request, kget_method) == 0) + { + curl_easy_setopt(curl_handle, CURLOPT_HTTPGET, 1); + } + else if (strcmp(request, kdelete_method) == 0) + { + curl_easy_setopt(curl_handle, CURLOPT_HTTPGET, 0); + curl_easy_setopt(curl_handle, CURLOPT_CUSTOMREQUEST, kdelete_method); + } + else if (strcmp(request, kput_method) == 0) + { + curl_easy_setopt(curl_handle, CURLOPT_HTTPGET, 0); + curl_easy_setopt(curl_handle, CURLOPT_CUSTOMREQUEST, kput_method); + curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDSIZE, strlen(body)); + curl_easy_setopt(curl_handle, CURLOPT_COPYPOSTFIELDS, body); + } + else if (strcmp(request, kpost_method) == 0) + { + curl_easy_setopt(curl_handle, CURLOPT_POST, 0); + curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDSIZE, strlen(body)); + curl_easy_setopt(curl_handle, CURLOPT_COPYPOSTFIELDS, body); + } + + curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, 2); + + if (debug) + curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1); + + /* send all data to this function */ + curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, &resp_body); + curl_easy_setopt(curl_handle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); + + /* get it! */ + res = curl_easy_perform(curl_handle); + if (res != CURLE_OK) + { + printf("Error: %d\n", res); + } + ASSERT_EQUAL_INT(res, CURLE_OK); + + curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &http_result_code); + ASSERT_EQUAL_INT(http_result_code, expected_code); + + if (resp_body == NULL) + { + res = 1; + } + else + { + res = strcmp(expected_body, resp_body); + if ((debug) && (res != 0)) + { + printf("res: != %d\n", res); + printf("resp_body:\n=========\n"); + dump_memory(resp_body, strlen(resp_body)); + printf("expected_body:\n==============\n"); + dump_memory(expected_body, strlen(expected_body)); + } + } + + if (debug) + printf ("body: %s != expected_body: %s\n", resp_body, expected_body); + + if (res != 0) + { + ret = 2; + goto exit; + } + ASSERT_EQUAL_INT(res, 0); + +exit: + free(resp_body); + + /* cleanup curl stuff */ + curl_easy_cleanup(curl_handle); + + /* we're done with libcurl, so clean it up */ + curl_global_cleanup(); + + return ret; +}