diff --git a/cpp/src/arrow/flight/sql/odbc/tests/connection_test.cc b/cpp/src/arrow/flight/sql/odbc/tests/connection_test.cc index 9488d62af31d..5bd7caf06d60 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/connection_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/connection_test.cc @@ -222,7 +222,7 @@ TEST(SQLSetEnvAttr, TestSQLSetEnvAttrNullValuePointer) { ASSERT_EQ(SQL_SUCCESS, SQLFreeEnv(env)); } -TYPED_TEST(ConnectionTest, TestSQLDriverConnect) { +TYPED_TEST(ODBCTestBase, TestSQLDriverConnect) { SQLHENV env; SQLHDBC conn; @@ -272,7 +272,7 @@ TYPED_TEST(ConnectionTest, TestSQLDriverConnect) { } #if defined _WIN32 -TYPED_TEST(ConnectionTest, TestSQLDriverConnectDsn) { +TYPED_TEST(ODBCTestBase, TestSQLDriverConnectDsn) { SQLHENV env; SQLHDBC conn; @@ -326,7 +326,7 @@ TYPED_TEST(ConnectionTest, TestSQLDriverConnectDsn) { ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_ENV, env)); } -TYPED_TEST(ConnectionTest, TestSQLConnect) { +TYPED_TEST(ODBCTestBase, TestSQLConnect) { SQLHENV env; SQLHDBC conn; @@ -376,7 +376,7 @@ TYPED_TEST(ConnectionTest, TestSQLConnect) { ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_ENV, env)); } -TEST_F(ConnectionRemoteTest, TestSQLConnectInputUidPwd) { +TEST_F(ODBCRemoteTestBase, TestSQLConnectInputUidPwd) { SQLHENV env; SQLHDBC conn; @@ -435,7 +435,7 @@ TEST_F(ConnectionRemoteTest, TestSQLConnectInputUidPwd) { ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_ENV, env)); } -TEST_F(ConnectionRemoteTest, TestSQLConnectInvalidUid) { +TEST_F(ODBCRemoteTestBase, TestSQLConnectInvalidUid) { SQLHENV env; SQLHDBC conn; @@ -492,7 +492,7 @@ TEST_F(ConnectionRemoteTest, TestSQLConnectInvalidUid) { ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_ENV, env)); } -TEST_F(ConnectionRemoteTest, TestSQLConnectDSNPrecedence) { +TEST_F(ODBCRemoteTestBase, TestSQLConnectDSNPrecedence) { SQLHENV env; SQLHDBC conn; @@ -547,7 +547,7 @@ TEST_F(ConnectionRemoteTest, TestSQLConnectDSNPrecedence) { #endif -TEST_F(ConnectionRemoteTest, TestSQLDriverConnectInvalidUid) { +TEST_F(ODBCRemoteTestBase, TestSQLDriverConnectInvalidUid) { SQLHENV env; SQLHDBC conn; @@ -634,7 +634,7 @@ TYPED_TEST(ConnectionTest, TestSQLAllocFreeStmt) { ASSERT_EQ(SQL_SUCCESS, SQLFreeStmt(statement, SQL_DROP)); } -TYPED_TEST(ConnectionTest, TestCloseConnectionWithOpenStatement) { +TYPED_TEST(ODBCTestBase, TestCloseConnectionWithOpenStatement) { SQLHENV env; SQLHDBC conn; SQLHSTMT statement; diff --git a/cpp/src/arrow/flight/sql/odbc/tests/errors_test.cc b/cpp/src/arrow/flight/sql/odbc/tests/errors_test.cc index 2da626e505b4..7515a74753f6 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/errors_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/errors_test.cc @@ -46,7 +46,7 @@ using TestTypesOdbcV2 = ::testing::Types; TYPED_TEST_SUITE(ErrorsOdbcV2Test, TestTypesOdbcV2); -TYPED_TEST(ErrorsTest, TestSQLGetDiagFieldWForConnectFailure) { +TYPED_TEST(ODBCTestBase, TestSQLGetDiagFieldWForConnectFailure) { // ODBC Environment SQLHENV env; SQLHDBC conn; @@ -137,7 +137,7 @@ TYPED_TEST(ErrorsTest, TestSQLGetDiagFieldWForConnectFailure) { EXPECT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_ENV, env)); } -TYPED_TEST(ErrorsTest, DISABLED_TestSQLGetDiagFieldWForConnectFailureNTS) { +TYPED_TEST(ODBCTestBase, DISABLED_TestSQLGetDiagFieldWForConnectFailureNTS) { // Test is disabled because driver manager on Windows does not pass through SQL_NTS // This test case can be potentially used on macOS/Linux SQLHENV env; @@ -287,7 +287,7 @@ TYPED_TEST(ErrorsTest, TestSQLGetDiagRecForDescriptorFailureFromDriverManager) { EXPECT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_DESC, descriptor)); } -TYPED_TEST(ErrorsTest, TestSQLGetDiagRecForConnectFailure) { +TYPED_TEST(ODBCTestBase, TestSQLGetDiagRecForConnectFailure) { // ODBC Environment SQLHENV env; SQLHDBC conn; diff --git a/cpp/src/arrow/flight/sql/odbc/tests/odbc_test_suite.cc b/cpp/src/arrow/flight/sql/odbc/tests/odbc_test_suite.cc index 2e58c713289a..34346502aa02 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/odbc_test_suite.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/odbc_test_suite.cc @@ -28,7 +28,7 @@ namespace arrow::flight::sql::odbc { -void FlightSQLODBCRemoteTestBase::AllocEnvConnHandles(SQLINTEGER odbc_ver) { +void ODBCRemoteTestBase::AllocEnvConnHandles(SQLINTEGER odbc_ver) { // Allocate an environment handle ASSERT_EQ(SQL_SUCCESS, SQLAllocEnv(&env)); @@ -41,13 +41,13 @@ void FlightSQLODBCRemoteTestBase::AllocEnvConnHandles(SQLINTEGER odbc_ver) { ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DBC, env, &conn)); } -void FlightSQLODBCRemoteTestBase::Connect(SQLINTEGER odbc_ver) { +void ODBCRemoteTestBase::Connect(SQLINTEGER odbc_ver) { ASSERT_NO_FATAL_FAILURE(AllocEnvConnHandles(odbc_ver)); std::string connect_str = GetConnectionString(); ASSERT_NO_FATAL_FAILURE(ConnectWithString(connect_str)); } -void FlightSQLODBCRemoteTestBase::ConnectWithString(std::string connect_str) { +void ODBCRemoteTestBase::ConnectWithString(std::string connect_str) { // Connect string std::vector connect_str0(connect_str.begin(), connect_str.end()); @@ -65,7 +65,7 @@ void FlightSQLODBCRemoteTestBase::ConnectWithString(std::string connect_str) { ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_STMT, conn, &stmt)); } -void FlightSQLODBCRemoteTestBase::Disconnect() { +void ODBCRemoteTestBase::Disconnect() { // Close statement EXPECT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_STMT, stmt)); @@ -80,20 +80,20 @@ void FlightSQLODBCRemoteTestBase::Disconnect() { EXPECT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_ENV, env)); } -std::string FlightSQLODBCRemoteTestBase::GetConnectionString() { +std::string ODBCRemoteTestBase::GetConnectionString() { std::string connect_str = arrow::internal::GetEnvVar(kTestConnectStr.data()).ValueOrDie(); return connect_str; } -std::string FlightSQLODBCRemoteTestBase::GetInvalidConnectionString() { +std::string ODBCRemoteTestBase::GetInvalidConnectionString() { std::string connect_str = GetConnectionString(); // Append invalid uid to connection string connect_str += std::string("uid=non_existent_id;"); return connect_str; } -std::wstring FlightSQLODBCRemoteTestBase::GetQueryAllDataTypes() { +std::wstring ODBCRemoteTestBase::GetQueryAllDataTypes() { std::wstring wsql = LR"( SELECT -- Numeric types @@ -144,11 +144,14 @@ std::wstring FlightSQLODBCRemoteTestBase::GetQueryAllDataTypes() { return wsql; } -void FlightSQLODBCRemoteTestBase::SetUp() { +void ODBCRemoteTestBase::SetUp() { if (arrow::internal::GetEnvVar(kTestConnectStr.data()).ValueOr("").empty()) { GTEST_SKIP() << "Skipping test: kTestConnectStr not set"; } +} +void FlightSQLODBCRemoteTestBase::SetUp() { + ODBCRemoteTestBase::SetUp(); this->Connect(); connected_ = true; } @@ -161,10 +164,7 @@ void FlightSQLODBCRemoteTestBase::TearDown() { } void FlightSQLOdbcV2RemoteTestBase::SetUp() { - if (arrow::internal::GetEnvVar(kTestConnectStr.data()).ValueOr("").empty()) { - GTEST_SKIP() << "Skipping test: kTestConnectStr not set"; - } - + ODBCRemoteTestBase::SetUp(); this->Connect(SQL_OV_ODBC2); connected_ = true; } @@ -209,7 +209,7 @@ Status MockServerMiddlewareFactory::StartCall( return Status::OK(); } -std::string FlightSQLODBCMockTestBase::GetConnectionString() { +std::string ODBCMockTestBase::GetConnectionString() { std::string connect_str( "driver={Apache Arrow Flight SQL ODBC Driver};HOST=localhost;port=" + std::to_string(port) + ";token=" + std::string(kTestToken) + @@ -217,14 +217,14 @@ std::string FlightSQLODBCMockTestBase::GetConnectionString() { return connect_str; } -std::string FlightSQLODBCMockTestBase::GetInvalidConnectionString() { +std::string ODBCMockTestBase::GetInvalidConnectionString() { std::string connect_str = GetConnectionString(); // Append invalid token to connection string connect_str += std::string("token=invalid_token;"); return connect_str; } -std::wstring FlightSQLODBCMockTestBase::GetQueryAllDataTypes() { +std::wstring ODBCMockTestBase::GetQueryAllDataTypes() { std::wstring wsql = LR"( SELECT -- Numeric types @@ -273,7 +273,7 @@ std::wstring FlightSQLODBCMockTestBase::GetQueryAllDataTypes() { return wsql; } -void FlightSQLODBCMockTestBase::CreateTestTables() { +void ODBCMockTestBase::CreateTestTables() { ASSERT_OK(server_->ExecuteSql(R"( CREATE TABLE TestTable ( id INTEGER PRIMARY KEY AUTOINCREMENT, @@ -286,7 +286,7 @@ void FlightSQLODBCMockTestBase::CreateTestTables() { )")); } -void FlightSQLODBCMockTestBase::CreateTableAllDataType() { +void ODBCMockTestBase::CreateTableAllDataType() { // Limitation on mock SQLite server: // Only int64, float64, binary, and utf8 Arrow Types are supported by // SQLiteFlightSqlServer::Impl::DoGetTables @@ -308,7 +308,7 @@ void FlightSQLODBCMockTestBase::CreateTableAllDataType() { )")); } -void FlightSQLODBCMockTestBase::CreateUnicodeTable() { +void ODBCMockTestBase::CreateUnicodeTable() { std::string unicode_sql = arrow::util::WideStringToUTF8( LR"( CREATE TABLE 数据( @@ -322,7 +322,7 @@ void FlightSQLODBCMockTestBase::CreateUnicodeTable() { ASSERT_OK(server_->ExecuteSql(unicode_sql)); } -void FlightSQLODBCMockTestBase::Initialize() { +void ODBCMockTestBase::SetUp() { ASSERT_OK_AND_ASSIGN(auto location, Location::ForGrpcTcp("0.0.0.0", 0)); arrow::flight::FlightServerOptions options(location); options.auth_handler = std::make_unique(); @@ -338,21 +338,26 @@ void FlightSQLODBCMockTestBase::Initialize() { } void FlightSQLODBCMockTestBase::SetUp() { - this->Initialize(); + ODBCMockTestBase::SetUp(); this->Connect(); connected_ = true; } +void ODBCMockTestBase::TearDown() { + ASSERT_OK(server_->Shutdown()); + ASSERT_OK(server_->Wait()); +} + void FlightSQLODBCMockTestBase::TearDown() { if (connected_) { this->Disconnect(); connected_ = false; } - ASSERT_OK(server_->Shutdown()); + ODBCMockTestBase::TearDown(); } void FlightSQLOdbcV2MockTestBase::SetUp() { - this->Initialize(); + ODBCMockTestBase::SetUp(); this->Connect(SQL_OV_ODBC2); connected_ = true; } diff --git a/cpp/src/arrow/flight/sql/odbc/tests/odbc_test_suite.h b/cpp/src/arrow/flight/sql/odbc/tests/odbc_test_suite.h index e35e6c38f851..d02ed6cce964 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/odbc_test_suite.h +++ b/cpp/src/arrow/flight/sql/odbc/tests/odbc_test_suite.h @@ -42,11 +42,11 @@ static constexpr std::string_view kTestDsn = "Apache Arrow Flight SQL Test DSN"; namespace arrow::flight::sql::odbc { /// \brief Base test fixture for running tests against a remote server. -/// Each test file running remote server tests should define a -/// fixture inheriting from this base fixture. /// The connection string for connecting to this server is defined /// in the ARROW_FLIGHT_SQL_ODBC_CONN environment variable. -class FlightSQLODBCRemoteTestBase : public ::testing::Test { +/// Note that this fixture does not handle the driver's connection/disconnection +/// during SetUp/Teardown. +class ODBCRemoteTestBase : public ::testing::Test { public: /// \brief Allocate environment and connection handles void AllocEnvConnHandles(SQLINTEGER odbc_ver = SQL_OV_ODBC3); @@ -75,6 +75,16 @@ class FlightSQLODBCRemoteTestBase : public ::testing::Test { /** ODBC Statement. */ SQLHSTMT stmt = 0; + protected: + void SetUp() override; +}; + +/// \brief Base test fixture for running tests against a remote server. +/// Each test file running remote server tests should define a +/// fixture inheriting from this base fixture. +/// The connection string for connecting to this server is defined +/// in the ARROW_FLIGHT_SQL_ODBC_CONN environment variable. +class FlightSQLODBCRemoteTestBase : public ODBCRemoteTestBase { protected: void SetUp() override; @@ -129,9 +139,7 @@ class MockServerMiddlewareFactory : public ServerMiddlewareFactory { }; /// \brief Base test fixture for running tests against a mock server. -/// Each test file running mock server tests should define a -/// fixture inheriting from this base fixture. -class FlightSQLODBCMockTestBase : public FlightSQLODBCRemoteTestBase { +class ODBCMockTestBase : public FlightSQLODBCRemoteTestBase { // Sets up a mock server for each test case public: /// \brief Get connection string for mock server @@ -152,8 +160,6 @@ class FlightSQLODBCMockTestBase : public FlightSQLODBCRemoteTestBase { int port; protected: - void Initialize(); - void SetUp() override; void TearDown() override; @@ -162,6 +168,16 @@ class FlightSQLODBCMockTestBase : public FlightSQLODBCRemoteTestBase { std::shared_ptr server_; }; +/// \brief Base test fixture for running tests against a mock server. +/// Each test file running mock server tests should define a +/// fixture inheriting from this base fixture. +class FlightSQLODBCMockTestBase : public ODBCMockTestBase { + protected: + void SetUp() override; + + void TearDown() override; +}; + /// \brief Base test fixture for running ODBC V2 tests against a mock server. /// Each test file running mock server ODBC V2 tests should define a /// fixture inheriting from this base fixture. @@ -170,6 +186,11 @@ class FlightSQLOdbcV2MockTestBase : public FlightSQLODBCMockTestBase { void SetUp() override; }; +template +class ODBCTestBase : public T {}; +using OdbcBaseTestTypes = ::testing::Types; +TYPED_TEST_SUITE(ODBCTestBase, OdbcBaseTestTypes); + /** ODBC read buffer size. */ static constexpr int kOdbcBufferSize = 1024;