Add another log subsystem test
authorDavin McCall <davmac@davmac.org>
Wed, 1 Jan 2020 01:00:06 +0000 (11:00 +1000)
committerDavin McCall <davmac@davmac.org>
Wed, 1 Jan 2020 01:00:06 +0000 (11:00 +1000)
src/dinit-log.cc
src/includes/dinit-log.h
src/tests/tests.cc

index e0ee69a369e635ba374f05f05312a9d185db1b19..60c447a54c1317f8c019e20dadb47ad64a5f547e 100644 (file)
@@ -267,7 +267,7 @@ rearm buffered_log_stream::fd_event(eventloop_t &loop, int fd, int flags) noexce
 void buffered_log_stream::watch_removed() noexcept
 {
     if (fd > STDERR_FILENO) {
-        close(fd);
+        bp_sys::close(fd);
         fd = -1;
     }
     // Here we rely on there only being two logs, console and "main"; we can check if we are the
@@ -292,6 +292,13 @@ void init_log(service_set *sset, bool syslog_format)
     log_format_syslog[DLOG_MAIN] = syslog_format;
 }
 
+// Close logging subsystem
+void close_log()
+{
+    if (log_stream[DLOG_CONS].fd != -1) log_stream[DLOG_CONS].deregister(event_loop);
+    if (log_stream[DLOG_MAIN].fd != -1) log_stream[DLOG_MAIN].deregister(event_loop);
+}
+
 // Set up the main log to output to the given file descriptor.
 // Potentially throws std::bad_alloc or std::system_error
 void setup_main_log(int fd)
index 534a0b7364ebf37f94e0f0a12c7fc9e3ad4b774b..ec70e12f3974161d15dce2dd96526e337a455ed9 100644 (file)
@@ -34,6 +34,7 @@ extern bool console_service_status;  // show service status messages to console?
 
 void enable_console_log(bool do_enable) noexcept;
 void init_log(service_set *sset, bool syslog_format);
+void close_log();
 void setup_main_log(int fd);
 bool is_log_flushed() noexcept;
 void discard_console_log_buffer() noexcept;
index fdc8e00325f998230aacffd96f1e0295e409ca8d..fd65a46aabcddec1decbe0536b7165a0c06551c4 100644 (file)
@@ -1,6 +1,8 @@
-#include <cassert>
 #include <iostream>
 
+#include <cerrno>
+#include <cassert>
+
 #include "service.h"
 #include "test_service.h"
 #include "baseproc-sys.h"
@@ -723,6 +725,7 @@ static void flush_log(int fd)
 
 void test_log1()
 {
+    // Basic test that output to log is written to log file
     service_set sset;
     init_log(&sset, true /* syslog format */);
 
@@ -743,6 +746,50 @@ void test_log1()
     std::string wstr {wdata.begin(), wdata.end()};
 
     assert(wstr == "<27>dinit: test one\n");
+    close_log();
+}
+
+void test_log2()
+{
+    // test that log is closed on write failure.
+    service_set sset;
+    init_log(&sset, true /* syslog format */);
+
+    bool was_closed = false;
+
+    class fail_writer : public bp_sys::write_handler {
+    public:
+        bool *was_closed = nullptr;
+
+        ssize_t write(int fd, const void *buf, size_t count) override
+        {
+            errno = ENOSPC;
+            return -1;
+        }
+
+        ~fail_writer() override
+        {
+            *was_closed = true;
+        }
+    };
+
+    fail_writer *fw = new fail_writer();
+    fw->was_closed = &was_closed;
+
+    int logfd = bp_sys::allocfd(fw);
+    setup_main_log(logfd);
+
+    event_loop.send_fd_event(logfd, dasynq::OUT_EVENTS);
+    event_loop.send_fd_event(STDOUT_FILENO, dasynq::OUT_EVENTS);
+
+    log(loglevel_t::ERROR, "test two");
+
+    // flush
+    //event_loop.
+    event_loop.send_fd_event(logfd, dasynq::OUT_EVENTS);
+
+    assert(was_closed);
+    close_log();
 }
 
 #define RUN_TEST(name, spacing) \
@@ -752,6 +799,8 @@ void test_log1()
 
 int main(int argc, char **argv)
 {
+    bp_sys::init_bpsys();
+
     RUN_TEST(test1, "                     ");
     RUN_TEST(test2, "                     ");
     RUN_TEST(test3, "                     ");
@@ -771,4 +820,5 @@ int main(int argc, char **argv)
     RUN_TEST(test14, "                    ");
     RUN_TEST(test15, "                    ");
     RUN_TEST(test_log1, "                 ");
+    RUN_TEST(test_log2, "                 ");
 }