diff --git a/test/unittests/test_loader.cpp b/test/unittests/test_loader.cpp index 06a92ac..8ae7ada 100644 --- a/test/unittests/test_loader.cpp +++ b/test/unittests/test_loader.cpp @@ -2,11 +2,12 @@ // Copyright 2018-2019 The EVMC Authors. // Licensed under the Apache License, Version 2.0. +#include #include - #include - #include +#include +#include #if _WIN32 static constexpr bool is_windows = true; @@ -15,22 +16,93 @@ static constexpr bool is_windows = false; #endif extern "C" { +/// The library path expected by mocked evmc_test_load_library(). extern const char* evmc_test_library_path; + +/// The symbol name expected by mocked evmc_test_get_symbol_address(). extern const char* evmc_test_library_symbol; + +/// The pointer to function returned by evmc_test_get_symbol_address(). extern evmc_create_fn evmc_test_create_fn; } class loader : public ::testing::Test { protected: + static int create_count; + static int destroy_count; + static std::unordered_map supported_options; + static std::vector> recorded_options; + + loader() noexcept + { + create_count = 0; + destroy_count = 0; + supported_options.clear(); + recorded_options.clear(); + } + void setup(const char* path, const char* symbol, evmc_create_fn fn) noexcept { evmc_test_library_path = path; evmc_test_library_symbol = symbol; evmc_test_create_fn = fn; } + + static void destroy(evmc_instance*) noexcept { ++destroy_count; } + + static evmc_set_option_result set_option(evmc_instance*, + const char* name, + const char* value) noexcept + { + recorded_options.push_back({name, value ? value : ""}); // NOLINT + + auto it = supported_options.find(name); + if (it == supported_options.end()) + return EVMC_SET_OPTION_INVALID_NAME; + if (it->second == nullptr) + return value == nullptr ? EVMC_SET_OPTION_SUCCESS : EVMC_SET_OPTION_INVALID_VALUE; + if (value == nullptr) + return EVMC_SET_OPTION_INVALID_VALUE; + return std::string{value} == it->second ? EVMC_SET_OPTION_SUCCESS : + EVMC_SET_OPTION_INVALID_VALUE; + } + + /// Creates a VM mock with only destroy() method. + static evmc_instance* create_vm_barebone() + { + static auto instance = + evmc_instance{EVMC_ABI_VERSION, "", "", destroy, nullptr, nullptr, nullptr, nullptr}; + ++create_count; + return &instance; + } + + /// Creates a VM mock with ABI version different than in this project. + static evmc_instance* create_vm_with_wrong_abi() + { + constexpr auto wrong_abi_version = 1985; + static_assert(wrong_abi_version != EVMC_ABI_VERSION, ""); + static auto instance = + evmc_instance{wrong_abi_version, "", "", destroy, nullptr, nullptr, nullptr, nullptr}; + ++create_count; + return &instance; + } + + /// Creates a VM mock with optional set_option() method. + static evmc_instance* create_vm_with_set_option() noexcept + { + static auto instance = + evmc_instance{EVMC_ABI_VERSION, "", "", destroy, nullptr, nullptr, nullptr, set_option}; + ++create_count; + return &instance; + } }; +int loader::create_count = 0; +int loader::destroy_count = 0; +std::unordered_map loader::supported_options; +std::vector> loader::recorded_options; + static evmc_instance* create_aaa() { return (evmc_instance*)0xaaa;