]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-8445 move PlatformDatabaseMigration to package migration
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Thu, 8 Dec 2016 10:53:37 +0000 (11:53 +0100)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Wed, 14 Dec 2016 11:11:52 +0000 (12:11 +0100)
instead of package migrations, so that it is located as if it was in sonar-db-migration

17 files changed:
server/sonar-server/src/main/java/org/sonar/server/platform/db/migration/DatabaseMigrationExecutorService.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/platform/db/migration/DatabaseMigrationExecutorServiceImpl.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/platform/db/migration/DatabaseMigrationImpl.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/platform/db/migration/package-info.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/platform/db/migrations/PlatformDatabaseMigration.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/platform/db/migrations/PlatformDatabaseMigrationExecutorService.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/platform/db/migrations/PlatformDatabaseMigrationExecutorServiceImpl.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel2.java
server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevelSafeMode.java
server/sonar-server/src/test/java/org/sonar/server/platform/db/migration/DatabaseMigrationExecutorServiceAdaptor.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/platform/db/migration/DatabaseMigrationImplAsynchronousTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/platform/db/migration/DatabaseMigrationImplConcurrentAccessTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/platform/db/migration/DatabaseMigrationImplTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/platform/db/migrations/PlatformDatabaseMigrationAsynchronousTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/platform/db/migrations/PlatformDatabaseMigrationConcurrentAccessTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/platform/db/migrations/PlatformDatabaseMigrationExecutorServiceAdaptor.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/platform/db/migrations/PlatformDatabaseMigrationTest.java [deleted file]

diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/db/migration/DatabaseMigrationExecutorService.java b/server/sonar-server/src/main/java/org/sonar/server/platform/db/migration/DatabaseMigrationExecutorService.java
new file mode 100644 (file)
index 0000000..4e6f70b
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.platform.db.migration;
+
+import java.util.concurrent.ExecutorService;
+
+/**
+ * Flag interface for the ExecutorService to be used by the {@link DatabaseMigrationImpl}
+ * component.
+ */
+public interface DatabaseMigrationExecutorService extends ExecutorService {
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/db/migration/DatabaseMigrationExecutorServiceImpl.java b/server/sonar-server/src/main/java/org/sonar/server/platform/db/migration/DatabaseMigrationExecutorServiceImpl.java
new file mode 100644 (file)
index 0000000..6afec11
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.platform.db.migration;
+
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+import org.sonar.server.util.AbstractStoppableExecutorService;
+
+import java.util.concurrent.Executors;
+
+/**
+ * Since only one DB migration can run at a time, this implementation of DatabaseMigrationExecutorService
+ * wraps a single thread executor from the JDK.
+ */
+public class DatabaseMigrationExecutorServiceImpl
+  extends AbstractStoppableExecutorService
+  implements DatabaseMigrationExecutorService {
+
+  public DatabaseMigrationExecutorServiceImpl() {
+    super(
+      Executors.newSingleThreadExecutor(
+        new ThreadFactoryBuilder()
+          .setDaemon(false)
+          .setNameFormat("DB_migration-%d")
+          .build()
+        ));
+  }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/db/migration/DatabaseMigrationImpl.java b/server/sonar-server/src/main/java/org/sonar/server/platform/db/migration/DatabaseMigrationImpl.java
new file mode 100644 (file)
index 0000000..4770873
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.platform.db.migration;
+
+import java.util.Date;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.ReentrantLock;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
+import org.sonar.api.utils.log.Profiler;
+import org.sonar.server.platform.Platform;
+import org.sonar.server.ruby.RubyBridge;
+
+import static org.sonar.server.platform.db.migration.DatabaseMigrationState.Status;
+
+/**
+ * Handles concurrency to make sure only one DB migration can run at a time.
+ */
+public class DatabaseMigrationImpl implements DatabaseMigration {
+
+  private static final Logger LOGGER = Loggers.get(DatabaseMigrationImpl.class);
+
+  private final RubyBridge rubyBridge;
+  /**
+   * ExecutorService implements threads management.
+   */
+  private final DatabaseMigrationExecutorService executorService;
+  private final Platform platform;
+  private final MutableDatabaseMigrationState migrationState;
+  /**
+   * This lock implements thread safety from concurrent calls of method {@link #startIt()}
+   */
+  private final ReentrantLock lock = new ReentrantLock();
+
+  /**
+   * This property acts as a semaphore to make sure at most one db migration task is created at a time.
+   * <p>
+   * It is set to {@code true} by the first thread to execute the {@link #startIt()} method and set to {@code false}
+   * by the thread executing the db migration.
+   * </p>
+   */
+  private final AtomicBoolean running = new AtomicBoolean(false);
+
+  public DatabaseMigrationImpl(RubyBridge rubyBridge, DatabaseMigrationExecutorService executorService, Platform platform,
+                               MutableDatabaseMigrationState migrationState) {
+    this.rubyBridge = rubyBridge;
+    this.executorService = executorService;
+    this.platform = platform;
+    this.migrationState = migrationState;
+  }
+
+  @Override
+  public void startIt() {
+    if (lock.isLocked() || this.running.get()) {
+      LOGGER.trace("{}: lock is already taken or process is already running", Thread.currentThread().getName());
+      return;
+    }
+
+    if (lock.tryLock()) {
+      try {
+        startAsynchronousDBMigration();
+      } finally {
+        lock.unlock();
+      }
+    }
+  }
+
+  /**
+   * This method is not thread safe and must be externally protected from concurrent executions.
+   */
+  private void startAsynchronousDBMigration() {
+    if (this.running.get()) {
+      return;
+    }
+
+    running.set(true);
+    executorService.execute(this::doDatabaseMigration);
+  }
+
+  private void doDatabaseMigration() {
+    migrationState.setStatus(Status.RUNNING);
+    migrationState.setStartedAt(new Date());
+    migrationState.setError(null);
+    Profiler profiler = Profiler.create(LOGGER);
+    try {
+      profiler.startInfo("Starting DB Migration");
+      doUpgradeDb();
+      doRestartContainer();
+      doRecreateWebRoutes();
+      migrationState.setStatus(Status.SUCCEEDED);
+      profiler.stopInfo("DB Migration ended successfully");
+    } catch (Throwable t) {
+      profiler.stopInfo("DB migration failed");
+      LOGGER.error("DB Migration or container restart failed. Process ended with an exception", t);
+      migrationState.setStatus(Status.FAILED);
+      migrationState.setError(t);
+    } finally {
+      running.getAndSet(false);
+    }
+  }
+
+  private void doUpgradeDb() {
+    Profiler profiler = Profiler.createIfTrace(LOGGER);
+    profiler.startTrace("Starting DB Migration");
+    rubyBridge.databaseMigration().trigger();
+    profiler.stopTrace("DB Migration ended");
+  }
+
+  private void doRestartContainer() {
+    Profiler profiler = Profiler.createIfTrace(LOGGER);
+    profiler.startTrace("Restarting container");
+    platform.doStart();
+    profiler.stopTrace("Container restarted successfully");
+  }
+
+  private void doRecreateWebRoutes() {
+    Profiler profiler = Profiler.createIfTrace(LOGGER);
+    profiler.startTrace("Recreating web routes");
+    rubyBridge.railsRoutes().recreate();
+    profiler.startTrace("Routes recreated successfully");
+  }
+
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/db/migration/package-info.java b/server/sonar-server/src/main/java/org/sonar/server/platform/db/migration/package-info.java
new file mode 100644 (file)
index 0000000..2c2419e
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.server.platform.db.migration;
+
+import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/db/migrations/PlatformDatabaseMigration.java b/server/sonar-server/src/main/java/org/sonar/server/platform/db/migrations/PlatformDatabaseMigration.java
deleted file mode 100644 (file)
index 6390a3e..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.platform.db.migrations;
-
-import java.util.Date;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.locks.ReentrantLock;
-import org.sonar.api.utils.log.Logger;
-import org.sonar.api.utils.log.Loggers;
-import org.sonar.api.utils.log.Profiler;
-import org.sonar.server.platform.Platform;
-import org.sonar.server.platform.db.migration.DatabaseMigration;
-import org.sonar.server.platform.db.migration.MutableDatabaseMigrationState;
-import org.sonar.server.ruby.RubyBridge;
-
-import static org.sonar.server.platform.db.migration.DatabaseMigrationState.Status;
-
-/**
- * Handles concurrency to make sure only one DB migration can run at a time.
- */
-public class PlatformDatabaseMigration implements DatabaseMigration {
-
-  private static final Logger LOGGER = Loggers.get(PlatformDatabaseMigration.class);
-
-  private final RubyBridge rubyBridge;
-  /**
-   * ExecutorService implements threads management.
-   */
-  private final PlatformDatabaseMigrationExecutorService executorService;
-  private final Platform platform;
-  private final MutableDatabaseMigrationState migrationState;
-  /**
-   * This lock implements thread safety from concurrent calls of method {@link #startIt()}
-   */
-  private final ReentrantLock lock = new ReentrantLock();
-
-  /**
-   * This property acts as a semaphore to make sure at most one db migration task is created at a time.
-   * <p>
-   * It is set to {@code true} by the first thread to execute the {@link #startIt()} method and set to {@code false}
-   * by the thread executing the db migration.
-   * </p>
-   */
-  private final AtomicBoolean running = new AtomicBoolean(false);
-
-  public PlatformDatabaseMigration(RubyBridge rubyBridge, PlatformDatabaseMigrationExecutorService executorService, Platform platform,
-    MutableDatabaseMigrationState migrationState) {
-    this.rubyBridge = rubyBridge;
-    this.executorService = executorService;
-    this.platform = platform;
-    this.migrationState = migrationState;
-  }
-
-  @Override
-  public void startIt() {
-    if (lock.isLocked() || this.running.get()) {
-      LOGGER.trace("{}: lock is already taken or process is already running", Thread.currentThread().getName());
-      return;
-    }
-
-    if (lock.tryLock()) {
-      try {
-        startAsynchronousDBMigration();
-      } finally {
-        lock.unlock();
-      }
-    }
-  }
-
-  /**
-   * This method is not thread safe and must be externally protected from concurrent executions.
-   */
-  private void startAsynchronousDBMigration() {
-    if (this.running.get()) {
-      return;
-    }
-
-    running.set(true);
-    executorService.execute(this::doDatabaseMigration);
-  }
-
-  private void doDatabaseMigration() {
-    migrationState.setStatus(Status.RUNNING);
-    migrationState.setStartedAt(new Date());
-    migrationState.setError(null);
-    Profiler profiler = Profiler.create(LOGGER);
-    try {
-      profiler.startInfo("Starting DB Migration");
-      doUpgradeDb();
-      doRestartContainer();
-      doRecreateWebRoutes();
-      migrationState.setStatus(Status.SUCCEEDED);
-      profiler.stopInfo("DB Migration ended successfully");
-    } catch (Throwable t) {
-      profiler.stopInfo("DB migration failed");
-      LOGGER.error("DB Migration or container restart failed. Process ended with an exception", t);
-      migrationState.setStatus(Status.FAILED);
-      migrationState.setError(t);
-    } finally {
-      running.getAndSet(false);
-    }
-  }
-
-  private void doUpgradeDb() {
-    Profiler profiler = Profiler.createIfTrace(LOGGER);
-    profiler.startTrace("Starting DB Migration");
-    rubyBridge.databaseMigration().trigger();
-    profiler.stopTrace("DB Migration ended");
-  }
-
-  private void doRestartContainer() {
-    Profiler profiler = Profiler.createIfTrace(LOGGER);
-    profiler.startTrace("Restarting container");
-    platform.doStart();
-    profiler.stopTrace("Container restarted successfully");
-  }
-
-  private void doRecreateWebRoutes() {
-    Profiler profiler = Profiler.createIfTrace(LOGGER);
-    profiler.startTrace("Recreating web routes");
-    rubyBridge.railsRoutes().recreate();
-    profiler.startTrace("Routes recreated successfully");
-  }
-
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/db/migrations/PlatformDatabaseMigrationExecutorService.java b/server/sonar-server/src/main/java/org/sonar/server/platform/db/migrations/PlatformDatabaseMigrationExecutorService.java
deleted file mode 100644 (file)
index 3efc61e..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.platform.db.migrations;
-
-import java.util.concurrent.ExecutorService;
-
-/**
- * Flag interface for the ExecutorService to be used by the {@link PlatformDatabaseMigration}
- * component.
- */
-public interface PlatformDatabaseMigrationExecutorService extends ExecutorService {
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/db/migrations/PlatformDatabaseMigrationExecutorServiceImpl.java b/server/sonar-server/src/main/java/org/sonar/server/platform/db/migrations/PlatformDatabaseMigrationExecutorServiceImpl.java
deleted file mode 100644 (file)
index 39d438d..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.platform.db.migrations;
-
-import com.google.common.util.concurrent.ThreadFactoryBuilder;
-import org.sonar.server.util.AbstractStoppableExecutorService;
-
-import java.util.concurrent.Executors;
-
-/**
- * Since only one DB migration can run at a time, this implementation of PlatformDatabaseMigrationExecutorService
- * wraps a single thread executor from the JDK.
- */
-public class PlatformDatabaseMigrationExecutorServiceImpl
-  extends AbstractStoppableExecutorService
-  implements PlatformDatabaseMigrationExecutorService {
-
-  public PlatformDatabaseMigrationExecutorServiceImpl() {
-    super(
-      Executors.newSingleThreadExecutor(
-        new ThreadFactoryBuilder()
-          .setDaemon(false)
-          .setNameFormat("DB_migration-%d")
-          .build()
-        ));
-  }
-}
index 0242d9348de8f37fd5d14d38fbdca0c04c89521d..9e9f2e95479918a2b86dd60cf7a70a6a7b6f1fb6 100644 (file)
@@ -29,10 +29,10 @@ import org.sonar.db.version.MigrationStepModule;
 import org.sonar.server.platform.DefaultServerUpgradeStatus;
 import org.sonar.server.platform.StartupMetadataProvider;
 import org.sonar.server.platform.db.CheckDatabaseCharsetAtStartup;
+import org.sonar.server.platform.db.migration.DatabaseMigrationExecutorServiceImpl;
 import org.sonar.server.platform.db.migration.DatabaseMigrationStateImpl;
 import org.sonar.server.platform.db.migration.history.MigrationHistoryTableImpl;
 import org.sonar.server.platform.db.migrations.DatabaseMigrator;
-import org.sonar.server.platform.db.migrations.PlatformDatabaseMigrationExecutorServiceImpl;
 import org.sonar.server.platform.web.RailsAppsDeployer;
 import org.sonar.server.plugins.InstalledPluginReferentialFactory;
 import org.sonar.server.plugins.ServerPluginJarExploder;
@@ -73,7 +73,7 @@ public class PlatformLevel2 extends PlatformLevel {
     // Full Java DB Migration framework and configuration
     addIfStartupLeader(MigrationHistoryTableImpl.class);
     add(DatabaseMigrationStateImpl.class,
-      PlatformDatabaseMigrationExecutorServiceImpl.class);
+      DatabaseMigrationExecutorServiceImpl.class);
     // Ruby DB Migration
     add(
       DatabaseMigrator.class,
index fa46f387a9df3c8d2835c2ff3bf871b1e882eda2..5d86d638fce1e14af91332e88979dceb726424b5 100644 (file)
@@ -21,7 +21,7 @@ package org.sonar.server.platform.platformlevel;
 
 import org.sonar.server.organization.NoopDefaultOrganizationCache;
 import org.sonar.server.platform.ServerImpl;
-import org.sonar.server.platform.db.migrations.PlatformDatabaseMigration;
+import org.sonar.server.platform.db.migration.DatabaseMigrationImpl;
 import org.sonar.server.platform.web.WebPagesFilter;
 import org.sonar.server.platform.ws.DbMigrationStatusAction;
 import org.sonar.server.platform.ws.IndexAction;
@@ -62,6 +62,6 @@ public class PlatformLevelSafeMode extends PlatformLevel {
       WebServiceFilter.class,
 
       NoopDefaultOrganizationCache.class);
-    add(PlatformDatabaseMigration.class);
+    add(DatabaseMigrationImpl.class);
   }
 }
diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/db/migration/DatabaseMigrationExecutorServiceAdaptor.java b/server/sonar-server/src/test/java/org/sonar/server/platform/db/migration/DatabaseMigrationExecutorServiceAdaptor.java
new file mode 100644 (file)
index 0000000..5e62812
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.platform.db.migration;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * Adaptor for the DatabaseMigrationExecutorService interface which implementation of methods all throw
+ * UnsupportedOperationException.
+ */
+class DatabaseMigrationExecutorServiceAdaptor implements DatabaseMigrationExecutorService {
+
+  @Override
+  public void execute(Runnable command) {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public void shutdown() {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public List<Runnable> shutdownNow() {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public boolean isShutdown() {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public boolean isTerminated() {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public <T> Future<T> submit(Callable<T> task) {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public <T> Future<T> submit(Runnable task, T result) {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public Future<?> submit(Runnable task) {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
+    throw new UnsupportedOperationException();
+  }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/db/migration/DatabaseMigrationImplAsynchronousTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/db/migration/DatabaseMigrationImplAsynchronousTest.java
new file mode 100644 (file)
index 0000000..d5904c9
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.platform.db.migration;
+
+import org.junit.Test;
+import org.sonar.server.platform.Platform;
+import org.sonar.server.ruby.RubyBridge;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+
+public class DatabaseMigrationImplAsynchronousTest {
+
+  private boolean taskSuppliedForAsyncProcess = false;
+  /**
+   * Implementation of execute wraps specified Runnable to add a delay of 200 ms before passing it
+   * to a SingleThread executor to execute asynchronously.
+   */
+  private DatabaseMigrationExecutorService executorService = new DatabaseMigrationExecutorServiceAdaptor() {
+    @Override
+    public void execute(final Runnable command) {
+      taskSuppliedForAsyncProcess = true;
+    }
+  };
+  private RubyBridge rubyBridge = mock(RubyBridge.class);
+  private Platform platform = mock(Platform.class);
+  private MutableDatabaseMigrationState migrationState = mock(MutableDatabaseMigrationState.class);
+  private DatabaseMigrationImpl underTest = new DatabaseMigrationImpl(rubyBridge, executorService, platform, migrationState);
+
+  @Test
+  public void testName() throws Exception {
+    underTest.startIt();
+
+    assertThat(taskSuppliedForAsyncProcess).isTrue();
+  }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/db/migration/DatabaseMigrationImplConcurrentAccessTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/db/migration/DatabaseMigrationImplConcurrentAccessTest.java
new file mode 100644 (file)
index 0000000..75fe3d4
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.platform.db.migration;
+
+import com.google.common.base.Throwables;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.junit.After;
+import org.junit.Test;
+import org.sonar.server.platform.Platform;
+import org.sonar.server.ruby.RubyBridge;
+import org.sonar.server.ruby.RubyDatabaseMigration;
+import org.sonar.server.ruby.RubyRailsRoutes;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class DatabaseMigrationImplConcurrentAccessTest {
+
+  private ExecutorService pool = Executors.newFixedThreadPool(2);
+  /**
+   * Latch is used to make sure both testing threads try and call {@link DatabaseMigrationImpl#startIt()} at the
+   * same time
+   */
+  private CountDownLatch latch = new CountDownLatch(2);
+
+  /**
+   * Implementation of execute runs Runnable synchronously
+   */
+  private DatabaseMigrationExecutorService executorService = new DatabaseMigrationExecutorServiceAdaptor() {
+    @Override
+    public void execute(Runnable command) {
+      command.run();
+    }
+  };
+  /**
+   * thread-safe counter of calls to the trigger method of {@link #rubyDatabaseMigration}
+   */
+  private AtomicInteger triggerCount = new AtomicInteger();
+  /**
+   * Implementation of RubyDatabaseMigration which trigger method increments a thread-safe counter and add a delay of 200ms
+   */
+  private RubyDatabaseMigration rubyDatabaseMigration = new RubyDatabaseMigration() {
+    @Override
+    public void trigger() {
+      triggerCount.incrementAndGet();
+      try {
+        Thread.currentThread().sleep(1000);
+      } catch (InterruptedException e) {
+        Throwables.propagate(e);
+      }
+    }
+  };
+  private RubyBridge rubyBridge = mock(RubyBridge.class);
+  private Platform platform = mock(Platform.class);
+  private RubyRailsRoutes railsRoutes = mock(RubyRailsRoutes.class);
+  private MutableDatabaseMigrationState migrationState = mock(MutableDatabaseMigrationState.class);
+  private DatabaseMigrationImpl underTest = new DatabaseMigrationImpl(rubyBridge, executorService, platform, migrationState);
+
+  @After
+  public void tearDown() {
+    pool.shutdownNow();
+  }
+
+  @Test
+  public void two_concurrent_calls_to_startit_call_trigger_only_once() throws Exception {
+    when(rubyBridge.databaseMigration()).thenReturn(rubyDatabaseMigration);
+    when(rubyBridge.railsRoutes()).thenReturn(railsRoutes);
+
+    pool.submit(new CallStartit());
+    pool.submit(new CallStartit());
+
+    pool.awaitTermination(2, TimeUnit.SECONDS);
+
+    assertThat(triggerCount.get()).isEqualTo(1);
+  }
+
+  private class CallStartit implements Runnable {
+    @Override
+    public void run() {
+      latch.countDown();
+      try {
+        latch.await();
+      } catch (InterruptedException e) {
+        // propagate interruption
+        Thread.currentThread().interrupt();
+      }
+      underTest.startIt();
+    }
+  }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/db/migration/DatabaseMigrationImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/db/migration/DatabaseMigrationImplTest.java
new file mode 100644 (file)
index 0000000..a1a248a
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.platform.db.migration;
+
+import java.util.Date;
+import org.junit.Test;
+import org.mockito.InOrder;
+import org.sonar.server.platform.Platform;
+import org.sonar.server.ruby.RubyBridge;
+import org.sonar.server.ruby.RubyDatabaseMigration;
+import org.sonar.server.ruby.RubyRailsRoutes;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+/**
+ * Unit test for DatabaseMigrationImpl which does not test any of its concurrency management and asynchronous execution code.
+ */
+public class DatabaseMigrationImplTest {
+  private static final Throwable AN_ERROR = new RuntimeException("runtime exception created on purpose");
+
+  /**
+   * Implementation of execute runs Runnable synchronously.
+   */
+  private DatabaseMigrationExecutorService executorService = new DatabaseMigrationExecutorServiceAdaptor() {
+    @Override
+    public void execute(Runnable command) {
+      command.run();
+    }
+  };
+  private RubyBridge rubyBridge = mock(RubyBridge.class);
+  private RubyDatabaseMigration rubyDatabaseMigration = mock(RubyDatabaseMigration.class);
+  private RubyRailsRoutes rubyRailsRoutes = mock(RubyRailsRoutes.class);
+  private Platform platform = mock(Platform.class);
+  private MutableDatabaseMigrationState migrationState = new DatabaseMigrationStateImpl();
+  private InOrder inOrder = inOrder(rubyDatabaseMigration, rubyBridge, rubyRailsRoutes, platform);
+
+  private DatabaseMigrationImpl underTest = new DatabaseMigrationImpl(rubyBridge, executorService, platform, migrationState);
+
+  @Test
+  public void startit_calls_databasemigration_trigger_in_a_separate_thread() {
+    when(rubyBridge.databaseMigration()).thenReturn(rubyDatabaseMigration);
+    when(rubyBridge.railsRoutes()).thenReturn(rubyRailsRoutes);
+
+    underTest.startIt();
+
+    inOrder.verify(rubyBridge).databaseMigration();
+    inOrder.verify(rubyDatabaseMigration).trigger();
+    inOrder.verify(platform).doStart();
+    inOrder.verify(rubyBridge).railsRoutes();
+    inOrder.verify(rubyRailsRoutes).recreate();
+    inOrder.verifyNoMoreInteractions();
+  }
+
+  @Test
+  public void status_is_SUCCEEDED_and_failure_is_null_when_trigger_runs_without_an_exception() {
+    when(rubyBridge.databaseMigration()).thenReturn(rubyDatabaseMigration);
+    when(rubyBridge.railsRoutes()).thenReturn(rubyRailsRoutes);
+
+    underTest.startIt();
+
+    assertThat(migrationState.getStatus()).isEqualTo(DatabaseMigrationState.Status.SUCCEEDED);
+    assertThat(migrationState.getError()).isNull();
+    assertThat(migrationState.getStartedAt()).isNotNull();
+  }
+
+  @Test
+  public void status_is_FAILED_and_failure_stores_the_exception_when_trigger_throws_an_exception() {
+    mockTriggerThrowsError();
+
+    underTest.startIt();
+
+    assertThat(migrationState.getStatus()).isEqualTo(DatabaseMigrationState.Status.FAILED);
+    assertThat(migrationState.getError()).isSameAs(AN_ERROR);
+    assertThat(migrationState.getStartedAt()).isNotNull();
+  }
+
+  @Test
+  public void successive_calls_to_startIt_reset_status_startedAt_and_failureError() {
+    mockTriggerThrowsError();
+
+    underTest.startIt();
+
+    assertThat(migrationState.getStatus()).isEqualTo(DatabaseMigrationState.Status.FAILED);
+    assertThat(migrationState.getError()).isSameAs(AN_ERROR);
+    Date firstStartDate = migrationState.getStartedAt();
+    assertThat(firstStartDate).isNotNull();
+
+    mockTriggerDoesNothing();
+
+    underTest.startIt();
+
+    assertThat(migrationState.getStatus()).isEqualTo(DatabaseMigrationState.Status.SUCCEEDED);
+    assertThat(migrationState.getError()).isNull();
+    assertThat(migrationState.getStartedAt()).isNotSameAs(firstStartDate);
+  }
+
+  private void mockTriggerThrowsError() {
+    when(rubyBridge.databaseMigration()).thenReturn(rubyDatabaseMigration);
+    doThrow(AN_ERROR).when(rubyDatabaseMigration).trigger();
+    when(rubyBridge.railsRoutes()).thenReturn(rubyRailsRoutes);
+  }
+
+  private void mockTriggerDoesNothing() {
+    when(rubyBridge.databaseMigration()).thenReturn(rubyDatabaseMigration);
+    doNothing().when(rubyDatabaseMigration).trigger();
+    when(rubyBridge.railsRoutes()).thenReturn(rubyRailsRoutes);
+  }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/db/migrations/PlatformDatabaseMigrationAsynchronousTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/db/migrations/PlatformDatabaseMigrationAsynchronousTest.java
deleted file mode 100644 (file)
index b76610d..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.platform.db.migrations;
-
-import org.junit.Test;
-import org.sonar.server.platform.Platform;
-import org.sonar.server.platform.db.migration.MutableDatabaseMigrationState;
-import org.sonar.server.ruby.RubyBridge;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-
-public class PlatformDatabaseMigrationAsynchronousTest {
-
-  private boolean taskSuppliedForAsyncProcess = false;
-  /**
-   * Implementation of execute wraps specified Runnable to add a delay of 200 ms before passing it
-   * to a SingleThread executor to execute asynchronously.
-   */
-  private PlatformDatabaseMigrationExecutorService executorService = new PlatformDatabaseMigrationExecutorServiceAdaptor() {
-    @Override
-    public void execute(final Runnable command) {
-      taskSuppliedForAsyncProcess = true;
-    }
-  };
-  private RubyBridge rubyBridge = mock(RubyBridge.class);
-  private Platform platform = mock(Platform.class);
-  private MutableDatabaseMigrationState migrationState = mock(MutableDatabaseMigrationState.class);
-  private PlatformDatabaseMigration underTest = new PlatformDatabaseMigration(rubyBridge, executorService, platform, migrationState);
-
-  @Test
-  public void testName() throws Exception {
-    underTest.startIt();
-
-    assertThat(taskSuppliedForAsyncProcess).isTrue();
-  }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/db/migrations/PlatformDatabaseMigrationConcurrentAccessTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/db/migrations/PlatformDatabaseMigrationConcurrentAccessTest.java
deleted file mode 100644 (file)
index 18f4594..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.platform.db.migrations;
-
-import com.google.common.base.Throwables;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-import org.junit.After;
-import org.junit.Test;
-import org.sonar.server.platform.Platform;
-import org.sonar.server.platform.db.migration.MutableDatabaseMigrationState;
-import org.sonar.server.ruby.RubyBridge;
-import org.sonar.server.ruby.RubyDatabaseMigration;
-import org.sonar.server.ruby.RubyRailsRoutes;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class PlatformDatabaseMigrationConcurrentAccessTest {
-
-  private ExecutorService pool = Executors.newFixedThreadPool(2);
-  /**
-   * Latch is used to make sure both testing threads try and call {@link PlatformDatabaseMigration#startIt()} at the
-   * same time
-   */
-  private CountDownLatch latch = new CountDownLatch(2);
-
-  /**
-   * Implementation of execute runs Runnable synchronously
-   */
-  private PlatformDatabaseMigrationExecutorService executorService = new PlatformDatabaseMigrationExecutorServiceAdaptor() {
-    @Override
-    public void execute(Runnable command) {
-      command.run();
-    }
-  };
-  /**
-   * thread-safe counter of calls to the trigger method of {@link #rubyDatabaseMigration}
-   */
-  private AtomicInteger triggerCount = new AtomicInteger();
-  /**
-   * Implementation of RubyDatabaseMigration which trigger method increments a thread-safe counter and add a delay of 200ms
-   */
-  private RubyDatabaseMigration rubyDatabaseMigration = new RubyDatabaseMigration() {
-    @Override
-    public void trigger() {
-      triggerCount.incrementAndGet();
-      try {
-        Thread.currentThread().sleep(1000);
-      } catch (InterruptedException e) {
-        Throwables.propagate(e);
-      }
-    }
-  };
-  private RubyBridge rubyBridge = mock(RubyBridge.class);
-  private Platform platform = mock(Platform.class);
-  private RubyRailsRoutes railsRoutes = mock(RubyRailsRoutes.class);
-  private MutableDatabaseMigrationState migrationState = mock(MutableDatabaseMigrationState.class);
-  private PlatformDatabaseMigration underTest = new PlatformDatabaseMigration(rubyBridge, executorService, platform, migrationState);
-
-  @After
-  public void tearDown() {
-    pool.shutdownNow();
-  }
-
-  @Test
-  public void two_concurrent_calls_to_startit_call_trigger_only_once() throws Exception {
-    when(rubyBridge.databaseMigration()).thenReturn(rubyDatabaseMigration);
-    when(rubyBridge.railsRoutes()).thenReturn(railsRoutes);
-
-    pool.submit(new CallStartit());
-    pool.submit(new CallStartit());
-
-    pool.awaitTermination(2, TimeUnit.SECONDS);
-
-    assertThat(triggerCount.get()).isEqualTo(1);
-  }
-
-  private class CallStartit implements Runnable {
-    @Override
-    public void run() {
-      latch.countDown();
-      try {
-        latch.await();
-      } catch (InterruptedException e) {
-        // propagate interruption
-        Thread.currentThread().interrupt();
-      }
-      underTest.startIt();
-    }
-  }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/db/migrations/PlatformDatabaseMigrationExecutorServiceAdaptor.java b/server/sonar-server/src/test/java/org/sonar/server/platform/db/migrations/PlatformDatabaseMigrationExecutorServiceAdaptor.java
deleted file mode 100644 (file)
index 2e05ba0..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.platform.db.migrations;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-/**
- * Adaptor for the PlatformDatabaseMigrationExecutorService interface which implementation of methods all throw
- * UnsupportedOperationException.
- */
-class PlatformDatabaseMigrationExecutorServiceAdaptor implements PlatformDatabaseMigrationExecutorService {
-
-  @Override
-  public void execute(Runnable command) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void shutdown() {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public List<Runnable> shutdownNow() {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public boolean isShutdown() {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public boolean isTerminated() {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public <T> Future<T> submit(Callable<T> task) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public <T> Future<T> submit(Runnable task, T result) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public Future<?> submit(Runnable task) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
-    throw new UnsupportedOperationException();
-  }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/db/migrations/PlatformDatabaseMigrationTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/db/migrations/PlatformDatabaseMigrationTest.java
deleted file mode 100644 (file)
index fb9601e..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.platform.db.migrations;
-
-import java.util.Date;
-import org.junit.Test;
-import org.mockito.InOrder;
-import org.sonar.server.platform.Platform;
-import org.sonar.server.platform.db.migration.DatabaseMigrationState;
-import org.sonar.server.platform.db.migration.DatabaseMigrationStateImpl;
-import org.sonar.server.platform.db.migration.MutableDatabaseMigrationState;
-import org.sonar.server.ruby.RubyBridge;
-import org.sonar.server.ruby.RubyDatabaseMigration;
-import org.sonar.server.ruby.RubyRailsRoutes;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-/**
- * Unit test for PlatformDatabaseMigration which does not test any of its concurrency management and asynchronous execution code.
- */
-public class PlatformDatabaseMigrationTest {
-  private static final Throwable AN_ERROR = new RuntimeException("runtime exception created on purpose");
-
-  /**
-   * Implementation of execute runs Runnable synchronously.
-   */
-  private PlatformDatabaseMigrationExecutorService executorService = new PlatformDatabaseMigrationExecutorServiceAdaptor() {
-    @Override
-    public void execute(Runnable command) {
-      command.run();
-    }
-  };
-  private RubyBridge rubyBridge = mock(RubyBridge.class);
-  private RubyDatabaseMigration rubyDatabaseMigration = mock(RubyDatabaseMigration.class);
-  private RubyRailsRoutes rubyRailsRoutes = mock(RubyRailsRoutes.class);
-  private Platform platform = mock(Platform.class);
-  private MutableDatabaseMigrationState migrationState = new DatabaseMigrationStateImpl();
-  private InOrder inOrder = inOrder(rubyDatabaseMigration, rubyBridge, rubyRailsRoutes, platform);
-
-  private PlatformDatabaseMigration underTest = new PlatformDatabaseMigration(rubyBridge, executorService, platform, migrationState);
-
-  @Test
-  public void startit_calls_databasemigration_trigger_in_a_separate_thread() {
-    when(rubyBridge.databaseMigration()).thenReturn(rubyDatabaseMigration);
-    when(rubyBridge.railsRoutes()).thenReturn(rubyRailsRoutes);
-
-    underTest.startIt();
-
-    inOrder.verify(rubyBridge).databaseMigration();
-    inOrder.verify(rubyDatabaseMigration).trigger();
-    inOrder.verify(platform).doStart();
-    inOrder.verify(rubyBridge).railsRoutes();
-    inOrder.verify(rubyRailsRoutes).recreate();
-    inOrder.verifyNoMoreInteractions();
-  }
-
-  @Test
-  public void status_is_SUCCEEDED_and_failure_is_null_when_trigger_runs_without_an_exception() {
-    when(rubyBridge.databaseMigration()).thenReturn(rubyDatabaseMigration);
-    when(rubyBridge.railsRoutes()).thenReturn(rubyRailsRoutes);
-
-    underTest.startIt();
-
-    assertThat(migrationState.getStatus()).isEqualTo(DatabaseMigrationState.Status.SUCCEEDED);
-    assertThat(migrationState.getError()).isNull();
-    assertThat(migrationState.getStartedAt()).isNotNull();
-  }
-
-  @Test
-  public void status_is_FAILED_and_failure_stores_the_exception_when_trigger_throws_an_exception() {
-    mockTriggerThrowsError();
-
-    underTest.startIt();
-
-    assertThat(migrationState.getStatus()).isEqualTo(DatabaseMigrationState.Status.FAILED);
-    assertThat(migrationState.getError()).isSameAs(AN_ERROR);
-    assertThat(migrationState.getStartedAt()).isNotNull();
-  }
-
-  @Test
-  public void successive_calls_to_startIt_reset_status_startedAt_and_failureError() {
-    mockTriggerThrowsError();
-
-    underTest.startIt();
-
-    assertThat(migrationState.getStatus()).isEqualTo(DatabaseMigrationState.Status.FAILED);
-    assertThat(migrationState.getError()).isSameAs(AN_ERROR);
-    Date firstStartDate = migrationState.getStartedAt();
-    assertThat(firstStartDate).isNotNull();
-
-    mockTriggerDoesNothing();
-
-    underTest.startIt();
-
-    assertThat(migrationState.getStatus()).isEqualTo(DatabaseMigrationState.Status.SUCCEEDED);
-    assertThat(migrationState.getError()).isNull();
-    assertThat(migrationState.getStartedAt()).isNotSameAs(firstStartDate);
-  }
-
-  private void mockTriggerThrowsError() {
-    when(rubyBridge.databaseMigration()).thenReturn(rubyDatabaseMigration);
-    doThrow(AN_ERROR).when(rubyDatabaseMigration).trigger();
-    when(rubyBridge.railsRoutes()).thenReturn(rubyRailsRoutes);
-  }
-
-  private void mockTriggerDoesNothing() {
-    when(rubyBridge.databaseMigration()).thenReturn(rubyDatabaseMigration);
-    doNothing().when(rubyDatabaseMigration).trigger();
-    when(rubyBridge.railsRoutes()).thenReturn(rubyRailsRoutes);
-  }
-}