Skip to content

Commit eea66f1

Browse files
Migrate tests to use FakeService extension (#182)
* Migrate ConcurrencyIntegrationTests to use FakeService * Migrate ResultSetIntegrationTests to use FakeService * Migrate ErrorHandlingIntegrationTests to use FakeService * Migrate ConnectionIntegrationTests to use FakeService * Migrate PreparedStatementIntegrationTests to use FakeService * Fix redundancies in tests * Address review comments (introduce a base class for fake service tests) * Exclude e2e tests from unit tests * Do not run DriverTester in unit tests
1 parent f1e7c3c commit eea66f1

File tree

200 files changed

+4954
-173
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

200 files changed

+4954
-173
lines changed

.github/workflows/prCheck.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ jobs:
6464
restore-keys: ${{ runner.os }}-m2
6565

6666
- name: Check Unit Tests
67-
run: mvn test
67+
run: mvn test -Dtest=!**/integration/**,!**/local/**
6868

6969
- name: Install xmllint
7070
if: runner.os == 'Linux'

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@
204204
<version>${maven-surefire-plugin.version}</version>
205205
<configuration>
206206
<excludes>
207-
<exclude>**/**IntegrationTests.java</exclude>
207+
<exclude>**/integration/**/*.java</exclude>
208208
<exclude>**/*MetadataBenchmarkingTest.java</exclude>
209209
</excludes>
210210
<argLine>
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
package com.databricks.jdbc.integration.e2e;
2+
3+
import static com.databricks.jdbc.integration.IntegrationTestUtil.*;
4+
import static org.junit.jupiter.api.Assertions.*;
5+
6+
import java.sql.Connection;
7+
import java.sql.PreparedStatement;
8+
import java.sql.ResultSet;
9+
import java.sql.SQLException;
10+
import java.util.concurrent.ExecutorService;
11+
import java.util.concurrent.Executors;
12+
import java.util.concurrent.TimeUnit;
13+
import java.util.concurrent.atomic.AtomicInteger;
14+
import org.junit.jupiter.api.AfterEach;
15+
import org.junit.jupiter.api.BeforeEach;
16+
import org.junit.jupiter.api.Test;
17+
18+
public class ConcurrencyTests {
19+
20+
private Connection connection;
21+
private static final String tableName = "concurrency_test_table";
22+
23+
@BeforeEach
24+
void setUp() throws SQLException {
25+
connection = getValidJDBCConnection();
26+
createTestTable();
27+
}
28+
29+
@AfterEach
30+
void cleanUp() throws SQLException {
31+
dropTestTable();
32+
if (connection != null) {
33+
connection.close();
34+
}
35+
}
36+
37+
private void createTestTable() throws SQLException {
38+
String sql =
39+
"CREATE TABLE IF NOT EXISTS "
40+
+ getFullyQualifiedTableName(tableName)
41+
+ " ("
42+
+ "id INT PRIMARY KEY, "
43+
+ "counter INT"
44+
+ ");";
45+
try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
46+
preparedStatement.execute();
47+
}
48+
String insertSQL =
49+
"INSERT INTO " + getFullyQualifiedTableName(tableName) + " (id, counter) VALUES (1, 0)";
50+
executeSQL(insertSQL);
51+
}
52+
53+
private void dropTestTable() throws SQLException {
54+
String sql = "DROP TABLE IF EXISTS " + getFullyQualifiedTableName(tableName);
55+
try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
56+
preparedStatement.execute();
57+
}
58+
}
59+
60+
@Test
61+
void testConcurrentUpdates() throws InterruptedException, SQLException {
62+
ExecutorService executor = Executors.newFixedThreadPool(2);
63+
64+
AtomicInteger counter = new AtomicInteger();
65+
66+
Runnable updateTask =
67+
() -> {
68+
String sql =
69+
"UPDATE "
70+
+ getFullyQualifiedTableName(tableName)
71+
+ " SET counter = counter + 1 WHERE id = 1";
72+
try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
73+
preparedStatement.executeUpdate();
74+
} catch (SQLException e) {
75+
counter.getAndIncrement();
76+
System.out.println("Expected exception on concurrent update: " + e.getMessage());
77+
}
78+
};
79+
80+
// Execute concurrent updates
81+
executor.submit(updateTask);
82+
executor.submit(updateTask);
83+
executor.shutdown();
84+
executor.awaitTermination(1, TimeUnit.MINUTES);
85+
86+
assertEquals(counter.get(), 1);
87+
88+
String selectSQL =
89+
"SELECT counter FROM " + getFullyQualifiedTableName(tableName) + " WHERE id = 1";
90+
ResultSet rs = executeQuery(selectSQL);
91+
rs.next();
92+
String r = rs.getString("counter");
93+
assertEquals(r, "1");
94+
}
95+
96+
@Test
97+
void testConcurrentReads() throws InterruptedException, SQLException {
98+
ExecutorService executor = Executors.newFixedThreadPool(2);
99+
100+
Runnable readTask =
101+
() -> {
102+
String sql =
103+
"SELECT counter FROM " + getFullyQualifiedTableName(tableName) + " WHERE id = 1";
104+
try (PreparedStatement preparedStatement = connection.prepareStatement(sql);
105+
ResultSet resultSet = preparedStatement.executeQuery()) {
106+
if (resultSet.next()) {
107+
System.out.println("Read counter: " + resultSet.getInt("counter"));
108+
}
109+
} catch (SQLException e) {
110+
fail("Read operation should not fail.");
111+
}
112+
};
113+
114+
// Execute concurrent reads
115+
executor.submit(readTask);
116+
executor.submit(readTask);
117+
executor.shutdown();
118+
executor.awaitTermination(1, TimeUnit.MINUTES);
119+
}
120+
}

src/test/java/com/databricks/jdbc/integration/connection/ConnectionIntegrationTests.java renamed to src/test/java/com/databricks/jdbc/integration/e2e/ConnectionTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.databricks.jdbc.integration.connection;
1+
package com.databricks.jdbc.integration.e2e;
22

33
import static com.databricks.jdbc.integration.IntegrationTestUtil.*;
44
import static org.junit.jupiter.api.Assertions.*;
@@ -9,7 +9,7 @@
99
import java.sql.SQLException;
1010
import org.junit.jupiter.api.Test;
1111

12-
public class ConnectionIntegrationTests {
12+
public class ConnectionTests {
1313

1414
@Test
1515
void testSuccessfulConnection() throws SQLException {
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package com.databricks.jdbc.integration.e2e;
2+
3+
import static com.databricks.jdbc.integration.IntegrationTestUtil.*;
4+
import static org.junit.jupiter.api.Assertions.*;
5+
6+
import com.databricks.jdbc.core.DatabricksParsingException;
7+
import com.databricks.jdbc.core.DatabricksSQLException;
8+
import com.databricks.jdbc.core.DatabricksSQLFeatureNotSupportedException;
9+
import java.sql.*;
10+
import org.junit.jupiter.api.Test;
11+
12+
public class ErrorHandlingTests {
13+
@Test
14+
void testFailureToLoadDriver() {
15+
Exception exception =
16+
assertThrows(
17+
ClassNotFoundException.class,
18+
() -> {
19+
Class.forName("incorrect.DatabricksDriver.class");
20+
});
21+
assertTrue(exception.getMessage().contains("incorrect.DatabricksDriver.class"));
22+
}
23+
24+
@Test
25+
void testInvalidURL() {
26+
Exception exception =
27+
assertThrows(
28+
DatabricksParsingException.class,
29+
() -> {
30+
Connection connection =
31+
getConnection("jdbc:abcde://invalidhost:0000/db", "username", "password");
32+
});
33+
assertTrue(exception.getMessage().contains("Invalid url"));
34+
}
35+
36+
@Test
37+
void testInvalidHostname() {
38+
SQLException e =
39+
assertThrows(
40+
SQLException.class,
41+
() -> {
42+
Connection connection =
43+
getConnection(
44+
"jdbc:databricks://e2-wrongfood.staging.cloud.databricks.com:443/default;transportMode=http;ssl=1;AuthMech=3;httpPath=/sql/1.0/warehouses/791ba2a31c7fd70a;",
45+
"username",
46+
"password");
47+
});
48+
assertTrue(e.getMessage().contains("Invalid or unknown token or hostname provided"));
49+
}
50+
51+
@Test
52+
void testQuerySyntaxError() {
53+
String tableName = "query_syntax_error_test_table";
54+
setupDatabaseTable(tableName);
55+
DatabricksSQLException e =
56+
assertThrows(
57+
DatabricksSQLException.class,
58+
() -> {
59+
Connection connection = getValidJDBCConnection();
60+
Statement statement = connection.createStatement();
61+
String sql =
62+
"INSER INTO "
63+
+ getFullyQualifiedTableName(tableName)
64+
+ " (id, col1, col2) VALUES (1, 'value1', 'value2')";
65+
statement.executeQuery(sql);
66+
});
67+
assertTrue(e.getMessage().contains("Error occurred during statement execution"));
68+
deleteTable(tableName);
69+
}
70+
71+
@Test
72+
void testAccessingClosedResultSet() {
73+
String tableName = "access_closed_result_set_test_table";
74+
setupDatabaseTable(tableName);
75+
executeSQL(
76+
"INSERT INTO "
77+
+ getFullyQualifiedTableName(tableName)
78+
+ " (id, col1, col2) VALUES (1, 'value1', 'value2')");
79+
ResultSet resultSet = executeQuery("SELECT * FROM " + getFullyQualifiedTableName(tableName));
80+
try {
81+
resultSet.close();
82+
assertThrows(SQLException.class, resultSet::next);
83+
} catch (SQLException e) {
84+
fail("Unexpected exception: " + e.getMessage());
85+
}
86+
deleteTable(tableName);
87+
}
88+
89+
@Test
90+
void testCallingUnsupportedSQLFeature() {
91+
String tableName = "unsupported_sql_feature_test_table";
92+
setupDatabaseTable(tableName);
93+
assertThrows(
94+
DatabricksSQLFeatureNotSupportedException.class,
95+
() -> {
96+
Connection connection = getValidJDBCConnection();
97+
Statement statement = connection.createStatement();
98+
String sql = "SELECT * FROM " + getFullyQualifiedTableName(tableName);
99+
ResultSet resultSet = statement.executeQuery(sql);
100+
resultSet.first(); // Currently unsupported method
101+
});
102+
deleteTable(tableName);
103+
}
104+
105+
private Connection getConnection(String url, String username, String password)
106+
throws SQLException {
107+
return DriverManager.getConnection(url, username, password);
108+
}
109+
}

src/test/java/com/databricks/jdbc/integration/execution/ExecutionIntegrationTests.java renamed to src/test/java/com/databricks/jdbc/integration/e2e/ExecutionTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.databricks.jdbc.integration.execution;
1+
package com.databricks.jdbc.integration.e2e;
22

33
import static com.databricks.jdbc.integration.IntegrationTestUtil.*;
44
import static org.junit.jupiter.api.Assertions.*;
@@ -7,7 +7,7 @@
77
import java.sql.SQLException;
88
import org.junit.jupiter.api.*;
99

10-
public class ExecutionIntegrationTests {
10+
public class ExecutionTests {
1111

1212
@Test
1313
void testInsertStatement() throws SQLException {

src/test/java/com/databricks/jdbc/integration/benchmarking/MetadataBenchmarkingTest.java renamed to src/test/java/com/databricks/jdbc/integration/e2e/MetadataBenchmarkingTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.databricks.jdbc.integration.benchmarking;
1+
package com.databricks.jdbc.integration.e2e;
22

33
import static com.databricks.jdbc.integration.IntegrationTestUtil.*;
44

@@ -9,7 +9,7 @@
99
import org.junit.jupiter.api.BeforeEach;
1010
import org.junit.jupiter.api.Test;
1111

12-
public class MetadataBenchmarkingTest {
12+
public class MetadataBenchmarkingTests {
1313

1414
private Connection connection;
1515
private static final int NUM_SCHEMAS = 10;

src/test/java/com/databricks/jdbc/integration/metadata/MetadataIntegrationTests.java renamed to src/test/java/com/databricks/jdbc/integration/e2e/MetadataTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.databricks.jdbc.integration.metadata;
1+
package com.databricks.jdbc.integration.e2e;
22

33
import static com.databricks.jdbc.integration.IntegrationTestUtil.*;
44
import static org.junit.jupiter.api.Assertions.*;
@@ -8,7 +8,7 @@
88
import org.junit.jupiter.api.BeforeEach;
99
import org.junit.jupiter.api.Test;
1010

11-
public class MetadataIntegrationTests {
11+
public class MetadataTests {
1212

1313
private Connection connection;
1414

0 commit comments

Comments
 (0)