Skip to content

Commit f5a8910

Browse files
committed
Reuse connections across test suite
1 parent ccab11d commit f5a8910

5 files changed

Lines changed: 145 additions & 82 deletions

File tree

cpp/src/arrow/flight/sql/odbc/tests/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ set(ARROW_FLIGHT_SQL_ODBC_TEST_SRCS
4242
# GH-46889: move protobuf_test_util to a more common location
4343
../../../../engine/substrait/protobuf_test_util.cc)
4444

45+
# Resolve segmentation fault error on Windows platform due to Arrow Compute Library Initialization
46+
if(WIN32)
47+
list(APPEND ARROW_FLIGHT_SQL_ODBC_TEST_SRCS ../../../../compute/test_env.cc)
48+
endif()
49+
4550
# GH-49652: TODO support static test linkage on macOS
4651
if(ARROW_TEST_LINKAGE STREQUAL "static")
4752
set(ARROW_FLIGHT_SQL_ODBC_TEST_LINK_LIBS arrow_flight_sql_odbc_static

cpp/src/arrow/flight/sql/odbc/tests/connection_attr_test.cc

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,15 +87,18 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrEnlistInDtcUnsupported)
8787
}
8888

8989
TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrOdbcCursorsDMOnly) {
90-
this->AllocEnvConnHandles();
90+
SQLHENV test_env = SQL_NULL_HENV;
91+
SQLHDBC test_conn = SQL_NULL_HDBC;
92+
this->AllocEnvConnHandles(test_env, test_conn);
9193

9294
// Verify DM-only attribute is settable via Driver Manager
9395
ASSERT_EQ(SQL_SUCCESS,
94-
SQLSetConnectAttr(conn, SQL_ATTR_ODBC_CURSORS,
96+
SQLSetConnectAttr(test_conn, SQL_ATTR_ODBC_CURSORS,
9597
reinterpret_cast<SQLPOINTER>(SQL_CUR_USE_DRIVER), 0));
9698

9799
std::string connect_str = this->GetConnectionString();
98-
this->ConnectWithString(connect_str);
100+
this->ConnectWithString(connect_str, test_conn);
101+
this->Disconnect(test_env, test_conn);
99102
}
100103

101104
TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrQuietModeReadOnly) {

cpp/src/arrow/flight/sql/odbc/tests/connection_info_test.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoAlterTable) {
614614
TYPED_TEST(ConnectionInfoHandleTest, TestSQLGetInfoCatalogLocation) {
615615
// GH-49482 TODO: resolve inconsitent return value for SQL_CATALOG_LOCATION and change
616616
// test type to `ConnectionInfoTest`
617-
this->ConnectWithString(this->GetConnectionString());
617+
this->ConnectWithString(this->GetConnectionString(), conn);
618618

619619
SQLUSMALLINT value;
620620
GetInfo(conn, SQL_CATALOG_LOCATION, &value);
@@ -750,7 +750,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDropDomain) {
750750
TYPED_TEST(ConnectionInfoHandleTest, TestSQLGetInfoDropSchema) {
751751
// GH-49482 TODO: resolve inconsitent return value for SQL_DROP_SCHEMA and change test
752752
// type to `ConnectionInfoTest`
753-
this->ConnectWithString(this->GetConnectionString());
753+
this->ConnectWithString(this->GetConnectionString(), conn);
754754

755755
SQLUINTEGER value;
756756
GetInfo(conn, SQL_DROP_SCHEMA, &value);
@@ -764,7 +764,7 @@ TYPED_TEST(ConnectionInfoHandleTest, TestSQLGetInfoDropSchema) {
764764
TYPED_TEST(ConnectionInfoHandleTest, TestSQLGetInfoDropTable) {
765765
// GH-49482 TODO: resolve inconsitent return value for SQL_DROP_TABLE and change test
766766
// type to `ConnectionInfoTest`
767-
this->ConnectWithString(this->GetConnectionString());
767+
this->ConnectWithString(this->GetConnectionString(), conn);
768768

769769
SQLUINTEGER value;
770770
GetInfo(conn, SQL_DROP_TABLE, &value);

cpp/src/arrow/flight/sql/odbc/tests/odbc_test_suite.cc

Lines changed: 103 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -51,28 +51,64 @@ class MockServerEnvironment : public ::testing::Environment {
5151
}
5252
};
5353

54-
::testing::Environment* mock_env =
54+
bool RunningRemoteTests() { return !remote_test_connect_str.empty(); }
55+
56+
class OdbcTestEnvironment : public ::testing::Environment {
57+
public:
58+
void SetUp() override {
59+
remote_test_connect_str = ODBCTestBase::GetConnectionString();
60+
if (RunningRemoteTests()) {
61+
ODBCTestBase::Connect(remote_test_connect_str, remote_odbcv3_handles.env,
62+
remote_odbcv3_handles.conn, SQL_OV_ODBC3);
63+
ODBCTestBase::Connect(remote_test_connect_str, remote_odbcv2_handles.env,
64+
remote_odbcv2_handles.conn, SQL_OV_ODBC2);
65+
}
66+
67+
std::string mock_test_connect_str = ODBCMockTestBase::GetConnectionString();
68+
ODBCMockTestBase::Connect(mock_test_connect_str, mock_odbcv3_handles.env,
69+
mock_odbcv3_handles.conn, SQL_OV_ODBC3);
70+
ODBCMockTestBase::Connect(mock_test_connect_str, mock_odbcv2_handles.env,
71+
mock_odbcv2_handles.conn, SQL_OV_ODBC2);
72+
}
73+
74+
void TearDown() override {
75+
if (RunningRemoteTests()) {
76+
ODBCTestBase::Disconnect(remote_odbcv3_handles.env, remote_odbcv3_handles.conn);
77+
ODBCTestBase::Disconnect(remote_odbcv2_handles.env, remote_odbcv2_handles.conn);
78+
}
79+
80+
ODBCTestBase::Disconnect(mock_odbcv3_handles.env, mock_odbcv3_handles.conn);
81+
ODBCTestBase::Disconnect(mock_odbcv2_handles.env, mock_odbcv2_handles.conn);
82+
}
83+
};
84+
85+
::testing::Environment* mock_server_env =
5586
::testing::AddGlobalTestEnvironment(new MockServerEnvironment);
5687

57-
void ODBCTestBase::AllocEnvConnHandles(SQLINTEGER odbc_ver) {
88+
::testing::Environment* odbc_test_env =
89+
::testing::AddGlobalTestEnvironment(new OdbcTestEnvironment);
90+
91+
void ODBCTestBase::AllocEnvConnHandles(SQLHENV& env_handle, SQLHDBC& conn_handle,
92+
SQLINTEGER odbc_ver) {
5893
// Allocate an environment handle
59-
ASSERT_EQ(SQL_SUCCESS, SQLAllocEnv(&env));
94+
ASSERT_EQ(SQL_SUCCESS, SQLAllocEnv(&env_handle));
6095

6196
ASSERT_EQ(
6297
SQL_SUCCESS,
63-
SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION,
98+
SQLSetEnvAttr(env_handle, SQL_ATTR_ODBC_VERSION,
6499
reinterpret_cast<SQLPOINTER>(static_cast<intptr_t>(odbc_ver)), 0));
65100

66101
// Allocate a connection using alloc handle
67-
ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DBC, env, &conn));
102+
ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DBC, env_handle, &conn_handle));
68103
}
69104

70-
void ODBCTestBase::Connect(std::string connect_str, SQLINTEGER odbc_ver) {
71-
ASSERT_NO_FATAL_FAILURE(AllocEnvConnHandles(odbc_ver));
72-
ASSERT_NO_FATAL_FAILURE(ConnectWithString(connect_str));
105+
void ODBCTestBase::Connect(std::string connect_str, SQLHENV& env_handle,
106+
SQLHDBC& conn_handle, SQLINTEGER odbc_ver) {
107+
ASSERT_NO_FATAL_FAILURE(AllocEnvConnHandles(env_handle, conn_handle, odbc_ver));
108+
ASSERT_NO_FATAL_FAILURE(ConnectWithString(connect_str, conn_handle));
73109
}
74110

75-
void ODBCTestBase::ConnectWithString(std::string connect_str) {
111+
void ODBCTestBase::ConnectWithString(std::string connect_str, SQLHDBC& conn_handle) {
76112
// Connect string
77113
std::vector<SQLWCHAR> connect_str0(connect_str.begin(), connect_str.end());
78114

@@ -81,31 +117,39 @@ void ODBCTestBase::ConnectWithString(std::string connect_str) {
81117

82118
// Connecting to ODBC server.
83119
ASSERT_EQ(SQL_SUCCESS,
84-
SQLDriverConnect(conn, NULL, &connect_str0[0],
120+
SQLDriverConnect(conn_handle, NULL, &connect_str0[0],
85121
static_cast<SQLSMALLINT>(connect_str0.size()), out_str,
86122
kOdbcBufferSize, &out_str_len, SQL_DRIVER_NOPROMPT))
87-
<< GetOdbcErrorMessage(SQL_HANDLE_DBC, conn);
123+
<< GetOdbcErrorMessage(SQL_HANDLE_DBC, conn_handle);
88124
}
89125

90-
void ODBCTestBase::Disconnect() {
126+
void ODBCTestBase::Disconnect(SQLHENV& env_handle, SQLHDBC& conn_handle) {
91127
// Disconnect from ODBC
92-
EXPECT_EQ(SQL_SUCCESS, SQLDisconnect(conn))
93-
<< GetOdbcErrorMessage(SQL_HANDLE_DBC, conn);
128+
if (conn_handle != SQL_NULL_HDBC) {
129+
EXPECT_EQ(SQL_SUCCESS, SQLDisconnect(conn_handle))
130+
<< GetOdbcErrorMessage(SQL_HANDLE_DBC, conn_handle);
131+
}
94132

95-
FreeEnvConnHandles();
133+
FreeEnvConnHandles(env_handle, conn_handle);
96134
}
97135

98-
void ODBCTestBase::FreeEnvConnHandles() {
136+
void ODBCTestBase::FreeEnvConnHandles(SQLHENV& env_handle, SQLHDBC& conn_handle) {
99137
// Free connection handle
100-
EXPECT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_DBC, conn));
138+
if (conn_handle != SQL_NULL_HDBC) {
139+
EXPECT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_DBC, conn_handle));
140+
conn_handle = SQL_NULL_HDBC;
141+
}
101142

102143
// Free environment handle
103-
EXPECT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_ENV, env));
144+
if (env_handle != SQL_NULL_HENV) {
145+
EXPECT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_ENV, env_handle));
146+
env_handle = SQL_NULL_HENV;
147+
}
104148
}
105149

