From 70c3e7276322510348e0d8ca2994feac4bd142c2 Mon Sep 17 00:00:00 2001 From: George Arama <50641385+gearama@users.noreply.github.com> Date: Tue, 22 Jun 2021 14:51:41 -0700 Subject: [PATCH] Add Unit Tests for EnvironmentLogLevelListener (#2454) * first UT * formatting * unused error * putenv * some refactoring * formatting * casting * again * Update sdk/core/azure-core/test/ut/environmentLogLevelListener_test.cpp Co-authored-by: Rick Winter * some refactoring * more tests * format * no env test * put back missing empty line * Update sdk/core/azure-core/test/ut/environmentLogLevelListener_test.cpp Co-authored-by: Rick Winter * PR comments * fix signed/unsigned mismatch that causes ci build to fail Co-authored-by: Rick Winter --- .gitignore | 1 + .../src/environment_log_level_listener.cpp | 13 +- .../environment_log_level_listener.hpp | 2 + sdk/core/azure-core/test/ut/CMakeLists.txt | 1 + .../ut/environmentLogLevelListener_test.cpp | 202 ++++++++++++++++++ 5 files changed, 216 insertions(+), 3 deletions(-) create mode 100644 sdk/core/azure-core/test/ut/environmentLogLevelListener_test.cpp diff --git a/.gitignore b/.gitignore index 8b48317a2..4da604452 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,7 @@ bld/ [Bb]in/ [Oo]bj/ [Ll]og/ +[Oo]ut/ # Visual Studio 2015/2017 cache/options directory .vs/ diff --git a/sdk/core/azure-core/src/environment_log_level_listener.cpp b/sdk/core/azure-core/src/environment_log_level_listener.cpp index 0afd71d4d..a9ed342f0 100644 --- a/sdk/core/azure-core/src/environment_log_level_listener.cpp +++ b/sdk/core/azure-core/src/environment_log_level_listener.cpp @@ -27,16 +27,16 @@ using namespace Azure::Core::Diagnostics; using namespace Azure::Core::Diagnostics::_detail; +using Azure::Core::Diagnostics::_detail::EnvironmentLogLevelListener; namespace { Logger::Level const* GetEnvironmentLogLevel() { static Logger::Level* envLogLevelPtr = nullptr; - static bool initialized = false; - if (!initialized) + if (!EnvironmentLogLevelListener::IsInitialized()) { - initialized = true; + EnvironmentLogLevelListener::SetInitialized(true); #if defined(_MSC_VER) #pragma warning(push) @@ -144,4 +144,11 @@ EnvironmentLogLevelListener::GetLogListener() return consoleLogger; } +namespace { +static bool g_initialized; +} // namespace + +bool EnvironmentLogLevelListener::IsInitialized() { return g_initialized; } + +void EnvironmentLogLevelListener::SetInitialized(bool value) { g_initialized = value; } #endif diff --git a/sdk/core/azure-core/src/private/environment_log_level_listener.hpp b/sdk/core/azure-core/src/private/environment_log_level_listener.hpp index 1e550c291..9fdf4b000 100644 --- a/sdk/core/azure-core/src/private/environment_log_level_listener.hpp +++ b/sdk/core/azure-core/src/private/environment_log_level_listener.hpp @@ -26,6 +26,8 @@ namespace Azure { namespace Core { namespace Diagnostics { namespace _detail { public: static Logger::Level GetLogLevel(Logger::Level defaultValue); static std::function GetLogListener(); + static bool IsInitialized(); + static void SetInitialized(bool value); }; #if (defined(WINAPI_PARTITION_DESKTOP) && !WINAPI_PARTITION_DESKTOP) // See azure/core/platform.hpp diff --git a/sdk/core/azure-core/test/ut/CMakeLists.txt b/sdk/core/azure-core/test/ut/CMakeLists.txt index 0cf92a83a..93658d86d 100644 --- a/sdk/core/azure-core/test/ut/CMakeLists.txt +++ b/sdk/core/azure-core/test/ut/CMakeLists.txt @@ -44,6 +44,7 @@ add_executable ( ${CURL_OPTIONS_TESTS} ${CURL_SESSION_TESTS} datetime_test.cpp + environmentLogLevelListener_test.cpp etag_test.cpp http_test.cpp http_test.hpp diff --git a/sdk/core/azure-core/test/ut/environmentLogLevelListener_test.cpp b/sdk/core/azure-core/test/ut/environmentLogLevelListener_test.cpp new file mode 100644 index 000000000..374648216 --- /dev/null +++ b/sdk/core/azure-core/test/ut/environmentLogLevelListener_test.cpp @@ -0,0 +1,202 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#include +#include + +using Azure::Core::Diagnostics::Logger; +using Azure::Core::Diagnostics::_detail::EnvironmentLogLevelListener; + +namespace { + +std::string environmentVariable = "AZURE_LOG_LEVEL"; + +void SetLogLevel(std::string const& value) +{ +#if defined(_MSC_VER) + static_cast(_putenv((environmentVariable + "=" + value).c_str())); +#else + static_cast(setenv(environmentVariable.c_str(), value.c_str(), 1)); +#endif +} + +} // namespace +class EnvironmentLogLevelListenerTest : public testing::Test { +protected: + void SetUp() override + { +#if defined(_MSC_VER) +#pragma warning(push) +// warning C4996: 'getenv': This function or variable may be unsafe. Consider using _dupenv_s +// instead. +#pragma warning(disable : 4996) +#endif + auto const value = std::getenv(environmentVariable.c_str()); + m_previousValue = value == nullptr ? "" : value; +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + } + + void TearDown() override { SetLogLevel(m_previousValue); }; + +private: + std::string m_previousValue; +}; + +TEST_F(EnvironmentLogLevelListenerTest, LogLevelDefault) +{ + EnvironmentLogLevelListener::SetInitialized(false); + SetLogLevel("unknown"); + auto level = EnvironmentLogLevelListener::GetLogLevel(Logger::Level::Verbose); + EXPECT_EQ(level, Logger::Level::Verbose); + + EnvironmentLogLevelListener::SetInitialized(false); + SetLogLevel(""); + level = EnvironmentLogLevelListener::GetLogLevel(Logger::Level::Verbose); + EXPECT_EQ(level, Logger::Level::Verbose); +} + +TEST_F(EnvironmentLogLevelListenerTest, LogLevelError) +{ + EnvironmentLogLevelListener::SetInitialized(false); + SetLogLevel("error"); + auto level = EnvironmentLogLevelListener::GetLogLevel(Logger::Level::Verbose); + EXPECT_EQ(level, Logger::Level::Error); + + EnvironmentLogLevelListener::SetInitialized(false); + SetLogLevel("err"); + level = EnvironmentLogLevelListener::GetLogLevel(Logger::Level::Verbose); + EXPECT_EQ(level, Logger::Level::Error); + + SetLogLevel("4"); + level = EnvironmentLogLevelListener::GetLogLevel(Logger::Level::Verbose); + EXPECT_EQ(level, Logger::Level::Error); +} + +TEST_F(EnvironmentLogLevelListenerTest, LogLevelWarning) +{ + EnvironmentLogLevelListener::SetInitialized(false); + SetLogLevel("warning"); + auto level = EnvironmentLogLevelListener::GetLogLevel(Logger::Level::Verbose); + EXPECT_EQ(level, Logger::Level::Warning); + + EnvironmentLogLevelListener::SetInitialized(false); + SetLogLevel("warn"); + level = EnvironmentLogLevelListener::GetLogLevel(Logger::Level::Verbose); + EXPECT_EQ(level, Logger::Level::Warning); + + EnvironmentLogLevelListener::SetInitialized(false); + SetLogLevel("3"); + level = EnvironmentLogLevelListener::GetLogLevel(Logger::Level::Verbose); + EXPECT_EQ(level, Logger::Level::Warning); +} + +TEST_F(EnvironmentLogLevelListenerTest, LogLevelInformational) +{ + EnvironmentLogLevelListener::SetInitialized(false); + SetLogLevel("informational"); + auto level = EnvironmentLogLevelListener::GetLogLevel(Logger::Level::Verbose); + EXPECT_EQ(level, Logger::Level::Informational); + + EnvironmentLogLevelListener::SetInitialized(false); + SetLogLevel("info"); + level = EnvironmentLogLevelListener::GetLogLevel(Logger::Level::Verbose); + EXPECT_EQ(level, Logger::Level::Informational); + + EnvironmentLogLevelListener::SetInitialized(false); + SetLogLevel("information"); + level = EnvironmentLogLevelListener::GetLogLevel(Logger::Level::Verbose); + EXPECT_EQ(level, Logger::Level::Informational); + + EnvironmentLogLevelListener::SetInitialized(false); + SetLogLevel("2"); + level = EnvironmentLogLevelListener::GetLogLevel(Logger::Level::Verbose); + EXPECT_EQ(level, Logger::Level::Informational); +} + +TEST_F(EnvironmentLogLevelListenerTest, LogLevelVerbose) +{ + EnvironmentLogLevelListener::SetInitialized(false); + SetLogLevel("verbose"); + auto level = EnvironmentLogLevelListener::GetLogLevel(Logger::Level::Verbose); + EXPECT_EQ(level, Logger::Level::Verbose); + + EnvironmentLogLevelListener::SetInitialized(false); + SetLogLevel("debug"); + level = EnvironmentLogLevelListener::GetLogLevel(Logger::Level::Verbose); + EXPECT_EQ(level, Logger::Level::Verbose); + + EnvironmentLogLevelListener::SetInitialized(false); + SetLogLevel("1"); + level = EnvironmentLogLevelListener::GetLogLevel(Logger::Level::Verbose); + EXPECT_EQ(level, Logger::Level::Verbose); +} + +TEST_F(EnvironmentLogLevelListenerTest, GetLogListenerVerbose) +{ + EnvironmentLogLevelListener::SetInitialized(false); + SetLogLevel("verbose"); + + std::stringstream buffer; + std::streambuf* old = std::cerr.rdbuf(buffer.rdbuf()); + + std::string text = buffer.str(); // text will now contain "Bla\n" + auto listener = EnvironmentLogLevelListener::GetLogListener(); + + listener(Logger::Level::Verbose, "message"); + EXPECT_NE(listener, nullptr); + EXPECT_NE(buffer.str().find("DEBUG : message"), std::string::npos); + std::cerr.rdbuf(old); +} + +TEST_F(EnvironmentLogLevelListenerTest, GetLogListenerError) +{ + EnvironmentLogLevelListener::SetInitialized(false); + SetLogLevel("verbose"); + + std::stringstream buffer; + std::streambuf* old = std::cerr.rdbuf(buffer.rdbuf()); + + std::string text = buffer.str(); // text will now contain "Bla\n" + auto listener = EnvironmentLogLevelListener::GetLogListener(); + + listener(Logger::Level::Error, "message"); + EXPECT_NE(listener, nullptr); + EXPECT_NE(buffer.str().find("ERROR : message"), std::string::npos); + std::cerr.rdbuf(old); +} + +TEST_F(EnvironmentLogLevelListenerTest, GetLogListenerWarning) +{ + EnvironmentLogLevelListener::SetInitialized(false); + SetLogLevel("verbose"); + + std::stringstream buffer; + std::streambuf* old = std::cerr.rdbuf(buffer.rdbuf()); + + std::string text = buffer.str(); // text will now contain "Bla\n" + auto listener = EnvironmentLogLevelListener::GetLogListener(); + + listener(Logger::Level::Warning, "message"); + EXPECT_NE(listener, nullptr); + EXPECT_NE(buffer.str().find("WARN : message"), std::string::npos); + std::cerr.rdbuf(old); +} + +TEST_F(EnvironmentLogLevelListenerTest, GetLogListenerInformational) +{ + EnvironmentLogLevelListener::SetInitialized(false); + SetLogLevel("verbose"); + + std::stringstream buffer; + std::streambuf* old = std::cerr.rdbuf(buffer.rdbuf()); + + std::string text = buffer.str(); // text will now contain "Bla\n" + auto listener = EnvironmentLogLevelListener::GetLogListener(); + + listener(Logger::Level::Informational, "message"); + EXPECT_NE(listener, nullptr); + EXPECT_NE(buffer.str().find("INFO : message"), std::string::npos); + std::cerr.rdbuf(old); +}