*/
package org.sonar.server.db;
+import com.google.common.annotations.VisibleForTesting;
import org.apache.commons.dbutils.DbUtils;
import org.apache.ibatis.session.SqlSession;
import org.slf4j.LoggerFactory;
try {
session = myBatis.openSession();
connection = session.getConnection();
- DdlUtils.createSchema(connection, database.getDialect().getId());
+ createSchema(connection, database.getDialect().getId());
return true;
} finally {
MyBatis.closeQuietly(session);
throw new IllegalStateException("Fail to execute database migration: " + className, e);
}
}
+
+ @VisibleForTesting
+ protected void createSchema(Connection connection, String dialectId) {
+ DdlUtils.createSchema(connection, dialectId);
+ }
}
*/
package org.sonar.server.db;
+import com.google.common.annotations.VisibleForTesting;
import org.apache.commons.lang.StringUtils;
import org.h2.Driver;
import org.h2.tools.Server;
this.settings = settings;
}
- private static File getDataDirectory(Settings settings) {
- String dirName = settings.getString(DatabaseProperties.PROP_EMBEDDED_DATA_DIR);
- if (!StringUtils.isBlank(dirName)) {
- return new File(dirName);
- }
-
- File sonarHome = new File(settings.getString(CoreProperties.SONAR_HOME));
- if (sonarHome.isDirectory() && sonarHome.exists()) {
- return new File(sonarHome, "data");
- }
-
- throw new IllegalStateException("SonarQube home directory does not exist");
- }
-
public void start() {
File dbHome = getDataDirectory(settings);
- if (dbHome.exists() && !dbHome.isDirectory()) {
- throw new SonarException("Database home " + dbHome.getPath() + " is not a directory");
- }
if (!dbHome.exists()) {
dbHome.mkdirs();
}
}
}
+ @VisibleForTesting
+ File getDataDirectory(Settings settings) {
+ String dirName = settings.getString(DatabaseProperties.PROP_EMBEDDED_DATA_DIR);
+ if (!StringUtils.isBlank(dirName)) {
+ return getEmbeddedDataDirectory(dirName);
+ }
+ return getSonarHomeDataDirectory(settings);
+ }
+
+ private File getEmbeddedDataDirectory(String directoryName) {
+ File embeddedDataDirectory = new File(directoryName);
+ if(embeddedDataDirectory.exists() && !embeddedDataDirectory.isDirectory()) {
+ throw new SonarException("Database home " + embeddedDataDirectory.getAbsolutePath() + " is not a directory");
+ }
+ return embeddedDataDirectory;
+ }
+
+ private File getSonarHomeDataDirectory(Settings settings) {
+ File sonarHome = new File(settings.getString(CoreProperties.SONAR_HOME));
+ if (!sonarHome.isDirectory()) {
+ throw new IllegalStateException("SonarQube home directory is not valid");
+ }
+ return new File(sonarHome, "data");
+ }
+
private String getSetting(String name, String defaultValue) {
return StringUtils.defaultIfBlank(settings.getString(name), defaultValue);
}
*/
package org.sonar.server.db;
+import com.google.common.annotations.VisibleForTesting;
import org.sonar.api.config.Settings;
import org.sonar.api.database.DatabaseProperties;
-import org.sonar.core.persistence.dialect.H2;
public class EmbeddedDatabaseFactory {
private final Settings settings;
- private final H2 dialect;
private EmbeddedDatabase embeddedDatabase;
public EmbeddedDatabaseFactory(Settings settings) {
this.settings = settings;
- dialect = new H2();
}
public void start() {
if (embeddedDatabase == null) {
String jdbcUrl = settings.getString(DatabaseProperties.PROP_URL);
- if (dialect.matchesJdbcURL(jdbcUrl)) {
- embeddedDatabase = new EmbeddedDatabase(settings);
+ if (jdbcUrl.startsWith("jdbc:h2:tcp:")) {
+ embeddedDatabase = getEmbeddedDatabase(settings);
embeddedDatabase.start();
}
}
embeddedDatabase.stop();
}
}
+
+ @VisibleForTesting
+ EmbeddedDatabase getEmbeddedDatabase(Settings settings) {
+ return new EmbeddedDatabase(settings);
+ }
}
*/
package org.sonar.server.db;
+import org.apache.ibatis.session.SqlSession;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.core.persistence.AbstractDaoTestCase;
import org.sonar.core.persistence.Database;
import org.sonar.core.persistence.MyBatis;
+import org.sonar.core.persistence.dialect.Dialect;
+import org.sonar.core.persistence.dialect.H2;
import org.sonar.core.persistence.dialect.MySql;
+import java.sql.Connection;
+
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Mockito.*;
assertThat(FakeMigration.executed).isTrue();
}
+ @Test
+ public void should_create_schema_on_h2() throws Exception {
+
+ Dialect supportedDialect = new H2();
+ when(database.getDialect()).thenReturn(supportedDialect);
+ Connection connection = mock(Connection.class);
+ SqlSession session = mock(SqlSession.class);
+ when(session.getConnection()).thenReturn(connection);
+ when(mybatis.openSession()).thenReturn(session);
+
+ DatabaseMigrator databaseMigrator = new DatabaseMigrator(mybatis, database) {
+ @Override
+ protected void createSchema(Connection connection, String dialectId) {
+ }
+ };
+
+ assertThat(databaseMigrator.createDatabase()).isTrue();
+ }
+
public static class FakeMigration implements DatabaseMigration {
static boolean executed = false;
@Override
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.db;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.config.Settings;
+import org.sonar.api.database.DatabaseProperties;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+public class EmbeddedDatabaseFactoryTest {
+
+ private Settings settings;
+
+ @Before
+ public void initSettings() {
+ settings = new Settings();
+ }
+
+ @Test
+ public void should_start_and_stop_tcp_h2_database() throws Exception {
+ settings.setProperty(DatabaseProperties.PROP_URL, "jdbc:h2:tcp:localhost");
+
+ final EmbeddedDatabase embeddedDatabase = mock(EmbeddedDatabase.class);
+
+ EmbeddedDatabaseFactory databaseFactory = new EmbeddedDatabaseFactory(settings) {
+ @Override
+ EmbeddedDatabase getEmbeddedDatabase(Settings settings) {
+ return embeddedDatabase;
+ }
+ };
+ databaseFactory.start();
+ databaseFactory.stop();
+
+ verify(embeddedDatabase).start();
+ verify(embeddedDatabase).stop();
+ }
+
+ @Test
+ public void should_not_start_mem_h2_database() throws Exception {
+ settings.setProperty(DatabaseProperties.PROP_URL, "jdbc:h2:mem");
+
+ final EmbeddedDatabase embeddedDatabase = mock(EmbeddedDatabase.class);
+
+ EmbeddedDatabaseFactory databaseFactory = new EmbeddedDatabaseFactory(settings) {
+ @Override
+ EmbeddedDatabase getEmbeddedDatabase(Settings settings) {
+ return embeddedDatabase;
+ }
+ };
+ databaseFactory.start();
+
+ verify(embeddedDatabase, never()).start();
+ }
+}
package org.sonar.server.db;
import org.h2.Driver;
-
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.CoreProperties;
import org.sonar.api.config.Settings;
import org.sonar.api.database.DatabaseProperties;
+import org.sonar.api.utils.SonarException;
+import java.io.File;
import java.io.IOException;
import java.net.ServerSocket;
import java.sql.DriverManager;
import static junit.framework.Assert.fail;
+import static org.fest.assertions.Assertions.assertThat;
public class EmbeddedDatabaseTest {
+
+ @Rule
+ public ExpectedException throwable = ExpectedException.none();
+
@Test(timeout = 10000)
public void should_start_and_stop() throws IOException {
int port = freeServerPort();
- EmbeddedDatabase database = new EmbeddedDatabase(settings(port));
+ EmbeddedDatabase database = new EmbeddedDatabase(testSettings(port));
database.start();
try {
public void should_support_memory_database() throws IOException {
int port = freeServerPort();
- EmbeddedDatabase database = new EmbeddedDatabase(settings(port)
+ EmbeddedDatabase database = new EmbeddedDatabase(testSettings(port)
.setProperty(DatabaseProperties.PROP_URL, "jdbc:h2:tcp://localhost:" + port + "/mem:sonarIT;USER=sonar;PASSWORD=sonar"));
database.start();
database.stop();
}
- static Settings settings(int port) {
+ @Test
+ public void should_return_sonar_home_directory() throws Exception {
+ Settings settings = testSettings(0);
+ settings.setProperty(CoreProperties.SONAR_HOME, ".");
+ settings.setProperty(DatabaseProperties.PROP_EMBEDDED_DATA_DIR, "");
+
+ EmbeddedDatabase database = new EmbeddedDatabase(settings);
+
+ File dataDirectory = database.getDataDirectory(settings);
+ assertThat(dataDirectory).isNotNull();
+ assertThat(dataDirectory.getPath()).endsWith("data");
+ }
+
+ @Test
+ public void should_fail_on_invalid_sonar_home_directory() throws Exception {
+ throwable.expect(IllegalStateException.class);
+
+ String testPath = getClass().getResource(".").getPath();
+
+ Settings settings = testSettings(0);
+ settings.setProperty(CoreProperties.SONAR_HOME, testPath + "/unmatched_directory");
+ settings.setProperty(DatabaseProperties.PROP_EMBEDDED_DATA_DIR, "");
+
+ EmbeddedDatabase database = new EmbeddedDatabase(settings);
+ database.getDataDirectory(settings);
+ }
+
+ @Test
+ public void should_return_embedded_data_directory() throws Exception {
+
+ Settings settings = testSettings(0);
+ EmbeddedDatabase database = new EmbeddedDatabase(settings);
+
+ File dataDirectory = database.getDataDirectory(settings);
+ assertThat(dataDirectory).isNotNull();
+ assertThat(dataDirectory.getPath()).endsWith("testDB");
+ }
+
+ @Test
+ public void should_fail_on_invalid_data_directory() throws Exception {
+ throwable.expect(SonarException.class);
+
+ String testPath = getClass().getResource(".").getPath();
+
+ Settings settings = testSettings(0);
+ settings.setProperty(DatabaseProperties.PROP_EMBEDDED_DATA_DIR, testPath + "/invalid_db_data_file");
+
+ EmbeddedDatabase database = new EmbeddedDatabase(settings);
+ database.start();
+ }
+
+ static Settings testSettings(int port) {
return new Settings()
.setProperty(DatabaseProperties.PROP_USER, "login")
.setProperty(DatabaseProperties.PROP_PASSWORD, "pwd")