changeset 356:f3f4a0235c68

fix tests
author Louis Opter <kalessin@kalessin.fr>
date Sat, 17 Oct 2015 17:50:07 -0700
parents 6cbee013ee07
children 0ff48d26fa44
files add_syslog_support.patch
diffstat 1 files changed, 1657 insertions(+), 76 deletions(-) [+]
line wrap: on
line diff
--- a/add_syslog_support.patch	Sat Oct 17 16:40:57 2015 -0700
+++ b/add_syslog_support.patch	Sat Oct 17 17:50:07 2015 -0700
@@ -15,6 +15,14 @@
      daemon.c
      jsmn.c
      jsonrpc.c
+@@ -25,6 +26,7 @@
+     setproctitle.c
+     stats.c
+     timer.c
++    utils.c
+ )
+ 
+ TARGET_LINK_LIBRARIES(
 diff --git a/core/console.c b/core/console.c
 new file mode 100644
 --- /dev/null
@@ -498,14 +506,16 @@
 diff --git a/core/log.c b/core/log.c
 --- a/core/log.c
 +++ b/core/log.c
-@@ -17,62 +17,25 @@
+@@ -15,211 +15,61 @@
+ // You should have received a copy of the GNU General Public License
+ // along with lighstd.  If not, see <http://www.gnu.org/licenses/>.
  
- #include <sys/socket.h>
+-#include <sys/socket.h>
  #include <sys/tree.h>
 -#include <sys/time.h>
- #include <sys/un.h>
- #include <arpa/inet.h>
- #include <assert.h>
+-#include <sys/un.h>
+-#include <arpa/inet.h>
+-#include <assert.h>
  #include <endian.h>
 -#include <err.h>
 -#include <errno.h>
@@ -514,7 +524,7 @@
  #include <stdint.h>
  #include <stdio.h>
  #include <stdlib.h>
- #include <string.h>
+-#include <string.h>
 -#include <time.h>
  
  #include <event2/event.h>
@@ -543,48 +553,6 @@
 -    return;
 -error:
 -    strbuf[0] = '\0';
--}
--
--static void
--lgtd_log_header(const char *loglvl, bool showprogname)
--{
--    if (lgtd_opts.log_timestamps) {
--        char timestr[64];
--        lgtd_isotime_now(timestr, sizeof(timestr));
--        fprintf(
--            stderr, "[%s] [%s] %s",
--            timestr, loglvl, showprogname ? "lightsd: " : ""
--        );
--        return;
--    }
--    fprintf(stderr, "[%s] %s", loglvl, showprogname ? "lightsd: " : "");
--}
--
- char *
- lgtd_iee8023mactoa(const uint8_t *addr, char *buf, int buflen)
- {
-@@ -163,63 +126,45 @@
-     return buf;
- }
- 
--void
--_lgtd_err(void (*errfn)(int, const char *, ...),
--           int eval,
--           const char *fmt,
--           ...)
--{
--    int errsave = errno;
--    va_list ap;
--    va_start(ap, fmt);
--    // lgtd_cleanup is probably going to free some of the arguments we got, so
--    // let's print to a buffer before we call err.
--    char errmsg[LGTD_ERROR_MSG_BUFSIZE];
--    vsnprintf(errmsg, sizeof(errmsg), fmt, ap);
--    va_end(ap);
--    lgtd_cleanup();
--    lgtd_log_header("ERR", false);
--    errno = errsave;
--    errfn(eval, errmsg);
 +#define ERRFN(fn)                               \
 +void                                            \
 +lgtd_##fn(int eval, const char *fmt, ...)       \
@@ -599,16 +567,19 @@
 +    /* not reached */                           \
  }
  
