Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Improve Sunshine compatibility #67

Merged
merged 2 commits into from
Jul 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/common/file_settings_persistence.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ namespace display_device {
return false;
}

std::ranges::copy(data, std::ostreambuf_iterator<char> { stream });
std::copy(std::begin(data), std::end(data), std::ostreambuf_iterator<char> { stream });
return true;
}
catch (const std::exception &error) {
Expand Down
3 changes: 2 additions & 1 deletion src/common/include/display_device/logging.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ namespace display_device {
debug,
info,
warning,
error
error,
fatal
};

/**
Expand Down
72 changes: 34 additions & 38 deletions src/common/logging.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
#if !defined(_MSC_VER) && !defined(_POSIX_THREAD_SAFE_FUNCTIONS)
#define _POSIX_THREAD_SAFE_FUNCTIONS // For localtime_r
#endif

// class header include
#include "display_device/logging.h"

Expand All @@ -8,14 +12,30 @@
#include <mutex>

namespace display_device {
namespace {
std::tm
threadSafeLocaltime(const std::time_t &time) {
#if defined(_MSC_VER) // MSVCRT (2005+): std::localtime is threadsafe
const auto tm_ptr { std::localtime(&time) };
#else // POSIX
std::tm buffer;
const auto tm_ptr { localtime_r(&time, &buffer) };
#endif // _MSC_VER
if (tm_ptr) {
return *tm_ptr;
}
return {};

Check warning on line 27 in src/common/logging.cpp

View check run for this annotation

Codecov / codecov/patch

src/common/logging.cpp#L27

Added line #L27 was not covered by tests
}
} // namespace

Logger &
Logger::get() {
static Logger instance; // GCOVR_EXCL_BR_LINE for some reason...
return instance;
}

void
Logger::setLogLevel(LogLevel log_level) {
Logger::setLogLevel(const LogLevel log_level) {
m_enabled_log_level = log_level;
}

Expand Down Expand Up @@ -44,45 +64,18 @@

std::stringstream stream;
{
// Time (limited by GCC 11, so it's not pretty and no timezones are supported...)
// Time (limited by GCC 10, so it's not pretty...)
{
static const auto get_time { []() {
static const auto to_year_month_day { [](const auto &now) {
return std::chrono::year_month_day { std::chrono::time_point_cast<std::chrono::days>(now) };
} };
static const auto to_hour_minute_second { [](const auto &now) {
const auto start_of_day { std::chrono::floor<std::chrono::days>(now) };
const auto time_since_start_of_day { std::chrono::round<std::chrono::seconds>(now - start_of_day) };
return std::chrono::hh_mm_ss { time_since_start_of_day };
} };
static const auto to_milliseconds { [](const auto &now) {
const auto now_ms { std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) };
const auto time_s { std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch()) };
return now_ms - time_s;
} };

const auto now { std::chrono::system_clock::now() };
return std::make_tuple(to_year_month_day(now), to_hour_minute_second(now), to_milliseconds(now));
} };

const auto [year_month_day, hh_mm_ss, ms] { get_time() };
const auto old_flags { stream.flags() }; // Save formatting flags so that they can be restored...
const auto now { std::chrono::system_clock::now() };
const auto now_ms { std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) };
const auto now_s { std::chrono::duration_cast<std::chrono::seconds>(now_ms) };

const std::time_t time { std::chrono::system_clock::to_time_t(now) };
const auto localtime { threadSafeLocaltime(time) };
const auto now_decimal_part { now_ms - now_s };

stream << "[";
stream << std::setfill('0') << std::setw(2) << static_cast<int>(year_month_day.year());
stream << "-";
stream << std::setfill('0') << std::setw(2) << static_cast<unsigned>(year_month_day.month());
stream << "-";
stream << std::setfill('0') << std::setw(2) << static_cast<unsigned>(year_month_day.day());
stream << " ";
stream << std::setfill('0') << std::setw(2) << hh_mm_ss.hours().count();
stream << ":";
stream << std::setfill('0') << std::setw(2) << hh_mm_ss.minutes().count();
stream << ":";
stream << std::setfill('0') << std::setw(2) << hh_mm_ss.seconds().count();
stream << ".";
stream << std::setfill('0') << std::setw(3) << ms.count();
stream << "] ";
const auto old_flags { stream.flags() }; // Save formatting flags so that they can be restored...
stream << std::put_time(&localtime, "[%Y-%m-%d %H:%M:%S.") << std::setfill('0') << std::setw(3) << now_decimal_part.count() << "] ";
stream.flags(old_flags);
}

Expand All @@ -103,6 +96,9 @@
case LogLevel::error:
stream << "ERROR: ";
break;
case LogLevel::fatal:
stream << "FATAL: ";
break;
}

// Value
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/general/test_file_settings_persistence.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ TEST_F_S(Store, FileOverwritten) {

{
std::ofstream file { filepath, std::ios_base::binary };
std::ranges::copy(data1, std::ostreambuf_iterator<char> { file });
std::copy(std::begin(data1), std::end(data1), std::ostreambuf_iterator<char> { file });
}

EXPECT_TRUE(std::filesystem::exists(filepath));
Expand Down Expand Up @@ -92,7 +92,7 @@ TEST_F_S(Load, FileRead) {

{
std::ofstream file { filepath, std::ios_base::binary };
std::ranges::copy(data, std::ostreambuf_iterator<char> { file });
std::copy(std::begin(data), std::end(data), std::ostreambuf_iterator<char> { file });
}

EXPECT_EQ(getImpl(filepath).load(), data);
Expand Down
24 changes: 24 additions & 0 deletions tests/unit/general/test_logging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ TEST_S(LogLevelVerbose) {
EXPECT_EQ(logger.isLogLevelEnabled(level::info), true);
EXPECT_EQ(logger.isLogLevelEnabled(level::warning), true);
EXPECT_EQ(logger.isLogLevelEnabled(level::error), true);
EXPECT_EQ(logger.isLogLevelEnabled(level::fatal), true);
}

TEST_S(LogLevelDebug) {
Expand All @@ -31,6 +32,7 @@ TEST_S(LogLevelDebug) {
EXPECT_EQ(logger.isLogLevelEnabled(level::info), true);
EXPECT_EQ(logger.isLogLevelEnabled(level::warning), true);
EXPECT_EQ(logger.isLogLevelEnabled(level::error), true);
EXPECT_EQ(logger.isLogLevelEnabled(level::fatal), true);
}

TEST_S(LogLevelInfo) {
Expand All @@ -44,6 +46,7 @@ TEST_S(LogLevelInfo) {
EXPECT_EQ(logger.isLogLevelEnabled(level::info), true);
EXPECT_EQ(logger.isLogLevelEnabled(level::warning), true);
EXPECT_EQ(logger.isLogLevelEnabled(level::error), true);
EXPECT_EQ(logger.isLogLevelEnabled(level::fatal), true);
}

TEST_S(LogLevelWarning) {
Expand All @@ -57,6 +60,7 @@ TEST_S(LogLevelWarning) {
EXPECT_EQ(logger.isLogLevelEnabled(level::info), false);
EXPECT_EQ(logger.isLogLevelEnabled(level::warning), true);
EXPECT_EQ(logger.isLogLevelEnabled(level::error), true);
EXPECT_EQ(logger.isLogLevelEnabled(level::fatal), true);
}

TEST_S(LogLevelError) {
Expand All @@ -70,6 +74,21 @@ TEST_S(LogLevelError) {
EXPECT_EQ(logger.isLogLevelEnabled(level::info), false);
EXPECT_EQ(logger.isLogLevelEnabled(level::warning), false);
EXPECT_EQ(logger.isLogLevelEnabled(level::error), true);
EXPECT_EQ(logger.isLogLevelEnabled(level::fatal), true);
}

TEST_S(LogLevelFatal) {
using level = display_device::Logger::LogLevel;
auto &logger { display_device::Logger::get() };

logger.setLogLevel(level::fatal);

EXPECT_EQ(logger.isLogLevelEnabled(level::verbose), false);
EXPECT_EQ(logger.isLogLevelEnabled(level::debug), false);
EXPECT_EQ(logger.isLogLevelEnabled(level::info), false);
EXPECT_EQ(logger.isLogLevelEnabled(level::warning), false);
EXPECT_EQ(logger.isLogLevelEnabled(level::error), false);
EXPECT_EQ(logger.isLogLevelEnabled(level::fatal), true);
}

TEST_S(DefaultLogger) {
Expand All @@ -89,6 +108,7 @@ TEST_S(DefaultLogger) {
EXPECT_TRUE(testRegex(write_and_get_cout(level::info, "Hello World!"), R"(\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}\] INFO: Hello World!\n)"));
EXPECT_TRUE(testRegex(write_and_get_cout(level::warning, "Hello World!"), R"(\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}\] WARNING: Hello World!\n)"));
EXPECT_TRUE(testRegex(write_and_get_cout(level::error, "Hello World!"), R"(\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}\] ERROR: Hello World!\n)"));
EXPECT_TRUE(testRegex(write_and_get_cout(level::fatal, "Hello World!"), R"(\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}\] FATAL: Hello World!\n)"));
// clang-format on
}

Expand Down Expand Up @@ -122,6 +142,10 @@ TEST_S(CustomCallback) {
logger.write(level::error, "Hello World!");
EXPECT_EQ(output, "4 Hello World!");
EXPECT_TRUE(m_cout_buffer.str().empty());

logger.write(level::fatal, "Hello World!");
EXPECT_EQ(output, "5 Hello World!");
EXPECT_TRUE(m_cout_buffer.str().empty());
}

TEST_S(WriteMethodRespectsLogLevel, DefaultLogger) {
Expand Down
Loading