Skip to content

Commit

Permalink
Clean-up code related to settings::RunMode. Also add unit tests of Lo…
Browse files Browse the repository at this point in the history
…ggingInfo and ProcessCommandsFromCLI
  • Loading branch information
sjanel committed Apr 22, 2023
1 parent 5f7ac0e commit 3b3c262
Show file tree
Hide file tree
Showing 26 changed files with 174 additions and 65 deletions.
5 changes: 2 additions & 3 deletions src/api-objects/include/apikeysprovider.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,10 @@ class APIKeysProvider {
public:
using KeyNames = SmallVector<std::string_view, kTypicalNbPrivateAccounts>;

explicit APIKeysProvider(std::string_view dataDir, settings::RunMode runMode = settings::RunMode::kProd)
APIKeysProvider(std::string_view dataDir, settings::RunMode runMode)
: APIKeysProvider(dataDir, ExchangeSecretsInfo(), runMode) {}

APIKeysProvider(std::string_view dataDir, const ExchangeSecretsInfo &exchangeSecretsInfo,
settings::RunMode runMode = settings::RunMode::kProd);
APIKeysProvider(std::string_view dataDir, const ExchangeSecretsInfo &exchangeSecretsInfo, settings::RunMode runMode);

KeyNames getKeyNames(std::string_view platform) const;

Expand Down
6 changes: 4 additions & 2 deletions src/api-objects/src/apikeysprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ namespace {

std::string_view GetSecretFileName(settings::RunMode runMode) {
switch (runMode) {
case settings::RunMode::kTest:
case settings::RunMode::kTestKeys:
[[fallthrough]];
case settings::RunMode::kTestKeysWithProxy:
log::info("Test mode activated, shifting to secret_test.json file.");
return "secret_test.json";
default:
Expand Down Expand Up @@ -73,7 +75,7 @@ APIKeysProvider::APIKeysMap APIKeysProvider::ParseAPIKeys(std::string_view dataD
} else {
std::string_view secretFileName = GetSecretFileName(runMode);
File secretsFile(dataDir, File::Type::kSecret, secretFileName,
runMode == settings::RunMode::kProd ? File::IfError::kNoThrow : File::IfError::kThrow);
AreTestKeysRequested(runMode) ? File::IfError::kThrow : File::IfError::kNoThrow);
json jsonData = secretsFile.readAllJson();
for (auto& [publicExchangeName, keyObj] : jsonData.items()) {
const auto& exchangesWithoutSecrets = exchangeSecretsInfo.exchangesWithoutSecrets();
Expand Down
6 changes: 3 additions & 3 deletions src/api/common/include/cryptowatchapi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ class CryptowatchAPI : public ExchangeBase {
public:
using Fiats = FlatSet<CurrencyCode>;

explicit CryptowatchAPI(const CoincenterInfo &config, settings::RunMode runMode = settings::RunMode::kProd,
Duration fiatsUpdateFrequency = std::chrono::hours(96), bool loadFromFileCacheAtInit = true);
CryptowatchAPI(const CoincenterInfo &config, settings::RunMode runMode,
Duration fiatsUpdateFrequency = std::chrono::hours(96), bool loadFromFileCacheAtInit = true);

/// Tells whether given exchange is supported by Cryptowatch.
bool queryIsExchangeSupported(std::string_view exchangeName) {
Expand All @@ -42,7 +42,7 @@ class CryptowatchAPI : public ExchangeBase {
}

/// Tells whether given currency code is a fiat currency or not.
/// Fiat currencies are traditionnal currencies, such as EUR, USD, GBP, KRW, etc.
/// Fiat currencies are traditional currencies, such as EUR, USD, GBP, KRW, etc.
/// Information here: https://en.wikipedia.org/wiki/Fiat_money
bool queryIsCurrencyCodeFiat(CurrencyCode currencyCode) {
std::lock_guard<std::mutex> guard(_fiatsMutex);
Expand Down
10 changes: 3 additions & 7 deletions src/api/common/test/cryptowatchapi_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,9 @@ namespace cct::api {

class CryptowatchAPITest : public ::testing::Test {
protected:
CryptowatchAPITest() : cryptowatchAPI(config) {}

void SetUp() override {}
void TearDown() override {}

CoincenterInfo config;
CryptowatchAPI cryptowatchAPI;
settings::RunMode runMode = settings::RunMode::kTestKeys;
CoincenterInfo config{runMode};
CryptowatchAPI cryptowatchAPI{config, runMode};
};

TEST_F(CryptowatchAPITest, Prices) {
Expand Down
4 changes: 2 additions & 2 deletions src/api/common/test/exchangeprivateapi_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ class ExchangePrivateTest : public ::testing::Test {
}

LoadConfiguration loadConfiguration{kDefaultDataDir, LoadConfiguration::ExchangeConfigFileType::kTest};
CoincenterInfo coincenterInfo{settings::RunMode::kProd, loadConfiguration};
CryptowatchAPI cryptowatchAPI{coincenterInfo, settings::RunMode::kProd, Duration::max(), true};
CoincenterInfo coincenterInfo{settings::RunMode::kTestKeys, loadConfiguration};
CryptowatchAPI cryptowatchAPI{coincenterInfo, settings::RunMode::kTestKeys, Duration::max(), true};
FiatConverter fiatConverter{coincenterInfo, Duration::max()}; // max to avoid real Fiat converter queries

MockExchangePublic exchangePublic{kSupportedExchanges[0], fiatConverter, cryptowatchAPI, coincenterInfo};
Expand Down
5 changes: 3 additions & 2 deletions src/api/common/test/exchangepublicapi_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ class ExchangePublicTest : public ::testing::Test {
void SetUp() override {}
void TearDown() override {}

settings::RunMode runMode = settings::RunMode::kTestKeys;
LoadConfiguration loadConfiguration{kDefaultDataDir, LoadConfiguration::ExchangeConfigFileType::kTest};
CoincenterInfo coincenterInfo{settings::RunMode::kProd, loadConfiguration};
CryptowatchAPI cryptowatchAPI{coincenterInfo};
CoincenterInfo coincenterInfo{runMode, loadConfiguration};
CryptowatchAPI cryptowatchAPI{coincenterInfo, runMode};
FiatConverter fiatConverter{coincenterInfo, Duration::max()}; // max to avoid real Fiat converter queries
MockExchangePublic exchangePublic{kSupportedExchanges[0], fiatConverter, cryptowatchAPI, coincenterInfo};
};
Expand Down
5 changes: 3 additions & 2 deletions src/api/exchanges/test/commonapi_test.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,12 @@ class TestAPI {
return sample;
}

settings::RunMode runMode = settings::RunMode::kProd;
LoadConfiguration loadConfig{kDefaultDataDir, LoadConfiguration::ExchangeConfigFileType::kTest};
CoincenterInfo coincenterInfo{settings::RunMode::kProd, loadConfig};
CoincenterInfo coincenterInfo{runMode, loadConfig};
APIKeysProvider apiKeysProvider{coincenterInfo.dataDir(), coincenterInfo.getRunMode()};
FiatConverter fiatConverter{coincenterInfo, Duration::max()}; // max to avoid real Fiat converter queries
CryptowatchAPI cryptowatchAPI{coincenterInfo};
CryptowatchAPI cryptowatchAPI{coincenterInfo, runMode};
PublicExchangeT exchangePublic{coincenterInfo, fiatConverter, cryptowatchAPI};
std::unique_ptr<PrivateExchangeT> exchangePrivatePtr{
CreatePrivateExchangeIfKeyPresent(exchangePublic, coincenterInfo, apiKeysProvider)};
Expand Down
6 changes: 6 additions & 0 deletions src/engine/include/coincentercommands.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,19 @@ namespace cct {

class CoincenterCommands {
public:
// Builds a CoincenterCommands without any commands.
CoincenterCommands() noexcept(std::is_nothrow_default_constructible_v<Commands>) = default;

// Builds a CoincenterCommands and add commands from given command line options.
explicit CoincenterCommands(const CoincenterCmdLineOptions &cmdLineOptions);

static CoincenterCmdLineOptions ParseOptions(int argc, const char *argv[]);

static MonitoringInfo CreateMonitoringInfo(std::string_view programName,
const CoincenterCmdLineOptions &cmdLineOptions);

/// @brief Set this CoincenterCommands from given command line options.
/// @return false if only help or version is asked, true otherwise
bool setFromOptions(const CoincenterCmdLineOptions &cmdLineOptions);

std::span<const CoincenterCommand> commands() const { return _commands; }
Expand Down
4 changes: 4 additions & 0 deletions src/engine/src/coincentercommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ std::pair<OrdersConstraints, ExchangeNames> ParseOrderRequest(const CoincenterCm
}
} // namespace

CoincenterCommands::CoincenterCommands(const CoincenterCmdLineOptions &cmdLineOptions) {
setFromOptions(cmdLineOptions);
}

bool CoincenterCommands::setFromOptions(const CoincenterCmdLineOptions &cmdLineOptions) {
if (cmdLineOptions.help || cmdLineOptions.version) {
return false;
Expand Down
5 changes: 3 additions & 2 deletions src/engine/test/exchangedata_test.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ class ExchangesBaseTest : public ::testing::Test {
void TearDown() override {}

LoadConfiguration loadConfiguration{kDefaultDataDir, LoadConfiguration::ExchangeConfigFileType::kTest};
CoincenterInfo coincenterInfo{settings::RunMode::kProd, loadConfiguration};
api::CryptowatchAPI cryptowatchAPI{coincenterInfo, settings::RunMode::kProd, Duration::max(), true};
settings::RunMode runMode = settings::RunMode::kTestKeys;
CoincenterInfo coincenterInfo{runMode, loadConfiguration};
api::CryptowatchAPI cryptowatchAPI{coincenterInfo, runMode, Duration::max(), true};
FiatConverter fiatConverter{coincenterInfo, Duration::max()}; // max to avoid real Fiat converter queries
api::MockExchangePublic exchangePublic1{kSupportedExchanges[0], fiatConverter, cryptowatchAPI, coincenterInfo};
api::MockExchangePublic exchangePublic2{kSupportedExchanges[1], fiatConverter, cryptowatchAPI, coincenterInfo};
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion src/iotools/src/curlhandle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
#include "abstractmetricgateway.hpp"
#include "cct_exception.hpp"
#include "cct_log.hpp"
#include "cct_proxy.hpp"
#include "curlmetrics.hpp"
#include "curloptions.hpp"
#include "proxy.hpp"
#include "stringhelpers.hpp"

namespace cct {
Expand Down
2 changes: 1 addition & 1 deletion src/iotools/test/curlhandle_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

#include <gtest/gtest.h>

#include "cct_proxy.hpp"
#include "curloptions.hpp"
#include "proxy.hpp"

/* URL available to test HTTPS, cf
* https://support.nmi.com/hc/en-gb/articles/360021544791-How-to-Check-If-the-Correct-Certificates-Are-Installed-on-Linux
Expand Down
8 changes: 8 additions & 0 deletions src/main/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,12 @@ set_target_properties(coincenter PROPERTIES
VERSION ${PROJECT_VERSION}
COMPILE_DEFINITIONS_DEBUG "JSON_DEBUG;JSON_SAFE;JSON_ISO_STRICT"
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
)

add_unit_test(
processcommandsfromcli_test
src/processcommandsfromcli.cpp
test/processcommandsfromcli_test.cpp
LIBRARIES
coincenter_engine
)
6 changes: 3 additions & 3 deletions src/main/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ int main(int argc, const char* argv[]) {
try {
auto cmdLineOptions = cct::CoincenterCommands::ParseOptions(argc, argv);

cct::CoincenterCommands coincenterCommands;
if (coincenterCommands.setFromOptions(cmdLineOptions)) {
if (!cmdLineOptions.help && !cmdLineOptions.version) {
cct::CoincenterCommands coincenterCommands(cmdLineOptions);
auto programName = std::filesystem::path(argv[0]).filename().string();

cct::ProcessCommandsFromCLI(programName, coincenterCommands, cmdLineOptions);
cct::ProcessCommandsFromCLI(programName, coincenterCommands, cmdLineOptions, cct::settings::RunMode::kProd);
}
} catch (const cct::invalid_argument& e) {
cct::log::critical("Invalid argument: {}", e.what());
Expand Down
20 changes: 11 additions & 9 deletions src/main/src/processcommandsfromcli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,17 @@ json LoadGeneralConfigAndOverrideOptionsFromCLI(const CoincenterCmdLineOptions &
} // namespace

void ProcessCommandsFromCLI(std::string_view programName, const CoincenterCommands &coincenterCommands,
const CoincenterCmdLineOptions &cmdLineOptions) {
const CoincenterCmdLineOptions &cmdLineOptions, settings::RunMode runMode) {
json generalConfigData = LoadGeneralConfigAndOverrideOptionsFromCLI(cmdLineOptions);

Duration fiatConversionQueryRate = ParseDuration(generalConfigData["fiatConversion"]["rate"].get<std::string_view>());
ApiOutputType apiOutputType = ApiOutputTypeFromString(generalConfigData["apiOutputType"].get<std::string_view>());

// Create LoggingInfo first as it is a RAII structure re-initializing spdlog loggers.
// It will be held by GeneralConfig and then itself by CoincenterInfo though.
LoggingInfo loggingInfo(static_cast<const json &>(generalConfigData["log"]));

Duration fiatConversionQueryRate = ParseDuration(generalConfigData["fiatConversion"]["rate"].get<std::string_view>());

GeneralConfig generalConfig(std::move(loggingInfo), fiatConversionQueryRate,
ApiOutputTypeFromString(generalConfigData["apiOutputType"].get<std::string_view>()));
GeneralConfig generalConfig(std::move(loggingInfo), fiatConversionQueryRate, apiOutputType);

LoadConfiguration loadConfiguration(cmdLineOptions.dataDir, LoadConfiguration::ExchangeConfigFileType::kProd);

Expand All @@ -55,7 +55,7 @@ void ProcessCommandsFromCLI(std::string_view programName, const CoincenterComman
File::IfError::kThrow);

// Should be outside the try / catch as it holds the RAII object managing the Logging (LoggingInfo)
CoincenterInfo coincenterInfo(settings::RunMode::kProd, loadConfiguration, std::move(generalConfig),
CoincenterInfo coincenterInfo(runMode, loadConfiguration, std::move(generalConfig),
CoincenterCommands::CreateMonitoringInfo(programName, cmdLineOptions),
currencyAcronymsTranslatorFile, stableCoinsFile, currencyPrefixesTranslatorFile);

Expand All @@ -73,10 +73,12 @@ void ProcessCommandsFromCLI(std::string_view programName, const CoincenterComman

int nbCommandsProcessed = coincenter.process(coincenterCommands);

// Write potentially updated cache data on disk at end of program
coincenter.updateFileCaches();
if (nbCommandsProcessed > 0) {
// Write potentially updated cache data on disk at end of program
coincenter.updateFileCaches();
}

log::debug("normal termination after {} command(s) processed", nbCommandsProcessed);
log::info("normal termination after {} command(s) processed", nbCommandsProcessed);
} catch (const exception &e) {
// Log exception here as LoggingInfo is still configured at this point (will be destroyed immediately afterwards)
log::critical("Exception: {}", e.what());
Expand Down
3 changes: 2 additions & 1 deletion src/main/src/processcommandsfromcli.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@

#include "coincentercommands.hpp"
#include "coincenteroptions.hpp"
#include "runmodes.hpp"

namespace cct {
void ProcessCommandsFromCLI(std::string_view programName, const CoincenterCommands &coincenterCommands,
const CoincenterCmdLineOptions &cmdLineOptions);
const CoincenterCmdLineOptions &cmdLineOptions, settings::RunMode runMode);
}
26 changes: 26 additions & 0 deletions src/main/test/processcommandsfromcli_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include "processcommandsfromcli.hpp"

#include <gtest/gtest.h>

namespace cct {
namespace {
constexpr settings::RunMode kRunMode = settings::RunMode::kTestKeys;
constexpr std::string_view kProgramName = "coincenter";
} // namespace

TEST(ProcessCommandsFromCLI, TestNoArguments) {
CoincenterCmdLineOptions cmdLineOptions;
CoincenterCommands coincenterCommands{cmdLineOptions};

EXPECT_NO_THROW(ProcessCommandsFromCLI(kProgramName, coincenterCommands, cmdLineOptions, kRunMode));
}

TEST(ProcessCommandsFromCLI, TestIncorrectArgument) {
CoincenterCmdLineOptions cmdLineOptions;
cmdLineOptions.apiOutputType = "invalid";
CoincenterCommands coincenterCommands{cmdLineOptions};

EXPECT_THROW(ProcessCommandsFromCLI(kProgramName, coincenterCommands, cmdLineOptions, kRunMode), invalid_argument);
}

} // namespace cct
7 changes: 7 additions & 0 deletions src/objects/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ add_unit_test(
CCT_DISABLE_SPDLOG
)

add_unit_test(
logginginfo_test
test/logginginfo_test.cpp
LIBRARIES
coincenter_objects
)

add_unit_test(
marketorderbook_test
test/marketorderbook_test.cpp
Expand Down
3 changes: 1 addition & 2 deletions src/objects/include/coincenterinfo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ class CoincenterInfo {
using CurrencyPrefixAcronymMap = std::map<string, string, std::less<>>;
using StableCoinsMap = std::unordered_map<CurrencyCode, CurrencyCode>;

explicit CoincenterInfo(settings::RunMode runMode = settings::RunMode::kProd,
const LoadConfiguration &loadConfiguration = LoadConfiguration(),
explicit CoincenterInfo(settings::RunMode runMode, const LoadConfiguration &loadConfiguration = LoadConfiguration(),
GeneralConfig &&generalConfig = GeneralConfig(),
MonitoringInfo &&monitoringInfo = MonitoringInfo(),
const Reader &currencyAcronymsReader = Reader(), const Reader &stableCoinsReader = Reader(),
Expand Down
2 changes: 1 addition & 1 deletion src/objects/include/logginginfo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class LoggingInfo {
LoggingInfo(const LoggingInfo &) = delete;
LoggingInfo(LoggingInfo &&loggingInfo) noexcept;
LoggingInfo &operator=(const LoggingInfo &) = delete;
LoggingInfo &operator=(LoggingInfo &&loggingInfo) noexcept;
LoggingInfo &operator=(LoggingInfo &&loggingInfo) = delete;

~LoggingInfo();

Expand Down
13 changes: 1 addition & 12 deletions src/objects/src/logginginfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,20 +81,9 @@ LoggingInfo::LoggingInfo(LoggingInfo &&loggingInfo) noexcept
_logLevelFilePos(loggingInfo._logLevelFilePos),
_destroyLoggers(std::exchange(loggingInfo._destroyLoggers, false)) {}

LoggingInfo &LoggingInfo::operator=(LoggingInfo &&loggingInfo) noexcept {
if (&loggingInfo != this) {
_maxFileSizeInBytes = loggingInfo._maxFileSizeInBytes;
_maxNbFiles = loggingInfo._maxNbFiles;
_logLevelConsolePos = loggingInfo._logLevelConsolePos;
_logLevelFilePos = loggingInfo._logLevelFilePos;
_destroyLoggers = std::exchange(loggingInfo._destroyLoggers, false);
}
return *this;
}

LoggingInfo::~LoggingInfo() {
if (_destroyLoggers) {
log::drop_all();
log::drop(kOutputLoggerName);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/objects/test/coincenterinfo_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class CoincenterInfoTest : public ::testing::Test {
MockReader currencyPrefixesReader;

CoincenterInfo createCoincenterInfo() const {
return CoincenterInfo(settings::RunMode::kTest, loadConfiguration, GeneralConfig(), MonitoringInfo(),
return CoincenterInfo(settings::RunMode::kTestKeysWithProxy, loadConfiguration, GeneralConfig(), MonitoringInfo(),
currencyAcronymsReader, stableCoinsReader, currencyPrefixesReader);
}
};
Expand Down
10 changes: 3 additions & 7 deletions src/objects/test/fiatconverter_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,9 @@ CurlHandle::~CurlHandle() {} // NOLINT

class FiatConverterTest : public ::testing::Test {
protected:
FiatConverterTest() : converter(coincenterInfo, std::chrono::milliseconds(1)) {}

void SetUp() override {}
void TearDown() override {}

CoincenterInfo coincenterInfo;
FiatConverter converter;
settings::RunMode runMode = settings::RunMode::kTestKeys;
CoincenterInfo coincenterInfo{runMode};
FiatConverter converter{coincenterInfo, std::chrono::milliseconds(1)};
};

TEST_F(FiatConverterTest, DirectConversion) {
Expand Down
Loading

0 comments on commit 3b3c262

Please sign in to comment.