diff --git a/cpp-client/deephaven/tests/include/private/deephaven/tests/test_util.h b/cpp-client/deephaven/tests/include/private/deephaven/tests/test_util.h index 00951675dc9..25a3d89307b 100644 --- a/cpp-client/deephaven/tests/include/private/deephaven/tests/test_util.h +++ b/cpp-client/deephaven/tests/include/private/deephaven/tests/test_util.h @@ -24,6 +24,35 @@ #include "deephaven/dhcore/utility/utility.h" namespace deephaven::client::tests { +/** + * Stores a static global map of environment variable key/value pairs. + * Initialized from the 'envp' variable passed in to main. + */ +class GlobalEnvironmentForTests { +public: + /** + * Initialize the environment_ map from the envp array passed into main(). + * @param envp The envp parameter that was passed by the OS into 'main'. + */ + static void Init(char **envp); + + /** + * Look up 'key' in the environment_ map. Returns the associated value if found; + * otherwise returns the value contained in 'defaultValue'. + * + * @param key The key + * @param default_value The value to return if the key is not found. + * @return The associated value if found, otherwise the value contained in 'defaultValue'. + */ + static std::string_view GetEnv(std::string_view key, std::string_view default_value); + + // This is a pointer, so we don't have to worry about global construction/destruction. + // At global teardown time we will just leak memory. + // Also, std::less<> gets us the transparent comparator, so we can do lookups + // directly with string_view. + static std::map> *environment_; +}; + class ColumnNamesForTests { public: ColumnNamesForTests(); diff --git a/cpp-client/deephaven/tests/src/main.cc b/cpp-client/deephaven/tests/src/main.cc index 6e42bfa35a8..e3106a5d466 100644 --- a/cpp-client/deephaven/tests/src/main.cc +++ b/cpp-client/deephaven/tests/src/main.cc @@ -1,5 +1,14 @@ /* * Copyright (c) 2016-2024 Deephaven Data Labs and Patent Pending */ -#define CATCH_CONFIG_MAIN +#define CATCH_CONFIG_RUNNER #include "deephaven/third_party/catch.hpp" +#include "deephaven/tests/test_util.h" + +using deephaven::client::tests::GlobalEnvironmentForTests; + +int main(int argc, char *argv[], char **envp) { + // Process envp so we don't have to call getenv(), which Windows complains about. + GlobalEnvironmentForTests::Init(envp); + return Catch::Session().run(argc, argv); +} diff --git a/cpp-client/deephaven/tests/src/test_util.cc b/cpp-client/deephaven/tests/src/test_util.cc index 66cbab992d4..cacc198b6f7 100644 --- a/cpp-client/deephaven/tests/src/test_util.cc +++ b/cpp-client/deephaven/tests/src/test_util.cc @@ -15,6 +15,40 @@ using deephaven::client::utility::TableMaker; using deephaven::client::utility::ValueOrThrow; namespace deephaven::client::tests { +std::map> *GlobalEnvironmentForTests::environment_ = nullptr; + +void GlobalEnvironmentForTests::Init(char **envp) { + if (environment_ != nullptr) { + throw std::runtime_error(DEEPHAVEN_LOCATION_STR("It's an error to call Init() twice")); + } + environment_ = new std::map>(); + + for (char **current = envp; *current != nullptr; ++current) { + std::string_view sv(*current); + + // Find the equal sign and split the strings into keys and values. + auto pos = sv.find('='); + if (pos == std::string_view::npos) { + continue; + } + auto key = sv.substr(0, pos); + auto value = sv.substr(pos + 1); + environment_->try_emplace(std::string(key), value); + } +} + +std::string_view GlobalEnvironmentForTests::GetEnv(std::string_view key, + std::string_view default_value) { + if (environment_ == nullptr) { + return default_value; + } + auto ip = environment_->find(key); + if (ip == environment_->end()) { + return default_value; + } + return ip->second; +} + ColumnNamesForTests::ColumnNamesForTests() : importDate_("ImportDate"), ticker_("Ticker"), open_("Open"), close_("Close"), volume_("Volume") {} ColumnNamesForTests::ColumnNamesForTests(ColumnNamesForTests &&other) noexcept = default; @@ -116,11 +150,9 @@ TableMakerForTests TableMakerForTests::Create() { } Client TableMakerForTests::CreateClient(const ClientOptions &options) { - const char *hostptr = std::getenv("DH_HOST"); - const char *portptr = std::getenv("DH_PORT"); - std::string host = (hostptr == nullptr) ? "localhost" : hostptr; - std::string port = (portptr == nullptr) ? "10000" : portptr; - std::string connection_string(host + ":" + port); + auto host = GlobalEnvironmentForTests::GetEnv("DH_HOST", "localhost"); + auto port = GlobalEnvironmentForTests::GetEnv("DH_PORT", "10000"); + auto connection_string = fmt::format("{}:{}", host, port); fmt::print(std::cerr, "Connecting to {}\n", connection_string); auto client = Client::Connect(connection_string, options); return client;