diff --git a/evergreen/config.yml b/evergreen/config.yml index 2b578b1703f..22f86521ef5 100644 --- a/evergreen/config.yml +++ b/evergreen/config.yml @@ -136,7 +136,6 @@ functions: set_cmake_var realm_vars CMAKE_TOOLCHAIN_FILE PATH "${cmake_toolchain_file}" fi - set_cmake_var realm_vars REALM_TEST_LOGGING BOOL On set_cmake_var realm_vars REALM_TEST_LOGGING_LEVEL STRING "${test_logging_level|debug}" if [[ -n "${test_timeout_extra|}" ]]; then diff --git a/src/realm/util/logger.cpp b/src/realm/util/logger.cpp index 02edb494371..c6862bf55ae 100644 --- a/src/realm/util/logger.cpp +++ b/src/realm/util/logger.cpp @@ -20,6 +20,7 @@ #include #include +#include namespace realm::util { @@ -110,6 +111,20 @@ const std::string_view Logger::level_to_string(Level level) noexcept return ""; } +bool Logger::get_env_log_level_if_set(Level& level) noexcept +{ + const char* str = getenv("UNITTEST_LOG_LEVEL"); + if (!str || strlen(str) == 0) + return true; + + std::istringstream in(str); + in.imbue(std::locale::classic()); + in.flags(in.flags() & ~std::ios_base::skipws); // Do not accept white space + in >> level; + + return in && in.get() == std::char_traits::eof(); +} + void StderrLogger::do_log(Level level, const std::string& message) { static Mutex mutex; diff --git a/src/realm/util/logger.hpp b/src/realm/util/logger.hpp index eb1d10d54e2..0dc9bed3b2b 100644 --- a/src/realm/util/logger.hpp +++ b/src/realm/util/logger.hpp @@ -107,6 +107,7 @@ class Logger { static void set_default_level_threshold(Level level) noexcept; static Level get_default_level_threshold() noexcept; static const std::string_view level_to_string(Level level) noexcept; + static bool get_env_log_level_if_set(Level& level) noexcept; protected: // Used by subclasses that link to a base logger diff --git a/test/combined_tests.cpp b/test/combined_tests.cpp index 9673e9930b9..52d056dc4fc 100644 --- a/test/combined_tests.cpp +++ b/test/combined_tests.cpp @@ -30,9 +30,10 @@ int main(int argc, const char* argv[]) return 1; int status = test_all(); if (status) { - std::cerr << "core and sync tests failed: " << status << std::endl; + std::cerr << "(!) Core/Sync tests failed: " << status << std::endl; return status; } - std::cout << "core and sync tests passed\n"; + std::cout << "--------------------------\n" + << "(+) Core/Sync tests passed\n\n"; return run_object_store_tests(argc, argv); } diff --git a/test/object-store/CMakeLists.txt b/test/object-store/CMakeLists.txt index aac511f7428..a4a12dd6457 100644 --- a/test/object-store/CMakeLists.txt +++ b/test/object-store/CMakeLists.txt @@ -152,20 +152,12 @@ if(REALM_ENABLE_SYNC) endif() endif() -if(REALM_TEST_LOGGING) - target_compile_definitions(ObjectStoreTestLib PRIVATE - TEST_ENABLE_LOGGING=1 - ) - - if(REALM_TEST_LOGGING_LEVEL) - message(STATUS "Test logging level: ${REALM_TEST_LOGGING_LEVEL}") - target_compile_definitions(ObjectStoreTestLib PRIVATE - TEST_LOGGING_LEVEL=${REALM_TEST_LOGGING_LEVEL} - ) - else() - message(STATUS "Test logging enabled") - endif() +set(REALM_TEST_LOGGING_LEVEL "off" CACHE STRING "Object-store tests logging level") +if ("${REALM_TEST_LOGGING_LEVEL}" STREQUAL "") + set(REALM_TEST_LOGGING_LEVEL "off" CACHE STRING "Object-store tests logging level" FORCE) endif() +message(STATUS "Test logging level: ${REALM_TEST_LOGGING_LEVEL}") +target_compile_definitions(ObjectStoreTestLib PRIVATE TEST_LOGGING_LEVEL=${REALM_TEST_LOGGING_LEVEL}) # Optional extra time to add to test timeout values if(REALM_TEST_TIMEOUT_EXTRA) diff --git a/test/object-store/sync/app.cpp b/test/object-store/sync/app.cpp index 29d8b64fb1d..e7e3c38d274 100644 --- a/test/object-store/sync/app.cpp +++ b/test/object-store/sync/app.cpp @@ -273,7 +273,7 @@ TEST_CASE("app: verify app error codes", "[sync][app][local]") { return false; } } - catch (nlohmann::json::exception ex) { + catch (const nlohmann::json::exception&) { // It's also a failure if parsing the json body throws an exception return false; } @@ -3929,7 +3929,6 @@ TEST_CASE("app: base_url", "[sync][app][base_url]") { std::string base_file_path = util::make_temp_dir() + random_string(10); auto redir_transport = std::make_shared(); AutoVerifiedEmailCredentials creds; - util::Logger::set_default_level_threshold(realm::util::Logger::Level::TEST_LOGGING_LEVEL); auto logger = util::Logger::get_default_logger(); App::Config app_config = {"fake-app-id"}; @@ -4148,7 +4147,7 @@ TEST_CASE("app: base_url", "[sync][app][base_url]") { SECTION("Verify new sync session updates location") { bool use_ssl = GENERATE(true, false); std::string expected_host = "redirect.someurl.fake"; - int expected_port = 8081; + sync::port_type expected_port = 8081; std::string init_url = util::format("http%1://alternate.someurl.fake", use_ssl ? "s" : ""); std::string init_wsurl = util::format("ws%1://alternate.someurl.fake", use_ssl ? "s" : ""); std::string redir_url = util::format("http%1://%2:%3", use_ssl ? "s" : "", expected_host, expected_port); diff --git a/test/object-store/util/test_file.cpp b/test/object-store/util/test_file.cpp index 54544c0ee52..f2a50b97fb3 100644 --- a/test/object-store/util/test_file.cpp +++ b/test/object-store/util/test_file.cpp @@ -70,7 +70,7 @@ TestFile::TestFile() disable_sync_to_disk(); m_temp_dir = util::make_temp_dir(); path = (fs::path(m_temp_dir) / "realm.XXXXXX").string(); - util::Logger::set_default_level_threshold(realm::util::Logger::Level::TEST_LOGGING_LEVEL); + util::Logger::set_default_level_threshold(TestSyncManager::default_log_level()); if (const char* crypt_key = test_util::crypt_key()) { encryption_key = std::vector(crypt_key, crypt_key + 64); } @@ -340,7 +340,7 @@ TestAppSession::TestAppSession(AppSession session, if (!m_transport) m_transport = instance_of; auto app_config = get_config(m_transport, *m_app_session); - util::Logger::set_default_level_threshold(realm::util::Logger::Level::TEST_LOGGING_LEVEL); + util::Logger::set_default_level_threshold(TestSyncManager::default_log_level()); set_app_config_defaults(app_config, m_transport); util::try_make_dir(m_base_file_path); @@ -423,6 +423,21 @@ std::vector TestAppSession::get_documents(SyncUser& user, co // MARK: - TestSyncManager +TestSyncManager::LoggerLevel TestSyncManager::default_log_level() +{ +#ifndef TEST_LOGGING_LEVEL +#define TEST_LOGGING_LEVEL off +#endif + + static LoggerLevel log_level = []() { + LoggerLevel level = LoggerLevel::TEST_LOGGING_LEVEL; + realm::util::Logger::get_env_log_level_if_set(level); + return level; + }(); + + return log_level; +} + TestSyncManager::TestSyncManager(const Config& config, const SyncServer::Config& sync_server_config) : transport(config.transport ? config.transport : std::make_shared(network_callback)) , m_sync_server(sync_server_config) diff --git a/test/object-store/util/test_file.hpp b/test/object-store/util/test_file.hpp index 552550bdba3..54bfb379b1f 100644 --- a/test/object-store/util/test_file.hpp +++ b/test/object-store/util/test_file.hpp @@ -100,18 +100,6 @@ struct InMemoryTestFile : realm::Realm::Config { void advance_and_notify(realm::Realm& realm); void on_change_but_no_notify(realm::Realm& realm); -#ifndef TEST_ENABLE_LOGGING -#define TEST_ENABLE_LOGGING 0 // change to 1 to enable trace-level logging -#endif - -#ifndef TEST_LOGGING_LEVEL -#if TEST_ENABLE_LOGGING -#define TEST_LOGGING_LEVEL all -#else -#define TEST_LOGGING_LEVEL off -#endif // TEST_ENABLE_LOGGING -#endif // TEST_LOGGING_LEVEL - #if REALM_ENABLE_SYNC using StartImmediately = realm::util::TaggedBool; @@ -221,13 +209,16 @@ class TestAppSession { class TestSyncManager { public: + using LoggerLevel = realm::util::Logger::Level; + static LoggerLevel default_log_level(); + struct Config { Config() {} realm::app::App::Config app_config; std::string base_path; realm::SyncManager::MetadataMode metadata_mode = realm::SyncManager::MetadataMode::NoMetadata; bool should_teardown_test_directory = true; - realm::util::Logger::Level log_level = realm::util::Logger::Level::TEST_LOGGING_LEVEL; + LoggerLevel log_level = TestSyncManager::default_log_level(); bool override_sync_route = true; std::shared_ptr transport; bool start_sync_client = true; diff --git a/test/test_all.cpp b/test/test_all.cpp index 6363776a887..71339c0667f 100644 --- a/test/test_all.cpp +++ b/test/test_all.cpp @@ -443,7 +443,8 @@ bool run_tests(const std::shared_ptr& logger = nullptr) reporters.push_back(std::make_unique(report_progress)); } if (const char* str = getenv("UNITTEST_XML"); str && strlen(str) != 0) { - std::cout << "Configuring jUnit reporter to store test results in " << str << std::endl; + if (!running_spawned_process) + std::cout << "Configuring jUnit reporter to store test results in " << str << std::endl; junit_file.open(str, util::File::mode_Write); const char* test_suite_name = getenv("UNITTEST_SUITE_NAME"); if (!test_suite_name || !strlen(test_suite_name)) @@ -451,11 +452,13 @@ bool run_tests(const std::shared_ptr& logger = nullptr) reporters.push_back(create_junit_reporter(junit_out, test_suite_name)); } else if (const char* str = getenv("UNITTEST_EVERGREEN_TEST_RESULTS"); str && strlen(str) != 0) { - std::cout << "Configuring evergreen reporter to store test results in " << str << std::endl; + if (!running_spawned_process) + std::cout << "Configuring evergreen reporter to store test results in " << str << std::endl; reporters.push_back(create_evergreen_reporter(str)); } auto reporter = create_combined_reporter(reporters); - config.reporter = reporter.get(); + if (!running_spawned_process) + config.reporter = reporter.get(); // Set up filter const char* filter_str = getenv("UNITTEST_FILTER"); @@ -468,18 +471,8 @@ bool run_tests(const std::shared_ptr& logger = nullptr) config.filter = filter.get(); // Set intra test log level threshold - { - const char* str = getenv("UNITTEST_LOG_LEVEL"); - if (str && strlen(str) != 0) { - std::istringstream in(str); - in.imbue(std::locale::classic()); - in.flags(in.flags() & ~std::ios_base::skipws); // Do not accept white space - in >> config.intra_test_log_level; - bool bad = !in || in.get() != std::char_traits::eof(); - if (bad) - throw std::runtime_error("Bad intra test log level"); - } - } + if (!util::Logger::get_env_log_level_if_set(config.intra_test_log_level)) + throw std::runtime_error("Bad intra test log level"); // Set up per-thread file logging { @@ -510,10 +503,11 @@ bool run_tests(const std::shared_ptr& logger = nullptr) list.sort(PatternBasedFileOrder(file_order)); bool success = list.run(config); - if (test_only) + if (test_only && !running_spawned_process) std::cout << "\n*** BE AWARE THAT MOST TESTS WERE EXCLUDED DUE TO USING 'ONLY' MACRO ***\n"; - std::cout << "\n"; + if (!running_spawned_process) + std::cout << "\n"; // The iOS Simulator has a separate set of kernel file caches from the parent // OS, and if the simulator is deleted immediately after running the tests diff --git a/test/util/test_path.cpp b/test/util/test_path.cpp index ea1c70ed7d6..c901d8ca1bc 100644 --- a/test/util/test_path.cpp +++ b/test/util/test_path.cpp @@ -323,17 +323,11 @@ std::string TestDirNameGenerator::next() std::shared_ptr get_test_db(const std::string& path, const char* crypt_key) { - const char* str = getenv("UNITTEST_LOG_LEVEL"); - realm::util::Logger::Level core_log_level = realm::util::Logger::Level::off; - if (str && strlen(str) != 0) { - std::istringstream in(str); - in.imbue(std::locale::classic()); - in.flags(in.flags() & ~std::ios_base::skipws); // Do not accept white space - in >> core_log_level; - } + auto log_level = Logger::Level::off; + Logger::get_env_log_level_if_set(log_level); DBOptions options; - options.logger = std::make_shared(core_log_level); + options.logger = std::make_shared(log_level); options.encryption_key = crypt_key; return DB::create(make_in_realm_history(), path, options); }