--void
--_lgtd_warn(void (*warnfn)(const char *, va_list), const char *fmt, ...)
+-static void
+-lgtd_log_header(const char *loglvl, bool showprogname)
 -{
--    if (lgtd_opts.verbosity <= LGTD_WARN) {
--        va_list ap;
--        va_start(ap, fmt);
--        lgtd_log_header("WARN", false);
--        warnfn(fmt, ap);
--        va_end(ap);
+-    if (lgtd_opts.log_timestamps) {
+-        char timestr[64];
+-        lgtd_isotime_now(timestr, sizeof(timestr));
+-        fprintf(
+-            stderr, "[%s] [%s] %s",
+-            timestr, loglvl, showprogname ? "lightsd: " : ""
+-        );
+-        return;
 -    }
+-    fprintf(stderr, "[%s] %s", loglvl, showprogname ? "lightsd: " : "");
 +ERRFN(err);
 +ERRFN(errx);
 +
@@ -630,6 +601,128 @@
 +    va_end(ap);                             \
  }
  
+-char *
+-lgtd_iee8023mactoa(const uint8_t *addr, char *buf, int buflen)
+-{
+-    assert(addr);
+-    assert(buf);
+-    assert(buflen >= 2 * 6 + 5 + 1);
+-
+-    snprintf(
+-        buf, buflen, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
+-        addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]
+-    );
+-    return buf;
+-}
+-
+-char *
+-lgtd_sockaddrtoa(const struct sockaddr *peer, char *buf, int buflen)
+-{
+-    assert(peer);
+-    assert(buf);
+-    assert(buflen > 1);
+-
+-    const char *printed = NULL;
+-    int i = 0;
+-    switch (peer->sa_family) {
+-    case AF_INET:
+-        (void)0;
+-        const struct sockaddr_in *in_peer = (const struct sockaddr_in *)peer;
+-        LGTD_SNPRINTF_APPEND(buf, i, buflen, "[::ffff:");
+-        printed = inet_ntop(AF_INET, &in_peer->sin_addr, &buf[i], buflen - i);
+-        if (printed) {
+-            i += strlen(printed);
+-            LGTD_SNPRINTF_APPEND(
+-                buf, i, buflen, "]:%hu", ntohs(in_peer->sin_port)
+-            );
+-        }
+-        break;
+-    case AF_INET6:
+-        (void)0;
+-        const struct sockaddr_in6 *in6_peer = (const struct sockaddr_in6 *)peer;
+-        LGTD_SNPRINTF_APPEND(buf, i, buflen, "[");
+-        printed = inet_ntop(AF_INET6, &in6_peer->sin6_addr, &buf[i], buflen - i);
+-        if (printed) {
+-            i += strlen(printed);
+-            LGTD_SNPRINTF_APPEND(
+-                buf, i, buflen, "]:%hu", ntohs(in6_peer->sin6_port)
+-            );
+-        }
+-        break;
+-    case AF_UNIX:
+-        (void)0;
+-        const struct sockaddr_un *un_path = (const struct sockaddr_un *)peer;
+-        LGTD_SNPRINTF_APPEND(buf, i, buflen, "at %s", un_path->sun_path);
+-        printed = buf;
+-        break;
+-    default:
+-        break;
+-    }
+-
+-    if (!printed) {
+-        buf[0] = 0;
+-        lgtd_warnx("not enough space to log an ip address");
+-#ifndef NDEBUG
+-        abort();
+-#endif
+-    }
+-
+-    return buf;
+-}
+-
+-char *
+-lgtd_print_duration(uint64_t secs, char *buf, int bufsz)
+-{
+-    assert(buf);
+-    assert(bufsz > 0);
+-
+-    int days = secs / (60 * 60 * 24);
+-    int minutes = secs / 60;
+-    int hours = minutes / 60;
+-    hours = hours % 24;
+-    minutes = minutes % 60;
+-
+-    int i = 0;
+-    if (days) {
+-        int n = snprintf(buf, bufsz, "%d days ", days);
+-        i = LGTD_MIN(i + n, bufsz);
+-    }
+-    snprintf(&buf[i], bufsz - i, "%02d:%02d", hours, minutes);
+-    return buf;
+-}
+-
+-void
+-_lgtd_err(void (*errfn)(int, const char *, ...),
+-           int eval,
+-           const char *fmt,
+-           ...)
+-{
+-    int errsave = errno;
+-    va_list ap;
+-    va_start(ap, fmt);
+-    // lgtd_cleanup is probably going to free some of the arguments we got, so
+-    // let's print to a buffer before we call err.
+-    char errmsg[LGTD_ERROR_MSG_BUFSIZE];
+-    vsnprintf(errmsg, sizeof(errmsg), fmt, ap);
+-    va_end(ap);
+-    lgtd_cleanup();
+-    lgtd_log_header("ERR", false);
+-    errno = errsave;
+-    errfn(eval, errmsg);
+-}
+-
+-void
+-_lgtd_warn(void (*warnfn)(const char *, va_list), const char *fmt, ...)
+-{
+-    if (lgtd_opts.verbosity <= LGTD_WARN) {
+-        va_list ap;
+-        va_start(ap, fmt);
+-        lgtd_log_header("WARN", false);
+-        warnfn(fmt, ap);
+-        va_end(ap);
+-    }
+-}
+-
 -void
 -lgtd_info(const char *fmt, ...)
 -{
@@ -662,7 +755,7 @@
  
  void
  lgtd_libevent_log(int severity, const char *msg)
-@@ -227,7 +172,7 @@
+@@ -227,7 +77,7 @@
      switch (severity) {
      case EVENT_LOG_DEBUG:   lgtd_debug("%s", msg); break;
      case EVENT_LOG_MSG:     lgtd_info("%s", msg);  break;
@@ -671,11 +764,674 @@
      case EVENT_LOG_ERR:     lgtd_warnx("%s", msg); break;
      default:                                       break;
      }
+diff --git a/core/utils.c b/core/utils.c
+new file mode 100644
+--- /dev/null
++++ b/core/utils.c
+@@ -0,0 +1,118 @@
++// Copyright (c) 2015, Louis Opter <kalessin@kalessin.fr>
++//
++// This file is part of lighstd.
++//
++// lighstd is free software: you can redistribute it and/or modify
++// it under the terms of the GNU General Public License as published by
++// the Free Software Foundation, either version 3 of the License, or
++// (at your option) any later version.
++//
++// lighstd 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 General Public License for more details.
++//
++// You should have received a copy of the GNU General Public License
++// along with lighstd.  If not, see <http://www.gnu.org/licenses/>.
++
++#include <sys/socket.h>
++#include <sys/un.h>
++#include <arpa/inet.h>
++#include <assert.h>
++#include <stdbool.h>
++#include <stdint.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++
++#include "lightsd.h"
++
++char *
++lgtd_iee8023mactoa(const uint8_t *addr, char *buf, int buflen)
++{
++    assert(addr);
++    assert(buf);
++    assert(buflen >= 2 * 6 + 5 + 1);
++
++    snprintf(
++        buf, buflen, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
++        addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]
++    );
++    return buf;
++}
++
++char *
++lgtd_sockaddrtoa(const struct sockaddr *peer, char *buf, int buflen)
++{
++    assert(peer);
++    assert(buf);
++    assert(buflen > 1);
++
++    const char *printed = NULL;
++    int i = 0;
++    switch (peer->sa_family) {
++    case AF_INET:
++        (void)0;
++        const struct sockaddr_in *in_peer = (const struct sockaddr_in *)peer;
++        LGTD_SNPRINTF_APPEND(buf, i, buflen, "[::ffff:");
++        printed = inet_ntop(AF_INET, &in_peer->sin_addr, &buf[i], buflen - i);
++        if (printed) {
++            i += strlen(printed);
++            LGTD_SNPRINTF_APPEND(
++                buf, i, buflen, "]:%hu", ntohs(in_peer->sin_port)
++            );
++        }
++        break;
++    case AF_INET6:
++        (void)0;
++        const struct sockaddr_in6 *in6_peer = (const struct sockaddr_in6 *)peer;
++        LGTD_SNPRINTF_APPEND(buf, i, buflen, "[");
++        printed = inet_ntop(AF_INET6, &in6_peer->sin6_addr, &buf[i], buflen - i);
++        if (printed) {
++            i += strlen(printed);
++            LGTD_SNPRINTF_APPEND(
++                buf, i, buflen, "]:%hu", ntohs(in6_peer->sin6_port)
++            );
++        }
++        break;
++    case AF_UNIX:
++        (void)0;
++        const struct sockaddr_un *un_path = (const struct sockaddr_un *)peer;
++        LGTD_SNPRINTF_APPEND(buf, i, buflen, "at %s", un_path->sun_path);
++        printed = buf;
++        break;
++    default:
++        break;
++    }
++
++    if (!printed) {
++        buf[0] = 0;
++        lgtd_warnx("not enough space to log an ip address");
++#ifndef NDEBUG
++        abort();
++#endif
++    }
++
++    return buf;
++}
++
++char *
++lgtd_print_duration(uint64_t secs, char *buf, int bufsz)
++{
++    assert(buf);
++    assert(bufsz > 0);
++
++    int days = secs / (60 * 60 * 24);
++    int minutes = secs / 60;
++    int hours = minutes / 60;
++    hours = hours % 24;
++    minutes = minutes % 60;
++
++    int i = 0;
++    if (days) {
++        int n = snprintf(buf, bufsz, "%d days ", days);
++        i = LGTD_MIN(i + n, bufsz);
++    }
++    snprintf(&buf[i], bufsz - i, "%02d:%02d", hours, minutes);
++    return buf;
++}
+diff --git a/tests/core/client/CMakeLists.txt b/tests/core/client/CMakeLists.txt
+--- a/tests/core/client/CMakeLists.txt
++++ b/tests/core/client/CMakeLists.txt
+@@ -6,8 +6,8 @@
+ ADD_CORE_LIBRARY(
+     test_core_client STATIC
+     ${LIGHTSD_SOURCE_DIR}/core/jsmn.c
+-    ${LIGHTSD_SOURCE_DIR}/core/log.c
+     ${LIGHTSD_SOURCE_DIR}/core/stats.c
++    ${LIGHTSD_SOURCE_DIR}/core/utils.c
+     ${LIGHTSD_SOURCE_DIR}/lifx/bulb.c
+     ${LIGHTSD_SOURCE_DIR}/lifx/tagging.c
+     ${LIGHTSD_SOURCE_DIR}/lifx/wire_proto.c
+diff --git a/tests/core/client/test_client_read_callback.c b/tests/core/client/test_client_read_callback.c
+--- a/tests/core/client/test_client_read_callback.c
++++ b/tests/core/client/test_client_read_callback.c
+@@ -11,6 +11,7 @@
+ #include "mock_gateway.h"
+ #define MOCKED_JSONRPC_DISPATCH_REQUEST
+ #include "mock_jsonrpc.h"
++#include "mock_log.h"
+ #include "mock_router.h"
+ #include "mock_timer.h"
+ 
+diff --git a/tests/core/client/test_client_read_callback_extra_data.c b/tests/core/client/test_client_read_callback_extra_data.c
+--- a/tests/core/client/test_client_read_callback_extra_data.c
++++ b/tests/core/client/test_client_read_callback_extra_data.c
+@@ -11,6 +11,7 @@
+ #include "mock_gateway.h"
+ #define MOCKED_JSONRPC_DISPATCH_REQUEST
+ #include "mock_jsonrpc.h"
++#include "mock_log.h"
+ #include "mock_router.h"
+ #include "mock_timer.h"
+ 
+diff --git a/tests/core/client/test_client_read_callback_multiple_requests.c b/tests/core/client/test_client_read_callback_multiple_requests.c
+--- a/tests/core/client/test_client_read_callback_multiple_requests.c
++++ b/tests/core/client/test_client_read_callback_multiple_requests.c
+@@ -11,6 +11,7 @@
+ #include "mock_gateway.h"
+ #define MOCKED_JSONRPC_DISPATCH_REQUEST
+ #include "mock_jsonrpc.h"
++#include "mock_log.h"
+ #include "mock_router.h"
+ #include "mock_timer.h"
+ 
+diff --git a/tests/core/client/test_client_read_callback_part_too_large.c b/tests/core/client/test_client_read_callback_part_too_large.c
+--- a/tests/core/client/test_client_read_callback_part_too_large.c
++++ b/tests/core/client/test_client_read_callback_part_too_large.c
+@@ -12,6 +12,7 @@
+ #include "mock_gateway.h"
+ #define MOCKED_JSONRPC_DISPATCH_REQUEST
+ #include "mock_jsonrpc.h"
++#include "mock_log.h"
+ #include "mock_router.h"
+ #include "mock_timer.h"
+ 
+diff --git a/tests/core/client/test_client_read_callback_yield_on_eagain.c b/tests/core/client/test_client_read_callback_yield_on_eagain.c
+--- a/tests/core/client/test_client_read_callback_yield_on_eagain.c
++++ b/tests/core/client/test_client_read_callback_yield_on_eagain.c
+@@ -12,6 +12,7 @@
+ #include "mock_gateway.h"
+ #define MOCKED_JSONRPC_DISPATCH_REQUEST
+ #include "mock_jsonrpc.h"
++#include "mock_log.h"
+ #include "mock_router.h"
+ #include "mock_timer.h"
+ 
+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
+@@ -5,9 +5,9 @@
+ 
+ ADD_CORE_LIBRARY(
+     test_core_daemon STATIC
+-    ${LIGHTSD_SOURCE_DIR}/core/log.c
+     ${LIGHTSD_SOURCE_DIR}/core/setproctitle.c
+     ${LIGHTSD_SOURCE_DIR}/core/stats.c
++    ${LIGHTSD_SOURCE_DIR}/core/utils.c
+     ${LIGHTSD_SOURCE_DIR}/lifx/bulb.c
+     ${LIGHTSD_SOURCE_DIR}/lifx/tagging.c
+     ${LIGHTSD_SOURCE_DIR}/lifx/wire_proto.c
+diff --git a/tests/core/daemon/test_daemon_update_proctitle.c b/tests/core/daemon/test_daemon_update_proctitle.c
+--- a/tests/core/daemon/test_daemon_update_proctitle.c
++++ b/tests/core/daemon/test_daemon_update_proctitle.c
+@@ -6,11 +6,10 @@
+ #define setproctitle mock_setproctitle
+ #include "daemon.c"
+ 
+-#include <err.h>
+-
+ #include "mock_gateway.h"
+ #include "mock_pipe.h"
+ #include "mock_router.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ 
+ #include "tests_utils.h"
+diff --git a/tests/core/jsonrpc/CMakeLists.txt b/tests/core/jsonrpc/CMakeLists.txt
+--- a/tests/core/jsonrpc/CMakeLists.txt
++++ b/tests/core/jsonrpc/CMakeLists.txt
+@@ -6,8 +6,8 @@
+ ADD_CORE_LIBRARY(
+     test_core_jsonrpc STATIC
+     ${LIGHTSD_SOURCE_DIR}/core/jsmn.c
+-    ${LIGHTSD_SOURCE_DIR}/core/log.c
+     ${LIGHTSD_SOURCE_DIR}/core/stats.c
++    ${LIGHTSD_SOURCE_DIR}/core/utils.c
+     ${LIGHTSD_SOURCE_DIR}/lifx/wire_proto.c
+     ${LIGHTSD_SOURCE_DIR}/lifx/bulb.c
+     ${CMAKE_CURRENT_SOURCE_DIR}/../tests_shims.c
+diff --git a/tests/core/jsonrpc/test_jsonrpc_batch.c b/tests/core/jsonrpc/test_jsonrpc_batch.c
+--- a/tests/core/jsonrpc/test_jsonrpc_batch.c
++++ b/tests/core/jsonrpc/test_jsonrpc_batch.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #define MOCKED_LGTD_PROTO_GET_LIGHT_STATE
+ #define MOCKED_LGTD_PROTO_POWER_ON
+ #include "mock_proto.h"
+diff --git a/tests/core/jsonrpc/test_jsonrpc_batch_notifications_only.c b/tests/core/jsonrpc/test_jsonrpc_batch_notifications_only.c
+--- a/tests/core/jsonrpc/test_jsonrpc_batch_notifications_only.c
++++ b/tests/core/jsonrpc/test_jsonrpc_batch_notifications_only.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #define MOCKED_LGTD_PROTO_GET_LIGHT_STATE
+ #define MOCKED_LGTD_PROTO_POWER_ON
+ #include "mock_proto.h"
+diff --git a/tests/core/jsonrpc/test_jsonrpc_batch_one_invalid_request.c b/tests/core/jsonrpc/test_jsonrpc_batch_one_invalid_request.c
+--- a/tests/core/jsonrpc/test_jsonrpc_batch_one_invalid_request.c
++++ b/tests/core/jsonrpc/test_jsonrpc_batch_one_invalid_request.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #define MOCKED_LGTD_PROTO_POWER_ON
+ #include "mock_proto.h"
+ #include "test_jsonrpc_utils.h"
+diff --git a/tests/core/jsonrpc/test_jsonrpc_batch_one_notification.c b/tests/core/jsonrpc/test_jsonrpc_batch_one_notification.c
+--- a/tests/core/jsonrpc/test_jsonrpc_batch_one_notification.c
++++ b/tests/core/jsonrpc/test_jsonrpc_batch_one_notification.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #define MOCKED_LGTD_PROTO_GET_LIGHT_STATE
+ #define MOCKED_LGTD_PROTO_POWER_ON
+ #include "mock_proto.h"
+diff --git a/tests/core/jsonrpc/test_jsonrpc_build_target_list.c b/tests/core/jsonrpc/test_jsonrpc_build_target_list.c
+--- a/tests/core/jsonrpc/test_jsonrpc_build_target_list.c
++++ b/tests/core/jsonrpc/test_jsonrpc_build_target_list.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #include "mock_proto.h"
+ #include "test_jsonrpc_utils.h"
+ 
+diff --git a/tests/core/jsonrpc/test_jsonrpc_check_and_call_power_off.c b/tests/core/jsonrpc/test_jsonrpc_check_and_call_power_off.c
+--- a/tests/core/jsonrpc/test_jsonrpc_check_and_call_power_off.c
++++ b/tests/core/jsonrpc/test_jsonrpc_check_and_call_power_off.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #define MOCKED_LGTD_PROTO_POWER_OFF
+ #include "mock_proto.h"
+ 
+diff --git a/tests/core/jsonrpc/test_jsonrpc_check_and_call_power_off_missing_target.c b/tests/core/jsonrpc/test_jsonrpc_check_and_call_power_off_missing_target.c
+--- a/tests/core/jsonrpc/test_jsonrpc_check_and_call_power_off_missing_target.c
++++ b/tests/core/jsonrpc/test_jsonrpc_check_and_call_power_off_missing_target.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #define MOCKED_LGTD_PROTO_POWER_OFF
+ #include "mock_proto.h"
+ 
+diff --git a/tests/core/jsonrpc/test_jsonrpc_check_and_call_power_on.c b/tests/core/jsonrpc/test_jsonrpc_check_and_call_power_on.c
+--- a/tests/core/jsonrpc/test_jsonrpc_check_and_call_power_on.c
++++ b/tests/core/jsonrpc/test_jsonrpc_check_and_call_power_on.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #define MOCKED_LGTD_PROTO_POWER_ON
+ #include "mock_proto.h"
+ 
+diff --git a/tests/core/jsonrpc/test_jsonrpc_check_and_call_power_on_missing_target.c b/tests/core/jsonrpc/test_jsonrpc_check_and_call_power_on_missing_target.c
+--- a/tests/core/jsonrpc/test_jsonrpc_check_and_call_power_on_missing_target.c
++++ b/tests/core/jsonrpc/test_jsonrpc_check_and_call_power_on_missing_target.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #define MOCKED_LGTD_PROTO_POWER_ON
+ #include "mock_proto.h"
+ 
+diff --git a/tests/core/jsonrpc/test_jsonrpc_check_and_call_power_toggle.c b/tests/core/jsonrpc/test_jsonrpc_check_and_call_power_toggle.c
+--- a/tests/core/jsonrpc/test_jsonrpc_check_and_call_power_toggle.c
++++ b/tests/core/jsonrpc/test_jsonrpc_check_and_call_power_toggle.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #define MOCKED_LGTD_PROTO_POWER_TOGGLE
+ #include "mock_proto.h"
+ 
+diff --git a/tests/core/jsonrpc/test_jsonrpc_check_and_call_set_label.c b/tests/core/jsonrpc/test_jsonrpc_check_and_call_set_label.c
+--- a/tests/core/jsonrpc/test_jsonrpc_check_and_call_set_label.c
++++ b/tests/core/jsonrpc/test_jsonrpc_check_and_call_set_label.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #define MOCKED_LGTD_PROTO_SET_LABEL
+ #include "mock_proto.h"
+ #include "mock_gateway.h"
+diff --git a/tests/core/jsonrpc/test_jsonrpc_check_and_call_set_light_from_hsbk.c b/tests/core/jsonrpc/test_jsonrpc_check_and_call_set_light_from_hsbk.c
+--- a/tests/core/jsonrpc/test_jsonrpc_check_and_call_set_light_from_hsbk.c
++++ b/tests/core/jsonrpc/test_jsonrpc_check_and_call_set_light_from_hsbk.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #define MOCKED_LGTD_PROTO_SET_LIGHT_FROM_HSBK
+ #include "mock_proto.h"
+ 
+diff --git a/tests/core/jsonrpc/test_jsonrpc_check_and_call_set_light_from_hsbk_from_array.c b/tests/core/jsonrpc/test_jsonrpc_check_and_call_set_light_from_hsbk_from_array.c
+--- a/tests/core/jsonrpc/test_jsonrpc_check_and_call_set_light_from_hsbk_from_array.c
++++ b/tests/core/jsonrpc/test_jsonrpc_check_and_call_set_light_from_hsbk_from_array.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #define MOCKED_LGTD_PROTO_SET_LIGHT_FROM_HSBK
+ #include "mock_proto.h"
+ 
+diff --git a/tests/core/jsonrpc/test_jsonrpc_check_and_call_set_light_from_hsbk_invalid_params.c b/tests/core/jsonrpc/test_jsonrpc_check_and_call_set_light_from_hsbk_invalid_params.c
+--- a/tests/core/jsonrpc/test_jsonrpc_check_and_call_set_light_from_hsbk_invalid_params.c
++++ b/tests/core/jsonrpc/test_jsonrpc_check_and_call_set_light_from_hsbk_invalid_params.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #define MOCKED_LGTD_PROTO_SET_LIGHT_FROM_HSBK
+ #include "mock_proto.h"
+ 
+diff --git a/tests/core/jsonrpc/test_jsonrpc_check_and_call_set_waveform.c b/tests/core/jsonrpc/test_jsonrpc_check_and_call_set_waveform.c
+--- a/tests/core/jsonrpc/test_jsonrpc_check_and_call_set_waveform.c
++++ b/tests/core/jsonrpc/test_jsonrpc_check_and_call_set_waveform.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #define MOCKED_LGTD_PROTO_SET_WAVEFORM
+ #include "mock_proto.h"
+ 
+diff --git a/tests/core/jsonrpc/test_jsonrpc_check_and_call_set_waveform_invalid_params.c b/tests/core/jsonrpc/test_jsonrpc_check_and_call_set_waveform_invalid_params.c
+--- a/tests/core/jsonrpc/test_jsonrpc_check_and_call_set_waveform_invalid_params.c
++++ b/tests/core/jsonrpc/test_jsonrpc_check_and_call_set_waveform_invalid_params.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #define MOCKED_LGTD_PROTO_SET_WAVEFORM
+ #include "mock_proto.h"
+ 
+diff --git a/tests/core/jsonrpc/test_jsonrpc_check_and_call_tag.c b/tests/core/jsonrpc/test_jsonrpc_check_and_call_tag.c
+--- a/tests/core/jsonrpc/test_jsonrpc_check_and_call_tag.c
++++ b/tests/core/jsonrpc/test_jsonrpc_check_and_call_tag.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #define MOCKED_LGTD_PROTO_TAG
+ #include "mock_proto.h"
+ #include "mock_gateway.h"
+diff --git a/tests/core/jsonrpc/test_jsonrpc_check_and_call_tag_missing_params.c b/tests/core/jsonrpc/test_jsonrpc_check_and_call_tag_missing_params.c
+--- a/tests/core/jsonrpc/test_jsonrpc_check_and_call_tag_missing_params.c
++++ b/tests/core/jsonrpc/test_jsonrpc_check_and_call_tag_missing_params.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #define MOCKED_LGTD_PROTO_TAG
+ #include "mock_proto.h"
+ #include "mock_gateway.h"
+diff --git a/tests/core/jsonrpc/test_jsonrpc_check_and_call_untag.c b/tests/core/jsonrpc/test_jsonrpc_check_and_call_untag.c
+--- a/tests/core/jsonrpc/test_jsonrpc_check_and_call_untag.c
++++ b/tests/core/jsonrpc/test_jsonrpc_check_and_call_untag.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #define MOCKED_LGTD_PROTO_UNTAG
+ #include "mock_proto.h"
+ #include "mock_gateway.h"
+diff --git a/tests/core/jsonrpc/test_jsonrpc_check_and_call_untag_invalid_params.c b/tests/core/jsonrpc/test_jsonrpc_check_and_call_untag_invalid_params.c
+--- a/tests/core/jsonrpc/test_jsonrpc_check_and_call_untag_invalid_params.c
++++ b/tests/core/jsonrpc/test_jsonrpc_check_and_call_untag_invalid_params.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #define MOCKED_LGTD_PROTO_UNTAG
+ #include "mock_proto.h"
+ #include "mock_gateway.h"
+diff --git a/tests/core/jsonrpc/test_jsonrpc_consume_object_or_array.c b/tests/core/jsonrpc/test_jsonrpc_consume_object_or_array.c
+--- a/tests/core/jsonrpc/test_jsonrpc_consume_object_or_array.c
++++ b/tests/core/jsonrpc/test_jsonrpc_consume_object_or_array.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #include "mock_proto.h"
+ #include "test_jsonrpc_utils.h"
+ 
+diff --git a/tests/core/jsonrpc/test_jsonrpc_dispatch_one_no_params.c b/tests/core/jsonrpc/test_jsonrpc_dispatch_one_no_params.c
+--- a/tests/core/jsonrpc/test_jsonrpc_dispatch_one_no_params.c
++++ b/tests/core/jsonrpc/test_jsonrpc_dispatch_one_no_params.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #define MOCKED_LGTD_PROTO_POWER_ON
+ #include "mock_proto.h"
+ 
+diff --git a/tests/core/jsonrpc/test_jsonrpc_extract_request_no_params.c b/tests/core/jsonrpc/test_jsonrpc_extract_request_no_params.c
+--- a/tests/core/jsonrpc/test_jsonrpc_extract_request_no_params.c
++++ b/tests/core/jsonrpc/test_jsonrpc_extract_request_no_params.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #include "mock_proto.h"
+ #include "test_jsonrpc_utils.h"
+ 
+diff --git a/tests/core/jsonrpc/test_jsonrpc_extract_request_notification_no_params.c b/tests/core/jsonrpc/test_jsonrpc_extract_request_notification_no_params.c
+--- a/tests/core/jsonrpc/test_jsonrpc_extract_request_notification_no_params.c
++++ b/tests/core/jsonrpc/test_jsonrpc_extract_request_notification_no_params.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #include "mock_proto.h"
+ #include "test_jsonrpc_utils.h"
+ 
+diff --git a/tests/core/jsonrpc/test_jsonrpc_extract_request_params_array.c b/tests/core/jsonrpc/test_jsonrpc_extract_request_params_array.c
+--- a/tests/core/jsonrpc/test_jsonrpc_extract_request_params_array.c
++++ b/tests/core/jsonrpc/test_jsonrpc_extract_request_params_array.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #include "mock_proto.h"
+ #include "test_jsonrpc_utils.h"
+ 
+diff --git a/tests/core/jsonrpc/test_jsonrpc_extract_request_params_obj.c b/tests/core/jsonrpc/test_jsonrpc_extract_request_params_obj.c
+--- a/tests/core/jsonrpc/test_jsonrpc_extract_request_params_obj.c
++++ b/tests/core/jsonrpc/test_jsonrpc_extract_request_params_obj.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #include "mock_proto.h"
+ #include "test_jsonrpc_utils.h"
+ 
+diff --git a/tests/core/jsonrpc/test_jsonrpc_extract_request_valid_notification.c b/tests/core/jsonrpc/test_jsonrpc_extract_request_valid_notification.c
+--- a/tests/core/jsonrpc/test_jsonrpc_extract_request_valid_notification.c
++++ b/tests/core/jsonrpc/test_jsonrpc_extract_request_valid_notification.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #include "mock_proto.h"
+ #include "test_jsonrpc_utils.h"
+ 
+diff --git a/tests/core/jsonrpc/test_jsonrpc_extract_values_from_schema_and_array_honors_objsize.c b/tests/core/jsonrpc/test_jsonrpc_extract_values_from_schema_and_array_honors_objsize.c
+--- a/tests/core/jsonrpc/test_jsonrpc_extract_values_from_schema_and_array_honors_objsize.c
++++ b/tests/core/jsonrpc/test_jsonrpc_extract_values_from_schema_and_array_honors_objsize.c
+@@ -3,6 +3,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #include "mock_proto.h"
+ #include "test_jsonrpc_utils.h"
+ 
+diff --git a/tests/core/jsonrpc/test_jsonrpc_send_error.c b/tests/core/jsonrpc/test_jsonrpc_send_error.c
+--- a/tests/core/jsonrpc/test_jsonrpc_send_error.c
++++ b/tests/core/jsonrpc/test_jsonrpc_send_error.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #include "mock_proto.h"
+ #include "test_jsonrpc_utils.h"
+ 
+diff --git a/tests/core/jsonrpc/test_jsonrpc_send_response.c b/tests/core/jsonrpc/test_jsonrpc_send_response.c
+--- a/tests/core/jsonrpc/test_jsonrpc_send_response.c
++++ b/tests/core/jsonrpc/test_jsonrpc_send_response.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #include "mock_proto.h"
+ #include "test_jsonrpc_utils.h"
+ 
+diff --git a/tests/core/jsonrpc/test_jsonrpc_type_float_between_0_and_1_invalid.c b/tests/core/jsonrpc/test_jsonrpc_type_float_between_0_and_1_invalid.c
+--- a/tests/core/jsonrpc/test_jsonrpc_type_float_between_0_and_1_invalid.c
++++ b/tests/core/jsonrpc/test_jsonrpc_type_float_between_0_and_1_invalid.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #include "mock_proto.h"
+ #include "test_jsonrpc_utils.h"
+ 
+diff --git a/tests/core/jsonrpc/test_jsonrpc_type_float_between_0_and_1_valid.c b/tests/core/jsonrpc/test_jsonrpc_type_float_between_0_and_1_valid.c
+--- a/tests/core/jsonrpc/test_jsonrpc_type_float_between_0_and_1_valid.c
++++ b/tests/core/jsonrpc/test_jsonrpc_type_float_between_0_and_1_valid.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #include "mock_proto.h"
+ #include "test_jsonrpc_utils.h"
+ 
+diff --git a/tests/core/jsonrpc/test_jsonrpc_type_float_between_0_and_360_invalid.c b/tests/core/jsonrpc/test_jsonrpc_type_float_between_0_and_360_invalid.c
+--- a/tests/core/jsonrpc/test_jsonrpc_type_float_between_0_and_360_invalid.c
++++ b/tests/core/jsonrpc/test_jsonrpc_type_float_between_0_and_360_invalid.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #include "mock_proto.h"
+ #include "test_jsonrpc_utils.h"
+ 
+diff --git a/tests/core/jsonrpc/test_jsonrpc_type_float_between_0_and_360_valid.c b/tests/core/jsonrpc/test_jsonrpc_type_float_between_0_and_360_valid.c
+--- a/tests/core/jsonrpc/test_jsonrpc_type_float_between_0_and_360_valid.c
++++ b/tests/core/jsonrpc/test_jsonrpc_type_float_between_0_and_360_valid.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #include "mock_proto.h"
+ #include "test_jsonrpc_utils.h"
+ 
+diff --git a/tests/core/jsonrpc/test_jsonrpc_type_integer.c b/tests/core/jsonrpc/test_jsonrpc_type_integer.c
+--- a/tests/core/jsonrpc/test_jsonrpc_type_integer.c
++++ b/tests/core/jsonrpc/test_jsonrpc_type_integer.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #include "mock_proto.h"
+ #include "test_jsonrpc_utils.h"
+ 
+diff --git a/tests/core/jsonrpc/test_jsonrpc_type_integer_invalid_characters.c b/tests/core/jsonrpc/test_jsonrpc_type_integer_invalid_characters.c
+--- a/tests/core/jsonrpc/test_jsonrpc_type_integer_invalid_characters.c
++++ b/tests/core/jsonrpc/test_jsonrpc_type_integer_invalid_characters.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #include "mock_proto.h"
+ #include "test_jsonrpc_utils.h"
+ 
+diff --git a/tests/core/jsonrpc/test_jsonrpc_type_integer_too_big.c b/tests/core/jsonrpc/test_jsonrpc_type_integer_too_big.c
+--- a/tests/core/jsonrpc/test_jsonrpc_type_integer_too_big.c
++++ b/tests/core/jsonrpc/test_jsonrpc_type_integer_too_big.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #include "mock_proto.h"
+ #include "test_jsonrpc_utils.h"
+ 
+diff --git a/tests/core/jsonrpc/test_jsonrpc_type_integer_too_small.c b/tests/core/jsonrpc/test_jsonrpc_type_integer_too_small.c
+--- a/tests/core/jsonrpc/test_jsonrpc_type_integer_too_small.c
++++ b/tests/core/jsonrpc/test_jsonrpc_type_integer_too_small.c
+@@ -1,6 +1,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #include "mock_proto.h"
+ #include "test_jsonrpc_utils.h"
+ 
+diff --git a/tests/core/jsonrpc/test_jsonrpc_uint16_range_to_float_string.c b/tests/core/jsonrpc/test_jsonrpc_uint16_range_to_float_string.c
+--- a/tests/core/jsonrpc/test_jsonrpc_uint16_range_to_float_string.c
++++ b/tests/core/jsonrpc/test_jsonrpc_uint16_range_to_float_string.c
+@@ -3,6 +3,7 @@
+ #include "jsonrpc.c"
+ 
+ #include "mock_client_buf.h"
++#include "mock_log.h"
+ #include "mock_proto.h"
+ #include "test_jsonrpc_utils.h"
+ 
 diff --git a/tests/core/mock_log.h b/tests/core/mock_log.h
 new file mode 100644
 --- /dev/null
 +++ b/tests/core/mock_log.h
-@@ -0,0 +1,98 @@
+@@ -0,0 +1,90 @@
 +#pragma once
 +
 +#include <errno.h>
@@ -686,13 +1442,9 @@
 +void
 +lgtd_err(int eval, const char *fmt, ...)
 +{
-+    if (lgtd_opts.verbosity > LGTD_ERN) {
-+        return;
-+    }
-+
 +    fprintf(stderr, "ERR: ");
 +    va_list ap;
-+    va_start(fmt, ap);
++    va_start(ap, fmt);
 +    vfprintf(stderr, fmt, ap);
 +    va_end(ap);
 +    fprintf(stderr, ": %s\n", strerror(errno));
@@ -702,16 +1454,12 @@
 +void
 +lgtd_errx(int eval, const char *fmt, ...)
 +{
-+    if (lgtd_opts.verbosity > LGTD_ERN) {
-+        return;
-+    }
-+
 +    fprintf(stderr, "ERR: ");
 +    va_list ap;
-+    va_start(fmt, ap);
++    va_start(ap, fmt);
 +    vfprintf(stderr, fmt, ap);
 +    va_end(ap);
-+    fputc("\n", stderr);
++    fputc('\n', stderr);
 +    exit(eval);
 +}
 +
@@ -724,7 +1472,7 @@
 +
 +    fprintf(stderr, "WARN: ");
 +    va_list ap;
-+    va_start(fmt, ap);
++    va_start(ap, fmt);
 +    vfprintf(stderr, fmt, ap);
 +    va_end(ap);
 +    fprintf(stderr, ": %s\n", strerror(errno));
@@ -739,10 +1487,10 @@
 +
 +    fprintf(stderr, "WARN: ");
 +    va_list ap;
-+    va_start(fmt, ap);
++    va_start(ap, fmt);
 +    vfprintf(stderr, fmt, ap);
 +    va_end(ap);
-+    fputc("\n", stderr);
++    fputc('\n', stderr);
 +}
 +
 +void
@@ -754,10 +1502,10 @@
 +
 +    fprintf(stderr, "INFO: ");
 +    va_list ap;
-+    va_start(fmt, ap);
++    va_start(ap, fmt);
 +    vfprintf(stderr, fmt, ap);
 +    va_end(ap);
-+    fputc("\n", stderr);
++    fputc('\n', stderr);
 +}
 +
 +void
@@ -769,8 +1517,841 @@
 +
 +    fprintf(stderr, "DEBUG: ");
 +    va_list ap;
-+    va_start(fmt, ap);
++    va_start(ap, fmt);
 +    vfprintf(stderr, fmt, ap);
 +    va_end(ap);
-+    fputc("\n", stderr);
++    fputc('\n', stderr);
 +}
+diff --git a/tests/core/pipe/CMakeLists.txt b/tests/core/pipe/CMakeLists.txt
+--- a/tests/core/pipe/CMakeLists.txt
++++ b/tests/core/pipe/CMakeLists.txt
+@@ -6,8 +6,8 @@
+ ADD_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}/core/utils.c
+     ${LIGHTSD_SOURCE_DIR}/lifx/bulb.c
+     ${LIGHTSD_SOURCE_DIR}/lifx/tagging.c
+     ${LIGHTSD_SOURCE_DIR}/lifx/wire_proto.c
+diff --git a/tests/core/pipe/test_pipe_close.c b/tests/core/pipe/test_pipe_close.c
+--- a/tests/core/pipe/test_pipe_close.c
++++ b/tests/core/pipe/test_pipe_close.c
+@@ -15,6 +15,7 @@
+ #include "mock_event2.h"
+ #include "mock_gateway.h"
+ #include "mock_jsonrpc.h"
++#include "mock_log.h"
+ #include "mock_router.h"
+ #include "mock_timer.h"
+ 
+diff --git a/tests/core/pipe/test_pipe_open.c b/tests/core/pipe/test_pipe_open.c
+--- a/tests/core/pipe/test_pipe_open.c
++++ b/tests/core/pipe/test_pipe_open.c
+@@ -14,6 +14,7 @@
+ #include "mock_event2.h"
+ #include "mock_gateway.h"
+ #include "mock_jsonrpc.h"
++#include "mock_log.h"
+ #include "mock_router.h"
+ #include "mock_timer.h"
+ 
+diff --git a/tests/core/pipe/test_pipe_open_fifo_already_exists.c b/tests/core/pipe/test_pipe_open_fifo_already_exists.c
+--- a/tests/core/pipe/test_pipe_open_fifo_already_exists.c
++++ b/tests/core/pipe/test_pipe_open_fifo_already_exists.c
+@@ -14,6 +14,7 @@
+ #include "mock_event2.h"
+ #include "mock_gateway.h"
+ #include "mock_jsonrpc.h"
++#include "mock_log.h"
+ #include "mock_router.h"
+ #include "mock_timer.h"
+ 
+diff --git a/tests/core/pipe/test_pipe_read_callback.c b/tests/core/pipe/test_pipe_read_callback.c
+--- a/tests/core/pipe/test_pipe_read_callback.c
++++ b/tests/core/pipe/test_pipe_read_callback.c
+@@ -18,6 +18,7 @@
+ #include "mock_gateway.h"
+ #define MOCKED_JSONRPC_DISPATCH_REQUEST
+ #include "mock_jsonrpc.h"
++#include "mock_log.h"
+ #include "mock_router.h"
+ #include "mock_timer.h"
+ 
+diff --git a/tests/core/pipe/test_pipe_read_callback_extra_data.c b/tests/core/pipe/test_pipe_read_callback_extra_data.c
+--- a/tests/core/pipe/test_pipe_read_callback_extra_data.c
++++ b/tests/core/pipe/test_pipe_read_callback_extra_data.c
+@@ -17,6 +17,7 @@
+ #include "mock_gateway.h"
+ #define MOCKED_JSONRPC_DISPATCH_REQUEST
+ #include "mock_jsonrpc.h"
++#include "mock_log.h"
+ #include "mock_router.h"
+ #include "mock_timer.h"
+ 
+diff --git a/tests/core/pipe/test_pipe_read_callback_multiple_requests.c b/tests/core/pipe/test_pipe_read_callback_multiple_requests.c
+--- a/tests/core/pipe/test_pipe_read_callback_multiple_requests.c
++++ b/tests/core/pipe/test_pipe_read_callback_multiple_requests.c
+@@ -17,6 +17,7 @@
+ #include "mock_gateway.h"
+ #define MOCKED_JSONRPC_DISPATCH_REQUEST
+ #include "mock_jsonrpc.h"
++#include "mock_log.h"
+ #include "mock_router.h"
+ #include "mock_timer.h"
+ 
+diff --git a/tests/core/pipe/test_pipe_read_callback_yield_on_eagain.c b/tests/core/pipe/test_pipe_read_callback_yield_on_eagain.c
+--- a/tests/core/pipe/test_pipe_read_callback_yield_on_eagain.c
++++ b/tests/core/pipe/test_pipe_read_callback_yield_on_eagain.c
+@@ -17,6 +17,7 @@
+ #include "mock_gateway.h"
+ #define MOCKED_JSONRPC_DISPATCH_REQUEST
+ #include "mock_jsonrpc.h"
++#include "mock_log.h"
+ #include "mock_router.h"
+ #include "mock_timer.h"
+ 
+diff --git a/tests/core/proto/CMakeLists.txt b/tests/core/proto/CMakeLists.txt
+--- a/tests/core/proto/CMakeLists.txt
++++ b/tests/core/proto/CMakeLists.txt
+@@ -5,9 +5,9 @@
+ 
+ ADD_CORE_LIBRARY(
+     test_core_proto STATIC
+-    ${LIGHTSD_SOURCE_DIR}/core/log.c
+     ${LIGHTSD_SOURCE_DIR}/core/jsonrpc.c
+     ${LIGHTSD_SOURCE_DIR}/core/stats.c
++    ${LIGHTSD_SOURCE_DIR}/core/utils.c
+     ${LIGHTSD_SOURCE_DIR}/lifx/bulb.c
+     ${LIGHTSD_SOURCE_DIR}/lifx/tagging.c
+     ${LIGHTSD_SOURCE_DIR}/lifx/wire_proto.c
+diff --git a/tests/core/proto/test_proto_get_light_state.c b/tests/core/proto/test_proto_get_light_state.c
+--- a/tests/core/proto/test_proto_get_light_state.c
++++ b/tests/core/proto/test_proto_get_light_state.c
+@@ -4,6 +4,7 @@
+ #include "mock_daemon.h"
+ #include "mock_gateway.h"
+ #include "mock_event2.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "tests_utils.h"
+ 
+diff --git a/tests/core/proto/test_proto_get_light_state_empty_device_list.c b/tests/core/proto/test_proto_get_light_state_empty_device_list.c
+--- a/tests/core/proto/test_proto_get_light_state_empty_device_list.c
++++ b/tests/core/proto/test_proto_get_light_state_empty_device_list.c
+@@ -3,6 +3,7 @@
+ #include "mock_client_buf.h"
+ #include "mock_daemon.h"
+ #include "mock_event2.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "tests_utils.h"
+ 
+diff --git a/tests/core/proto/test_proto_get_light_state_label_overflow.c b/tests/core/proto/test_proto_get_light_state_label_overflow.c
+--- a/tests/core/proto/test_proto_get_light_state_label_overflow.c
++++ b/tests/core/proto/test_proto_get_light_state_label_overflow.c
+@@ -4,6 +4,7 @@
+ #include "mock_daemon.h"
+ #include "mock_gateway.h"
+ #include "mock_event2.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "tests_utils.h"
+ 
+diff --git a/tests/core/proto/test_proto_get_light_state_null_device_list.c b/tests/core/proto/test_proto_get_light_state_null_device_list.c
+--- a/tests/core/proto/test_proto_get_light_state_null_device_list.c
++++ b/tests/core/proto/test_proto_get_light_state_null_device_list.c
+@@ -3,6 +3,7 @@
+ #include "mock_client_buf.h"
+ #include "mock_daemon.h"
+ #include "mock_event2.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "tests_utils.h"
+ 
+diff --git a/tests/core/proto/test_proto_get_light_state_unknown_tag_id.c b/tests/core/proto/test_proto_get_light_state_unknown_tag_id.c
+--- a/tests/core/proto/test_proto_get_light_state_unknown_tag_id.c
++++ b/tests/core/proto/test_proto_get_light_state_unknown_tag_id.c
+@@ -4,6 +4,7 @@
+ #include "mock_daemon.h"
+ #include "mock_gateway.h"
+ #include "mock_event2.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "tests_utils.h"
+ 
+diff --git a/tests/core/proto/test_proto_power_off.c b/tests/core/proto/test_proto_power_off.c
+--- a/tests/core/proto/test_proto_power_off.c
++++ b/tests/core/proto/test_proto_power_off.c
+@@ -3,6 +3,7 @@
+ #include "mock_client_buf.h"
+ #include "mock_daemon.h"
+ #include "mock_event2.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "tests_utils.h"
+ 
+diff --git a/tests/core/proto/test_proto_power_off_routing_error.c b/tests/core/proto/test_proto_power_off_routing_error.c
+--- a/tests/core/proto/test_proto_power_off_routing_error.c
++++ b/tests/core/proto/test_proto_power_off_routing_error.c
+@@ -3,6 +3,7 @@
+ #include "mock_client_buf.h"
+ #include "mock_daemon.h"
+ #include "mock_event2.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "tests_utils.h"
+ 
+diff --git a/tests/core/proto/test_proto_power_on.c b/tests/core/proto/test_proto_power_on.c
+--- a/tests/core/proto/test_proto_power_on.c
++++ b/tests/core/proto/test_proto_power_on.c
+@@ -3,6 +3,7 @@
+ #include "mock_client_buf.h"
+ #include "mock_daemon.h"
+ #include "mock_event2.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "tests_utils.h"
+ 
+diff --git a/tests/core/proto/test_proto_power_on_routing_error.c b/tests/core/proto/test_proto_power_on_routing_error.c
+--- a/tests/core/proto/test_proto_power_on_routing_error.c
++++ b/tests/core/proto/test_proto_power_on_routing_error.c
+@@ -3,6 +3,7 @@
+ #include "mock_client_buf.h"
+ #include "mock_daemon.h"
+ #include "mock_event2.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "tests_utils.h"
+ 
+diff --git a/tests/core/proto/test_proto_power_toggle.c b/tests/core/proto/test_proto_power_toggle.c
+--- a/tests/core/proto/test_proto_power_toggle.c
++++ b/tests/core/proto/test_proto_power_toggle.c
+@@ -4,6 +4,7 @@
+ #include "mock_daemon.h"
+ #include "mock_gateway.h"
+ #include "mock_event2.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "tests_utils.h"
+ 
+diff --git a/tests/core/proto/test_proto_power_toggle_targets_to_device_fails.c b/tests/core/proto/test_proto_power_toggle_targets_to_device_fails.c
+--- a/tests/core/proto/test_proto_power_toggle_targets_to_device_fails.c
++++ b/tests/core/proto/test_proto_power_toggle_targets_to_device_fails.c
+@@ -4,6 +4,7 @@
+ #include "mock_daemon.h"
+ #include "mock_gateway.h"
+ #include "mock_event2.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "tests_utils.h"
+ 
+diff --git a/tests/core/proto/test_proto_set_label.c b/tests/core/proto/test_proto_set_label.c
+--- a/tests/core/proto/test_proto_set_label.c
++++ b/tests/core/proto/test_proto_set_label.c
+@@ -3,6 +3,7 @@
+ #include "mock_client_buf.h"
+ #include "mock_daemon.h"
+ #include "mock_event2.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "tests_utils.h"
+ 
+diff --git a/tests/core/proto/test_proto_set_label_too_long.c b/tests/core/proto/test_proto_set_label_too_long.c
+--- a/tests/core/proto/test_proto_set_label_too_long.c
++++ b/tests/core/proto/test_proto_set_label_too_long.c
+@@ -3,6 +3,7 @@
+ #include "mock_client_buf.h"
+ #include "mock_daemon.h"
+ #include "mock_event2.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "tests_utils.h"
+ 
+diff --git a/tests/core/proto/test_proto_set_light_from_hsbk.c b/tests/core/proto/test_proto_set_light_from_hsbk.c
+--- a/tests/core/proto/test_proto_set_light_from_hsbk.c
++++ b/tests/core/proto/test_proto_set_light_from_hsbk.c
+@@ -5,6 +5,7 @@
+ #include "mock_client_buf.h"
+ #include "mock_daemon.h"
+ #include "mock_event2.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "tests_utils.h"
+ 
+diff --git a/tests/core/proto/test_proto_set_light_from_hsbk_on_routing_error.c b/tests/core/proto/test_proto_set_light_from_hsbk_on_routing_error.c
+--- a/tests/core/proto/test_proto_set_light_from_hsbk_on_routing_error.c
++++ b/tests/core/proto/test_proto_set_light_from_hsbk_on_routing_error.c
+@@ -5,6 +5,7 @@
+ #include "mock_client_buf.h"
+ #include "mock_daemon.h"
+ #include "mock_event2.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "tests_utils.h"
+ 
+diff --git a/tests/core/proto/test_proto_set_waveform.c b/tests/core/proto/test_proto_set_waveform.c
+--- a/tests/core/proto/test_proto_set_waveform.c
++++ b/tests/core/proto/test_proto_set_waveform.c
+@@ -5,6 +5,7 @@
+ #include "mock_client_buf.h"
+ #include "mock_daemon.h"
+ #include "mock_event2.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "tests_utils.h"
+ 
+diff --git a/tests/core/proto/test_proto_set_waveform_on_routing_error.c b/tests/core/proto/test_proto_set_waveform_on_routing_error.c
+--- a/tests/core/proto/test_proto_set_waveform_on_routing_error.c
++++ b/tests/core/proto/test_proto_set_waveform_on_routing_error.c
+@@ -5,6 +5,7 @@
+ #include "mock_client_buf.h"
+ #include "mock_daemon.h"
+ #include "mock_event2.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "tests_utils.h"
+ 
+diff --git a/tests/core/proto/test_proto_tag_create.c b/tests/core/proto/test_proto_tag_create.c
+--- a/tests/core/proto/test_proto_tag_create.c
++++ b/tests/core/proto/test_proto_tag_create.c
+@@ -6,6 +6,7 @@
+ #define MOCKED_LIFX_GATEWAY_ALLOCATE_TAG_ID
+ #include "mock_gateway.h"
+ #include "mock_event2.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "tests_utils.h"
+ 
+diff --git a/tests/core/proto/test_proto_tag_create_lifx_gw_tag_ids_full.c b/tests/core/proto/test_proto_tag_create_lifx_gw_tag_ids_full.c
+--- a/tests/core/proto/test_proto_tag_create_lifx_gw_tag_ids_full.c
++++ b/tests/core/proto/test_proto_tag_create_lifx_gw_tag_ids_full.c
+@@ -6,6 +6,7 @@
+ #define MOCKED_LIFX_GATEWAY_ALLOCATE_TAG_ID
+ #include "mock_gateway.h"
+ #include "mock_event2.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "tests_utils.h"
+ 
+diff --git a/tests/core/proto/test_proto_tag_update.c b/tests/core/proto/test_proto_tag_update.c
+--- a/tests/core/proto/test_proto_tag_update.c
++++ b/tests/core/proto/test_proto_tag_update.c
+@@ -6,6 +6,7 @@
+ #define MOCKED_LIFX_GATEWAY_ALLOCATE_TAG_ID
+ #include "mock_gateway.h"
+ #include "mock_event2.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "tests_utils.h"
+ 
+diff --git a/tests/core/proto/test_proto_untag.c b/tests/core/proto/test_proto_untag.c
+--- a/tests/core/proto/test_proto_untag.c
++++ b/tests/core/proto/test_proto_untag.c
+@@ -4,6 +4,7 @@
+ #include "mock_daemon.h"
+ #include "mock_gateway.h"
+ #include "mock_event2.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "tests_utils.h"
+ 
+diff --git a/tests/core/proto/test_proto_untag_tag_does_not_exist.c b/tests/core/proto/test_proto_untag_tag_does_not_exist.c
+--- a/tests/core/proto/test_proto_untag_tag_does_not_exist.c
++++ b/tests/core/proto/test_proto_untag_tag_does_not_exist.c
+@@ -4,6 +4,7 @@
+ #include "mock_daemon.h"
+ #include "mock_gateway.h"
+ #include "mock_event2.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "tests_utils.h"
+ 
+diff --git a/tests/core/router/CMakeLists.txt b/tests/core/router/CMakeLists.txt
+--- a/tests/core/router/CMakeLists.txt
++++ b/tests/core/router/CMakeLists.txt
+@@ -5,9 +5,9 @@
+ 
+ ADD_CORE_LIBRARY(
+     test_core_router STATIC
+-    ${LIGHTSD_SOURCE_DIR}/core/log.c
+     ${LIGHTSD_SOURCE_DIR}/core/proto.c
+     ${LIGHTSD_SOURCE_DIR}/core/stats.c
++    ${LIGHTSD_SOURCE_DIR}/core/utils.c
+     ${LIGHTSD_SOURCE_DIR}/lifx/bulb.c
+     ${LIGHTSD_SOURCE_DIR}/lifx/tagging.c
+     ${LIGHTSD_SOURCE_DIR}/lifx/wire_proto.c
+diff --git a/tests/core/router/test_router_send_to_broadcast.c b/tests/core/router/test_router_send_to_broadcast.c
+--- a/tests/core/router/test_router_send_to_broadcast.c
++++ b/tests/core/router/test_router_send_to_broadcast.c
+@@ -1,6 +1,7 @@
+ #include "router.c"
+ 
+ #include "mock_daemon.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "tests_utils.h"
+ 
+diff --git a/tests/core/router/test_router_send_to_device.c b/tests/core/router/test_router_send_to_device.c
+--- a/tests/core/router/test_router_send_to_device.c
++++ b/tests/core/router/test_router_send_to_device.c
+@@ -1,6 +1,7 @@
+ #include "router.c"
+ 
+ #include "mock_daemon.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "tests_utils.h"
+ #include "tests_router_utils.h"
+diff --git a/tests/core/router/test_router_send_to_invalid_targets.c b/tests/core/router/test_router_send_to_invalid_targets.c
+--- a/tests/core/router/test_router_send_to_invalid_targets.c
++++ b/tests/core/router/test_router_send_to_invalid_targets.c
+@@ -1,6 +1,7 @@
+ #include "router.c"
+ 
+ #include "mock_daemon.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "tests_utils.h"
+ #include "tests_router_utils.h"
+diff --git a/tests/core/router/test_router_send_to_label.c b/tests/core/router/test_router_send_to_label.c
+--- a/tests/core/router/test_router_send_to_label.c
++++ b/tests/core/router/test_router_send_to_label.c
+@@ -1,6 +1,7 @@
+ #include "router.c"
+ 
+ #include "mock_daemon.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "tests_utils.h"
+ #include "tests_router_utils.h"
+diff --git a/tests/core/router/test_router_send_to_tag.c b/tests/core/router/test_router_send_to_tag.c
+--- a/tests/core/router/test_router_send_to_tag.c
++++ b/tests/core/router/test_router_send_to_tag.c
+@@ -1,6 +1,7 @@
+ #include "router.c"
+ 
+ #include "mock_daemon.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "tests_utils.h"
+ #include "tests_router_utils.h"
+diff --git a/tests/core/router/test_router_targets_to_devices.c b/tests/core/router/test_router_targets_to_devices.c
+--- a/tests/core/router/test_router_targets_to_devices.c
++++ b/tests/core/router/test_router_targets_to_devices.c
+@@ -1,6 +1,7 @@
+ #include "router.c"
+ 
+ #include "mock_daemon.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "tests_utils.h"
+ #include "tests_router_utils.h"
+diff --git a/tests/lifx/bulb/CMakeLists.txt b/tests/lifx/bulb/CMakeLists.txt
+--- a/tests/lifx/bulb/CMakeLists.txt
++++ b/tests/lifx/bulb/CMakeLists.txt
+@@ -5,8 +5,8 @@
+ 
+ ADD_CORE_LIBRARY(
+     test_lifx_bulb_core STATIC
+-    ${LIGHTSD_SOURCE_DIR}/core/log.c
+     ${LIGHTSD_SOURCE_DIR}/core/stats.c
++    ${LIGHTSD_SOURCE_DIR}/core/utils.c
+     ${CMAKE_CURRENT_SOURCE_DIR}/../tests_shims.c
+     ${CMAKE_CURRENT_SOURCE_DIR}/../../core/tests_utils.c
+ )
+diff --git a/tests/lifx/bulb/test_bulb_close.c b/tests/lifx/bulb/test_bulb_close.c
+--- a/tests/lifx/bulb/test_bulb_close.c
++++ b/tests/lifx/bulb/test_bulb_close.c
+@@ -1,6 +1,7 @@
+ #include "bulb.c"
+ 
+ #include "mock_gateway.h"
++#include "mock_log.h"
+ #include "mock_router.h"
+ #include "mock_timer.h"
+ 
+diff --git a/tests/lifx/bulb/test_bulb_fetch_hardware_info.c b/tests/lifx/bulb/test_bulb_fetch_hardware_info.c
+--- a/tests/lifx/bulb/test_bulb_fetch_hardware_info.c
++++ b/tests/lifx/bulb/test_bulb_fetch_hardware_info.c
+@@ -1,6 +1,7 @@
+ #include "bulb.c"
+ 
+ #include "mock_gateway.h"
++#include "mock_log.h"
+ #define MOCKED_LGTD_ROUTER_SEND_TO_DEVICE
+ #include "mock_router.h"
+ #define MOCKED_LGTD_TIMER_STOP
+diff --git a/tests/lifx/bulb/test_bulb_has_label.c b/tests/lifx/bulb/test_bulb_has_label.c
+--- a/tests/lifx/bulb/test_bulb_has_label.c
++++ b/tests/lifx/bulb/test_bulb_has_label.c
+@@ -1,6 +1,7 @@
+ #include "bulb.c"
+ 
+ #include "mock_gateway.h"
++#include "mock_log.h"
+ #include "mock_router.h"
+ #include "mock_timer.h"
+ 
+diff --git a/tests/lifx/bulb/test_bulb_open.c b/tests/lifx/bulb/test_bulb_open.c
+--- a/tests/lifx/bulb/test_bulb_open.c
++++ b/tests/lifx/bulb/test_bulb_open.c
+@@ -1,6 +1,7 @@
+ #include "bulb.c"
+ 
+ #include "mock_gateway.h"
++#include "mock_log.h"
+ #include "mock_router.h"
+ #define MOCKED_LGTD_TIMER_START
+ #include "mock_timer.h"
+diff --git a/tests/lifx/bulb/test_bulb_set_light_state.c b/tests/lifx/bulb/test_bulb_set_light_state.c
+--- a/tests/lifx/bulb/test_bulb_set_light_state.c
++++ b/tests/lifx/bulb/test_bulb_set_light_state.c
+@@ -2,6 +2,7 @@
+ 
+ #define MOCKED_LGTD_LIFX_GATEWAY_UPDATE_TAG_REFCOUNTS
+ #include "mock_gateway.h"
++#include "mock_log.h"
+ #include "mock_router.h"
+ #include "mock_timer.h"
+ 
+diff --git a/tests/lifx/bulb/test_bulb_set_power_state.c b/tests/lifx/bulb/test_bulb_set_power_state.c
+--- a/tests/lifx/bulb/test_bulb_set_power_state.c
++++ b/tests/lifx/bulb/test_bulb_set_power_state.c
+@@ -1,6 +1,7 @@
+ #include "bulb.c"
+ 
+ #include "mock_gateway.h"
++#include "mock_log.h"
+ #include "mock_router.h"
+ #include "mock_timer.h"
+ 
+diff --git a/tests/lifx/bulb/test_bulb_set_tags.c b/tests/lifx/bulb/test_bulb_set_tags.c
+--- a/tests/lifx/bulb/test_bulb_set_tags.c
++++ b/tests/lifx/bulb/test_bulb_set_tags.c
+@@ -2,6 +2,7 @@
+ 
+ #define MOCKED_LGTD_LIFX_GATEWAY_UPDATE_TAG_REFCOUNTS
+ #include "mock_gateway.h"
++#include "mock_log.h"
+ #include "mock_router.h"
+ #include "mock_timer.h"
+ 
+diff --git a/tests/lifx/gateway/CMakeLists.txt b/tests/lifx/gateway/CMakeLists.txt
+--- a/tests/lifx/gateway/CMakeLists.txt
++++ b/tests/lifx/gateway/CMakeLists.txt
+@@ -5,10 +5,10 @@
+ 
+ ADD_CORE_LIBRARY(
+     test_lifx_gateway_core STATIC
+-    ${LIGHTSD_SOURCE_DIR}/core/log.c
+     ${LIGHTSD_SOURCE_DIR}/core/proto.c
+     ${LIGHTSD_SOURCE_DIR}/core/router.c
+     ${LIGHTSD_SOURCE_DIR}/core/stats.c
++    ${LIGHTSD_SOURCE_DIR}/core/utils.c
+     ${CMAKE_CURRENT_SOURCE_DIR}/../tests_shims.c
+     ${CMAKE_CURRENT_SOURCE_DIR}/../../core/tests_utils.c
+ )
+diff --git a/tests/lifx/gateway/test_gateway_allocate_tag_id.c b/tests/lifx/gateway/test_gateway_allocate_tag_id.c
+--- a/tests/lifx/gateway/test_gateway_allocate_tag_id.c
++++ b/tests/lifx/gateway/test_gateway_allocate_tag_id.c
+@@ -4,6 +4,7 @@
+ 
+ #define MOCKED_LIFX_TAGGING_INCREF
+ #include "test_gateway_utils.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ 
+ static bool tagging_incref_called = false;
+diff --git a/tests/lifx/gateway/test_gateway_allocate_tag_id_from_lifx_network.c b/tests/lifx/gateway/test_gateway_allocate_tag_id_from_lifx_network.c
+--- a/tests/lifx/gateway/test_gateway_allocate_tag_id_from_lifx_network.c
++++ b/tests/lifx/gateway/test_gateway_allocate_tag_id_from_lifx_network.c
+@@ -4,6 +4,7 @@
+ 
+ #define MOCKED_LIFX_TAGGING_INCREF
+ #include "test_gateway_utils.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ 
+ static bool tagging_incref_called = false;
+diff --git a/tests/lifx/gateway/test_gateway_allocate_tag_id_no_tag_id_left.c b/tests/lifx/gateway/test_gateway_allocate_tag_id_no_tag_id_left.c
+--- a/tests/lifx/gateway/test_gateway_allocate_tag_id_no_tag_id_left.c
++++ b/tests/lifx/gateway/test_gateway_allocate_tag_id_no_tag_id_left.c
+@@ -5,6 +5,7 @@
+ 
+ #define MOCKED_LIFX_TAGGING_INCREF
+ #include "test_gateway_utils.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ 
+ static bool tagging_incref_called = false;
+diff --git a/tests/lifx/gateway/test_gateway_deallocate_tag_id_from_lifx_network.c b/tests/lifx/gateway/test_gateway_deallocate_tag_id_from_lifx_network.c
+--- a/tests/lifx/gateway/test_gateway_deallocate_tag_id_from_lifx_network.c
++++ b/tests/lifx/gateway/test_gateway_deallocate_tag_id_from_lifx_network.c
+@@ -4,6 +4,7 @@
+ 
+ #define MOCKED_LIFX_TAGGING_DECREF
+ #include "test_gateway_utils.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ 
+ static bool tagging_decref_called = false;
+diff --git a/tests/lifx/gateway/test_gateway_enqueue_packet.c b/tests/lifx/gateway/test_gateway_enqueue_packet.c
+--- a/tests/lifx/gateway/test_gateway_enqueue_packet.c
++++ b/tests/lifx/gateway/test_gateway_enqueue_packet.c
+@@ -1,6 +1,7 @@
+ #include "gateway.c"
+ 
+ #include "test_gateway_utils.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ 
+ int
+diff --git a/tests/lifx/gateway/test_gateway_enqueue_packet_ring_full.c b/tests/lifx/gateway/test_gateway_enqueue_packet_ring_full.c
+--- a/tests/lifx/gateway/test_gateway_enqueue_packet_ring_full.c
++++ b/tests/lifx/gateway/test_gateway_enqueue_packet_ring_full.c
+@@ -1,6 +1,7 @@
+ #include "gateway.c"
+ 
+ #include "test_gateway_utils.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ 
+ int
+diff --git a/tests/lifx/gateway/test_gateway_enqueue_packet_ring_wraparound.c b/tests/lifx/gateway/test_gateway_enqueue_packet_ring_wraparound.c
+--- a/tests/lifx/gateway/test_gateway_enqueue_packet_ring_wraparound.c
++++ b/tests/lifx/gateway/test_gateway_enqueue_packet_ring_wraparound.c
+@@ -1,6 +1,7 @@
+ #include "gateway.c"
+ 
+ #include "test_gateway_utils.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ 
+ int
+diff --git a/tests/lifx/gateway/test_gateway_handle_ambient_light.c b/tests/lifx/gateway/test_gateway_handle_ambient_light.c
+--- a/tests/lifx/gateway/test_gateway_handle_ambient_light.c
++++ b/tests/lifx/gateway/test_gateway_handle_ambient_light.c
+@@ -2,6 +2,7 @@
+ 
+ #include "gateway.c"
+ 
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "test_gateway_utils.h"
+ #include "tests_utils.h"
+diff --git a/tests/lifx/gateway/test_gateway_handle_bulb_label.c b/tests/lifx/gateway/test_gateway_handle_bulb_label.c
+--- a/tests/lifx/gateway/test_gateway_handle_bulb_label.c
++++ b/tests/lifx/gateway/test_gateway_handle_bulb_label.c
+@@ -2,6 +2,7 @@
+ 
+ #include "gateway.c"
+ 
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "test_gateway_utils.h"
+ #include "tests_utils.h"
+diff --git a/tests/lifx/gateway/test_gateway_handle_ip_firmware_info.c b/tests/lifx/gateway/test_gateway_handle_ip_firmware_info.c
+--- a/tests/lifx/gateway/test_gateway_handle_ip_firmware_info.c
++++ b/tests/lifx/gateway/test_gateway_handle_ip_firmware_info.c
+@@ -2,6 +2,7 @@
+ 
+ #include "gateway.c"
+ 
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "test_gateway_utils.h"
+ #include "tests_utils.h"
+diff --git a/tests/lifx/gateway/test_gateway_handle_ip_state.c b/tests/lifx/gateway/test_gateway_handle_ip_state.c
+--- a/tests/lifx/gateway/test_gateway_handle_ip_state.c
++++ b/tests/lifx/gateway/test_gateway_handle_ip_state.c
+@@ -2,6 +2,7 @@
+ 
+ #include "gateway.c"
+ 
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "test_gateway_utils.h"
+ #include "tests_utils.h"
+diff --git a/tests/lifx/gateway/test_gateway_handle_product_info.c b/tests/lifx/gateway/test_gateway_handle_product_info.c
+--- a/tests/lifx/gateway/test_gateway_handle_product_info.c
++++ b/tests/lifx/gateway/test_gateway_handle_product_info.c
+@@ -2,6 +2,7 @@
+ 
+ #include "gateway.c"
+ 
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "test_gateway_utils.h"
+ #include "tests_utils.h"
+diff --git a/tests/lifx/gateway/test_gateway_handle_runtime_info.c b/tests/lifx/gateway/test_gateway_handle_runtime_info.c
+--- a/tests/lifx/gateway/test_gateway_handle_runtime_info.c
++++ b/tests/lifx/gateway/test_gateway_handle_runtime_info.c
+@@ -2,6 +2,7 @@
+ 
+ #include "gateway.c"
+ 
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "test_gateway_utils.h"
+ #include "tests_utils.h"
+diff --git a/tests/lifx/gateway/test_gateway_handle_tag_labels.c b/tests/lifx/gateway/test_gateway_handle_tag_labels.c
+--- a/tests/lifx/gateway/test_gateway_handle_tag_labels.c
++++ b/tests/lifx/gateway/test_gateway_handle_tag_labels.c
+@@ -3,6 +3,7 @@
+ #include "gateway.c"
+ 
+ #include "test_gateway_utils.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ 
+ int
+diff --git a/tests/lifx/gateway/test_gateway_handle_tags.c b/tests/lifx/gateway/test_gateway_handle_tags.c
+--- a/tests/lifx/gateway/test_gateway_handle_tags.c
++++ b/tests/lifx/gateway/test_gateway_handle_tags.c
+@@ -2,6 +2,7 @@
+ 
+ #include "gateway.c"
+ 
++#include "mock_log.h"
+ #include "mock_timer.h"
+ #include "test_gateway_utils.h"
+ #include "tests_utils.h"
+diff --git a/tests/lifx/gateway/test_gateway_update_tag_refcounts.c b/tests/lifx/gateway/test_gateway_update_tag_refcounts.c
+--- a/tests/lifx/gateway/test_gateway_update_tag_refcounts.c
++++ b/tests/lifx/gateway/test_gateway_update_tag_refcounts.c
+@@ -1,6 +1,7 @@
+ #include "gateway.c"
+ 
+ #include "test_gateway_utils.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ 
+ int
+diff --git a/tests/lifx/gateway/test_gateway_write_callback.c b/tests/lifx/gateway/test_gateway_write_callback.c
+--- a/tests/lifx/gateway/test_gateway_write_callback.c
++++ b/tests/lifx/gateway/test_gateway_write_callback.c
+@@ -3,6 +3,7 @@
+ #define MOCKED_EVBUFFER_WRITE_ATMOST
+ #define MOCKED_EVBUFFER_GET_LENGTH
+ #include "test_gateway_utils.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ 
+ size_t
+diff --git a/tests/lifx/gateway/test_gateway_write_callback_clears_ring_full_flag.c b/tests/lifx/gateway/test_gateway_write_callback_clears_ring_full_flag.c
+--- a/tests/lifx/gateway/test_gateway_write_callback_clears_ring_full_flag.c
++++ b/tests/lifx/gateway/test_gateway_write_callback_clears_ring_full_flag.c
+@@ -3,6 +3,7 @@
+ #define MOCKED_EVBUFFER_WRITE_ATMOST
+ #define MOCKED_EVBUFFER_GET_LENGTH
+ #include "test_gateway_utils.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ 
+ size_t
+diff --git a/tests/lifx/gateway/test_gateway_write_callback_last_packet_on_ring.c b/tests/lifx/gateway/test_gateway_write_callback_last_packet_on_ring.c
+--- a/tests/lifx/gateway/test_gateway_write_callback_last_packet_on_ring.c
++++ b/tests/lifx/gateway/test_gateway_write_callback_last_packet_on_ring.c
+@@ -3,6 +3,7 @@
+ #define MOCKED_EVBUFFER_WRITE_ATMOST
+ #define MOCKED_EVBUFFER_GET_LENGTH
+ #include "test_gateway_utils.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ 
+ size_t
+diff --git a/tests/lifx/gateway/test_gateway_write_callback_partial_write.c b/tests/lifx/gateway/test_gateway_write_callback_partial_write.c
+--- a/tests/lifx/gateway/test_gateway_write_callback_partial_write.c
++++ b/tests/lifx/gateway/test_gateway_write_callback_partial_write.c
+@@ -3,6 +3,7 @@
+ #define MOCKED_EVBUFFER_WRITE_ATMOST
+ #define MOCKED_EVBUFFER_GET_LENGTH
+ #include "test_gateway_utils.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ 
+ size_t
+diff --git a/tests/lifx/gateway/test_gateway_write_callback_ring_wraparound.c b/tests/lifx/gateway/test_gateway_write_callback_ring_wraparound.c
+--- a/tests/lifx/gateway/test_gateway_write_callback_ring_wraparound.c
++++ b/tests/lifx/gateway/test_gateway_write_callback_ring_wraparound.c
+@@ -3,6 +3,7 @@
+ #define MOCKED_EVBUFFER_WRITE_ATMOST
+ #define MOCKED_EVBUFFER_GET_LENGTH
+ #include "test_gateway_utils.h"
++#include "mock_log.h"
+ #include "mock_timer.h"
+ 
+ size_t
+diff --git a/tests/lifx/tagging/CMakeLists.txt b/tests/lifx/tagging/CMakeLists.txt
+--- a/tests/lifx/tagging/CMakeLists.txt
++++ b/tests/lifx/tagging/CMakeLists.txt
+@@ -5,8 +5,8 @@
+ 
+ ADD_CORE_LIBRARY(
+     test_lifx_tagging STATIC
+-    ${LIGHTSD_SOURCE_DIR}/core/log.c
+     ${LIGHTSD_SOURCE_DIR}/core/stats.c
++    ${LIGHTSD_SOURCE_DIR}/core/utils.c
+     ${CMAKE_CURRENT_SOURCE_DIR}/../tests_shims.c
+ )
+ 
+diff --git a/tests/lifx/tagging/test_tagging_decref.c b/tests/lifx/tagging/test_tagging_decref.c
+--- a/tests/lifx/tagging/test_tagging_decref.c
++++ b/tests/lifx/tagging/test_tagging_decref.c
+@@ -1,5 +1,7 @@
+ #include "tagging.c"
+ 
++#include "mock_log.h"
++
+ static int
+ count_tag(const char *tag_label)
+ {
+diff --git a/tests/lifx/tagging/test_tagging_incref.c b/tests/lifx/tagging/test_tagging_incref.c
+--- a/tests/lifx/tagging/test_tagging_incref.c
++++ b/tests/lifx/tagging/test_tagging_incref.c
+@@ -1,5 +1,7 @@
+ #include "tagging.c"
+ 
++#include "mock_log.h"
++
+ static int
+ count_tag(const char *tag_label)
+ {
+diff --git a/tests/lifx/wire_proto/CMakeLists.txt b/tests/lifx/wire_proto/CMakeLists.txt
+--- a/tests/lifx/wire_proto/CMakeLists.txt
++++ b/tests/lifx/wire_proto/CMakeLists.txt
+@@ -5,8 +5,8 @@
+ 
+ ADD_CORE_LIBRARY(
+     test_lifx_wire_proto_core STATIC
+-    ${LIGHTSD_SOURCE_DIR}/core/log.c
+     ${LIGHTSD_SOURCE_DIR}/core/stats.c
++    ${LIGHTSD_SOURCE_DIR}/core/utils.c
+     ${CMAKE_CURRENT_SOURCE_DIR}/../tests_shims.c
+ )
+ 
+diff --git a/tests/lifx/wire_proto/test_wire_proto_encode_decode_header.c b/tests/lifx/wire_proto/test_wire_proto_encode_decode_header.c
+--- a/tests/lifx/wire_proto/test_wire_proto_encode_decode_header.c
++++ b/tests/lifx/wire_proto/test_wire_proto_encode_decode_header.c
+@@ -3,6 +3,7 @@
+ #include "wire_proto.c"
+ 
+ #include "mock_gateway.h"
++#include "mock_log.h"
+ 
+ int
+ main(void)
+diff --git a/tests/lifx/wire_proto/test_wire_proto_waveform_table.c b/tests/lifx/wire_proto/test_wire_proto_waveform_table.c
+--- a/tests/lifx/wire_proto/test_wire_proto_waveform_table.c
++++ b/tests/lifx/wire_proto/test_wire_proto_waveform_table.c
+@@ -2,6 +2,8 @@
+ 
+ #include "mock_gateway.h"
+ 
++#include "mock_log.h"
++
+ int
+ main(void)
+ {