Repository: neo4j-contrib/neo4j-jdbc
Pull request #279 (2021-09-03 15:08:19)

Parameterize Neo4j version in container tests


Patch:
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index ef945fc6..87274791 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -2,19 +2,30 @@ name: CI
 
 on:
   push:
-    branches: '**'
+    branches: ['**']
   pull_request:
-    branches: '**'
+    branches: ['**']
 
 jobs:
   build:
     runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        neo4j_version:
+          - "3.5"
+          - "4.0"
+          - "4.1"
+          - "4.2"
+          - "4.3"
+        neo4j_enterprise_edition:
+          - "true"
+          - "false"
     steps:
       - uses: actions/checkout@v2
       - name: Set up JDK
         uses: actions/setup-java@v1
         with:
-          java-version: 11
+          java-version: 8
       - name: Cache ~/.m2/repository
         uses: actions/cache@v1
         with:
@@ -24,3 +35,6 @@ jobs:
             ${{ runner.os }}-maven-
       - name: Build with Maven
         run: mvn --batch-mode --show-version clean test
+        env:
+          NEO4J_VERSION: ${{ matrix.neo4j_version }}
+          NEO4J_ENTERPRISE_EDITION: ${{ matrix.neo4j_enterprise_edition }}
diff --git a/neo4j-jdbc-bolt/src/main/java/org/neo4j/jdbc/bolt/BoltDriver.java b/neo4j-jdbc-bolt/src/main/java/org/neo4j/jdbc/bolt/BoltDriver.java
index aab66ba1..7c53fb3e 100644
--- a/neo4j-jdbc-bolt/src/main/java/org/neo4j/jdbc/bolt/BoltDriver.java
+++ b/neo4j-jdbc-bolt/src/main/java/org/neo4j/jdbc/bolt/BoltDriver.java
@@ -81,7 +81,7 @@ public class BoltDriver extends BoltNeo4jDriverImpl {
     }
 
 	// visible for testing
-	protected static void clearCache() {
+	public static void clearCache() {
 		cache.clear();
 	}
 }
diff --git a/neo4j-jdbc-bolt/src/main/java/org/neo4j/jdbc/boltrouting/BoltRoutingNeo4jDriver.java b/neo4j-jdbc-bolt/src/main/java/org/neo4j/jdbc/boltrouting/BoltRoutingNeo4jDriver.java
index 14f6ee55..cc371b6d 100644
--- a/neo4j-jdbc-bolt/src/main/java/org/neo4j/jdbc/boltrouting/BoltRoutingNeo4jDriver.java
+++ b/neo4j-jdbc-bolt/src/main/java/org/neo4j/jdbc/boltrouting/BoltRoutingNeo4jDriver.java
@@ -142,7 +142,7 @@ public class BoltRoutingNeo4jDriver extends BoltNeo4jDriverImpl {
     }
 
     // visible for testing
-    protected static void clearCache() {
+    public static void clearCache() {
         cache.clear();
     }
 }
diff --git a/neo4j-jdbc/src/main/java/org/neo4j/jdbc/Neo4jDatabaseMetaData.java b/neo4j-jdbc/src/main/java/org/neo4j/jdbc/Neo4jDatabaseMetaData.java
index ad0d8ba0..28348a10 100644
--- a/neo4j-jdbc/src/main/java/org/neo4j/jdbc/Neo4jDatabaseMetaData.java
+++ b/neo4j-jdbc/src/main/java/org/neo4j/jdbc/Neo4jDatabaseMetaData.java
@@ -22,7 +22,6 @@ package org.neo4j.jdbc;
 import org.neo4j.jdbc.impl.ListNeo4jResultSet;
 import org.neo4j.jdbc.metadata.Column;
 import org.neo4j.jdbc.metadata.Table;
-import org.neo4j.jdbc.utils.ExceptionBuilder;
 import org.neo4j.jdbc.utils.Neo4jJdbcRuntimeException;
 
 import java.io.InputStream;
@@ -772,24 +771,24 @@ public abstract class Neo4jDatabaseMetaData implements java.sql.DatabaseMetaData
 		return emptyResultSet();
 	}
 