106150
std::string ODBCTestBase::GetConnectionString() {
107151
std::string connect_str =
108-
arrow::internal::GetEnvVar(kTestConnectStr.data()).ValueOrDie();
152+
arrow::internal::GetEnvVar(kTestConnectStr.data()).ValueOr("");
109153
return connect_str;
110154
}
111155

@@ -168,68 +212,58 @@ std::wstring ODBCTestBase::GetQueryAllDataTypes() {
168212
}
169213

170214
void ODBCTestBase::SetUp() {
171-
if (connected) {
172-
ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_STMT, conn, &stmt));
173-
}
215+
ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_STMT, conn, &stmt));
174216
}
175217

176218
void ODBCTestBase::TearDown() {
177-
if (connected) {
178-
ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_STMT, stmt));
179-
}
180-
}
181-
182-
void ODBCTestBase::TearDownTestSuite() {
183-
if (connected) {
184-
Disconnect();
185-
connected = false;
186-
}
187-
}
188-
189-
void FlightSQLODBCRemoteTestBase::CheckForRemoteTest() {
190-
if (arrow::internal::GetEnvVar(kTestConnectStr.data()).ValueOr("").empty()) {
191-
skipping_test = true;
192-
GTEST_SKIP() << "Skipping test: kTestConnectStr not set";
193-
}
219+
ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_STMT, stmt));
194220
}
195221

