Browse Source

SONAR-8520 remove H2 specific way of creating database in Unit tests

tags/8.0
Sébastien Lesaint 4 years ago
parent
commit
b83c58503a

+ 2
- 2
server/sonar-db-dao/src/test/java/org/sonar/db/MyBatisTest.java View File

import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;


public class MyBatisTest { public class MyBatisTest {
private static H2Database database;
private static SQDatabase database;


@BeforeClass @BeforeClass
public static void start() { public static void start() {
database = new H2Database("sonar2", true);
database = SQDatabase.newH2Database("sonar2", true);
database.start(); database.start();
} }



server/sonar-db-dao/src/test/java/org/sonar/db/H2Database.java → server/sonar-db-dao/src/test/java/org/sonar/db/SQDatabase.java View File

*/ */
package org.sonar.db; package org.sonar.db;


import java.io.PrintWriter;
import java.sql.Connection; import java.sql.Connection;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.List; import java.util.List;
import javax.sql.DataSource; import javax.sql.DataSource;
import org.apache.commons.dbutils.DbUtils; import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.io.output.NullWriter;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.jdbc.ScriptRunner;
import org.sonar.api.SonarEdition; import org.sonar.api.SonarEdition;
import org.sonar.api.SonarQubeSide; import org.sonar.api.SonarQubeSide;
import org.sonar.api.config.Settings;
import org.sonar.api.config.internal.MapSettings;
import org.sonar.api.internal.SonarRuntimeImpl; import org.sonar.api.internal.SonarRuntimeImpl;
import org.sonar.api.utils.System2; import org.sonar.api.utils.System2;
import org.sonar.api.utils.Version; import org.sonar.api.utils.Version;
import org.sonar.core.util.UuidFactoryFast; import org.sonar.core.util.UuidFactoryFast;
import org.sonar.core.util.logs.Profiler; import org.sonar.core.util.logs.Profiler;
import org.sonar.db.dialect.Dialect; import org.sonar.db.dialect.Dialect;
import org.sonar.db.dialect.H2;
import org.sonar.process.logging.LogbackHelper;
import org.sonar.server.platform.db.migration.MigrationConfigurationModule; import org.sonar.server.platform.db.migration.MigrationConfigurationModule;
import org.sonar.server.platform.db.migration.engine.MigrationContainer; import org.sonar.server.platform.db.migration.engine.MigrationContainer;
import org.sonar.server.platform.db.migration.engine.MigrationContainerImpl; import org.sonar.server.platform.db.migration.engine.MigrationContainerImpl;


import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Preconditions.checkState;


/**
* H2 in-memory database, used for unit tests against an empty DB, a specific script or against SQ schema.
*/
public class H2Database extends CoreH2Database {
public class SQDatabase extends DefaultDatabase {
private final boolean createSchema; private final boolean createSchema;


/**
* IMPORTANT: change DB name in order to not conflict with {@link DefaultDatabaseTest}
*/
public H2Database(String name, boolean createSchema) {
super(name);
private SQDatabase(Settings settings, boolean createSchema) {
super(new LogbackHelper(), settings);
this.createSchema = createSchema; this.createSchema = createSchema;
} }


public static SQDatabase newDatabase(Settings settings, boolean createSchema) {
return new SQDatabase(settings, createSchema);
}

public static SQDatabase newH2Database(String name, boolean createSchema) {
MapSettings settings = new MapSettings()
.setProperty("sonar.jdbc.dialect", "h2")
.setProperty("sonar.jdbc.driverClassName", "org.h2.Driver")
.setProperty("sonar.jdbc.url", "jdbc:h2:mem:" + name)
.setProperty("sonar.jdbc.username", "sonar")
.setProperty("sonar.jdbc.password", "sonar");
return new SQDatabase(settings, createSchema);
}

@Override @Override
public void start() { public void start() {
super.start(); super.start();
Connection connection = null; Connection connection = null;
try { try {
connection = getDataSource().getConnection(); connection = getDataSource().getConnection();
NoopH2Database noopH2Database = new NoopH2Database();
NoopDatabase noopDatabase = new NoopDatabase(getDialect(), getDataSource());
// create and populate schema // create and populate schema
createMigrationHistoryTable(noopH2Database);
executeDbMigrations(noopH2Database);
createMigrationHistoryTable(noopDatabase);
executeDbMigrations(noopDatabase);
} catch (SQLException e) { } catch (SQLException e) {
throw new IllegalStateException("Fail to create schema", e); throw new IllegalStateException("Fail to create schema", e);
} finally { } finally {
} }


private void execute(RegisteredMigrationStep step, MigrationStep migrationStep) { private void execute(RegisteredMigrationStep step, MigrationStep migrationStep) {
Profiler stepProfiler = Profiler.create(Loggers.get(H2Database.class));
Profiler stepProfiler = Profiler.create(Loggers.get(SQDatabase.class));
stepProfiler.startInfo(STEP_START_PATTERN, step); stepProfiler.startInfo(STEP_START_PATTERN, step);
boolean done = false; boolean done = false;
try { try {
} }
} }


private void executeDbMigrations(NoopH2Database noopH2Database) {
private void executeDbMigrations(NoopDatabase noopDatabase) {
ComponentContainer parentContainer = new ComponentContainer(); ComponentContainer parentContainer = new ComponentContainer();
parentContainer.add(noopH2Database);
parentContainer.add(noopDatabase);
parentContainer.add(H2MigrationContainerPopulator.class); parentContainer.add(H2MigrationContainerPopulator.class);
MigrationConfigurationModule migrationConfigurationModule = new MigrationConfigurationModule(); MigrationConfigurationModule migrationConfigurationModule = new MigrationConfigurationModule();
migrationConfigurationModule.configure(parentContainer); migrationConfigurationModule.configure(parentContainer);
.execute(migrationSteps.readAll()); .execute(migrationSteps.readAll());
} }


private void createMigrationHistoryTable(NoopH2Database noopH2Database) {
new MigrationHistoryTableImpl(noopH2Database).start();
private void createMigrationHistoryTable(NoopDatabase noopDatabase) {
new MigrationHistoryTableImpl(noopDatabase).start();
} }


private class NoopH2Database implements Database {
private class NoopDatabase implements Database {
private final Dialect dialect;
private final DataSource dataSource;

private NoopDatabase(Dialect dialect, DataSource dataSource) {
this.dialect = dialect;
this.dataSource = dataSource;
}

@Override @Override
public DataSource getDataSource() { public DataSource getDataSource() {
return H2Database.this.getDataSource();
return dataSource;
} }


@Override @Override
public Dialect getDialect() { public Dialect getDialect() {
return new H2();
return dialect;
} }


@Override @Override
// do nothing // do nothing
} }
} }

public void executeScript(String classloaderPath) {
try (Connection connection = getDataSource().getConnection()) {
executeScript(connection, classloaderPath);
} catch (SQLException e) {
throw new IllegalStateException("Fail to execute script: " + classloaderPath, e);
}
}

private static void executeScript(Connection connection, String path) {
ScriptRunner scriptRunner = newScriptRunner(connection);
try {
scriptRunner.runScript(Resources.getResourceAsReader(path));
connection.commit();

} catch (Exception e) {
throw new IllegalStateException("Fail to restore: " + path, e);
}
}

private static ScriptRunner newScriptRunner(Connection connection) {
ScriptRunner scriptRunner = new ScriptRunner(connection);
scriptRunner.setDelimiter(";");
scriptRunner.setStopOnError(true);
scriptRunner.setLogWriter(new PrintWriter(new NullWriter()));
return scriptRunner;
}
} }

server/sonar-db-dao/src/test/java/org/sonar/db/H2DatabaseTest.java → server/sonar-db-dao/src/test/java/org/sonar/db/SQDatabaseForH2Test.java View File



import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;


public class H2DatabaseTest {
H2Database db = new H2Database("sonar2", true);
public class SQDatabaseForH2Test {
SQDatabase db = SQDatabase.newH2Database("sonar2", true);


@Before @Before
public void startDb() { public void startDb() {

+ 2
- 2
server/sonar-db-dao/src/test/java/org/sonar/db/TestDbImpl.java View File

if (dialect != null && !"h2".equals(dialect)) { if (dialect != null && !"h2".equals(dialect)) {
return new DefaultDatabase(new LogbackHelper(), settings); return new DefaultDatabase(new LogbackHelper(), settings);
} }
return new H2Database("h2Tests" + DigestUtils.md5Hex(StringUtils.defaultString(schemaPath)), schemaPath == null);
return SQDatabase.newH2Database("h2Tests" + DigestUtils.md5Hex(StringUtils.defaultString(schemaPath)), schemaPath == null);
}; };
Consumer<Database> schemaPathExecutor = database -> { Consumer<Database> schemaPathExecutor = database -> {
if (schemaPath == null) { if (schemaPath == null) {
database.stop(); database.stop();
throw new AssumptionViolatedException("This test is intended to be run on H2 only"); throw new AssumptionViolatedException("This test is intended to be run on H2 only");
} }
((H2Database) database).executeScript(schemaPath);
((SQDatabase) database).executeScript(schemaPath);
}; };
BiConsumer<Database, Boolean> createMyBatis = (db, created) -> myBatis = newMyBatis(db, confExtensions); BiConsumer<Database, Boolean> createMyBatis = (db, created) -> myBatis = newMyBatis(db, confExtensions);
init(databaseCreator, schemaPathExecutor, createMyBatis); init(databaseCreator, schemaPathExecutor, createMyBatis);

+ 2
- 2
server/sonar-db-dao/src/test/java/org/sonar/db/dump/SQSchemaDumper.java View File

import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import org.sonar.db.H2Database;
import org.sonar.db.SQDatabase;


import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Preconditions.checkState;


}).thenComparing(String.CASE_INSENSITIVE_ORDER); }).thenComparing(String.CASE_INSENSITIVE_ORDER);


String dumpToText() throws SQLException { String dumpToText() throws SQLException {
H2Database database = new H2Database("SQSchemaDumper", true);
SQDatabase database = SQDatabase.newH2Database("SQSchemaDumper", true);
database.start(); database.start();


try (Connection connection = database.getDataSource().getConnection(); try (Connection connection = database.getDataSource().getConnection();

+ 1
- 1
sonar-application/src/main/assembly/conf/sonar.properties View File

# Permissions to create tables, indices and triggers must be granted to JDBC user. # Permissions to create tables, indices and triggers must be granted to JDBC user.
# The schema must be created first. # The schema must be created first.
#sonar.jdbc.username= #sonar.jdbc.username=
#sonar.jdbc.password=
#sonar.jdbc.=


#----- Embedded Database (default) #----- Embedded Database (default)
# H2 embedded database server listening port, defaults to 9092 # H2 embedded database server listening port, defaults to 9092

Loading…
Cancel
Save