-	private String getIndexesV3X(String table, boolean unique, boolean hasTable) {
+	private String getIndexesV3X(boolean unique, boolean hasTable) {
 		List<String> filters = new ArrayList<>();
 		if (hasTable) {
-			filters.add("label = ?");
+			filters.add("? IN tokenNames");
 		}
 		if (unique) {
 			filters.add("type = 'node_unique_property'");
 		}
 		StringBuilder queryBuilder = new StringBuilder();
-		queryBuilder.append("CALL db.indexes() YIELD description, label, properties, state, type\n");
+		queryBuilder.append("CALL db.indexes() YIELD description, tokenNames, properties, state, type\n");
 		if (!filters.isEmpty()) {
-			queryBuilder.append("WHERE " + String.join(" AND ", filters) + "\n");
+			queryBuilder.append("WHERE ").append(String.join(" AND ", filters)).append("\n");
 		}
-		queryBuilder.append("WITH description, label, properties, state, type\n");
+		queryBuilder.append("WITH description, tokenNames, properties, state, type\n");
 		queryBuilder.append("UNWIND range(0, size(properties) - 1) AS index\n");
 		queryBuilder.append("RETURN null AS TABLE_CAT,\n");
 		queryBuilder.append("null AS TABLE_SCHEM,\n");
-		queryBuilder.append("label AS TABLE_NAME,\n");
+		queryBuilder.append("tokenNames[0] AS TABLE_NAME,\n");
 		queryBuilder.append("type <> 'node_unique_property' AS NON_UNIQUE,\n");
 		queryBuilder.append("description AS INDEX_QUALIFIER,\n");
 		queryBuilder.append("description AS INDEX_NAME,\n");
@@ -842,7 +841,7 @@ public abstract class Neo4jDatabaseMetaData implements java.sql.DatabaseMetaData
 	public ResultSet getIndexInfo(String catalog, String schema, String table, boolean unique, boolean approximate) throws SQLException {
 		boolean hasTable = table != null && !table.trim().isEmpty();
 		final String query = databaseVersion.startsWith("4") ?
-				getIndexesV4X(table, unique, hasTable) : getIndexesV3X(table, unique, hasTable);
+				getIndexesV4X(table, unique, hasTable) : getIndexesV3X(unique, hasTable);
 		PreparedStatement ps = this.connection.prepareStatement(query);
 		if (hasTable) {
 			ps.setString(1, table);


Test patch:
diff --git a/neo4j-jdbc-bolt/src/test/java/org/neo4j/TestcontainersCausalCluster.java b/neo4j-jdbc-bolt/src/test/java/org/neo4j/TestcontainersCausalCluster.java
index 8886403b..59370d6e 100644
--- a/neo4j-jdbc-bolt/src/test/java/org/neo4j/TestcontainersCausalCluster.java
+++ b/neo4j-jdbc-bolt/src/test/java/org/neo4j/TestcontainersCausalCluster.java
@@ -4,8 +4,6 @@ import org.neo4j.driver.AuthTokens;
 import org.neo4j.driver.Driver;
 import org.neo4j.driver.GraphDatabase;
 import org.neo4j.driver.Session;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.testcontainers.containers.GenericContainer;
 import org.testcontainers.containers.Neo4jContainer;
 import org.testcontainers.containers.Network;
@@ -15,6 +13,7 @@ import org.testcontainers.containers.wait.strategy.WaitStrategy;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.time.Duration;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.CompletableFuture;
@@ -28,9 +27,9 @@ import java.util.stream.Stream;
 import static java.util.stream.Collectors.joining;
 import static java.util.stream.Collectors.toList;
 import static java.util.stream.Collectors.toMap;
+import static org.neo4j.jdbc.bolt.utils.Neo4jContainerUtils.neo4jImageCoordinates;
 
 public class TestcontainersCausalCluster {
-    private static final Logger logger = LoggerFactory.getLogger(TestcontainersCausalCluster.class);
     private static final int DEFAULT_BOLT_PORT = 7687;
 
     public enum ClusterInstanceType {CORE, READ_REPLICA}
@@ -58,14 +57,14 @@ public class TestcontainersCausalCluster {
         Network network = Network.newNetwork();
 
         // Prepare proxys as sidecars
-        Map<String, GenericContainer> sidecars = createSidecars(numberOfCoreMembers, network, ClusterInstanceType.CORE);
+        Map<String, GenericContainer<?>> sidecars = createSidecars(numberOfCoreMembers, network, ClusterInstanceType.CORE);
         sidecars.putAll(createSidecars(numberOfReadReplica, network, ClusterInstanceType.READ_REPLICA));
 
         // Start the sidecars so that the exposed ports are available
         sidecars.values().forEach(GenericContainer::start);
 
         // Build the core/read_replica
-        List<Neo4jContainer> members = getClusterMembers(numberOfCoreMembers, ClusterInstanceType.CORE, sidecars, network, initialDiscoveryMembers, neo4jConfig, timeout);
+        List<Neo4jContainer<?>> members = getClusterMembers(numberOfCoreMembers, ClusterInstanceType.CORE, sidecars, network, initialDiscoveryMembers, neo4jConfig, timeout);
         members.addAll(getClusterMembers(numberOfReadReplica, ClusterInstanceType.READ_REPLICA, sidecars, network, initialDiscoveryMembers, neo4jConfig, timeout));
 
         // Start all of them in parallel
@@ -81,12 +80,12 @@ public class TestcontainersCausalCluster {
             e.printStackTrace();
         }
 
-        return new TestcontainersCausalCluster(members, sidecars.values().stream().collect(toList()));
+        return new TestcontainersCausalCluster(members, new ArrayList<>(sidecars.values()));
     }
 
-    private static List<Neo4jContainer> getClusterMembers(int numberOfCoreMembers,
+    private static List<Neo4jContainer<?>> getClusterMembers(int numberOfCoreMembers,
                                                                    ClusterInstanceType instanceType,
-                                                                   Map<String, GenericContainer> sidecars,
+                                                                   Map<String, GenericContainer<?>> sidecars,
                                                                    Network network,
                                                                    String initialDiscoveryMembers,
                                                                    Map<String, Object> neo4jConfig,
@@ -95,18 +94,18 @@ public class TestcontainersCausalCluster {
         WaitStrategy waitForBolt = new LogMessageWaitStrategy()
                 .withRegEx(String.format(".*Bolt enabled on 0\\.0\\.0\\.0:%d\\.\n", DEFAULT_BOLT_PORT))
                 .withStartupTimeout(timeout);
-        Function<GenericContainer, String> getProxyUrl = instance ->
+        Function<GenericContainer<?>, String> getProxyUrl = instance ->
                 String.format("%s:%d", instance.getContainerIpAddress(), instance.getMappedPort(DEFAULT_BOLT_PORT));
         return iterateMembers(numberOfCoreMembers, instanceType)
                 .map(name -> getNeo4jContainer(waitForBolt, network, initialDiscoveryMembers, sidecars, getProxyUrl, instanceType, neo4jConfig, name))
                 .collect(toList());
     }
 
-    private static Map<String, GenericContainer> createSidecars(int numOfMembers, Network network, ClusterInstanceType instanceType) {
+    private static Map<String, GenericContainer<?>> createSidecars(int numOfMembers, Network network, ClusterInstanceType instanceType) {
         return iterateMembers(numOfMembers, instanceType)
                 .collect(toMap(
                         Function.identity(),
-                        name -> new GenericContainer("alpine/socat")
+                        name -> new GenericContainer<>("alpine/socat")
                                 .withNetwork(network)
                                 .withLabel("memberType", instanceType.toString())
                                 // Expose the default bolt port on the sidecar
@@ -117,15 +116,15 @@ public class TestcontainersCausalCluster {
                 ));
     }
 
-    private static Neo4jContainer getNeo4jContainer(WaitStrategy waitForBolt,
+    private static Neo4jContainer<?> getNeo4jContainer(WaitStrategy waitForBolt,
                                                                       Network network,
                                                                       String initialDiscoveryMembers,
-                                                                      Map<String, GenericContainer> sidecars,
-                                                                      Function<GenericContainer, String> getProxyUrl,
+                                                                      Map<String, GenericContainer<?>> sidecars,
+                                                                      Function<GenericContainer<?>, String> getProxyUrl,
                                                                       ClusterInstanceType instanceType,
                                                                       Map<String, Object> neo4jConfig,
                                                                       String name) {
-        Neo4jContainer container = (Neo4jContainer) new Neo4jContainer("neo4j:3.5-enterprise")
+        Neo4jContainer<?> container = new Neo4jContainer<>(neo4jImageCoordinates())
                 .withNeo4jConfig("dbms.mode", instanceType.toString())
                 .withNeo4jConfig("dbms.connectors.default_listen_address", "0.0.0.0")
                 .withNeo4jConfig("dbms.connectors.default_advertised_address", name)
@@ -142,14 +141,14 @@ public class TestcontainersCausalCluster {
         return container;
     }
 
-    private final List<Neo4jContainer> clusterMembers;
-    private final List<GenericContainer> sidecars;
+    private final List<Neo4jContainer<?>> clusterMembers;
+    private final List<GenericContainer<?>> sidecars;
 
-    private Driver driver;
-    private Session session;
+    private final Driver driver;
+    private final Session session;
 
-    public TestcontainersCausalCluster(List<Neo4jContainer> clusterMembers,
-                                       List<GenericContainer> sidecars) {
+    public TestcontainersCausalCluster(List<Neo4jContainer<?>> clusterMembers,
+                                       List<GenericContainer<?>> sidecars) {
         this.clusterMembers = clusterMembers;
         this.sidecars = sidecars;
         this.driver = GraphDatabase.driver(getURI(), AuthTokens.basic("neo4j", "jdbc"));
diff --git a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jAuthenticationIT.java b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jAuthenticationIT.java
index 08a66a88..71ff38cd 100644
--- a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jAuthenticationIT.java
+++ b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jAuthenticationIT.java
@@ -26,7 +26,6 @@ import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.neo4j.driver.exceptions.ClientException;
 import org.testcontainers.containers.GenericContainer;
-import org.testcontainers.containers.Neo4jContainer;
 import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy;
 
 import java.sql.Connection;
@@ -35,6 +34,7 @@ import java.sql.SQLException;
 import java.sql.Statement;
 
 import static org.hamcrest.CoreMatchers.isA;
+import static org.neo4j.jdbc.bolt.utils.Neo4jContainerUtils.neo4jImageCoordinates;
 
 
 /**
@@ -46,7 +46,7 @@ public class BoltNeo4jAuthenticationIT {
 	// Neo4jContainer overwrites the default password so in order to replicate a use-case
 	// where we use the default password that needs to be changed we use a GenericContainer
 	@ClassRule
-	public static final GenericContainer<?> neo4j = new GenericContainer<>("neo4j:4.3.0-enterprise").withEnv("NEO4J_ACCEPT_LICENSE_AGREEMENT", "yes")
+	public static final GenericContainer<?> neo4j = new GenericContainer<>(neo4jImageCoordinates()).withEnv("NEO4J_ACCEPT_LICENSE_AGREEMENT", "yes")
 			.waitingFor((new LogMessageWaitStrategy()).withRegEx(String.format(".*Bolt enabled on 0\\.0\\.0\\.0:%d\\.\n", 7687)));
 
 	@Rule public ExpectedException expectedEx = ExpectedException.none();
diff --git a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jConnectionIT.java b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jConnectionIT.java
index a0903a07..2041e373 100644
--- a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jConnectionIT.java
+++ b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jConnectionIT.java
@@ -55,6 +55,7 @@ import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
+import static org.neo4j.jdbc.bolt.utils.Neo4jContainerUtils.neo4jImageCoordinates;
 
 /**
  * @author AgileLARUS
@@ -63,7 +64,7 @@ import static org.junit.Assert.assertTrue;
 public class BoltNeo4jConnectionIT {
 
 	@ClassRule
-	public static final Neo4jContainer<?> neo4j = new Neo4jContainer<>("neo4j:4.3.0-enterprise").withEnv("NEO4J_ACCEPT_LICENSE_AGREEMENT", "yes").withAdminPassword(null);
+	public static final Neo4jContainer<?> neo4j = new Neo4jContainer<>(neo4jImageCoordinates()).withEnv("NEO4J_ACCEPT_LICENSE_AGREEMENT", "yes").withAdminPassword(null);
 	@Rule public ExpectedException expectedEx = ExpectedException.none();
 
 	Connection writer;
diff --git a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jConnectionTest.java b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jConnectionTest.java
index 5b3ea5ea..66841a78 100644
--- a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jConnectionTest.java
+++ b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jConnectionTest.java
@@ -19,6 +19,7 @@
  */
 package org.neo4j.jdbc.bolt;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Rule;
@@ -35,6 +36,7 @@ import org.neo4j.driver.internal.handlers.pulln.FetchSizeUtil;
 import org.neo4j.driver.internal.logging.DevNullLogging;
 import org.neo4j.jdbc.bolt.data.StatementData;
 import org.neo4j.jdbc.bolt.impl.BoltNeo4jConnectionImpl;
+import org.neo4j.jdbc.bolt.utils.JdbcConnectionTestUtils;
 
 import java.sql.*;
 import java.util.Properties;
@@ -63,6 +65,14 @@ public class BoltNeo4jConnectionTest {
 		exceptionOpenConnection = new BoltNeo4jConnectionImpl(mockDriverException(), new Properties(), "");
 	}
 
+	@After
+	public void close() {
+		JdbcConnectionTestUtils.closeConnection(openConnection);
+		JdbcConnectionTestUtils.closeConnection(closedConnection);
+		JdbcConnectionTestUtils.closeConnection(slowOpenConnection);
+		JdbcConnectionTestUtils.closeConnection(exceptionOpenConnection);
+	}
+
 	/*------------------------------*/
 	/*        setHoldability        */
 	/*------------------------------*/
@@ -502,6 +512,7 @@ public class BoltNeo4jConnectionTest {
 		when(driver.session()).thenReturn(session);
 		Connection connection = new BoltNeo4jConnectionImpl(driver, new Properties(), "");
 		connection.setAutoCommit(true);
+		JdbcConnectionTestUtils.closeConnection(connection);
 	}
 
 	@Test public void setAutoCommitShouldSetWhatIsPassed() throws SQLException {
diff --git a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jDataSourceIT.java b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jDataSourceIT.java
index dac9c319..1b838938 100644
--- a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jDataSourceIT.java
+++ b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jDataSourceIT.java
@@ -33,6 +33,7 @@ import java.sql.Statement;
 
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
+import static org.neo4j.jdbc.bolt.utils.Neo4jContainerUtils.neo4jImageCoordinates;
 
 /**
  * @author AgileLARUS
@@ -44,7 +45,7 @@ public class BoltNeo4jDataSourceIT {
 	public ExpectedException expectedEx = ExpectedException.none();
 
 	@ClassRule
-	public static final Neo4jContainer<?> neo4j = new Neo4jContainer<>("neo4j:4.3.0-enterprise").withEnv("NEO4J_ACCEPT_LICENSE_AGREEMENT", "yes").withAdminPassword(null);
+	public static final Neo4jContainer<?> neo4j = new Neo4jContainer<>(neo4jImageCoordinates()).withEnv("NEO4J_ACCEPT_LICENSE_AGREEMENT", "yes").withAdminPassword(null);
 
 	/*------------------------------*/
 	/*        getConnection         */
diff --git a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jDatabaseMetaDataIT.java b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jDatabaseMetaDataIT.java
index 10082579..e0f171a4 100644
--- a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jDatabaseMetaDataIT.java
+++ b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jDatabaseMetaDataIT.java
@@ -35,6 +35,7 @@ import java.sql.Statement;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Locale;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -42,6 +43,9 @@ import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
+import static org.neo4j.jdbc.bolt.utils.Neo4jContainerUtils.isV3;
+import static org.neo4j.jdbc.bolt.utils.Neo4jContainerUtils.isV4;
+import static org.neo4j.jdbc.bolt.utils.Neo4jContainerUtils.neo4jImageCoordinates;
 
 /**
  * Neo4jDatabaseMetaData IT Tests class
@@ -50,7 +54,7 @@ public class BoltNeo4jDatabaseMetaDataIT {
 
 
 	@ClassRule
-	public static final Neo4jContainer<?> neo4j = new Neo4jContainer<>("neo4j:4.3.0-enterprise").withEnv("NEO4J_ACCEPT_LICENSE_AGREEMENT", "yes").withAdminPassword(null);
+	public static final Neo4jContainer<?> neo4j = new Neo4jContainer<>(neo4jImageCoordinates()).withEnv("NEO4J_ACCEPT_LICENSE_AGREEMENT", "yes").withAdminPassword(null);
 
 	Connection connection;
 
@@ -79,9 +83,9 @@ public class BoltNeo4jDatabaseMetaDataIT {
 			statement.execute("create (a:A {one:1, two:2})");
 			statement.execute("create (b:B {three:3, four:4})");
 		}
-		
+
 		ResultSet labels = connection.getMetaData().getTables(null, null, null, null);
-		
+
 		assertNotNull(labels);
 		assertTrue(labels.next());
 		assertEquals("A", labels.getString("TABLE_NAME"));
@@ -251,8 +255,12 @@ public class BoltNeo4jDatabaseMetaDataIT {
 		assertTrue(resultSet.next());
 		assertEquals("Bar", resultSet.getString("TABLE_NAME"));
 		assertFalse(resultSet.getBoolean("NON_UNIQUE"));
-		assertTrue(resultSet.getString("INDEX_NAME").startsWith("constraint_"));
-		assertTrue(resultSet.getString("INDEX_QUALIFIER").startsWith("constraint_"));
+		String prefix = "constraint_";
+		if (isV3(neo4j)) {
+			prefix = "index";
+		}
+		assertTrue(resultSet.getString("INDEX_NAME").toLowerCase(Locale.ROOT).startsWith(prefix));
+		assertTrue(resultSet.getString("INDEX_QUALIFIER").toLowerCase(Locale.ROOT).startsWith(prefix));
 		assertEquals(3, resultSet.getInt("TYPE"));
 		assertEquals(1, resultSet.getInt("ORDINAL_POSITION"));
 		assertEquals("uuid", resultSet.getString("COLUMN_NAME"));
@@ -278,8 +286,12 @@ public class BoltNeo4jDatabaseMetaDataIT {
 		assertTrue(resultSet.next());
 		assertEquals("Bar Ext", resultSet.getString("TABLE_NAME"));
 		assertFalse(resultSet.getBoolean("NON_UNIQUE"));
-		assertTrue(resultSet.getString("INDEX_NAME").startsWith("constraint_"));
-		assertTrue(resultSet.getString("INDEX_QUALIFIER").startsWith("constraint_"));
+		String prefix = "constraint_";
+		if (isV3(neo4j)) {
+			prefix = "index";
+		}
+		assertTrue(resultSet.getString("INDEX_NAME").toLowerCase(Locale.ROOT).startsWith(prefix));
+		assertTrue(resultSet.getString("INDEX_QUALIFIER").toLowerCase(Locale.ROOT).startsWith(prefix));
 		assertEquals(3, resultSet.getInt("TYPE"));
 		assertEquals(1, resultSet.getInt("ORDINAL_POSITION"));
 		assertEquals("uuid", resultSet.getString("COLUMN_NAME"));
@@ -318,8 +330,8 @@ public class BoltNeo4jDatabaseMetaDataIT {
 		assertTrue(resultSet.next());
 		assertEquals("Bar", resultSet.getString("TABLE_NAME"));
 		assertTrue(resultSet.getBoolean("NON_UNIQUE"));
-		assertTrue(resultSet.getString("INDEX_NAME").startsWith("index_"));
-		assertTrue(resultSet.getString("INDEX_QUALIFIER").startsWith("index_"));
+		assertTrue(resultSet.getString("INDEX_NAME").toLowerCase(Locale.ROOT).startsWith("index"));
+		assertTrue(resultSet.getString("INDEX_QUALIFIER").toLowerCase(Locale.ROOT).startsWith("index"));
 		assertEquals(3, resultSet.getInt("TYPE"));
 		assertEquals(1, resultSet.getInt("ORDINAL_POSITION"));
 		assertEquals("uuid", resultSet.getString("COLUMN_NAME"));
diff --git a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jDateIT.java b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jDateIT.java
index 0211d4c8..1a01f53c 100644
--- a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jDateIT.java
+++ b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jDateIT.java
@@ -1,5 +1,6 @@
 package org.neo4j.jdbc.bolt;
 
+import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.ClassRule;
@@ -37,6 +38,7 @@ import java.util.TimeZone;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
+import static org.neo4j.jdbc.bolt.utils.Neo4jContainerUtils.neo4jImageCoordinates;
 
 /**
  * Test for the date types
@@ -45,18 +47,18 @@ import static org.junit.Assert.assertTrue;
 public class BoltNeo4jDateIT {
 
     @ClassRule
-    public static final Neo4jContainer<?> neo4j = new Neo4jContainer<>("neo4j:4.3.0-enterprise").withEnv("NEO4J_ACCEPT_LICENSE_AGREEMENT", "yes").withAdminPassword(null);
+    public static final Neo4jContainer<?> neo4j = new Neo4jContainer<>(neo4jImageCoordinates()).withEnv("NEO4J_ACCEPT_LICENSE_AGREEMENT", "yes").withAdminPassword(null);
 
     static Connection connection;
 
     @Before
-    public void cleanDB() throws SQLException {
+    public void cleanDB() {
         JdbcConnectionTestUtils.clearDatabase(neo4j);
         connection = JdbcConnectionTestUtils.verifyConnection(connection, neo4j);
     }
 
-    @AfterClass
-    public static void tearDown(){
+    @After
+    public void tearDown(){
         JdbcConnectionTestUtils.closeConnection(connection);
     }
 
diff --git a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jDriverTest.java b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jDriverTest.java
index a54682f1..70b94c06 100644
--- a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jDriverTest.java
+++ b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jDriverTest.java
@@ -19,16 +19,20 @@
  */
 package org.neo4j.jdbc.bolt;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.BeforeClass;
+import org.junit.FixMethodOrder;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
 import org.mockito.Mockito;
 import org.neo4j.driver.AuthTokens;
 import org.neo4j.driver.Config;
 import org.neo4j.driver.GraphDatabase;
+import org.neo4j.driver.internal.SecuritySettings;
 import org.neo4j.driver.internal.async.pool.PoolSettings;
 import org.neo4j.driver.internal.security.InternalAuthToken;
 import org.neo4j.jdbc.Neo4jDriver;
@@ -64,8 +68,8 @@ import static org.powermock.api.mockito.PowerMockito.verifyStatic;
  * @since 3.0.0
  */
 @RunWith(PowerMockRunner.class)
-@PrepareForTest({GraphDatabase.class, Config.TrustStrategy.class, AuthTokens.class})
-
+@PrepareForTest({GraphDatabase.class, Config.TrustStrategy.class, AuthTokens.class, SecuritySettings.class})
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class BoltNeo4jDriverTest {
 
 	@Rule public ExpectedException expectedEx = ExpectedException.none();
@@ -78,7 +82,7 @@ public class BoltNeo4jDriverTest {
 		mockedDriver = Mocker.mockDriver();
 	}
 
-	@Before
+	@After
 	public void prepare() {
 		BoltDriver.clearCache();
 	}
@@ -134,6 +138,7 @@ public class BoltNeo4jDriverTest {
 	@Test public void shouldAcceptTrustStrategyParamsSystemCertificates() throws SQLException, URISyntaxException {
 		PowerMockito.mockStatic(GraphDatabase.class);
 		PowerMockito.mockStatic(Config.TrustStrategy.class);
+		PowerMockito.mockStatic(SecuritySettings.class);
 		Mockito.when(GraphDatabase.driver(Mockito.eq(new URI(BOLT_URL)), Mockito.eq(AuthTokens.none()), any(Config.class))).thenReturn(mockedDriver);
 
 		Properties properties = new Properties();
@@ -231,7 +236,6 @@ public class BoltNeo4jDriverTest {
 			// assertEquals(Config.LoadBalancingStrategy.LEAST_CONNECTED, config.loadBalancingStrategy());
 			assertEquals(PoolSettings.DEFAULT_MAX_CONNECTION_LIFETIME, config.maxConnectionLifetimeMillis());
 			assertEquals(PoolSettings.DEFAULT_MAX_CONNECTION_POOL_SIZE, config.maxConnectionPoolSize());
-			assertEquals(Config.TrustStrategy.trustSystemCertificates().strategy(), config.trustStrategy().strategy());
 
 			return mockedDriver;
 		});
diff --git a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jDriverUrlTest.java b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jDriverUrlTest.java
index 05cc59b0..ca2c3be7 100644
--- a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jDriverUrlTest.java
+++ b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jDriverUrlTest.java
@@ -19,6 +19,7 @@
  */
 package org.neo4j.jdbc.bolt;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Rule;
@@ -74,7 +75,7 @@ public class BoltNeo4jDriverUrlTest {
 		mockedDriver = Mocker.mockDriver();
 	}
 
-	@Before
+	@After
 	public void prepare() {
 		BoltDriver.clearCache();
 	}
diff --git a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jPreparedStatementIT.java b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jPreparedStatementIT.java
index 05ed817e..4a70f8b3 100644
--- a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jPreparedStatementIT.java
+++ b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jPreparedStatementIT.java
@@ -19,6 +19,7 @@
  */
 package org.neo4j.jdbc.bolt;
 
+import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.ClassRule;
@@ -48,6 +49,7 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.neo4j.jdbc.bolt.utils.Neo4jContainerUtils.neo4jImageCoordinates;
 
 /**
  * @author AgileLARUS
@@ -56,7 +58,7 @@ import static org.junit.Assert.fail;
 public class BoltNeo4jPreparedStatementIT {
 
 	@ClassRule
-	public static final Neo4jContainer<?> neo4j = new Neo4jContainer<>("neo4j:4.3.0-enterprise").withEnv("NEO4J_ACCEPT_LICENSE_AGREEMENT", "yes").withAdminPassword(null);
+	public static final Neo4jContainer<?> neo4j = new Neo4jContainer<>(neo4jImageCoordinates()).withEnv("NEO4J_ACCEPT_LICENSE_AGREEMENT", "yes").withAdminPassword(null);
 
 	static Connection connection;
 
@@ -64,8 +66,8 @@ public class BoltNeo4jPreparedStatementIT {
 		connection = JdbcConnectionTestUtils.verifyConnection(connection, neo4j);
 	}
 
-	@AfterClass
-	public static void tearDown(){
+	@After
+	public  void tearDown(){
 		JdbcConnectionTestUtils.closeConnection(connection);
 	}
 
diff --git a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jResultSetIT.java b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jResultSetIT.java
index 245d80c2..1e7257e4 100644
--- a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jResultSetIT.java
+++ b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jResultSetIT.java
@@ -20,7 +20,6 @@
 package org.neo4j.jdbc.bolt;
 
 import org.junit.Before;
-import org.junit.BeforeClass;
 import org.junit.ClassRule;
 import org.junit.FixMethodOrder;
 import org.junit.Rule;
@@ -40,26 +39,21 @@ import java.util.Map;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.neo4j.jdbc.bolt.utils.Neo4jContainerUtils.neo4jImageCoordinates;
 
 /**
  * @author AgileLARUS
  * @since 3.0.0
  */
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class BoltNeo4jResultSetIT {
 
-	@ClassRule
-	public static final Neo4jContainer<?> neo4j = new Neo4jContainer<>("neo4j:4.3.0-enterprise")
+	@Rule
+	public final Neo4jContainer<?> neo4j = new Neo4jContainer<>(neo4jImageCoordinates())
 			.withEnv("NEO4J_ACCEPT_LICENSE_AGREEMENT", "yes")
 			.withAdminPassword(null);
 
 	@Rule public ExpectedException expectedEx = ExpectedException.none();
 
-	@Before
-	public void setUp() throws SQLException {
-		JdbcConnectionTestUtils.clearDatabase(neo4j);
-	}
-
 	/*------------------------------*/
 	/*          flattening          */
 	/*------------------------------*/
diff --git a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jResultSetMetaDataIT.java b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jResultSetMetaDataIT.java
index 5fce454a..5aba2846 100644
--- a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jResultSetMetaDataIT.java
+++ b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jResultSetMetaDataIT.java
@@ -48,6 +48,7 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 import static org.neo4j.driver.internal.types.InternalTypeSystem.TYPE_SYSTEM;
+import static org.neo4j.jdbc.bolt.utils.Neo4jContainerUtils.neo4jImageCoordinates;
 
 /**
  * @author AgileLARUS
@@ -58,7 +59,7 @@ public class BoltNeo4jResultSetMetaDataIT {
 	static Connection connectionFlatten;
 
 	@ClassRule
-	public static final Neo4jContainer<?> neo4j = new Neo4jContainer<>("neo4j:4.3.0-enterprise").withEnv("NEO4J_ACCEPT_LICENSE_AGREEMENT", "yes").withAdminPassword(null);
+	public static final Neo4jContainer<?> neo4j = new Neo4jContainer<>(neo4jImageCoordinates()).withEnv("NEO4J_ACCEPT_LICENSE_AGREEMENT", "yes").withAdminPassword(null);
 
 	@Before public void setUp() {
 		connectionFlatten = JdbcConnectionTestUtils.verifyConnection(connectionFlatten, neo4j,",flatten=1");
@@ -68,8 +69,8 @@ public class BoltNeo4jResultSetMetaDataIT {
 		JdbcConnectionTestUtils.clearDatabase(neo4j);
 	}
 
-	@AfterClass
-	public static void tearDownConnection(){
+	@After
+	public void tearDownConnection(){
 		JdbcConnectionTestUtils.closeConnection(connectionFlatten);
 	}
 
diff --git a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jSetParameterDateIT.java b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jSetParameterDateIT.java
index 4572e55d..b805070a 100644
--- a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jSetParameterDateIT.java
+++ b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jSetParameterDateIT.java
@@ -1,5 +1,6 @@
 package org.neo4j.jdbc.bolt;
 
+import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.ClassRule;
@@ -29,6 +30,7 @@ import java.util.TimeZone;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
+import static org.neo4j.jdbc.bolt.utils.Neo4jContainerUtils.neo4jImageCoordinates;
 
 /**
  * Test for the setParameter for Date, Time and Timestamp
@@ -37,7 +39,7 @@ import static org.junit.Assert.assertTrue;
 public class BoltNeo4jSetParameterDateIT {
 
     @ClassRule
-    public static final Neo4jContainer<?> neo4j = new Neo4jContainer<>("neo4j:4.3.0-enterprise").withEnv("NEO4J_ACCEPT_LICENSE_AGREEMENT", "yes").withAdminPassword(null);
+    public static final Neo4jContainer<?> neo4j = new Neo4jContainer<>(neo4jImageCoordinates()).withEnv("NEO4J_ACCEPT_LICENSE_AGREEMENT", "yes").withAdminPassword(null);
 
     static Connection connection;
 
@@ -47,8 +49,8 @@ public class BoltNeo4jSetParameterDateIT {
         connection = JdbcConnectionTestUtils.verifyConnection(connection, neo4j);
     }
 
-    @AfterClass
-    public static void tearDown(){
+    @After
+    public void tearDown(){
         JdbcConnectionTestUtils.closeConnection(connection);
     }
 
diff --git a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jSpatialIT.java b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jSpatialIT.java
index 880082e9..37ce8cac 100644
--- a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jSpatialIT.java
+++ b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jSpatialIT.java
@@ -1,5 +1,6 @@
 package org.neo4j.jdbc.bolt;
 
+import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.ClassRule;
@@ -18,6 +19,7 @@ import java.util.Map;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.neo4j.jdbc.bolt.utils.Neo4jContainerUtils.neo4jImageCoordinates;
 
 /**
   * Test for the spatial objects (point)
@@ -25,7 +27,7 @@ import static org.junit.Assert.assertTrue;
  */
 public class BoltNeo4jSpatialIT {
     @ClassRule
-    public static final Neo4jContainer<?> neo4j = new Neo4jContainer<>("neo4j:4.3.0-enterprise").withEnv("NEO4J_ACCEPT_LICENSE_AGREEMENT", "yes").withAdminPassword(null);
+    public static final Neo4jContainer<?> neo4j = new Neo4jContainer<>(neo4jImageCoordinates()).withEnv("NEO4J_ACCEPT_LICENSE_AGREEMENT", "yes").withAdminPassword(null);
 
     static Connection connection;
 
@@ -35,8 +37,8 @@ public class BoltNeo4jSpatialIT {
         connection = JdbcConnectionTestUtils.verifyConnection(connection, neo4j);
     }
 
-    @AfterClass
-    public static void tearDown(){
+    @After
+    public void tearDown(){
         JdbcConnectionTestUtils.closeConnection(connection);
     }
 
diff --git a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jStatementIT.java b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jStatementIT.java
index fe9d6d68..4745d89e 100644
--- a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jStatementIT.java
+++ b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/BoltNeo4jStatementIT.java
@@ -19,6 +19,7 @@
  */
 package org.neo4j.jdbc.bolt;
 
+import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.ClassRule;
@@ -46,6 +47,7 @@ import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.neo4j.jdbc.bolt.utils.Neo4jContainerUtils.neo4jImageCoordinates;
 
 /**
  * @author AgileLARUS
@@ -54,7 +56,7 @@ import static org.junit.Assert.fail;
 public class BoltNeo4jStatementIT {
 
 	@ClassRule
-	public static final Neo4jContainer<?> neo4j = new Neo4jContainer<>("neo4j:4.3.0-enterprise").withEnv("NEO4J_ACCEPT_LICENSE_AGREEMENT", "yes").withAdminPassword(null);
+	public static final Neo4jContainer<?> neo4j = new Neo4jContainer<>(neo4jImageCoordinates()).withEnv("NEO4J_ACCEPT_LICENSE_AGREEMENT", "yes").withAdminPassword(null);
 
 	@Rule public ExpectedException expectedEx = ExpectedException.none();
 
@@ -65,8 +67,8 @@ public class BoltNeo4jStatementIT {
 		connection = JdbcConnectionTestUtils.verifyConnection(connection, neo4j);
 	}
 
-	@AfterClass
-	public static void tearDown(){
+	@After
+	public void tearDown(){
 		JdbcConnectionTestUtils.closeConnection(connection);
 	}
 
diff --git a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/SampleIT.java b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/SampleIT.java
index 9daadd93..b3c860ec 100644
--- a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/SampleIT.java
+++ b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/SampleIT.java
@@ -38,6 +38,7 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.neo4j.driver.Config.builder;
+import static org.neo4j.jdbc.bolt.utils.Neo4jContainerUtils.neo4jImageCoordinates;
 
 /**
  * @author Stefan Armbruster
@@ -45,7 +46,7 @@ import static org.neo4j.driver.Config.builder;
 public class SampleIT {
 
 	@ClassRule
-	public static final Neo4jContainer<?> neo4j = new Neo4jContainer<>("neo4j:4.3.0-enterprise").withEnv("NEO4J_ACCEPT_LICENSE_AGREEMENT", "yes").withAdminPassword(null);
+	public static final Neo4jContainer<?> neo4j = new Neo4jContainer<>(neo4jImageCoordinates()).withEnv("NEO4J_ACCEPT_LICENSE_AGREEMENT", "yes").withAdminPassword(null);
 
 	@Before
 	public void prepare() {
diff --git a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/cache/BoltDriverCacheTest.java b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/cache/BoltDriverCacheTest.java
index e08ddc44..6cb5598d 100644
--- a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/cache/BoltDriverCacheTest.java
+++ b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/cache/BoltDriverCacheTest.java
@@ -1,5 +1,6 @@
 package org.neo4j.jdbc.bolt.cache;
 
+import org.junit.AfterClass;
 import org.junit.Test;
 import org.mockito.Mockito;
 import org.neo4j.driver.AccessMode;
@@ -10,6 +11,8 @@ import org.neo4j.driver.Driver;
 import org.neo4j.driver.Session;
 import org.neo4j.driver.SessionConfig;
 import org.neo4j.driver.internal.InternalBookmark;
+import org.neo4j.jdbc.bolt.BoltDriver;
+import org.neo4j.jdbc.boltrouting.BoltRoutingNeo4jDriver;
 
 import java.net.URI;
 import java.net.URISyntaxException;
@@ -38,6 +41,12 @@ public class BoltDriverCacheTest {
 
     Function<BoltDriverCacheKey, Driver> builder = (params -> Mockito.mock(Driver.class));
 
+    @AfterClass
+    public static void tearDown() {
+        BoltRoutingNeo4jDriver.clearCache();
+        BoltDriver.clearCache();
+    }
+
     @Test
     public void cacheShouldBeThreadSafe() throws ExecutionException, InterruptedException {
         List<URI> url = Arrays.asList(URI.create("bolt://localhost"));
diff --git a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/utils/JdbcConnectionTestUtils.java b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/utils/JdbcConnectionTestUtils.java
index b3277d6e..0c8c2cce 100644
--- a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/utils/JdbcConnectionTestUtils.java
+++ b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/utils/JdbcConnectionTestUtils.java
@@ -1,11 +1,11 @@
 package org.neo4j.jdbc.bolt.utils;
 
+import org.neo4j.driver.AccessMode;
 import org.neo4j.driver.GraphDatabase;
-import org.neo4j.driver.Record;
 import org.neo4j.driver.Session;
 import org.neo4j.driver.SessionConfig;
 import org.neo4j.jdbc.bolt.BoltDriver;
-import org.neo4j.jdbc.bolt.data.StatementData;
+import org.neo4j.jdbc.boltrouting.BoltRoutingNeo4jDriver;
 import org.testcontainers.containers.Neo4jContainer;
 
 import java.sql.Connection;
@@ -17,6 +17,10 @@ import java.sql.Statement;
 import java.util.Enumeration;
 import java.util.Properties;
 
+import static org.neo4j.jdbc.bolt.utils.Neo4jContainerUtils.getVersion;
+import static org.neo4j.jdbc.bolt.utils.Neo4jContainerUtils.isEnterpriseEdition;
+import static org.neo4j.jdbc.bolt.utils.Neo4jContainerUtils.isV4;
+
 /**
  * Help to build the connection for the IT test
  */
@@ -28,14 +32,14 @@ public class JdbcConnectionTestUtils {
 
     public static boolean warmedup = false;
 
-    private static boolean warmup(){
+    private static boolean warmup() {
         // WARM UP
         long t0 = System.currentTimeMillis();
         boolean driverLoaded = false;
-        while (!driverLoaded && System.currentTimeMillis() - t0 < 10_000){
+        while (!driverLoaded && System.currentTimeMillis() - t0 < 10_000) {
             Enumeration<Driver> drivers = DriverManager.getDrivers();
-            while (drivers.hasMoreElements()){
-                if(BoltDriver.class.equals(drivers.nextElement().getClass())){
+            while (drivers.hasMoreElements()) {
+                if (BoltDriver.class.equals(drivers.nextElement().getClass())) {
                     driverLoaded = true;
                 }
             }
@@ -48,101 +52,103 @@ public class JdbcConnectionTestUtils {
 
     public static Connection getConnection(Neo4jContainer<?> neo4j, String parameters) throws SQLException {
         //return DriverManager.getConnection("jdbc:neo4j:" + neo4j.boltURI() + "?nossl,user=neo4j,password=neo4j");
-        if(!warmedup){
+        if (!warmedup) {
             warmup();
         }
-        return DriverManager.getConnection("jdbc:neo4j:" + neo4j.getBoltUrl() + "?nossl"+parameters,USERNAME,PASSWORD);
+        return DriverManager.getConnection("jdbc:neo4j:" + neo4j.getBoltUrl() + "?nossl" + parameters, USERNAME, PASSWORD);
     }
 
-    public static Properties defaultInfo(){
+    public static Properties defaultInfo() {
         Properties info = new Properties();
-        info.setProperty("user",USERNAME);
-        info.setProperty("password",PASSWORD);
-        info.setProperty("nossl","true");
+        info.setProperty("user", USERNAME);
+        info.setProperty("password", PASSWORD);
+        info.setProperty("nossl", "true");
         return info;
     }
 
     public static Connection getConnection(Neo4jContainer<?> neo4j, Properties info) throws SQLException {
-        if(!warmedup){
+        if (!warmedup) {
             warmup();
         }
-        return DriverManager.getConnection("jdbc:neo4j:" + neo4j.getBoltUrl(),info);
+        return DriverManager.getConnection("jdbc:neo4j:" + neo4j.getBoltUrl(), info);
     }
 
     public static Connection getConnection(Neo4jContainer<?> neo4j) throws SQLException {
         return getConnection(neo4j, "");
     }
 
-    public static Connection verifyConnection(Connection connection, Neo4jContainer<?> neo4j, String parameters){
+    public static Connection verifyConnection(Connection connection, Neo4jContainer<?> neo4j, String parameters) {
         Connection res = connection;
 
         try {
-            if(connection == null || connection.isClosed()){
-                res =  JdbcConnectionTestUtils.getConnection(neo4j,parameters);
-            }else{
+            if (connection == null || connection.isClosed()) {
+                res = JdbcConnectionTestUtils.getConnection(neo4j, parameters);
+            } else {
                 res.setAutoCommit(true);
             }
         } catch (SQLException e) {
-            throw new IllegalStateException(e.getMessage(),e);
+            throw new IllegalStateException(e.getMessage(), e);
         }
 
         return res;
     }
 
-    public static Connection verifyConnection(Connection connection, Neo4jContainer<?> neo4j){
-        return verifyConnection(connection,neo4j,"");
+    public static Connection verifyConnection(Connection connection, Neo4jContainer<?> neo4j) {
+        return verifyConnection(connection, neo4j, "");
     }
 
-    public static void closeConnection(Connection connection){
+    public static void closeConnection(Connection connection) {
         closeConnection(connection, null, null);
     }
 
-    public static void closeConnection(Connection connection, Statement stmt){
+    public static void closeConnection(Connection connection, Statement stmt) {
         closeConnection(connection, stmt, null);
     }
 
-    public static void closeStatement(Statement stmt, ResultSet rs){
+    public static void closeStatement(Statement stmt, ResultSet rs) {
         closeConnection(null, stmt, rs);
     }
 
-    public static void closeStatement(Statement stmt){
+    public static void closeStatement(Statement stmt) {
         closeConnection(null, stmt, null);
     }
 
-    public static void closeResultSet(ResultSet rs){
+    public static void closeResultSet(ResultSet rs) {
         closeConnection(null, null, rs);
     }
 
-    public static void closeConnection(Connection connection, Statement stmt, ResultSet rs){
+    public static void closeConnection(Connection connection, Statement stmt, ResultSet rs) {
         try {
-            if(rs != null &&  !rs.isClosed()){
+            if (rs != null && !rs.isClosed()) {
                 rs.close();
             }
-            if(stmt != null &&  !stmt.isClosed()){
+            if (stmt != null && !stmt.isClosed()) {
                 stmt.close();
             }
-            if(connection != null &&  !connection.isClosed()){
+            if (connection != null && !connection.isClosed()) {
                 connection.close();
             }
         } catch (SQLException e) {
             e.printStackTrace();
+        } finally {
+            BoltRoutingNeo4jDriver.clearCache();
+            BoltDriver.clearCache();
         }
     }
 
     public static void clearDatabase(Neo4jContainer<?> neo4j) {
+        if (!(isV4(neo4j) && isEnterpriseEdition(neo4j))) {
+            try (org.neo4j.driver.Driver driver = GraphDatabase.driver(neo4j.getBoltUrl());
+                 Session session = driver.session(SessionConfig.builder().withDefaultAccessMode(AccessMode.WRITE).build())) {
+                session.run("MATCH (n) DETACH DELETE n");
+            }
+            return;
+        }
         try (org.neo4j.driver.Driver driver = GraphDatabase.driver(neo4j.getBoltUrl());
              Session session = driver.session(SessionConfig.forDatabase("system"))) {
             session.run("DROP DATABASE neo4j").consume();
             session.run("CREATE DATABASE neo4j").consume();
-            int counter = 0;
-            while (++counter < 5 && session.run("show databases yield name where name = 'neo4j' return count(*) AS count")
-                    .single()
-                    .get("count")
-                    .asLong() <= 0) {
-                try {
-                    Thread.sleep(100);
-                } catch (InterruptedException ignored) {}
-            }
+            waitForDatabase(getVersion(neo4j), session);
         }
     }
 
@@ -152,4 +158,26 @@ public class JdbcConnectionTestUtils {
             session.run(statement).consume();
         }
     }
+
+    private static void waitForDatabase(String version, Session session) {
+        // YIELD is not supported in Neo4j 4.0
+        // SHOW..YIELD..RETURN is not supported until Neo4j 4.2
+        if (version.startsWith("4.0") || version.startsWith("4.1")) {
+            try {
+                Thread.sleep(500);
+            } catch (InterruptedException ignored) {
+            }
+            return;
+        }
+        int counter = 0;
+        while (++counter < 5 && session.run("SHOW DATABASES YIELD name WHERE name = 'neo4j' RETURN count(*) AS count")
+                .single()
+                .get("count")
+                .asLong() <= 0) {
+            try {
+                Thread.sleep(100);
+            } catch (InterruptedException ignored) {
+            }
+        }
+    }
 }
diff --git a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/utils/Neo4jContainerUtils.java b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/utils/Neo4jContainerUtils.java
new file mode 100644
index 00000000..07b06cfb
--- /dev/null
+++ b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/utils/Neo4jContainerUtils.java
@@ -0,0 +1,35 @@
+package org.neo4j.jdbc.bolt.utils;
+
+import org.testcontainers.containers.Neo4jContainer;
+import org.testcontainers.utility.DockerImageName;
+
+public class Neo4jContainerUtils {
+
+    public static String neo4jImageCoordinates() {
+        String neo4jVersion = System.getenv("NEO4J_VERSION");
+        if (neo4jVersion == null) neo4jVersion = "4.3";
+        String enterpriseEdition = System.getenv("NEO4J_ENTERPRISE_EDITION");
+        if (enterpriseEdition == null) enterpriseEdition = "false";
+        return String.format("neo4j:%s%s", neo4jVersion, Boolean.parseBoolean(enterpriseEdition) ? "-enterprise": "");
+    }
+
+    public static boolean isV3(Neo4jContainer<?> neo4j) {
+        return versionStartsWith(neo4j, "3");
+    }
+
+    public static boolean isV4(Neo4jContainer<?> neo4j) {
+        return versionStartsWith(neo4j, "4");
+    }
+
+    public static boolean isEnterpriseEdition(Neo4jContainer<?> neo4j) {
+        return getVersion(neo4j).endsWith("-enterprise");
+    }
+
+    public static String getVersion(Neo4jContainer<?> neo4j) {
+        return DockerImageName.parse(neo4j.getDockerImageName()).getVersionPart();
+    }
+
+    private static boolean versionStartsWith(Neo4jContainer<?> neo4j, String prefix) {
+        return getVersion(neo4j).startsWith(prefix);
+    }
+}
diff --git a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/boltrouting/BoltRoutingIT.java b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/boltrouting/BoltRoutingIT.java
index 5622e974..8763e400 100644
--- a/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/boltrouting/BoltRoutingIT.java
+++ b/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/boltrouting/BoltRoutingIT.java
@@ -21,6 +21,7 @@ package org.neo4j.jdbc.boltrouting;
 import org.junit.*;
 import org.junit.rules.ExpectedException;
 import org.neo4j.TestcontainersCausalCluster;
+import org.neo4j.jdbc.bolt.BoltDriver;
 
 import java.sql.*;
 import java.time.Duration;
@@ -57,6 +58,8 @@ public class BoltRoutingIT {
         if (cluster != null) {
             cluster.close();
         }
+        BoltRoutingNeo4jDriver.clearCache();
+        BoltDriver.clearCache();
     }
 
     @Rule public ExpectedException expectedEx = ExpectedException.none();
diff --git a/neo4j-jdbc-driver/src/test/java/org/neo4j/jdbc/DriverTestIT.java b/neo4j-jdbc-driver/src/test/java/org/neo4j/jdbc/DriverTestIT.java
index 02fc75ea..be7fbeb1 100644
--- a/neo4j-jdbc-driver/src/test/java/org/neo4j/jdbc/DriverTestIT.java
+++ b/neo4j-jdbc-driver/src/test/java/org/neo4j/jdbc/DriverTestIT.java
@@ -50,7 +50,7 @@ public class DriverTestIT {
 	@Rule public ExpectedException expectedEx = ExpectedException.none();
 
 	@ClassRule
-	public static final Neo4jContainer<?> neo4j = new Neo4jContainer<>("neo4j:4.3.0-enterprise").withEnv("NEO4J_ACCEPT_LICENSE_AGREEMENT", "yes").withAdminPassword(null);
+	public static final Neo4jContainer<?> neo4j = new Neo4jContainer<>(neo4jImageCoordinates()).withEnv("NEO4J_ACCEPT_LICENSE_AGREEMENT", "yes").withAdminPassword(null);
 
 	@Test public void shouldReturnAHttpConnection() throws SQLException {
 		Driver driver = new Driver();
@@ -112,4 +112,12 @@ public class DriverTestIT {
 		verify(mysqlDriver, times(1)).connect(anyString(), any(Properties.class));
 	}
 
+	// duplicate of neo4j-jdbc-bolt ContainerUtils
+	private static String neo4jImageCoordinates() {
+		String neo4jVersion = System.getenv("NEO4J_VERSION");
+		if (neo4jVersion == null) neo4jVersion = "4.3";
+		String enterpriseEdition = System.getenv("NEO4J_ENTERPRISE_EDITION");
+		if (enterpriseEdition == null) enterpriseEdition = "false";
+		return String.format("neo4j:%s%s", neo4jVersion, Boolean.parseBoolean(enterpriseEdition) ? "-enterprise": "");
+	}
 }