From patchwork Fri Jul 12 20:16:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 1675 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2622861607 for ; Fri, 12 Jul 2019 22:16:30 +0200 (CEST) Received: from neptunite.amanokami.net (softbank126209254147.bbtec.net [126.209.254.147]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 05E9D2B2; Fri, 12 Jul 2019 22:16:27 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1562962589; bh=gx/DccBevK4La2pqBOrMLHG9t5pn8PfGRm3BvQulAQg=; h=From:To:Cc:Subject:Date:From; b=MO6PbkduJj/mjjcHDhX2SJ2vDRdywU0C1rCz+9tUByPwZ9Y7PnteE/H6W/SVjfYNZ XUKpDw/OIKPOM4sAb42YQmMSQw0xc0FKBy7dCEAAocxj022PnrkEZISfsHvPVNV23y VypkTsmfX6YMUWw+XA9EzjaTUlK4Y/61XVTNChSs= From: Paul Elder To: libcamera-devel@lists.libcamera.org Date: Sat, 13 Jul 2019 05:16:17 +0900 Message-Id: <20190712201620.30457-1-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 1/4] libcamera: logging: add syslog, stream, and nowhere logging targets X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 12 Jul 2019 20:16:30 -0000 Allow logging to syslog, or any given ostream, or to nowhere. The logging API is updated to accomodate these new logging destinations. LogMessage is modified to allow this. Signed-off-by: Paul Elder --- include/libcamera/logging.h | 13 +- src/libcamera/include/log.h | 11 ++ src/libcamera/log.cpp | 345 +++++++++++++++++++++++++++++------- 3 files changed, 306 insertions(+), 63 deletions(-) diff --git a/include/libcamera/logging.h b/include/libcamera/logging.h index a8495cf..a6fa8dc 100644 --- a/include/libcamera/logging.h +++ b/include/libcamera/logging.h @@ -9,8 +9,17 @@ namespace libcamera { -void logSetFile(const char *file); -int logSetLevel(const char *category, const char *level); +enum LoggingTarget { + LoggingTargetNone, + LoggingTargetSyslog, + LoggingTargetFile, + LoggingTargetStream, +}; + +int logSetFile(const char *path); +int logSetStream(std::ostream &stream); +int logSetTarget(LoggingTarget target); +void logSetLevel(const char *category, const char *level); } /* namespace libcamera */ diff --git a/src/libcamera/include/log.h b/src/libcamera/include/log.h index 802836d..394db83 100644 --- a/src/libcamera/include/log.h +++ b/src/libcamera/include/log.h @@ -60,12 +60,23 @@ public: std::ostream &stream() { return msgStream_; } + std::string ×tamp() { return logTimestamp_; } + LogSeverity severity() { return severity_; } + std::string &category() { return logCategory_; } + std::string &fileInfo() { return logFileInfo_; } + std::string &msg() { return msg_; } + private: void init(const char *fileName, unsigned int line); std::ostringstream msgStream_; const LogCategory &category_; LogSeverity severity_; + + std::string logTimestamp_; + std::string logCategory_; + std::string logFileInfo_; + std::string msg_; }; class Loggable diff --git a/src/libcamera/log.cpp b/src/libcamera/log.cpp index 709c669..df63e81 100644 --- a/src/libcamera/log.cpp +++ b/src/libcamera/log.cpp @@ -15,8 +15,11 @@ #include #include #include +#include #include +#include + #include "utils.h" /** @@ -60,7 +63,12 @@ class Logger public: static Logger *instance(); - void write(const std::string &msg); + void write(LogMessage *msg); + + int logSetFile(const char *path); + int logSetStream(std::ostream &stream); + int logSetTarget(LoggingTarget target); + void logSetLevel(const char *category, const char *level); private: Logger(); @@ -68,9 +76,7 @@ private: void parseLogFile(); void parseLogLevels(); static LogSeverity parseLogLevel(const std::string &level); - - friend int logSetFile(const char *file); - friend void logSetLevel(const char *category, const char *level); + void closeLog(); friend LogCategory; void registerCategory(LogCategory *category); @@ -81,40 +87,83 @@ private: std::ofstream file_; std::ostream *output_; + + enum LoggingTarget target_; }; +/** + * \enum LoggingTarget + * \brief Log destination type + * \var LoggingTargetNone + * \brief No logging destination + * \sa logSetTarget + * \var LoggingTargetSyslog + * \brief Log to syslog + * \sa logSetTarget + * \var LoggingTargetFile + * \brief Log to file + * \sa logSetFile + * \var LoggingTargetStream + * \brief Log to stream + * \sa logSetStream + */ + /** * \brief Set the log file - * \param[in] file Full path to the log file + * \param[in] path Full path to the log file * - * This function sets the logging output file to \a file. The previous log file, + * This function sets the logging output file to \a path. The previous log file, * if any, is closed, and all new log messages will be written to the new log * file. * - * If \a file is a null pointer, the log is directed to stderr. If the - * function returns an error, the log file is not changed. + * If the function returns an error, the log file is not changed. * * \return Zero on success, or a negative error code otherwise. */ -int logSetFile(const char *file) +int logSetFile(const char *path) { - Logger *logger = Logger::instance(); - - if (!file) { - logger->output_ = &std::cerr; - logger->file_.close(); - return 0; - } + return Logger::instance()->logSetFile(path); +} - std::ofstream logFile(file); - if (!logFile.good()) - return -EINVAL; +/** + * \brief Set the log stream + * \param[in] stream Stream to send log output to + * + * This function sets the logging output stream to \a stream. The previous log file, + * if any, is closed, and all new log messages will be written to the new log + * stream. + * + * If the function returns an error, the log file is not changed. + * + * \return Zero on success, or a negative error code otherwise. + */ +int logSetStream(std::ostream &stream) +{ + return Logger::instance()->logSetStream(stream); +} - if (logger->output_ != &std::cerr) - logger->file_.close(); - logger->file_ = std::move(logFile); - logger->output_ = &logger->file_; - return 0; +/** + * \brief Set the log target + * \param[in] target Log destination + * + * This function sets the logging output to the target specified by \a target. + * The allowed values of \a target are LoggingTargetNone and LoggingTargetSyslog. + * LoggingTargetNone will send the log output to nowhere, and LoggingTargetSyslog + * will send the log output to syslog. The previous log file, if any, is closed, + * and all new log messages will be written to the new log destination. + * + * LoggingTargetFile and LoggingTargetStream are not valid values for \a target. + * Use logSetFile() and logSetStream() instead, respectively. + * + * \sa LoggingTarget + * + * If the function returns an error, the log file is not changed. + * + * \return Zero on success, or a negative error code otherwise. + */ +int logSetTarget(LoggingTarget target) +{ + return Logger::instance()->logSetTarget(target); } /** @@ -134,15 +183,41 @@ int logSetFile(const char *file) */ void logSetLevel(const char *category, const char *level) { - Logger *logger = Logger::instance(); + Logger::instance()->logSetLevel(category, level); +} - LogSeverity severity = Logger::parseLogLevel(level); - if (severity == LogInvalid) - return; +static int log_severity_to_syslog(LogSeverity severity) +{ + switch (severity) { + case LogDebug: + return LOG_DEBUG; + case LogInfo: + return LOG_INFO; + case LogWarning: + return LOG_WARNING; + case LogError: + return LOG_ERR; + case LogFatal: + return LOG_ALERT; + default: + return LOG_NOTICE; + } +} - for (LogCategory *c : logger->categories_) - if (!strcmp(c->name(), category)) - c->setSeverity(severity); +static const char *log_severity_name(LogSeverity severity) +{ + static const char *const names[] = { + " DBG", + " INFO", + " WARN", + " ERR", + "FATAL", + }; + + if (static_cast(severity) < ARRAY_SIZE(names)) + return names[severity]; + else + return "UNKWN"; } /** @@ -163,17 +238,119 @@ Logger *Logger::instance() * \brief Write a message to the configured logger output * \param[in] msg The message string */ -void Logger::write(const std::string &msg) +void Logger::write(LogMessage *msg) +{ + std::string str; + + switch (target_) { + case LoggingTargetNone: + break; + case LoggingTargetSyslog: + str = std::string(log_severity_name(msg->severity())) + " " + + msg->category() + " " + msg->fileInfo() + " " + msg->msg(); + syslog(log_severity_to_syslog(msg->severity()), "%s", str.c_str()); + break; + case LoggingTargetFile: + case LoggingTargetStream: + str = msg->timestamp() + log_severity_name(msg->severity()) + + " " + msg->category() + " " + msg->fileInfo() + " " + + msg->msg(); + output_->write(str.c_str(), str.size()); + output_->flush(); + break; + } +} + +/** + * \brief Set the log file + * \param[in] path Full path to the log file + * + * \sa logSetFile + * + * \return Zero on success, or a negative error code otherwise. + */ +int Logger::logSetFile(const char *path) +{ + std::ofstream logFile(path); + if (!logFile.good()) + return -EINVAL; + + closeLog(); + file_ = std::move(logFile); + output_ = &file_; + target_ = LoggingTargetFile; + + return 0; +} + +/** + * \brief Set the log stream + * \param[in] stream Stream to send log output to + * + * \sa logSetStream + * + * \return Zero on success, or a negative error code otherwise. + */ +int Logger::logSetStream(std::ostream &stream) { - output_->write(msg.c_str(), msg.size()); - output_->flush(); + closeLog(); + output_ = &stream; + target_ = LoggingTargetStream; + return 0; +} + +/** + * \brief Set the log target + * \param[in] target Log destination + * + * \sa logSetTarget + * + * \return Zero on success, or a negative error code otherwise. + */ +int Logger::logSetTarget(enum LoggingTarget target) +{ + switch (target) { + case LoggingTargetNone: + closeLog(); + output_ = nullptr; + target_ = LoggingTargetNone; + break; + case LoggingTargetSyslog: + openlog("libcamera", LOG_PID, 0); + closeLog(); + output_ = nullptr; + target_ = LoggingTargetSyslog; + break; + default: + return -EINVAL; + } + + return 0; +} + +/** + * \brief Set the log level + * \param[in] category Logging category + * \param[in] level Log level + * + * \sa logSetLevel + */ +void Logger::logSetLevel(const char *category, const char *level) +{ + LogSeverity severity = Logger::parseLogLevel(level); + if (severity == LogInvalid) + return; + + for (LogCategory *c : categories_) + if (!strcmp(c->name(), category)) + c->setSeverity(severity); } /** * \brief Construct a logger */ Logger::Logger() - : output_(&std::cerr) + : output_(&std::cerr), target_(LoggingTargetStream) { parseLogFile(); parseLogLevels(); @@ -184,6 +361,7 @@ Logger::Logger() * * If the LIBCAMERA_LOG_FILE environment variable is set, open the file it * points to and redirect the logger output to it. Errors are silently ignored + * * and don't affect the logger output (set to stderr). */ void Logger::parseLogFile() @@ -192,9 +370,16 @@ void Logger::parseLogFile() if (!file) return; + if (!strcmp(file, "syslog")) { + openlog("libcamera", LOG_PID, 0); + target_ = LoggingTargetSyslog; + return; + } + file_.open(file); if (file_.good()) output_ = &file_; + target_ = LoggingTargetFile; } /** @@ -286,6 +471,25 @@ LogSeverity Logger::parseLogLevel(const std::string &level) return static_cast(severity); } +/** + * \brief Close the current log file + */ +void Logger::closeLog() +{ + switch (target_) { + case LoggingTargetNone: + break; + case LoggingTargetSyslog: + closelog(); + break; + case LoggingTargetFile: + file_.close(); + break; + case LoggingTargetStream: + break; + } +} + /** * \brief Register a log category with the logger * \param[in] category The log category @@ -408,22 +612,6 @@ const LogCategory &LogCategory::defaultCategory() return category; } -static const char *log_severity_name(LogSeverity severity) -{ - static const char *const names[] = { - " DBG", - " INFO", - " WARN", - " ERR", - "FATAL", - }; - - if (static_cast(severity) < ARRAY_SIZE(names)) - return names[severity]; - else - return "UNKWN"; -} - /** * \class LogMessage * \brief Internal log message representation. @@ -495,16 +683,22 @@ void LogMessage::init(const char *fileName, unsigned int line) /* Log the timestamp, severity and file information. */ struct timespec timestamp; clock_gettime(CLOCK_MONOTONIC, ×tamp); - msgStream_.fill('0'); - msgStream_ << "[" << timestamp.tv_sec / (60 * 60) << ":" + std::ostringstream ossTimestamp; + ossTimestamp.fill('0'); + ossTimestamp << "[" << timestamp.tv_sec / (60 * 60) << ":" << std::setw(2) << (timestamp.tv_sec / 60) % 60 << ":" << std::setw(2) << timestamp.tv_sec % 60 << "." << std::setw(9) << timestamp.tv_nsec << "]"; - msgStream_.fill(' '); + ossTimestamp.fill(' '); + logTimestamp_ = ossTimestamp.str(); + + std::ostringstream ossCategory; + ossCategory << category_.name(); + logCategory_ = ossCategory.str(); - msgStream_ << " " << log_severity_name(severity_); - msgStream_ << " " << category_.name(); - msgStream_ << " " << utils::basename(fileName) << ":" << line << " "; + std::ostringstream ossFileInfo; + ossFileInfo << utils::basename(fileName) << ":" << line; + logFileInfo_ = ossFileInfo.str(); } LogMessage::~LogMessage() @@ -514,11 +708,10 @@ LogMessage::~LogMessage() return; msgStream_ << std::endl; + msg_ = msgStream_.str(); - if (severity_ >= category_.severity()) { - std::string msg(msgStream_.str()); - Logger::instance()->write(msg); - } + if (severity_ >= category_.severity()) + Logger::instance()->write(this); if (severity_ == LogSeverity::LogFatal) std::abort(); @@ -534,6 +727,36 @@ LogMessage::~LogMessage() * \return A reference to the log message stream */ +/** + * \fn LogMessage::timestamp() + * \brief Getter for the timestamp of the log message + * \return The timestamp of the message, as a string + */ + +/** + * \fn LogMessage::severity() + * \brief Getter for the severity of the log message + * \return The severity of the message + */ + +/** + * \fn LogMessage::category() + * \brief Getter for the category of the log message + * \return The category of the message, as a string + */ + +/** + * \fn LogMessage::fileInfo() + * \brief Getter for the file info of the log message + * \return The file info of the message, as a string + */ + +/** + * \fn LogMessage::msg() + * \brief Getter for the message text of the log message + * \return The message text of the message, as a string + */ + /** * \class Loggable * \brief Base class to support log message extensions From patchwork Fri Jul 12 20:16:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 1676 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1D9F861607 for ; Fri, 12 Jul 2019 22:16:32 +0200 (CEST) Received: from neptunite.amanokami.net (softbank126209254147.bbtec.net [126.209.254.147]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 6396D2B2; Fri, 12 Jul 2019 22:16:30 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1562962591; bh=rvkyK7edjzN2JWOT54Mw0k+Pn94QaMBEyyw+XbTYZlc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hZXxtFUzPF3Mu2mplqub5xQGBpnbO3QTDugbMxSA4a0TjH3SxFCBn9EhGP57Gru+F LnXCGj/scBTusws6Ldl07Sy0Yp7pfJhTQ7thV2qeqPW0ENhFmDOh6hO75yoaPeB6vS uW3JQgRC2LaWMr6D3tiK7b7hKifiCy87FM2iFrDs= From: Paul Elder To: libcamera-devel@lists.libcamera.org Date: Sat, 13 Jul 2019 05:16:18 +0900 Message-Id: <20190712201620.30457-2-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190712201620.30457-1-paul.elder@ideasonboard.com> References: <20190712201620.30457-1-paul.elder@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 2/4] test: logging: add logSetStream test X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 12 Jul 2019 20:16:32 -0000 Test the new logSetStream loggin API call. Reorganize the logging API tests at the same time. logSetTarget is not tested since the nowhere and syslog logging destinations do not really need to be tested. Signed-off-by: Paul Elder --- test/log.cpp | 82 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 58 insertions(+), 24 deletions(-) diff --git a/test/log.cpp b/test/log.cpp index 89fb5ca..c1446bd 100644 --- a/test/log.cpp +++ b/test/log.cpp @@ -29,19 +29,8 @@ LOG_DEFINE_CATEGORY(LogAPITest) class LogAPITest : public Test { protected: - int run() override + void doLogging() { - int fd = open("/tmp", O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR); - if (fd < 0) { - cerr << "Failed to open tmp log file" << endl; - return TestFail; - } - - char path[32]; - snprintf(path, sizeof(path), "/proc/self/fd/%u", fd); - - logSetFile(path); - logSetLevel("LogAPITest", "DEBUG"); LOG(LogAPITest, Info) << "good 1"; @@ -55,19 +44,13 @@ protected: logSetLevel("LogAPITest", "WARN"); LOG(LogAPITest, Warning) << "good 5"; LOG(LogAPITest, Info) << "bad"; + } - char buf[1000]; - memset(buf, 0, sizeof(buf)); - lseek(fd, 0, SEEK_SET); - if (read(fd, buf, sizeof(buf)) < 0) { - cerr << "Failed to read tmp log file" << endl; - return TestFail; - } - close(fd); - - std::list goodList = { 1, 3, 5 }; - std::basic_istringstream iss((std::string(buf))); - std::string line; + int verifyOutput(string &str) + { + list goodList = { 1, 3, 5 }; + basic_istringstream iss(str); + string line; while (getline(iss, line)) { if (goodList.empty()) { cout << "Too many log lines" << endl; @@ -90,6 +73,57 @@ protected: return TestPass; } + + int testFile() + { + int fd = open("/tmp", O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR); + if (fd < 0) { + cerr << "Failed to open tmp log file" << endl; + return TestFail; + } + + char path[32]; + snprintf(path, sizeof(path), "/proc/self/fd/%u", fd); + + logSetFile(path); + + doLogging(); + + char buf[1000]; + memset(buf, 0, sizeof(buf)); + lseek(fd, 0, SEEK_SET); + if (read(fd, buf, sizeof(buf)) < 0) { + cerr << "Failed to read tmp log file" << endl; + return TestFail; + } + close(fd); + + string str(buf); + return verifyOutput(str); + } + + int testStream() + { + ostringstream log; + logSetStream(log); + + doLogging(); + + string str(log.str()); + return verifyOutput(str); + } + + int run() override + { + int ret1 = testFile(); + + int ret2 = testStream(); + + if (ret1 == TestPass && ret2 == TestPass) + return TestPass; + + return TestFail; + } }; TEST_REGISTER(LogAPITest) From patchwork Fri Jul 12 20:16:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 1677 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C357861607 for ; Fri, 12 Jul 2019 22:16:33 +0200 (CEST) Received: from neptunite.amanokami.net (softbank126209254147.bbtec.net [126.209.254.147]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 37A4652A; Fri, 12 Jul 2019 22:16:31 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1562962593; bh=gbfLOx3cNidhrGPTI4nj/hVvML5EWPVOtM1C3D6c2MM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=d18Sbdz4n1tPWBFFKJLsWoz+Z8/4aVQ/EP1QqldlZh9oK1JgiC9CPLeGY8GhEcDYR u5Y5rch1Q3DNEZnPFMk8NpehDgal4uqXfBZvkO5e70WNnJXVH0mo/YV9ugg49D8WTZ xnWfpfRElx830gqMUHe4Cv0YFoN29yKl3qGAJ5Tg= From: Paul Elder To: libcamera-devel@lists.libcamera.org Date: Sat, 13 Jul 2019 05:16:19 +0900 Message-Id: <20190712201620.30457-3-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190712201620.30457-1-paul.elder@ideasonboard.com> References: <20190712201620.30457-1-paul.elder@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 3/4] test: logging: add logging process test X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 12 Jul 2019 20:16:34 -0000 Add a test to test that logging works in child processes. Only logSetFile is tested. Signed-off-by: Paul Elder --- test/log_process.cpp | 147 +++++++++++++++++++++++++++++++++++++++++++ test/meson.build | 1 + 2 files changed, 148 insertions(+) create mode 100644 test/log_process.cpp diff --git a/test/log_process.cpp b/test/log_process.cpp new file mode 100644 index 0000000..feda687 --- /dev/null +++ b/test/log_process.cpp @@ -0,0 +1,147 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * process_test.cpp - Process test + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "log.h" +#include "process.h" +#include "test.h" +#include "utils.h" + +using namespace std; +using namespace libcamera; + +static string message("hello from the child"); + +LOG_DEFINE_CATEGORY(LogProcessTest) + +class LogProcessTestChild +{ +public: + int run(int status, int num) + { + usleep(50000); + + string logPath = "/tmp/libcamera.worker.test." + + to_string(num) + ".log"; + if (logSetFile(logPath.c_str()) < 0) + return TestSkip; + LOG(LogProcessTest, Warning) << message; + + return status; + } +}; + +class LogProcessTest : public Test +{ +public: + LogProcessTest() + { + } + +protected: + int run() + { + EventDispatcher *dispatcher = CameraManager::instance()->eventDispatcher(); + Timer timeout; + + srand(time(0)); + int num = rand(); + + int exitCode = 42; + vector args; + args.push_back(to_string(exitCode)); + args.push_back(to_string(num)); + int ret = proc_.start("/proc/self/exe", args); + if (ret) { + cerr << "failed to start process" << endl; + return TestFail; + } + proc_.finished.connect(this, &LogProcessTest::procFinished); + + timeout.start(200); + while (timeout.isRunning()) + dispatcher->processEvents(); + + if (exitStatus_ != Process::NormalExit) { + cerr << "process did not exit normally" << endl; + return TestFail; + } + + if (exitCode_ == TestSkip) + return TestSkip; + + if (exitCode != exitCode_) { + cerr << "exit code should be " << exitCode + << ", actual is " << exitCode_ << endl; + return TestFail; + } + + string logPath = "/tmp/libcamera.worker.test." + + to_string(num) + ".log"; + int fd = open(logPath.c_str(), O_RDONLY, S_IRUSR); + if (fd < 0) { + cerr << "failed to open tmp log file" << endl; + return TestFail; + } + + char buf[200]; + memset(buf, 0, sizeof(buf)); + lseek(fd, 0, SEEK_SET); + if (read(fd, buf, sizeof(buf)) < 0) { + cerr << "Failed to read tmp log file" << endl; + return TestFail; + } + close(fd); + + string str(buf); + if (str.find(message) == string::npos) + return TestFail; + + return TestPass; + } + +private: + void procFinished(Process *proc, enum Process::ExitStatus exitStatus, int exitCode) + { + exitStatus_ = exitStatus; + exitCode_ = exitCode; + } + + Process proc_; + enum Process::ExitStatus exitStatus_; + int exitCode_; +}; + +/* + * Can't use TEST_REGISTER() as single binary needs to act as both + * parent and child processes. + */ +int main(int argc, char **argv) +{ + if (argc == 3) { + int status = std::stoi(argv[1]); + int num = std::stoi(argv[2]); + LogProcessTestChild child; + return child.run(status, num); + } + + return LogProcessTest().execute(); +} diff --git a/test/meson.build b/test/meson.build index ad1a2f2..658f283 100644 --- a/test/meson.build +++ b/test/meson.build @@ -23,6 +23,7 @@ public_tests = [ internal_tests = [ ['camera-sensor', 'camera-sensor.cpp'], ['log', 'log.cpp'], + ['log_process', 'log_process.cpp'], ['message', 'message.cpp'], ['signal-threads', 'signal-threads.cpp'], ['threads', 'threads.cpp'], From patchwork Fri Jul 12 20:16:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 1678 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9CD936161E for ; Fri, 12 Jul 2019 22:16:35 +0200 (CEST) Received: from neptunite.amanokami.net (softbank126209254147.bbtec.net [126.209.254.147]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 2B6CF2B2; Fri, 12 Jul 2019 22:16:33 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1562962595; bh=OQIEQRCcPGx9pAHX9Q/6uDOX/HZxrGeWgWmcxPpp6M8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=JWZmjgF6WN//m0Mi86+/rwwFFV2Y6aZnhJakdIrzUnop0kkC49ADCKeRSqffW/hZW h9jwF0g/rlGnZeO9XJYCZAroPF7MZ2W+JEXApnxf6SjA7CTKbkn34i3FolZfjvGsch TWgoHtVH7NfIoUbSpALLd0/SUy83kA/cHlF+qUcc= From: Paul Elder To: libcamera-devel@lists.libcamera.org Date: Sat, 13 Jul 2019 05:16:20 +0900 Message-Id: <20190712201620.30457-4-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190712201620.30457-1-paul.elder@ideasonboard.com> References: <20190712201620.30457-1-paul.elder@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 4/4] test: logging: move logging tests to a subdirectory X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 12 Jul 2019 20:16:35 -0000 Since there are two logging tests now, move them to their own subdirectory. Update meson as necessary. Signed-off-by: Paul Elder Reviewed-by: Laurent Pinchart --- test/{log.cpp => log/log_api.cpp} | 0 test/{ => log}/log_process.cpp | 0 test/log/meson.build | 13 +++++++++++++ test/meson.build | 3 +-- 4 files changed, 14 insertions(+), 2 deletions(-) rename test/{log.cpp => log/log_api.cpp} (100%) rename test/{ => log}/log_process.cpp (100%) create mode 100644 test/log/meson.build diff --git a/test/log.cpp b/test/log/log_api.cpp similarity index 100% rename from test/log.cpp rename to test/log/log_api.cpp diff --git a/test/log_process.cpp b/test/log/log_process.cpp similarity index 100% rename from test/log_process.cpp rename to test/log/log_process.cpp diff --git a/test/log/meson.build b/test/log/meson.build new file mode 100644 index 0000000..95f6c1a --- /dev/null +++ b/test/log/meson.build @@ -0,0 +1,13 @@ +log_test = [ + ['log_api', 'log_api.cpp'], + ['log_process', 'log_process.cpp'], +] + +foreach t : log_test + exe = executable(t[0], t[1], + dependencies : libcamera_dep, + link_with : test_libraries, + include_directories : test_includes_internal) + + test(t[0], exe, suite : 'log') +endforeach diff --git a/test/meson.build b/test/meson.build index 658f283..b2f809e 100644 --- a/test/meson.build +++ b/test/meson.build @@ -4,6 +4,7 @@ subdir('camera') subdir('controls') subdir('ipa') subdir('ipc') +subdir('log') subdir('media_device') subdir('pipeline') subdir('process') @@ -22,8 +23,6 @@ public_tests = [ internal_tests = [ ['camera-sensor', 'camera-sensor.cpp'], - ['log', 'log.cpp'], - ['log_process', 'log_process.cpp'], ['message', 'message.cpp'], ['signal-threads', 'signal-threads.cpp'], ['threads', 'threads.cpp'],