From 1640e6eef3ef675e2fc6f14d4e23d5908562d2fc Mon Sep 17 00:00:00 2001 From: justing-bq <62349012+justing-bq@users.noreply.github.com> Date: Tue, 10 Feb 2026 16:17:44 -0800 Subject: [PATCH 1/2] Handle mock setup/teardown at test suite level --- .../flight/sql/odbc/tests/columns_test.cc | 74 ++++++++++++++----- .../flight/sql/odbc/tests/odbc_test_suite.cc | 40 +++++----- .../flight/sql/odbc/tests/odbc_test_suite.h | 26 ++++--- .../flight/sql/odbc/tests/tables_test.cc | 24 ++++-- 4 files changed, 113 insertions(+), 51 deletions(-) diff --git a/cpp/src/arrow/flight/sql/odbc/tests/columns_test.cc b/cpp/src/arrow/flight/sql/odbc/tests/columns_test.cc index 0eeff7d4d2c..a3e40bf4f1d 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/columns_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/columns_test.cc @@ -580,7 +580,7 @@ TEST_F(ColumnsMockTest, TestSQLColumnsAllTypes) { // octet length from column size. // Checks filtering table with table name pattern - this->CreateTableAllDataType(); + CreateAllDataTypeTable(); // Attempt to get all columns from AllTypesTable SQLWCHAR table_pattern[] = L"AllTypesTable"; @@ -675,13 +675,15 @@ TEST_F(ColumnsMockTest, TestSQLColumnsAllTypes) { // There should be no more column data ASSERT_EQ(SQL_NO_DATA, SQLFetch(this->stmt)); + + DropAllDataTypeTable(); } TEST_F(ColumnsMockTest, TestSQLColumnsUnicode) { // Limitation: Mock server returns incorrect values for column size for some columns. // For character and binary type columns, the driver calculates buffer length and char // octet length from column size. - this->CreateUnicodeTable(); + CreateUnicodeTable(); // Attempt to get all columns SQLWCHAR table_pattern[] = L"数据"; @@ -713,6 +715,8 @@ TEST_F(ColumnsMockTest, TestSQLColumnsUnicode) { // There should be no more column data EXPECT_EQ(SQL_NO_DATA, SQLFetch(this->stmt)); + + DropUnicodeTable(); } TEST_F(ColumnsRemoteTest, TestSQLColumnsAllTypes) { @@ -1313,7 +1317,7 @@ TYPED_TEST(ColumnsTest, SQLColAttributeInvalidColId) { } TEST_F(ColumnsMockTest, TestSQLColAttributeAllTypes) { - this->CreateTableAllDataType(); + CreateAllDataTypeTable(); std::wstring wsql = L"SELECT * from AllTypesTable;"; std::vector sql0(wsql.begin(), wsql.end()); @@ -1390,13 +1394,15 @@ TEST_F(ColumnsMockTest, TestSQLColAttributeAllTypes) { 8, // expected_octet_length SQL_PRED_NONE, // expected_searchable SQL_FALSE); // expected_unsigned_column + + DropAllDataTypeTable(); } // iODBC does not support SQLColAttributes for ODBC 3.0 attributes. #ifndef __APPLE__ TEST_F(ColumnsOdbcV2MockTest, TestSQLColAttributesAllTypes) { // Tests ODBC 2.0 API SQLColAttributes - this->CreateTableAllDataType(); + CreateAllDataTypeTable(); std::wstring wsql = L"SELECT * from AllTypesTable;"; std::vector sql0(wsql.begin(), wsql.end()); @@ -1452,6 +1458,8 @@ TEST_F(ColumnsOdbcV2MockTest, TestSQLColAttributesAllTypes) { SQL_NULLABLE, // expected_column_nullability SQL_PRED_NONE, // expected_searchable SQL_FALSE); // expected_unsigned_column + + DropAllDataTypeTable(); } #endif // __APPLE__ @@ -1787,7 +1795,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributeAllTypesODBCVer2) { } // iODBC does not support SQLColAttributes for ODBC 3.0 attributes. -TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesAllTypesODBCVer2) { +TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesAllTypes) { // Tests ODBC 2.0 API SQLColAttributes // Test assumes there is a table $scratch.ODBCTest in remote server std::wstring wsql = L"SELECT * from $scratch.ODBCTest;"; @@ -1942,12 +1950,14 @@ TYPED_TEST(ColumnsOdbcV2Test, TestSQLColAttributesCaseSensitive) { TEST_F(ColumnsMockTest, TestSQLColAttributeUniqueValue) { // Mock server limitation: returns false for auto-increment column - this->CreateTableAllDataType(); + CreateAllDataTypeTable(); std::wstring wsql = L"SELECT * from AllTypesTable;"; SQLLEN value; GetSQLColAttributeNumeric(this->stmt, wsql, 1, SQL_DESC_AUTO_UNIQUE_VALUE, &value); ASSERT_EQ(SQL_FALSE, value); + + DropAllDataTypeTable(); } // iODBC does not support SQLColAttributes for ODBC 3.0 attributes. @@ -1955,46 +1965,54 @@ TEST_F(ColumnsMockTest, TestSQLColAttributeUniqueValue) { TEST_F(ColumnsOdbcV2MockTest, TestSQLColAttributesAutoIncrement) { // Tests ODBC 2.0 API SQLColAttributes // Mock server limitation: returns false for auto-increment column - this->CreateTableAllDataType(); + CreateAllDataTypeTable(); std::wstring wsql = L"SELECT * from AllTypesTable;"; SQLLEN value; GetSQLColAttributeNumeric(this->stmt, wsql, 1, SQL_COLUMN_AUTO_INCREMENT, &value); ASSERT_EQ(SQL_FALSE, value); + + DropAllDataTypeTable(); } #endif // __APPLE__ TEST_F(ColumnsMockTest, TestSQLColAttributeBaseTableName) { - this->CreateTableAllDataType(); + CreateAllDataTypeTable(); std::wstring wsql = L"SELECT * from AllTypesTable;"; std::wstring value; GetSQLColAttributeString(this->stmt, wsql, 1, SQL_DESC_BASE_TABLE_NAME, value); ASSERT_EQ(std::wstring(L"AllTypesTable"), value); + + DropAllDataTypeTable(); } // iODBC does not support SQLColAttributes for ODBC 3.0 attributes. #ifndef __APPLE__ TEST_F(ColumnsOdbcV2MockTest, TestSQLColAttributesTableName) { // Tests ODBC 2.0 API SQLColAttributes - this->CreateTableAllDataType(); + CreateAllDataTypeTable(); std::wstring wsql = L"SELECT * from AllTypesTable;"; std::wstring value; GetSQLColAttributesString(this->stmt, wsql, 1, SQL_COLUMN_TABLE_NAME, value); ASSERT_EQ(std::wstring(L"AllTypesTable"), value); + + DropAllDataTypeTable(); } #endif // __APPLE__ TEST_F(ColumnsMockTest, TestSQLColAttributeCatalogName) { // Mock server limitattion: mock doesn't return catalog for result metadata, // and the defautl catalog should be 'main' - this->CreateTableAllDataType(); + CreateAllDataTypeTable(); std::wstring wsql = L"SELECT * from AllTypesTable;"; std::wstring value; GetSQLColAttributeString(this->stmt, wsql, 1, SQL_DESC_CATALOG_NAME, value); ASSERT_EQ(std::wstring(L""), value); + + DropAllDataTypeTable(); } TEST_F(ColumnsRemoteTest, TestSQLColAttributeCatalogName) { @@ -2012,12 +2030,14 @@ TEST_F(ColumnsOdbcV2MockTest, TestSQLColAttributesQualifierName) { // Mock server limitattion: mock doesn't return catalog for result metadata, // and the defautl catalog should be 'main' // Tests ODBC 2.0 API SQLColAttributes - this->CreateTableAllDataType(); + CreateAllDataTypeTable(); std::wstring wsql = L"SELECT * from AllTypesTable;"; std::wstring value; GetSQLColAttributeString(this->stmt, wsql, 1, SQL_COLUMN_QUALIFIER_NAME, value); ASSERT_EQ(std::wstring(L""), value); + + DropAllDataTypeTable(); } TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesQualifierName) { @@ -2054,13 +2074,15 @@ TEST_F(ColumnsRemoteTest, TestSQLColAttributeLocalTypeName) { } TEST_F(ColumnsMockTest, TestSQLColAttributeSchemaName) { - this->CreateTableAllDataType(); + CreateAllDataTypeTable(); std::wstring wsql = L"SELECT * from AllTypesTable;"; // Mock server doesn't have schemas std::wstring value; GetSQLColAttributeString(this->stmt, wsql, 1, SQL_DESC_SCHEMA_NAME, value); ASSERT_EQ(std::wstring(L""), value); + + DropAllDataTypeTable(); } TEST_F(ColumnsRemoteTest, TestSQLColAttributeSchemaName) { @@ -2078,13 +2100,15 @@ TEST_F(ColumnsRemoteTest, TestSQLColAttributeSchemaName) { #ifndef __APPLE__ TEST_F(ColumnsOdbcV2MockTest, TestSQLColAttributesOwnerName) { // Tests ODBC 2.0 API SQLColAttributes - this->CreateTableAllDataType(); + CreateAllDataTypeTable(); std::wstring wsql = L"SELECT * from AllTypesTable;"; // Mock server doesn't have schemas std::wstring value; GetSQLColAttributesString(this->stmt, wsql, 1, SQL_COLUMN_OWNER_NAME, value); ASSERT_EQ(std::wstring(L""), value); + + DropAllDataTypeTable(); } TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesOwnerName) { @@ -2100,16 +2124,18 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesOwnerName) { #endif // __APPLE__ TEST_F(ColumnsMockTest, TestSQLColAttributeTableName) { - this->CreateTableAllDataType(); + CreateAllDataTypeTable(); std::wstring wsql = L"SELECT * from AllTypesTable;"; std::wstring value; GetSQLColAttributeString(this->stmt, wsql, 1, SQL_DESC_TABLE_NAME, value); ASSERT_EQ(std::wstring(L"AllTypesTable"), value); + + DropAllDataTypeTable(); } TEST_F(ColumnsMockTest, TestSQLColAttributeTypeName) { - this->CreateTableAllDataType(); + CreateAllDataTypeTable(); std::wstring wsql = L"SELECT * from AllTypesTable;"; std::wstring value; @@ -2121,6 +2147,8 @@ TEST_F(ColumnsMockTest, TestSQLColAttributeTypeName) { ASSERT_EQ(std::wstring(L"BINARY"), value); GetSQLColAttributeString(this->stmt, L"", 4, SQL_DESC_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"DOUBLE"), value); + + DropAllDataTypeTable(); } TEST_F(ColumnsRemoteTest, TestSQLColAttributeTypeName) { @@ -2150,7 +2178,7 @@ TEST_F(ColumnsRemoteTest, TestSQLColAttributeTypeName) { #ifndef __APPLE__ TEST_F(ColumnsOdbcV2MockTest, TestSQLColAttributesTypeName) { // Tests ODBC 2.0 API SQLColAttributes - this->CreateTableAllDataType(); + CreateAllDataTypeTable(); std::wstring wsql = L"SELECT * from AllTypesTable;"; // Mock server doesn't return data source-dependent data type name @@ -2163,6 +2191,8 @@ TEST_F(ColumnsOdbcV2MockTest, TestSQLColAttributesTypeName) { ASSERT_EQ(std::wstring(L"BINARY"), value); GetSQLColAttributesString(this->stmt, L"", 4, SQL_COLUMN_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"DOUBLE"), value); + + DropAllDataTypeTable(); } TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesTypeName) { @@ -2218,7 +2248,7 @@ TYPED_TEST(ColumnsOdbcV2Test, TestSQLColAttributesUpdatable) { #endif // __APPLE__ TEST_F(ColumnsMockTest, SQLDescribeColValidateInput) { - this->CreateTestTables(); + CreateTestTable(); SQLWCHAR sql_query[] = L"SELECT * FROM TestTable LIMIT 1;"; SQLINTEGER query_length = static_cast(wcslen(sql_query)); @@ -2261,6 +2291,8 @@ TEST_F(ColumnsMockTest, SQLDescribeColValidateInput) { buf_char_len, &name_length, &data_type, &column_size, &decimal_digits, &nullable)); VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState07009); + + DropTestTable(); } TEST_F(ColumnsMockTest, SQLDescribeColQueryAllDataTypesMetadata) { @@ -2555,7 +2587,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, SQLDescribeColODBCTestTableMetadataODBCVer2) { } TEST_F(ColumnsMockTest, SQLDescribeColAllTypesTableMetadata) { - this->CreateTableAllDataType(); + CreateAllDataTypeTable(); SQLWCHAR column_name[1024]; SQLSMALLINT buf_char_len = @@ -2603,10 +2635,12 @@ TEST_F(ColumnsMockTest, SQLDescribeColAllTypesTableMetadata) { decimal_digits = 0; nullable = 0; } + + DropAllDataTypeTable(); } TEST_F(ColumnsMockTest, SQLDescribeColUnicodeTableMetadata) { - this->CreateUnicodeTable(); + CreateUnicodeTable(); SQLWCHAR column_name[1024]; SQLSMALLINT buf_char_len = @@ -2641,6 +2675,8 @@ TEST_F(ColumnsMockTest, SQLDescribeColUnicodeTableMetadata) { EXPECT_EQ(column_size, expected_column_size); EXPECT_EQ(0, decimal_digits); EXPECT_EQ(SQL_NULLABLE, nullable); + + DropUnicodeTable(); } TYPED_TEST(ColumnsTest, SQLColumnsGetMetadataBySQLDescribeCol) { 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 d35713581cd..800f32f7922 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 @@ -305,7 +305,7 @@ std::wstring ODBCMockTestBase::GetQueryAllDataTypes() { return wsql; } -void ODBCMockTestBase::CreateTestTables() { +void ODBCMockTestBase::CreateTestTable() { ASSERT_OK(server_->ExecuteSql(R"( CREATE TABLE TestTable ( id INTEGER PRIMARY KEY AUTOINCREMENT, @@ -318,7 +318,11 @@ void ODBCMockTestBase::CreateTestTables() { )")); } -void ODBCMockTestBase::CreateTableAllDataType() { +void ODBCMockTestBase::DropTestTable() { + ASSERT_OK(server_->ExecuteSql("DROP TABLE TestTable;")); +} + +void ODBCMockTestBase::CreateAllDataTypeTable() { // Limitation on mock SQLite server: // Only int64, float64, binary, and utf8 Arrow Types are supported by // SQLiteFlightSqlServer::Impl::DoGetTables @@ -340,6 +344,10 @@ void ODBCMockTestBase::CreateTableAllDataType() { )")); } +void ODBCMockTestBase::DropAllDataTypeTable() { + ASSERT_OK(server_->ExecuteSql("DROP TABLE AllTypesTable;")); +} + void ODBCMockTestBase::CreateUnicodeTable() { std::string unicode_sql = arrow::util::WideStringToUTF8( LR"( @@ -354,7 +362,13 @@ void ODBCMockTestBase::CreateUnicodeTable() { ASSERT_OK(server_->ExecuteSql(unicode_sql)); } -void ODBCMockTestBase::SetUp() { +void ODBCMockTestBase::DropUnicodeTable() { + std::string unicode_sql = + arrow::util::WideStringToUTF8(L"DROP TABLE 数据;").ValueOr(""); + ASSERT_OK(server_->ExecuteSql(unicode_sql)); +} + +void FlightSQLODBCMockTestBase::SetUpTestSuite() { ASSERT_OK_AND_ASSIGN(auto location, Location::ForGrpcTcp("0.0.0.0", 0)); arrow::flight::FlightServerOptions options(location); options.auth_handler = std::make_unique(); @@ -369,35 +383,29 @@ void ODBCMockTestBase::SetUp() { ASSERT_OK_AND_ASSIGN(auto client, arrow::flight::FlightClient::Connect(location)); } +void FlightSQLODBCMockTestBase::TearDownTestSuite() { + ASSERT_OK(server_->Shutdown()); + ASSERT_OK(server_->Wait()); +} + void FlightSQLODBCMockTestBase::SetUp() { - 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; } - ODBCMockTestBase::TearDown(); } void FlightSQLOdbcV2MockTestBase::SetUp() { - ODBCMockTestBase::SetUp(); this->Connect(SQL_OV_ODBC2); connected_ = true; } -void FlightSQLOdbcEnvConnHandleMockTestBase::SetUp() { - ODBCMockTestBase::SetUp(); - AllocEnvConnHandles(); -} +void FlightSQLOdbcEnvConnHandleMockTestBase::SetUp() { AllocEnvConnHandles(); } void FlightSQLOdbcEnvConnHandleMockTestBase::TearDown() { // Free connection handle @@ -405,8 +413,6 @@ void FlightSQLOdbcEnvConnHandleMockTestBase::TearDown() { // Free environment handle EXPECT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_ENV, env)); - - ASSERT_OK(server_->Shutdown()); } bool CompareConnPropertyMap(Connection::ConnPropertyMap map1, 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 2de951690b1..3a19e860a31 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 @@ -164,21 +164,25 @@ class ODBCMockTestBase : public FlightSQLODBCRemoteTestBase { std::wstring GetQueryAllDataTypes() override; /// \brief Run a SQL query to create default table for table test cases - void CreateTestTables(); + static void CreateTestTable(); + /// \brief Run a SQL query to drop default table for table test cases + static void DropTestTable(); /// \brief run a SQL query to create a table with all data types - void CreateTableAllDataType(); + static void CreateAllDataTypeTable(); + /// \brief run a SQL query to drop a table with all data types + static void DropAllDataTypeTable(); + /// \brief run a SQL query to create a table with unicode name - void CreateUnicodeTable(); + static void CreateUnicodeTable(); + /// \brief run a SQL query to drop a table with unicode name + static void DropUnicodeTable(); - int port; + inline static int port = 0; protected: - void SetUp() override; - - void TearDown() override; - - std::shared_ptr server_; + inline static std::shared_ptr + server_; }; /// \brief Base test fixture for running tests against a mock server. @@ -186,6 +190,10 @@ class ODBCMockTestBase : public FlightSQLODBCRemoteTestBase { /// fixture inheriting from this base fixture. class FlightSQLODBCMockTestBase : public ODBCMockTestBase { protected: + static void SetUpTestSuite(); + + static void TearDownTestSuite(); + void SetUp() override; void TearDown() override; diff --git a/cpp/src/arrow/flight/sql/odbc/tests/tables_test.cc b/cpp/src/arrow/flight/sql/odbc/tests/tables_test.cc index db9a55cf161..ede705724be 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/tables_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/tables_test.cc @@ -99,7 +99,7 @@ TEST_F(TablesMockTest, SQLTablesTestGetMetadataForAllCatalogs) { } TEST_F(TablesMockTest, SQLTablesTestGetMetadataForNamedCatalog) { - this->CreateTestTables(); + CreateTestTable(); SQLWCHAR catalog_name[] = L"main"; const SQLWCHAR* table_names[] = {static_cast(L"TestTable"), @@ -126,6 +126,8 @@ TEST_F(TablesMockTest, SQLTablesTestGetMetadataForNamedCatalog) { } ValidateFetch(this->stmt, SQL_NO_DATA); + + DropTestTable(); } TEST_F(TablesMockTest, SQLTablesTestGetSchemaHasNoData) { @@ -252,7 +254,7 @@ TEST_F(TablesRemoteTest, SQLTablesGetMetadataForNamedSchema) { } TEST_F(TablesMockTest, SQLTablesTestGetMetadataForAllTables) { - this->CreateTestTables(); + CreateTestTable(); SQLWCHAR SQL_ALL_TABLES_W[] = L"%"; const SQLWCHAR* table_names[] = {static_cast(L"TestTable"), @@ -279,10 +281,12 @@ TEST_F(TablesMockTest, SQLTablesTestGetMetadataForAllTables) { } ValidateFetch(this->stmt, SQL_NO_DATA); + + DropTestTable(); } TEST_F(TablesMockTest, SQLTablesTestGetMetadataForTableName) { - this->CreateTestTables(); + CreateTestTable(); // Use mutable arrays to pass SQLWCHAR parameters to SQLTables SQLWCHAR test_table[] = L"TestTable"; @@ -311,10 +315,12 @@ TEST_F(TablesMockTest, SQLTablesTestGetMetadataForTableName) { ValidateFetch(this->stmt, SQL_NO_DATA); } + + DropTestTable(); } TEST_F(TablesMockTest, SQLTablesTestGetMetadataForUnicodeTableByTableName) { - this->CreateUnicodeTable(); + CreateUnicodeTable(); SQLWCHAR unicodetable_name[] = L"数据"; std::wstring expected_catalog_name = std::wstring(L"main"); @@ -335,10 +341,12 @@ TEST_F(TablesMockTest, SQLTablesTestGetMetadataForUnicodeTableByTableName) { CheckNullColumnW(this->stmt, 5); ValidateFetch(this->stmt, SQL_NO_DATA); + + DropUnicodeTable(); } TEST_F(TablesMockTest, SQLTablesTestGetMetadataForInvalidTableNameNoData) { - this->CreateTestTables(); + CreateTestTable(); SQLWCHAR invalid_table_name[] = L"NonExistenttable_name"; @@ -347,11 +355,13 @@ TEST_F(TablesMockTest, SQLTablesTestGetMetadataForInvalidTableNameNoData) { invalid_table_name, SQL_NTS, nullptr, SQL_NTS)); ValidateFetch(this->stmt, SQL_NO_DATA); + + DropTestTable(); } TEST_F(TablesMockTest, SQLTablesGetMetadataForTableType) { // Mock server only supports table type "table" in lowercase - this->CreateTestTables(); + CreateTestTable(); SQLWCHAR table_type_table_lowercase[] = L"table"; SQLWCHAR table_type_table_uppercase[] = L"TABLE"; @@ -398,6 +408,8 @@ TEST_F(TablesMockTest, SQLTablesGetMetadataForTableType) { } ValidateFetch(this->stmt, SQL_NO_DATA); + + DropTestTable(); } TEST_F(TablesRemoteTest, SQLTablesGetMetadataForTableTypeTable) { From 2922812d99e1f080d55e3895bb3a07b154814fc4 Mon Sep 17 00:00:00 2001 From: justing-bq <62349012+justing-bq@users.noreply.github.com> Date: Wed, 11 Feb 2026 11:36:49 -0800 Subject: [PATCH 2/2] Define Mock Server SetUp/TearDown at Environment level --- ci/scripts/cpp_test.sh | 1 - .../flight/sql/odbc/tests/odbc_test_suite.cc | 63 +++++++++++-------- .../flight/sql/odbc/tests/odbc_test_suite.h | 10 --- 3 files changed, 36 insertions(+), 38 deletions(-) diff --git a/ci/scripts/cpp_test.sh b/ci/scripts/cpp_test.sh index 88239a0bd1e..5d6d5e099ab 100755 --- a/ci/scripts/cpp_test.sh +++ b/ci/scripts/cpp_test.sh @@ -59,7 +59,6 @@ case "$(uname)" in ;; Darwin) n_jobs=$(sysctl -n hw.ncpu) - exclude_tests+=("arrow-flight-sql-odbc-test") # TODO: https://github.com/apache/arrow/issues/40410 exclude_tests+=("arrow-s3fs-test") ;; 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 800f32f7922..866aae5bf48 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 @@ -26,8 +26,37 @@ #include "arrow/flight/sql/odbc/odbc_impl/encoding_utils.h" #include "arrow/flight/sql/odbc/odbc_impl/odbc_connection.h" +std::shared_ptr mock_server; +int mock_server_port = 0; + namespace arrow::flight::sql::odbc { +class MockServerEnvironment : public ::testing::Environment { + public: + void SetUp() override { + ASSERT_OK_AND_ASSIGN(auto location, Location::ForGrpcTcp("0.0.0.0", 0)); + arrow::flight::FlightServerOptions options(location); + options.auth_handler = std::make_unique(); + options.middleware.push_back( + {"bearer-auth-server", std::make_shared()}); + ASSERT_OK_AND_ASSIGN(mock_server, + arrow::flight::sql::example::SQLiteFlightSqlServer::Create()); + ASSERT_OK(mock_server->Init(options)); + + mock_server_port = mock_server->port(); + ASSERT_OK_AND_ASSIGN(location, Location::ForGrpcTcp("localhost", mock_server_port)); + ASSERT_OK_AND_ASSIGN(auto client, arrow::flight::FlightClient::Connect(location)); + } + + void TearDown() override { + ASSERT_OK(mock_server->Shutdown()); + ASSERT_OK(mock_server->Wait()); + } +}; + +::testing::Environment* mock_env = + ::testing::AddGlobalTestEnvironment(new MockServerEnvironment); + void ODBCRemoteTestBase::AllocEnvConnHandles(SQLINTEGER odbc_ver) { // Allocate an environment handle ASSERT_EQ(SQL_SUCCESS, SQLAllocEnv(&env)); @@ -244,7 +273,7 @@ Status MockServerMiddlewareFactory::StartCall( 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) + + std::to_string(mock_server_port) + ";token=" + std::string(kTestToken) + ";useEncryption=false;UseWideChar=true;"); return connect_str; } @@ -306,7 +335,7 @@ std::wstring ODBCMockTestBase::GetQueryAllDataTypes() { } void ODBCMockTestBase::CreateTestTable() { - ASSERT_OK(server_->ExecuteSql(R"( + ASSERT_OK(mock_server->ExecuteSql(R"( CREATE TABLE TestTable ( id INTEGER PRIMARY KEY AUTOINCREMENT, keyName varchar(100), @@ -319,14 +348,14 @@ void ODBCMockTestBase::CreateTestTable() { } void ODBCMockTestBase::DropTestTable() { - ASSERT_OK(server_->ExecuteSql("DROP TABLE TestTable;")); + ASSERT_OK(mock_server->ExecuteSql("DROP TABLE TestTable;")); } void ODBCMockTestBase::CreateAllDataTypeTable() { // Limitation on mock SQLite server: // Only int64, float64, binary, and utf8 Arrow Types are supported by // SQLiteFlightSqlServer::Impl::DoGetTables - ASSERT_OK(server_->ExecuteSql(R"( + ASSERT_OK(mock_server->ExecuteSql(R"( CREATE TABLE AllTypesTable( bigint_col INTEGER PRIMARY KEY AUTOINCREMENT, char_col varchar(100), @@ -345,7 +374,7 @@ void ODBCMockTestBase::CreateAllDataTypeTable() { } void ODBCMockTestBase::DropAllDataTypeTable() { - ASSERT_OK(server_->ExecuteSql("DROP TABLE AllTypesTable;")); + ASSERT_OK(mock_server->ExecuteSql("DROP TABLE AllTypesTable;")); } void ODBCMockTestBase::CreateUnicodeTable() { @@ -359,33 +388,13 @@ void ODBCMockTestBase::CreateUnicodeTable() { INSERT INTO 数据 (资料) VALUES ('3rd Row'); )") .ValueOr(""); - ASSERT_OK(server_->ExecuteSql(unicode_sql)); + ASSERT_OK(mock_server->ExecuteSql(unicode_sql)); } void ODBCMockTestBase::DropUnicodeTable() { std::string unicode_sql = arrow::util::WideStringToUTF8(L"DROP TABLE 数据;").ValueOr(""); - ASSERT_OK(server_->ExecuteSql(unicode_sql)); -} - -void FlightSQLODBCMockTestBase::SetUpTestSuite() { - ASSERT_OK_AND_ASSIGN(auto location, Location::ForGrpcTcp("0.0.0.0", 0)); - arrow::flight::FlightServerOptions options(location); - options.auth_handler = std::make_unique(); - options.middleware.push_back( - {"bearer-auth-server", std::make_shared()}); - ASSERT_OK_AND_ASSIGN(server_, - arrow::flight::sql::example::SQLiteFlightSqlServer::Create()); - ASSERT_OK(server_->Init(options)); - - port = server_->port(); - ASSERT_OK_AND_ASSIGN(location, Location::ForGrpcTcp("localhost", port)); - ASSERT_OK_AND_ASSIGN(auto client, arrow::flight::FlightClient::Connect(location)); -} - -void FlightSQLODBCMockTestBase::TearDownTestSuite() { - ASSERT_OK(server_->Shutdown()); - ASSERT_OK(server_->Wait()); + ASSERT_OK(mock_server->ExecuteSql(unicode_sql)); } void FlightSQLODBCMockTestBase::SetUp() { 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 3a19e860a31..90e837bfd03 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 @@ -177,12 +177,6 @@ class ODBCMockTestBase : public FlightSQLODBCRemoteTestBase { static void CreateUnicodeTable(); /// \brief run a SQL query to drop a table with unicode name static void DropUnicodeTable(); - - inline static int port = 0; - - protected: - inline static std::shared_ptr - server_; }; /// \brief Base test fixture for running tests against a mock server. @@ -190,10 +184,6 @@ class ODBCMockTestBase : public FlightSQLODBCRemoteTestBase { /// fixture inheriting from this base fixture. class FlightSQLODBCMockTestBase : public ODBCMockTestBase { protected: - static void SetUpTestSuite(); - - static void TearDownTestSuite(); - void SetUp() override; void TearDown() override;