diff --git a/Makefile.am b/Makefile.am index ccd26d1f7fcca4..094581bcc0f440 100644 --- a/Makefile.am +++ b/Makefile.am @@ -644,10 +644,32 @@ if ENABLE_UNITTESTS check_PROGRAMS = \ libnetdata/tests/str2ld_testdriver \ libnetdata/storage_number/tests/storage_number_testdriver \ + web/api/tests/web_api_testdriver \ $(NULL) TESTS = $(check_PROGRAMS) + web_api_tests_web_api_testdriver_LDFLAGS = \ + -Wl,--wrap=rrdhost_find_by_hostname \ + -Wl,--wrap=finished_web_request_statistics \ + -Wl,--wrap=config_get \ + -Wl,--wrap=web_client_api_request_v1 \ + -Wl,--wrap=rrdhost_find_by_guid \ + -Wl,--wrap=rrdset_find_byname \ + -Wl,--wrap=rrdset_find \ + -Wl,--wrap=rrdpush_receiver_thread_spawn \ + -Wl,--wrap=debug_int \ + -Wl,--wrap=error_int \ + -Wl,--wrap=info_int \ + $(TEST_LDFLAGS) \ + $(NULL) + web_api_tests_web_api_testdriver_SOURCES = \ + web/api/tests/web_api.c \ + web/server/web_client.c \ + $(LIBNETDATA_FILES) \ + $(NULL) + web_api_tests_web_api_testdriver_LDADD = $(NETDATA_COMMON_LIBS) $(TEST_LIBS) + libnetdata_tests_str2ld_testdriver_SOURCES = \ libnetdata/tests/test_str2ld.c \ $(LIBNETDATA_FILES) \ diff --git a/web/api/tests/web_api.c b/web/api/tests/web_api.c new file mode 100644 index 00000000000000..77d3458de40a1d --- /dev/null +++ b/web/api/tests/web_api.c @@ -0,0 +1,168 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "../../../libnetdata/libnetdata.h" +#include "../../../libnetdata/required_dummies.h" +#include "../../../database/rrd.h" +#include "../../../web/server/web_client.h" +#include +#include +#include + +RRDHOST *__wrap_rrdhost_find_by_hostname(const char *hostname, uint32_t hash) +{ + return NULL; +} + +/* Note: we've got some intricate code inside the global statistics module, might be useful to pull it inside the + test set instead of mocking it. */ +void __wrap_finished_web_request_statistics( + uint64_t dt, uint64_t bytes_received, uint64_t bytes_sent, uint64_t content_size, uint64_t compressed_content_size) +{ +} + +char *__wrap_config_get(struct config *root, const char *section, const char *name, const char *default_value) +{ + if (!strcmp(section, CONFIG_SECTION_WEB) && !strcmp(name, "web files owner")) + return "netdata"; + return "UNKNOWN FIX ME"; +} + +int __wrap_web_client_api_request_v1(RRDHOST *host, struct web_client *w, char *url) +{ + printf("api requests: %s\n", url); +} + +int __wrap_rrdpush_receiver_thread_spawn(RRDHOST *host, struct web_client *w, char *url) +{ + return 0; +} + +RRDHOST *__wrap_rrdhost_find_by_guid(const char *guid, uint32_t hash) +{ + printf("FIXME: rrdset_find_guid\n"); + return NULL; +} + +RRDSET *__wrap_rrdset_find_byname(RRDHOST *host, const char *name) +{ + printf("FIXME: rrdset_find_byname\n"); + return NULL; +} + +RRDSET *__wrap_rrdset_find(RRDHOST *host, const char *id) +{ + printf("FIXME: rrdset_find\n"); + return NULL; +} + +void __wrap_debug_int(const char *file, const char *function, const unsigned long line, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + printf("DEBUG: "); + vprintf(fmt, args); + printf("\n"); + va_end(args); +} + +void __wrap_info_int(const char *file, const char *function, const unsigned long line, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + printf("INFO: "); + vprintf(fmt, args); + printf("\n"); + va_end(args); +} + +void __wrap_error_int( + const char *prefix, const char *file, const char *function, const unsigned long line, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + printf("ERROR: "); + vprintf(fmt, args); + printf("\n"); + va_end(args); +} + +WEB_SERVER_MODE web_server_mode = WEB_SERVER_MODE_STATIC_THREADED; +char *netdata_configured_web_dir = "UNKNOWN FIXME"; +RRDHOST *localhost = NULL; + +struct config netdata_config = { .sections = NULL, + .mutex = NETDATA_MUTEX_INITIALIZER, + .index = { .avl_tree = { .root = NULL, .compar = appconfig_section_compare }, + .rwlock = AVL_LOCK_INITIALIZER } }; + +const char *http_headers[] = { "Host: 254.254.0.1", + "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_" // No , + "0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36", + "Connection: keep-alive", + "X-Forwarded-For: 1.254.1.251", + "Cookie: _ga=GA1.1.1227576758.1571113676; _gid=GA1.2.1222321739.1573628979", + "X-Requested-With: XMLHttpRequest", + "Accept-Encoding: gzip, deflate", + "Cache-Control: no-cache, no-store" }; +#define MAX_HEADERS (sizeof(http_headers) / (sizeof(const char *))) + +static void build_request(struct web_buffer *wb, const char *url, bool use_cr, size_t num_headers) +{ + buffer_reset(wb); + buffer_strcat(wb, "GET "); + buffer_strcat(wb, url); + buffer_strcat(wb, " HTTP/1.1"); + if (use_cr) + buffer_strcat(wb, "\r"); + buffer_strcat(wb, "\n"); + for (size_t i = 0; i < num_headers && i < MAX_HEADERS; i++) { + buffer_strcat(wb, http_headers[i]); + if (use_cr) + buffer_strcat(wb, "\r"); + buffer_strcat(wb, "\n"); + } + if (use_cr) + buffer_strcat(wb, "\r"); + buffer_strcat(wb, "\n"); +} + +static struct web_client *pre_test_setup() +{ + localhost = malloc(sizeof(RRDHOST)); + struct web_client *w = (struct web_client *)malloc(sizeof(struct web_client)); + w->response.data = buffer_create(NETDATA_WEB_RESPONSE_INITIAL_SIZE); + w->response.header = buffer_create(NETDATA_WEB_RESPONSE_HEADER_SIZE); + w->response.header_output = buffer_create(NETDATA_WEB_RESPONSE_HEADER_SIZE); + strcpy(w->origin, "*"); // Simulate web_client_create_on_fd() + w->cookie1[0] = 0; // Simulate web_client_create_on_fd() + w->cookie2[0] = 0; // Simulate web_client_create_on_fd() + return w; +} + +static void post_test_cleanup(struct web_client *w) +{ + buffer_free(w->response.data); + buffer_free(w->response.header); + buffer_free(w->response.header_output); + free(w); + free(localhost); +} + +static void api_info(void **state) +{ + for (size_t i = 0; i < MAX_HEADERS; i++) { + struct web_client *w = pre_test_setup(); + build_request(w->response.data, "/api/v1/info", true, i); + web_client_process_request(w); + assert_int_equal(w->flags & WEB_CLIENT_FLAG_WAIT_RECEIVE, 0); + post_test_cleanup(w); + } +} + +int main(void) +{ + const struct CMUnitTest tests[] = { cmocka_unit_test(api_info) }; + debug_flags = 0xffffffffffff; + + return cmocka_run_group_tests_name("web_api", tests, NULL, NULL); +}