diff --git a/driver/CMakeLists.txt b/driver/CMakeLists.txt index 6366f05e9..1827c2cbd 100644 --- a/driver/CMakeLists.txt +++ b/driver/CMakeLists.txt @@ -151,15 +151,7 @@ WHILE(${DRIVER_INDEX} LESS ${DRIVERS_COUNT}) # but a dynamic module that will be loaded by ODBC manager. One # consequence of this is that on Windows import libraries will not # be generated nor installed. - IF(WIN32) - IF(ENABLE_UNIT_TESTS) - ADD_LIBRARY(${DRIVER_NAME} ${DRIVER_SRCS} ${AWSSDK_LIB_DIR}) - ELSE(ENABLE_UNIT_TESTS) - ADD_LIBRARY(${DRIVER_NAME} SHARED ${DRIVER_SRCS} ${AWSSDK_LIB_DIR}) - ENDIF(ENABLE_UNIT_TESTS) - ELSE(WIN32) - ADD_LIBRARY(${DRIVER_NAME} SHARED ${DRIVER_SRCS} ${AWSSDK_LIB_DIR}) - ENDIF(WIN32) + ADD_LIBRARY(${DRIVER_NAME} SHARED ${DRIVER_SRCS} ${AWSSDK_LIB_DIR}) ADD_COVERAGE(${DRIVER_NAME}) diff --git a/driver/cluster_aware_metrics_container.h b/driver/cluster_aware_metrics_container.h index 405df8e3b..046663117 100644 --- a/driver/cluster_aware_metrics_container.h +++ b/driver/cluster_aware_metrics_container.h @@ -42,7 +42,7 @@ struct DBC; struct DataSource; -class CLUSTER_AWARE_METRICS_CONTAINER { +class __declspec(dllexport) CLUSTER_AWARE_METRICS_CONTAINER { public: CLUSTER_AWARE_METRICS_CONTAINER(); CLUSTER_AWARE_METRICS_CONTAINER(DBC* dbc, DataSource* ds); diff --git a/driver/cluster_topology_info.h b/driver/cluster_topology_info.h index 90d840370..931c93c5d 100644 --- a/driver/cluster_topology_info.h +++ b/driver/cluster_topology_info.h @@ -39,7 +39,7 @@ // This class holds topology information for one cluster. // Cluster topology consists of an instance endpoint, a set of nodes in the cluster, // the type of each node in the cluster, and the status of each node in the cluster. -class CLUSTER_TOPOLOGY_INFO { +class __declspec(dllexport) CLUSTER_TOPOLOGY_INFO { public: CLUSTER_TOPOLOGY_INFO(); CLUSTER_TOPOLOGY_INFO(const CLUSTER_TOPOLOGY_INFO& src_info); //copy constructor diff --git a/driver/connection_handler.h b/driver/connection_handler.h index 0c6f3a7d6..1d49771ad 100644 --- a/driver/connection_handler.h +++ b/driver/connection_handler.h @@ -46,7 +46,7 @@ struct DataSource; class CONNECTION_PROXY; typedef short SQLRETURN; -class CONNECTION_HANDLER { +class __declspec(dllexport) CONNECTION_HANDLER { public: CONNECTION_HANDLER(DBC* dbc); virtual ~CONNECTION_HANDLER(); diff --git a/driver/connection_proxy.h b/driver/connection_proxy.h index d3539b0c2..dd3289bfb 100644 --- a/driver/connection_proxy.h +++ b/driver/connection_proxy.h @@ -35,8 +35,8 @@ struct DBC; struct DataSource; -class CONNECTION_PROXY { -public: +class __declspec(dllexport) CONNECTION_PROXY { + public: CONNECTION_PROXY() = default; CONNECTION_PROXY(DBC* dbc, DataSource* ds); virtual ~CONNECTION_PROXY(); diff --git a/driver/efm_proxy.h b/driver/efm_proxy.h index 4cdba86ad..e3eb8afa2 100644 --- a/driver/efm_proxy.h +++ b/driver/efm_proxy.h @@ -34,7 +34,7 @@ #include "driver.h" #include "monitor_service.h" -class EFM_PROXY : public CONNECTION_PROXY { +class __declspec(dllexport) EFM_PROXY : public CONNECTION_PROXY { public: EFM_PROXY(DBC* dbc, DataSource* ds); EFM_PROXY(DBC* dbc, DataSource* ds, CONNECTION_PROXY* next_proxy); diff --git a/driver/failover.h b/driver/failover.h index 4fe837bee..9eaf52175 100644 --- a/driver/failover.h +++ b/driver/failover.h @@ -37,7 +37,7 @@ #include -struct READER_FAILOVER_RESULT { +struct __declspec(dllexport) READER_FAILOVER_RESULT { bool connected = false; std::shared_ptr new_host; CONNECTION_PROXY* new_connection; @@ -53,7 +53,7 @@ struct READER_FAILOVER_RESULT { }; // FAILOVER_SYNC enables synchronization between threads -class FAILOVER_SYNC { +class __declspec(dllexport) FAILOVER_SYNC { public: FAILOVER_SYNC(int num_tasks); void increment_task(); @@ -67,7 +67,7 @@ class FAILOVER_SYNC { std::condition_variable cv; }; -class FAILOVER_READER_HANDLER { +class __declspec(dllexport) FAILOVER_READER_HANDLER { public: FAILOVER_READER_HANDLER( std::shared_ptr topology_service, @@ -109,7 +109,7 @@ class FAILOVER_READER_HANDLER { }; // This struct holds results of Writer Failover Process. -struct WRITER_FAILOVER_RESULT { +struct __declspec(dllexport) WRITER_FAILOVER_RESULT { bool connected = false; bool is_new_host = false; // True if process connected to a new host. False if // process re-connected to the same host @@ -131,7 +131,7 @@ struct WRITER_FAILOVER_RESULT { new_connection{new_connection} {} }; -class FAILOVER_WRITER_HANDLER { +class __declspec(dllexport) FAILOVER_WRITER_HANDLER { public: FAILOVER_WRITER_HANDLER( std::shared_ptr topology_service, @@ -158,7 +158,7 @@ class FAILOVER_WRITER_HANDLER { ctpl::thread_pool& thread_pool; }; -class FAILOVER_HANDLER { +class __declspec(dllexport) FAILOVER_HANDLER { public: FAILOVER_HANDLER(DBC* dbc, DataSource* ds); FAILOVER_HANDLER( @@ -230,7 +230,7 @@ class FAILOVER_HANDLER { // file, but here for now // -class FAILOVER { +class __declspec(dllexport) FAILOVER { public: FAILOVER(std::shared_ptr connection_handler, std::shared_ptr topology_service, @@ -264,7 +264,7 @@ class CONNECT_TO_READER_HANDLER : public FAILOVER { std::shared_ptr result); }; -class RECONNECT_TO_WRITER_HANDLER : public FAILOVER { +class __declspec(dllexport) RECONNECT_TO_WRITER_HANDLER : public FAILOVER { public: RECONNECT_TO_WRITER_HANDLER( std::shared_ptr connection_handler, @@ -286,7 +286,7 @@ class RECONNECT_TO_WRITER_HANDLER : public FAILOVER { std::shared_ptr latest_topology); }; -class WAIT_NEW_WRITER_HANDLER : public FAILOVER { +class __declspec(dllexport) WAIT_NEW_WRITER_HANDLER : public FAILOVER { public: WAIT_NEW_WRITER_HANDLER( std::shared_ptr connection_handler, diff --git a/driver/host_info.h b/driver/host_info.h index e5c64a420..2a648a07b 100644 --- a/driver/host_info.h +++ b/driver/host_info.h @@ -37,8 +37,8 @@ enum HOST_STATE { UP, DOWN }; // TODO Think about char types. Using strings for now, but should SQLCHAR *, or CHAR * be employed? // Most of the strings are for internal failover things -class HOST_INFO { -public: +class __declspec(dllexport) HOST_INFO { + public: HOST_INFO(); //TODO - probably choose one of the following constructors, or more precisely choose which data type they should take HOST_INFO(std::string host, int port); diff --git a/driver/iam_proxy.cc b/driver/iam_proxy.cc index 33e69a0d7..892ba3db2 100644 --- a/driver/iam_proxy.cc +++ b/driver/iam_proxy.cc @@ -192,3 +192,8 @@ bool IAM_PROXY::invoke_func_with_generated_token(std::function& IAM_PROXY::get_token_cache() { + return token_cache; +} + diff --git a/driver/iam_proxy.h b/driver/iam_proxy.h index 7f16904a2..5d5f166b7 100644 --- a/driver/iam_proxy.h +++ b/driver/iam_proxy.h @@ -39,7 +39,11 @@ constexpr auto DEFAULT_TOKEN_EXPIRATION_SEC = 15 * 60; -class TOKEN_INFO { +#ifdef UNIT_TEST_BUILD + class TEST_UTILS; +#endif + +class __declspec(dllexport) TOKEN_INFO { public: TOKEN_INFO() {}; TOKEN_INFO(std::string token) : TOKEN_INFO(token, DEFAULT_TOKEN_EXPIRATION_SEC) {}; @@ -59,7 +63,7 @@ class TOKEN_INFO { std::chrono::system_clock::time_point expiration_time; }; -class TOKEN_GENERATOR { +class __declspec(dllexport) TOKEN_GENERATOR { public: TOKEN_GENERATOR() {} // Default constructor used only in unit tests TOKEN_GENERATOR(Aws::Auth::AWSCredentials credentials, Aws::RDS::RDSClientConfiguration client_config) { @@ -79,7 +83,7 @@ class TOKEN_GENERATOR { std::shared_ptr rds_client; }; -class IAM_PROXY : public CONNECTION_PROXY { +class __declspec(dllexport) IAM_PROXY : public CONNECTION_PROXY { public: IAM_PROXY() = default; IAM_PROXY(DBC* dbc, DataSource* ds); @@ -106,6 +110,8 @@ class IAM_PROXY : public CONNECTION_PROXY { const char* user, unsigned int time_until_expiration, bool force_generate_new_token = false); + static std::unordered_map& get_token_cache(); + protected: static std::unordered_map token_cache; static std::mutex token_cache_mutex; diff --git a/driver/monitor.h b/driver/monitor.h index 7f8095559..640b880ec 100644 --- a/driver/monitor.h +++ b/driver/monitor.h @@ -37,7 +37,7 @@ #include #include -struct CONNECTION_STATUS { +struct __declspec(dllexport) CONNECTION_STATUS { bool is_valid; std::chrono::milliseconds elapsed_time; }; @@ -51,8 +51,9 @@ namespace { const unsigned int failure_detection_timeout_default = 5; } -class MONITOR : public std::enable_shared_from_this { -public: +class __declspec(dllexport) MONITOR + : public std::enable_shared_from_this { + public: MONITOR( std::shared_ptr host_info, std::shared_ptr connection_handler, diff --git a/driver/monitor_connection_context.h b/driver/monitor_connection_context.h index 40f29b5e9..e198070ec 100644 --- a/driver/monitor_connection_context.h +++ b/driver/monitor_connection_context.h @@ -41,8 +41,8 @@ struct DBC; // Monitoring context for each connection. This contains each connection's criteria for // whether a server should be considered unhealthy. -class MONITOR_CONNECTION_CONTEXT { -public: +class __declspec(dllexport) MONITOR_CONNECTION_CONTEXT { + public: MONITOR_CONNECTION_CONTEXT(DBC* connection_to_abort, std::set node_keys, std::chrono::milliseconds failure_detection_time, diff --git a/driver/monitor_service.h b/driver/monitor_service.h index 1d772f4ee..6f020bc4e 100644 --- a/driver/monitor_service.h +++ b/driver/monitor_service.h @@ -32,8 +32,9 @@ #include "monitor_thread_container.h" -class MONITOR_SERVICE : public std::enable_shared_from_this { -public: +class __declspec(dllexport) MONITOR_SERVICE + : public std::enable_shared_from_this { + public: MONITOR_SERVICE(bool enable_logging = false); MONITOR_SERVICE( std::shared_ptr monitor_thread_container, diff --git a/driver/monitor_thread_container.h b/driver/monitor_thread_container.h index d8c9f58fa..0b578bf2e 100644 --- a/driver/monitor_thread_container.h +++ b/driver/monitor_thread_container.h @@ -38,8 +38,8 @@ #include #include -class MONITOR_THREAD_CONTAINER { -public: +class __declspec(dllexport) MONITOR_THREAD_CONTAINER { + public: MONITOR_THREAD_CONTAINER(MONITOR_THREAD_CONTAINER const&) = delete; MONITOR_THREAD_CONTAINER& operator=(MONITOR_THREAD_CONTAINER const&) = delete; virtual ~MONITOR_THREAD_CONTAINER() = default; diff --git a/driver/myutil.h b/driver/myutil.h index 6dec2dbc9..eac534b33 100755 --- a/driver/myutil.h +++ b/driver/myutil.h @@ -276,7 +276,7 @@ SQLRETURN SQL_API my_SQLAllocConnect (SQLHENV henv, SQLHDBC *phdbc); SQLRETURN SQL_API my_SQLFreeConnect (SQLHDBC hdbc); SQLRETURN SQL_API my_SQLFreeEnv (SQLHENV henv); -void myodbc_end(); +void __declspec(dllexport) myodbc_end(); my_bool set_dynamic_result (STMT *stmt); void set_current_cursor_data (STMT *stmt,SQLUINTEGER irow); my_bool is_minimum_version (const char *server_version,const char *version); diff --git a/driver/query_parsing.h b/driver/query_parsing.h index 160af95ad..d9d15aa3e 100644 --- a/driver/query_parsing.h +++ b/driver/query_parsing.h @@ -33,6 +33,6 @@ #include #include -std::vector parse_query_into_statements(const char* original_query); +std::vector __declspec(dllexport) parse_query_into_statements(const char* original_query); #endif /* __QUERY_PARSING_H__ */ diff --git a/driver/secrets_manager_proxy.cc b/driver/secrets_manager_proxy.cc index 0c4fec915..3ea5be00e 100644 --- a/driver/secrets_manager_proxy.cc +++ b/driver/secrets_manager_proxy.cc @@ -215,3 +215,8 @@ bool SECRETS_MANAGER_PROXY::try_parse_region_from_secret(std::string secret, std return false; } + +std::map, Aws::Utils::Json::JsonValue>& SECRETS_MANAGER_PROXY::get_secrets_cache() { + return secrets_cache; +} + diff --git a/driver/secrets_manager_proxy.h b/driver/secrets_manager_proxy.h index 7a6176309..800be7901 100644 --- a/driver/secrets_manager_proxy.h +++ b/driver/secrets_manager_proxy.h @@ -38,7 +38,11 @@ #include "connection_proxy.h" #include "driver.h" -class SECRETS_MANAGER_PROXY : public CONNECTION_PROXY { +#ifdef UNIT_TEST_BUILD + class TEST_UTILS; +#endif + +class __declspec(dllexport) SECRETS_MANAGER_PROXY : public CONNECTION_PROXY { public: SECRETS_MANAGER_PROXY(DBC* dbc, DataSource* ds); #ifdef UNIT_TEST_BUILD @@ -52,6 +56,8 @@ class SECRETS_MANAGER_PROXY : public CONNECTION_PROXY { bool change_user(const char* user, const char* passwd, const char* db) override; + static std::map, Aws::Utils::Json::JsonValue>& get_secrets_cache(); + private: std::shared_ptr sm_client; std::pair secret_key; diff --git a/driver/topology_service.h b/driver/topology_service.h index 60f4b6d4d..0e776b3dd 100644 --- a/driver/topology_service.h +++ b/driver/topology_service.h @@ -53,8 +53,8 @@ static std::map> topology_cache; static std::mutex topology_cache_mutex; -class TOPOLOGY_SERVICE { -public: +class __declspec(dllexport) TOPOLOGY_SERVICE { + public: TOPOLOGY_SERVICE(unsigned long dbc_id, bool enable_logging = false); TOPOLOGY_SERVICE(const TOPOLOGY_SERVICE&); virtual ~TOPOLOGY_SERVICE(); diff --git a/setupgui/CMakeLists.txt b/setupgui/CMakeLists.txt index 64c888ff2..9e693da17 100644 --- a/setupgui/CMakeLists.txt +++ b/setupgui/CMakeLists.txt @@ -97,7 +97,7 @@ add_compile_options(${PLATFORM_CFLAGS}) add_library(awsmysqlodbcS SHARED ${SETUP_SRCS}) -target_link_libraries(awsmysqlodbcS ${ODBCLIB} ${ODBCINSTLIB}) +target_link_libraries(awsmysqlodbcS ${ODBCLIB} ${ODBCINSTLIB} awsmysqlodbca) # Note: When using GTK+, these libraries will be linked to -gtk modules. diff --git a/unit_testing/CMakeLists.txt b/unit_testing/CMakeLists.txt index 9b58b671e..564a36395 100644 --- a/unit_testing/CMakeLists.txt +++ b/unit_testing/CMakeLists.txt @@ -41,6 +41,8 @@ FetchContent_Declare( # For Windows: Prevent overriding the parent project's compiler/linker settings set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) +set(CMAKE_VERBOSE_MAKEFILE ON) +message(STATUS "CMAKE_BINARY_DIR is ${CMAKE_BINARY_DIR}") FetchContent_MakeAvailable(googletest) @@ -70,15 +72,28 @@ add_executable( topology_service_test.cc ) +file(COPY + ${CMAKE_BINARY_DIR}/lib/Release/awsmysqlodbca.dll + ${CMAKE_BINARY_DIR}/lib/Release/awsmysqlodbca.lib + ${CMAKE_BINARY_DIR}/lib/Release/awsmysqlodbca.exp + ${CMAKE_BINARY_DIR}/lib/Release/libcrypto-3-x64.dll + ${CMAKE_BINARY_DIR}/lib/Release/libssl-3-x64.dll + DESTINATION ${CMAKE_BINARY_DIR}/unit_testing/bin/Release +) + +TARGET_INCLUDE_DIRECTORIES(unit_testing PUBLIC ${AWSSDK_INCLUDE_DIR} ${CMAKE_SOURCE_DIR}/driver) target_link_libraries( unit_testing gtest_main gmock_main awsmysqlodbca + myodbc-util + ${AWSSDK_LINK_LIBRARIES} ) + include(GoogleTest) -gtest_discover_tests(unit_testing PROPERTIES DISCOVERY_TIMEOUT 30) +#gtest_discover_tests(unit_testing PROPERTIES DISCOVERY_TIMEOUT 30) set_target_properties(unit_testing PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) diff --git a/unit_testing/test_utils.cc b/unit_testing/test_utils.cc index c614881c8..3924da787 100644 --- a/unit_testing/test_utils.cc +++ b/unit_testing/test_utils.cc @@ -29,6 +29,9 @@ #include "test_utils.h" +//std::unordered_map IAM_PROXY::token_cache; +//std::map, Aws::Utils::Json::JsonValue> SECRETS_MANAGER_PROXY::secrets_cache; + void allocate_odbc_handles(SQLHENV& env, DBC*& dbc, DataSource*& ds) { SQLHDBC hdbc = nullptr; @@ -116,7 +119,7 @@ std::string TEST_UTILS::build_cache_key(const char* host, const char* region, un } bool TEST_UTILS::token_cache_contains_key(std::string cache_key) { - return IAM_PROXY::token_cache.find(cache_key) != IAM_PROXY::token_cache.end(); + return IAM_PROXY::get_token_cache().find(cache_key) != IAM_PROXY::get_token_cache().end(); } void TEST_UTILS::clear_token_cache(IAM_PROXY &iam_proxy) { @@ -124,7 +127,7 @@ void TEST_UTILS::clear_token_cache(IAM_PROXY &iam_proxy) { } std::map, Aws::Utils::Json::JsonValue>& TEST_UTILS::get_secrets_cache() { - return std::ref(SECRETS_MANAGER_PROXY::secrets_cache); + return std::ref(SECRETS_MANAGER_PROXY::get_secrets_cache()); } bool TEST_UTILS::try_parse_region_from_secret(std::string secret, std::string& region) {