196222
void FlightSQLODBCRemoteTestBase::SetUpTestSuite() {
197-
CheckForRemoteTest();
198-
if (skipping_test) {
223+
if (!RunningRemoteTests()) {
224+
GTEST_SKIP() << "Skipping Test Suite: Environment Variable " << kTestConnectStr.data()
225+
<< " is not set";
199226
return;
200227
}
201228

202-
std::string connect_str = GetConnectionString();
203-
Connect(connect_str, SQL_OV_ODBC3);
204-
connected = true;
229+
env = remote_odbcv3_handles.env;
230+
conn = remote_odbcv3_handles.conn;
231+
stmt = remote_odbcv3_handles.stmt;
205232
}
206233

207234
void FlightSQLOdbcV2RemoteTestBase::SetUpTestSuite() {
208-
CheckForRemoteTest();
209-
if (skipping_test) {
235+
if (!RunningRemoteTests()) {
236+
GTEST_SKIP() << "Skipping Test Suite: Environment Variable " << kTestConnectStr.data()
237+
<< " is not set";
210238
return;
211239
}
212240

213-
std::string connect_str = GetConnectionString();
214-
Connect(connect_str, SQL_OV_ODBC2);
215-
connected = true;
241+
env = remote_odbcv2_handles.env;
242+
conn = remote_odbcv2_handles.conn;
243+
stmt = remote_odbcv2_handles.stmt;
216244
}
217245

218246
void FlightSQLOdbcEnvConnHandleRemoteTestBase::SetUpTestSuite() {
219-
CheckForRemoteTest();
220-
if (skipping_test) {
247+
if (!RunningRemoteTests()) {
248+
GTEST_SKIP() << "Skipping Test Suite: Environment Variable " << kTestConnectStr.data()
249+
<< " is not set";
221250
return;
222251
}
223252

224-
AllocEnvConnHandles();
253+
AllocEnvConnHandles(remote_non_connection_handles.env,
254+
remote_non_connection_handles.conn);
255+
env = remote_non_connection_handles.env;
256+
conn = remote_non_connection_handles.conn;
257+
stmt = remote_non_connection_handles.stmt;
225258
}
226259

227260
void FlightSQLOdbcEnvConnHandleRemoteTestBase::TearDownTestSuite() {
228-
if (skipping_test) {
261+
if (!RunningRemoteTests()) {
229262
return;
230263
}
231264

232-
FreeEnvConnHandles();
265+
FreeEnvConnHandles(remote_non_connection_handles.env,
266+
remote_non_connection_handles.conn);
233267
}
234268

235269
std::string FindTokenInCallHeaders(const CallHeaders& incoming_headers) {
@@ -400,20 +434,27 @@ void ODBCMockTestBase::DropUnicodeTable() {
400434
}
401435

402436
void FlightSQLODBCMockTestBase::SetUpTestSuite() {
403-
std::string connect_str = GetConnectionString();
404-
Connect(connect_str, SQL_OV_ODBC3);
405-
connected = true;
437+
env = mock_odbcv3_handles.env;
438+
conn = mock_odbcv3_handles.conn;
439+
stmt = mock_odbcv3_handles.stmt;
406440
}
407441

408442
void FlightSQLOdbcV2MockTestBase::SetUpTestSuite() {
409-
std::string connect_str = GetConnectionString();
410-
Connect(connect_str, SQL_OV_ODBC2);
411-
connected = true;
443+
env = mock_odbcv2_handles.env;
444+
conn = mock_odbcv2_handles.conn;
445+
stmt = mock_odbcv2_handles.stmt;
412446
}
413447

414-
void FlightSQLOdbcEnvConnHandleMockTestBase::SetUpTestSuite() { AllocEnvConnHandles(); }
448+
void FlightSQLOdbcEnvConnHandleMockTestBase::SetUpTestSuite() {
449+
AllocEnvConnHandles(mock_non_connection_handles.env, mock_non_connection_handles.conn);
450+
env = mock_non_connection_handles.env;
451+
conn = mock_non_connection_handles.conn;
452+
stmt = mock_non_connection_handles.stmt;
453+
}
415454

416-
void FlightSQLOdbcEnvConnHandleMockTestBase::TearDownTestSuite() { FreeEnvConnHandles(); }
455+
void FlightSQLOdbcEnvConnHandleMockTestBase::TearDownTestSuite() {
456+
FreeEnvConnHandles(mock_non_connection_handles.env, mock_non_connection_handles.conn);
457+
}
417458

418459
bool CompareConnPropertyMap(Connection::ConnPropertyMap map1,
419460
Connection::ConnPropertyMap map2) {

0 commit comments

Comments
 (0)