public static DataSource createTestDataSource(final AbstractDbConfig dbConfig,
                                                  final String name,
                                                  final boolean unique,
                                                  final boolean isSharedDatabase) {

        if ("org.sqlite.JDBC".equals(dbConfig.getConnectionConfig().getClassName())) {
            final HikariConfig hikariConfig = HikariUtil.createConfig(dbConfig);
            return new HikariDataSource(hikariConfig);
        }


        // See if we have a local data source.
        AbstractDbConfig testDbConfig = getDbConfigThreadLocal(isSharedDatabase).get();
        String dbName = getDbNameThreadLocal(isSharedDatabase).get();

        LOGGER.info("createDataSource - isSharedDatabase: {}, testDbConfig: {}, dbName: {}",
                isSharedDatabase,
                NullSafe.get(testDbConfig, Objects::toIdentityString),
                dbName);
        if (testDbConfig == null || dbName == null || !isSharedDatabase) {
            // Create a merged config using the common db config as a base.
            final ConnectionConfig connectionConfig = createConnectionConfig(dbConfig);
            final ConnectionConfig rootConnectionConfig = createRootConnectionConfig(connectionConfig);

            // Create new db.
            final Properties connectionProps = new Properties();
            connectionProps.put("user", rootConnectionConfig.getUser());
            connectionProps.put("password", rootConnectionConfig.getPassword());

            LOGGER.debug("Connecting to DB as root connection with URL: {}",
                    rootConnectionConfig.getUrl());

            if (dbName == null || !isSharedDatabase) {
                dbName = createTestDbName();
                LOGGER.info("Created new database name '{}'", dbName);
//                dbName = Objects.requireNonNullElseGet(
//                        getDbNameThreadLocal(isSharedDatabase).get(),
//                        DbTestUtil::createTestDbName);
                getDbNameThreadLocal(isSharedDatabase).set(dbName);
            }

            LOGGER.info(LogUtil.inBoxOnNewLine("Creating {} test database: {} for thread: {}",
                    (isSharedDatabase
                            ? "shared"
                            : "independent"),
                    dbName,
                    Thread.currentThread().getName()));

            // ********************************************************************************
            // NOTE: the test database created here for this thread will be dropped once
            // all tests (on this JVM) have finished. See:
            // stroom.test.common.util.test.StroomTestExecutionListener
            // See also stroom.test.DatabaseCommonTestControl#main for a manual way of deleting
            // all these test DBs.
            // ********************************************************************************

            try (final Connection connection = DriverManager.getConnection(rootConnectionConfig.getUrl(),
                    connectionProps)) {
                final String username = connectionConfig.getUser();
                final String password = connectionConfig.getPassword();
                createStroomDatabaseAndUser(connection, dbName, username, password);
            } catch (final SQLException e) {
                throw new RuntimeException(e.getMessage(), e);
            }

            // Create a URL for connecting to the new DB.
            final String url = DbUrl
                    .builder()
                    .parse(rootConnectionConfig.getUrl())
                    .dbName(dbName)
                    .build()
                    .toString();

            final ConnectionConfig newConnectionConfig = connectionConfig
                    .copy()
                    .url(url)
                    .build();
            LOGGER.info("Using DB connection url: {}", url);
            testDbConfig = new AbstractDbConfig(
                    newConnectionConfig,
                    dbConfig.getConnectionPoolConfig()) {
            };

            getDbConfigThreadLocal(isSharedDatabase).set(testDbConfig);
        } else {
            LOGGER.info(LogUtil.inBoxOnNewLine("Reusing shared database: {}, on thread: {}",
                    getDbNameThreadLocal(true).get(),
                    Thread.currentThread().getName()));
        }

        final DataSource dataSource = createDataSource(
                name,
                (unique || !isSharedDatabase),
                testDbConfig);

        Set<DataSource> dataSources = LOCAL_DATA_SOURCES.get();
        if (dataSources == null) {
            dataSources = new HashSet<>();
            LOCAL_DATA_SOURCES.set(dataSources);
        }
        dataSources.add(dataSource);

        return dataSource;
    }
@param dbConfig         The config to use
@param name             The name of the datasource, i.e. the module name
@param unique           True if we want our own dedicated connection pool
@param isSharedDatabase True if we want to re-use the DB between tests. We normally do
                        to save on the cost of running migrations, but not for
                        migration tests as for those we want a blank db.
stroom-test-common/src/main/java/stroom/test/common/util/db/DbTestUtil.java