Mercurial > louis > mq > lightsd
changeset 213:f90069882b45
wip, kickoff command pipe testing
author | Louis Opter <kalessin@kalessin.fr> |
---|---|
date | Sat, 01 Aug 2015 23:09:48 -0700 |
parents | 61b96816af2f |
children | ab8a871e92bf |
files | series testing_command_pipe.patch |
diffstat | 2 files changed, 454 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/series Sat Aug 01 18:23:13 2015 -0700 +++ b/series Sat Aug 01 23:09:48 2015 -0700 @@ -4,3 +4,4 @@ add_command_pipe.patch fix_usage_and_version.patch daemon_module.patch +testing_command_pipe.patch
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/testing_command_pipe.patch Sat Aug 01 23:09:48 2015 -0700 @@ -0,0 +1,453 @@ +# HG changeset patch +# Parent 4e1471c983f9e4e62394e77cb70fbe07328950da + +diff --git a/CMakeLists.txt b/CMakeLists.txt +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -43,6 +43,8 @@ + "-D_BSD_SOURCE=1" + "-D_DEFAULT_SOURCE=1" + ++ "-D_DARWIN_C_SOURCE=1" ++ + "-DLGTD_BIG_ENDIAN_SYSTEM=${BIG_ENDIAN_SYSTEM}" + "-DLGTD_SIZEOF_VOID_P=${CMAKE_SIZEOF_VOID_P}" + +diff --git a/tests/core/daemon/CMakeLists.txt b/tests/core/daemon/CMakeLists.txt +--- a/tests/core/daemon/CMakeLists.txt ++++ b/tests/core/daemon/CMakeLists.txt +@@ -8,8 +8,8 @@ + ${LIGHTSD_SOURCE_DIR}/core/log.c + ${LIGHTSD_SOURCE_DIR}/core/stats.c + ${LIGHTSD_SOURCE_DIR}/lifx/bulb.c ++ ${LIGHTSD_SOURCE_DIR}/lifx/tagging.c + ${LIGHTSD_SOURCE_DIR}/lifx/wire_proto.c +- ${LIGHTSD_SOURCE_DIR}/lifx/tagging.c + ${CMAKE_CURRENT_SOURCE_DIR}/../tests_shims.c + ${CMAKE_CURRENT_SOURCE_DIR}/../tests_utils.c + ) +diff --git a/tests/core/mock_event2.h b/tests/core/mock_event2.h +new file mode 100644 +--- /dev/null ++++ b/tests/core/mock_event2.h +@@ -0,0 +1,109 @@ ++#pragma once ++ ++#ifndef MOCKED_EVBUFFER_DRAN ++int ++evbuffer_drain(struct evbuffer *buf, size_t len) ++{ ++ (void)buf; ++ (void)len; ++ return 0; ++} ++#endif ++ ++#ifndef MOCKED_EVBUFFER_NEW ++struct evbuffer * ++evbuffer_new(void) ++{ ++ return NULL; ++} ++#endif ++ ++#ifndef MOCKED_EVENT_FREE ++void ++evbuffer_free(struct evbuffer *buf) ++{ ++ (void)buf; ++} ++#endif ++ ++#ifndef MOCKED_EVBUFFER_GET_LENGTH ++size_t ++evbuffer_get_length(const struct evbuffer *buf) ++{ ++ (void)buf; ++ return 0; ++} ++#endif ++ ++#ifndef MOCKED_EVBUFFER_PULLUP ++unsigned char * ++evbuffer_pullup(struct evbuffer *buf, ev_ssize_t size) ++{ ++ (void)buf; ++ (void)size; ++ return NULL; ++} ++#endif ++ ++#ifndef MOCKED_EVBUFFER_READ ++int ++evbuffer_read(struct evbuffer *buffer, evutil_socket_t fd, int howmuch) ++{ ++ (void)buffer; ++ (void)fd; ++ return howmuch; ++} ++#endif ++ ++#ifndef MOCKED_EVENT_ADD ++int ++event_add(struct event *ev, const struct timeval *timeout) ++{ ++ (void)ev; ++ (void)timeout; ++ return 0; ++} ++#endif ++ ++#ifndef MOCKED_EVENT_DEL ++int ++event_del(struct event *ev) ++{ ++ (void)ev; ++ return 0; ++} ++#endif ++ ++#ifndef MOCKED_EVENT_FREE ++void ++event_free(struct event *ev) ++{ ++ (void)ev; ++} ++#endif ++ ++#ifndef MOCKED_EVENT_NEW ++struct event * ++event_new(struct event_base *base, ++ evutil_socket_t fd, ++ short events, ++ event_callback_fn cb, ++ void *ctx) ++{ ++ (void)base; ++ (void)fd; ++ (void)events; ++ (void)cb; ++ (void)ctx; ++ return NULL; ++} ++#endif ++ ++#ifndef MOCKED_EVUTIL_MAKE_SOCKET_NONBLOCKING ++int ++evutil_make_socket_nonblocking(evutil_socket_t fd) ++{ ++ (void)fd; ++ return 0; ++} ++#endif +diff --git a/tests/core/pipe/CMakeLists.txt b/tests/core/pipe/CMakeLists.txt +new file mode 100644 +--- /dev/null ++++ b/tests/core/pipe/CMakeLists.txt +@@ -0,0 +1,25 @@ ++INCLUDE_DIRECTORIES( ++ ${CMAKE_CURRENT_SOURCE_DIR} ++ ${CMAKE_CURRENT_BINARY_DIR} ++) ++ ++ADD_CORE_LIBRARY( ++ test_core_pipe STATIC ++ ${LIGHTSD_SOURCE_DIR}/core/jsmn.c ++ ${LIGHTSD_SOURCE_DIR}/core/log.c ++ ${LIGHTSD_SOURCE_DIR}/core/stats.c ++ ${LIGHTSD_SOURCE_DIR}/lifx/bulb.c ++ ${LIGHTSD_SOURCE_DIR}/lifx/tagging.c ++ ${LIGHTSD_SOURCE_DIR}/lifx/wire_proto.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../tests_shims.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../tests_utils.c ++) ++ ++FUNCTION(ADD_PIPE_TEST TEST_SOURCE) ++ ADD_TEST_FROM_C_SOURCES(${TEST_SOURCE} test_core_pipe) ++ENDFUNCTION() ++ ++FILE(GLOB TESTS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "test_*.c") ++FOREACH(TEST ${TESTS}) ++ ADD_PIPE_TEST(${TEST}) ++ENDFOREACH() +diff --git a/tests/core/pipe/test_pipe_open.c b/tests/core/pipe/test_pipe_open.c +new file mode 100644 +--- /dev/null ++++ b/tests/core/pipe/test_pipe_open.c +@@ -0,0 +1,162 @@ ++#include "pipe.c" ++ ++#include <sys/tree.h> ++#include <endian.h> ++#include <limits.h> ++ ++#include "lifx/wire_proto.h" ++ ++#define MOCKED_EVUTIL_MAKE_SOCKET_NONBLOCKING ++#define MOCKED_EVENT_NEW ++#define MOCKED_EVBUFFER_NEW ++#define MOCKED_EVENT_ADD ++#include "mock_event2.h" ++#include "mock_gateway.h" ++#include "mock_daemon.h" ++ ++#include "tests_utils.h" ++#define MOCKED_CLIENT_OPEN_FROM_PIPE ++#include "tests_pipe_utils.h" ++ ++char *tmpdir = NULL; ++ ++void ++cleanup_tmpdir(void) ++{ ++ lgtd_tests_remove_temp_dir(tmpdir); ++} ++ ++static bool make_socket_nonblocking_call_count = 0; ++ ++int ++evutil_make_socket_nonblocking(evutil_socket_t fd) ++{ ++ if (fd <= 0) { ++ errx(1, "got invalid fd %d in make_socket_nonblocking", fd); ++ } ++ ++ make_socket_nonblocking_call_count++; ++ ++ return 0; ++} ++ ++static int event_new_call_count = 0; ++ ++struct event * ++event_new(struct event_base *base, ++ evutil_socket_t fd, ++ short events, ++ event_callback_fn cb, ++ void *ctx) ++{ ++ if (base != lgtd_ev_base) { ++ errx( ++ 1, "unexpected lgtd_ev_base = %p (expected %p)", ++ base, lgtd_ev_base ++ ); ++ } ++ if (fd <= 0) { ++ errx(1, "got invalid fd %d in event_new", fd); ++ } ++ if (events != (EV_READ|EV_PERSIST)) { ++ errx(1, "got events %#x (expected %#x)", events, EV_READ|EV_PERSIST); ++ } ++ if (cb != lgtd_command_pipe_read_callback) { ++ errx(1, "the read callback wasn't set correctly"); ++ } ++ if (!ctx) { ++ errx(1, "the callback context wasn't set correctly"); ++ } ++ ++ event_new_call_count++; ++ ++ return (void *)1; ++} ++ ++static int evbuffer_new_call_count = 0; ++ ++struct evbuffer * ++evbuffer_new(void) ++{ ++ evbuffer_new_call_count++; ++ ++ return (void *)2; ++} ++ ++static int event_add_call_count = 0; ++ ++int ++event_add(struct event *ev, const struct timeval *timeout) ++{ ++ if (ev != (void *)1) { ++ errx(1, "got unexpected event %p (expected %p)", ev, (void*)1); ++ } ++ ++ if (timeout) { ++ errx(1, "a timeout shouldn't have been passed"); ++ } ++ ++ event_add_call_count++; ++ ++ return 0; ++} ++ ++static int client_open_from_pipe_call_count = 0; ++ ++void ++lgtd_client_open_from_pipe(struct lgtd_client *pipe_client) ++{ ++ if (!pipe_client) { ++ errx(1, "missing pipe_client"); ++ } ++ ++ client_open_from_pipe_call_count++; ++} ++ ++int ++main(void) ++{ ++ tmpdir = lgtd_tests_make_temp_dir(); ++ atexit(cleanup_tmpdir); ++ ++ char path[PATH_MAX] = { 0 }; ++ snprintf(path, sizeof(path), "%s/lightsd.pipe", tmpdir); ++ if (!lgtd_command_pipe_open(path)) { ++ errx(1, "couldn't open pipe"); ++ } ++ ++ if (make_socket_nonblocking_call_count != 1) { ++ errx( ++ 1, "make_socket_nonblocking_call_count = %d", ++ make_socket_nonblocking_call_count ++ ); ++ } ++ if (event_new_call_count != 1) { ++ errx(1, "event_new_call_count = %d", event_new_call_count); ++ } ++ if (evbuffer_new_call_count != 1) { ++ errx(1, "evbuffer_new_call_count = %d", evbuffer_new_call_count); ++ } ++ if (event_add_call_count != 1) { ++ errx(1, "event_add_call_count = %d", event_add_call_count); ++ } ++ if (SLIST_EMPTY(&lgtd_command_pipes)) { ++ errx(1, "the list of command pipes shouldn't be empty"); ++ } ++ ++ struct stat sb; ++ if (stat(path, &sb)) { ++ errx(1, "can't stat pipe %s", path); ++ } ++ ++ mode_t expected_mode; ++ expected_mode = S_IFIFO|S_IWUSR|S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IWGRP; ++ if (sb.st_mode != expected_mode) { ++ errx( ++ 1, "unexpected mode %#x (expected %hx)", ++ sb.st_mode, expected_mode ++ ); ++ } ++ ++ return 0; ++} +diff --git a/tests/core/pipe/tests_pipe_utils.h b/tests/core/pipe/tests_pipe_utils.h +new file mode 100644 +--- /dev/null ++++ b/tests/core/pipe/tests_pipe_utils.h +@@ -0,0 +1,19 @@ ++#pragma once ++ ++#ifndef MOCKED_CLIENT_OPEN_FROM_PIPE ++void ++lgtd_client_open_from_pipe(struct lgtd_client *pipe_client) ++{ ++ memset(pipe_client, 0, sizeof(*pipe_client)); ++ jsmn_init(&pipe_client->jsmn_ctx); ++} ++#endif ++ ++#ifndef MOCKED_JSONRPC_DISPATCH_REQUEST ++void ++lgtd_jsonrpc_dispatch_request(struct lgtd_client *client, int parsed) ++{ ++ (void)client; ++ (void)parsed; ++} ++#endif +diff --git a/tests/core/tests_shims.c b/tests/core/tests_shims.c +--- a/tests/core/tests_shims.c ++++ b/tests/core/tests_shims.c +@@ -24,7 +24,7 @@ + .verbosity = LGTD_DEBUG + }; + +-struct event_base *lgtd_ev_base = NULL; ++struct event_base *lgtd_ev_base = (void *)0x1234; + + const char *lgtd_binds = NULL; + +diff --git a/tests/core/tests_utils.c b/tests/core/tests_utils.c +--- a/tests/core/tests_utils.c ++++ b/tests/core/tests_utils.c +@@ -2,13 +2,18 @@ + #include <sys/tree.h> + #include <sys/socket.h> + #include <assert.h> ++#include <dirent.h> + #include <endian.h> ++#include <err.h> ++#include <limits.h> + #include <netinet/in.h> + #include <stdarg.h> + #include <stdbool.h> + #include <stdlib.h> + #include <stdint.h> ++#include <stdio.h> + #include <string.h> ++#include <unistd.h> + + #include <event2/util.h> + +@@ -131,3 +136,42 @@ + + return listener; + } ++ ++char * ++lgtd_tests_make_temp_dir(void) ++{ ++ char buf[PATH_MAX] = { 0 }; ++ int n = snprintf(buf, sizeof(buf), "%slightsd.test.XXXXXXXX", P_tmpdir); ++ if (n >= (int)sizeof(buf)) { ++ errx(1, "cannot allocate temporary directory"); ++ } ++ return strdup(mkdtemp(buf)); ++} ++ ++void ++lgtd_tests_remove_temp_dir(char *path) ++{ ++ DIR *tmpdir = opendir(path); ++ if (!tmpdir) { ++ return; ++ } ++ ++ struct dirent db; ++ struct dirent *entry = &db; ++ while (!readdir_r(tmpdir, entry, &entry) && entry) { ++ if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")) { ++ continue; ++ } ++ char buf[PATH_MAX] = { 0 }; ++ snprintf(buf, sizeof(buf), "%s/%s", path, entry->d_name); ++ unlink(buf); ++ } ++ ++ closedir(tmpdir); ++ ++ if (rmdir(path)) { ++ warn("couldn't remove tempdir %s", path); ++ } ++ ++ free(path); ++} +diff --git a/tests/core/tests_utils.h b/tests/core/tests_utils.h +--- a/tests/core/tests_utils.h ++++ b/tests/core/tests_utils.h +@@ -30,6 +30,9 @@ + return true; + } + ++char *lgtd_tests_make_temp_dir(void); ++void lgtd_tests_remove_temp_dir(char *); ++ + struct lgtd_lifx_gateway *lgtd_tests_insert_mock_gateway(int); + struct lgtd_lifx_bulb *lgtd_tests_insert_mock_bulb(struct lgtd_lifx_gateway *, uint64_t); + struct lgtd_proto_target_list *lgtd_tests_build_target_list(const char *, ...);