]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-5329 - added ChangeLog Migration scripts
authorStephane Gamard <stephane.gamard@searchbox.com>
Wed, 18 Jun 2014 11:57:09 +0000 (13:57 +0200)
committerStephane Gamard <stephane.gamard@searchbox.com>
Wed, 18 Jun 2014 11:57:09 +0000 (13:57 +0200)
14 files changed:
sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java
sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql
sonar-core/src/test/java/org/sonar/core/persistence/TestDatabase.java
sonar-server/src/main/java/org/sonar/server/activity/db/ActivityDao.java
sonar-server/src/main/java/org/sonar/server/db/BaseDao.java
sonar-server/src/main/java/org/sonar/server/db/migrations/DatabaseMigrations.java
sonar-server/src/main/java/org/sonar/server/db/migrations/v44/ChangeLog.java [new file with mode: 0644]
sonar-server/src/main/java/org/sonar/server/db/migrations/v44/ChangeLogMapper.java [new file with mode: 0644]
sonar-server/src/main/java/org/sonar/server/db/migrations/v44/ChangeLogMigration.java [new file with mode: 0644]
sonar-server/src/main/java/org/sonar/server/qualityprofile/ActiveRuleChange.java
sonar-server/src/main/java/org/sonar/server/search/IndexSynchronizer.java
sonar-server/src/main/webapp/WEB-INF/db/migrate/548_update_logs_to_activities.rb [new file with mode: 0644]
sonar-server/src/test/java/org/sonar/server/db/migrations/v44/ChangeLogMigrationTest.java [new file with mode: 0644]
sonar-server/src/test/resources/org/sonar/server/db/migrations/v44/ChangeLogMigrationTest/active_rules_changes.xml [new file with mode: 0644]

index 70fa98a55762eb18b2133578d558ad5c65a3348e..b6ff97835d59effb6af9ff802f6786686aef348f 100644 (file)
@@ -33,7 +33,7 @@ import java.util.List;
  */
 public class DatabaseVersion implements BatchComponent, ServerComponent {
 
-  public static final int LAST_VERSION = 547;
+  public static final int LAST_VERSION = 548;
 
   public static enum Status {
     UP_TO_DATE, REQUIRES_UPGRADE, REQUIRES_DOWNGRADE, FRESH_INSTALL
@@ -94,7 +94,7 @@ public class DatabaseVersion implements BatchComponent, ServerComponent {
     "widgets",
     "widget_properties",
     "activities"
-    );
+  );
 
   private MyBatis mybatis;
 
index e1764335391abf5ca09702a4c75c1047680096b3..40529333d553c5963247cfcc056f2b2bb6bb4435 100644 (file)
@@ -241,6 +241,7 @@ INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('544');
 INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('545');
 INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('546');
 INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('547');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('548');
 
 INSERT INTO USERS(ID, LOGIN, NAME, EMAIL, CRYPTED_PASSWORD, SALT, CREATED_AT, UPDATED_AT, REMEMBER_TOKEN, REMEMBER_TOKEN_EXPIRES_AT) VALUES (1, 'admin', 'Administrator', '', 'a373a0e667abb2604c1fd571eb4ad47fe8cc0878', '48bc4b0d93179b5103fd3885ea9119498e9d161b', '2011-09-26 22:27:48.0', '2011-09-26 22:27:48.0', null, null);
 ALTER TABLE USERS ALTER COLUMN ID RESTART WITH 2;
index 198b7def501d94a9d6bdcb3eeca92c1a97c15fb5..b42a4e36428cc53c288ac06641f5258a92baa72b 100644 (file)
@@ -257,6 +257,7 @@ public class TestDatabase extends ExternalResource {
       dataSet.addReplacementObject("[null]", null);
       dataSet.addReplacementObject("[false]", Boolean.FALSE);
       dataSet.addReplacementObject("[true]", Boolean.TRUE);
+
       return dataSet;
     } catch (Exception e) {
       throw translateException("Could not read the dataset stream", e);
index d009113dcf99f24d86f14e910cba09338494cdda..4c723ae668ad5c12224c92217024f3c7f73ec408 100644 (file)
@@ -71,6 +71,6 @@ public class ActivityDao extends BaseDao<ActivityMapper, ActivityDto, ActivityKe
 
   @Override
   public void synchronizeAfter(DbSession session, long timestamp) {
-    throw new IllegalStateException("Log Index does not synchronize!");
+
   }
 }
index a1e7ea9c0cfe7f05ddb445fbae9ae2b3f9d3df40..b79ee9015836fd4a607ac672c57bb2b3fa7abfa4 100644 (file)
@@ -214,7 +214,9 @@ public abstract class BaseDao<M, E extends Dto<K>, K extends Serializable> imple
   }
 
   private void insert(DbSession session, E item, Date now) {
-    item.setCreatedAt(now);
+    if (item.getCreatedAt() == null) {
+      item.setCreatedAt(now);
+    }
     item.setUpdatedAt(now);
     doInsert(session, item);
     if (hasIndex()) {
index 4cb30bd9a561d7ac526300ff8c393f72a68b23a0..414c27a7e3d9b68bfe86ef55723ef58531e51bc6 100644 (file)
@@ -23,8 +23,15 @@ import com.google.common.collect.ImmutableList;
 import org.sonar.server.db.migrations.v36.ViolationMigration;
 import org.sonar.server.db.migrations.v42.CompleteIssueMessageMigration;
 import org.sonar.server.db.migrations.v42.PackageKeysMigration;
-import org.sonar.server.db.migrations.v43.*;
-import org.sonar.server.db.migrations.v44.*;
+import org.sonar.server.db.migrations.v43.DevelopmentCostMeasuresMigration;
+import org.sonar.server.db.migrations.v43.IssueChangelogMigration;
+import org.sonar.server.db.migrations.v43.IssueMigration;
+import org.sonar.server.db.migrations.v43.NotResolvedIssuesOnRemovedComponentsMigration;
+import org.sonar.server.db.migrations.v43.RequirementMeasuresMigration;
+import org.sonar.server.db.migrations.v43.TechnicalDebtMeasuresMigration;
+import org.sonar.server.db.migrations.v44.ChangeLogMigration;
+import org.sonar.server.db.migrations.v44.IssueActionPlanKeyMigration;
+import org.sonar.server.db.migrations.v44.MeasureDataMigration;
 
 import java.util.List;
 
@@ -47,7 +54,8 @@ public interface DatabaseMigrations {
 
     // 4.4
     IssueActionPlanKeyMigration.class,
-    MeasureDataMigration.class
+    MeasureDataMigration.class,
+    ChangeLogMigration.class
   );
 
 }
diff --git a/sonar-server/src/main/java/org/sonar/server/db/migrations/v44/ChangeLog.java b/sonar-server/src/main/java/org/sonar/server/db/migrations/v44/ChangeLog.java
new file mode 100644 (file)
index 0000000..59729fd
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 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.migrations.v44;
+
+import org.apache.ibatis.type.Alias;
+
+import java.util.Date;
+
+/**
+ * SONAR-5329
+ * Transition ActiveRuleChanges to ActivityLog
+ * <p/>
+ * Used in the Active Record Migration 548.
+ *
+ * @since 4.4
+ */
+@Alias("ChangeLogMigration")
+public class ChangeLog {
+
+  private Date createdAt;
+  private String userLogin;
+
+  public Date getCreatedAt() {
+    return createdAt;
+  }
+
+  public void setCreatedAt(Date createdAt) {
+    this.createdAt = createdAt;
+  }
+
+  public String getUserLogin() {
+    return userLogin;
+  }
+
+  public void setUserLogin(String userLogin) {
+    this.userLogin = userLogin;
+  }
+}
diff --git a/sonar-server/src/main/java/org/sonar/server/db/migrations/v44/ChangeLogMapper.java b/sonar-server/src/main/java/org/sonar/server/db/migrations/v44/ChangeLogMapper.java
new file mode 100644 (file)
index 0000000..45a34c9
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 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.migrations.v44;
+
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+
+/**
+ * SONAR-5329
+ * Transition ActiveRuleChanges to ActivityLog
+ * <p/>
+ * Used in the Active Record Migration 548.
+ *
+ * @since 4.4
+ */
+public interface ChangeLogMapper {
+
+  @Select("select rule_change.change_date as createdAt," +
+    "  rule_change.username as userLogin " +
+    "from active_rule_changes rule_change")
+  List<ChangeLog> selectAll();
+}
+
diff --git a/sonar-server/src/main/java/org/sonar/server/db/migrations/v44/ChangeLogMigration.java b/sonar-server/src/main/java/org/sonar/server/db/migrations/v44/ChangeLogMigration.java
new file mode 100644 (file)
index 0000000..395d504
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 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.migrations.v44;
+
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.core.activity.Activity;
+import org.sonar.core.activity.db.ActivityDto;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.qualityprofile.db.ActiveRuleKey;
+import org.sonar.core.qualityprofile.db.QualityProfileKey;
+import org.sonar.core.rule.SeverityUtil;
+import org.sonar.server.activity.ActivityService;
+import org.sonar.server.activity.db.ActivityDao;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.db.migrations.DatabaseMigration;
+import org.sonar.server.qualityprofile.ActiveRuleChange;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Date;
+
+/**
+ * SONAR-5329
+ * Transition ActiveRuleChanges to ActivityLog
+ * <p/>
+ * Used in the Active Record Migration 548.
+ *
+ * @since 4.4
+ */
+public class ChangeLogMigration implements DatabaseMigration {
+
+  private static final String PARAM_VALUE = "param_value";
+  private static final String PARAM_NAME = "param_name";
+  private static final String RULE_NAME = "rule_name";
+  private static final String PROFILE_KEY = "profile_key";
+  private static final String RULE_KEY = "rule_key";
+  private static final String CREATED_AT = "created_at";
+  private static final String SEVERITY = "severity";
+  private static final String USER_LOGIN = "user_login";
+
+  private final ActivityDao dao;
+  private DbSession session;
+  private final DbClient db;
+
+
+  private final String allActivation =
+    "select" +
+      "   rule_change.id," +
+      "   rule_change.change_date as " + CREATED_AT + "," +
+      "   users.login as " + USER_LOGIN + "," +
+      "   CONCAT(rule_def.plugin_name,':',rule_def.plugin_rule_key) as " + RULE_KEY + "," +
+      "   CONCAT(profile.name,':',profile.language) as " + PROFILE_KEY + "," +
+      "   rule_change.new_severity as " + SEVERITY + "," +
+      "   rule_def.name as " + RULE_NAME + "," +
+      "   rule_def_param.name as " + PARAM_NAME + "," +
+      "   rule_param_change.new_value as " + PARAM_VALUE +
+      " from active_rule_changes rule_change" +
+      "   left join users on users.name = rule_change.username" +
+      "   left join rules rule_def on rule_def.id = rule_change.rule_id" +
+      "   left join rules_profiles profile on profile.id = rule_change.profile_id" +
+      "   left join active_rule_param_changes rule_param_change on rule_param_change.active_rule_change_id = rule_change.id" +
+      "   left join rules_parameters rule_def_param on rule_def_param.id = rule_param_change.rules_parameter_id" +
+      " WHERE rule_change.enabled is true" +
+      "       AND profile.name is not null" +
+      "       AND profile.language is not null" +
+      "       AND rule_def.plugin_name is not null" +
+      "       AND rule_def.plugin_name is not null" +
+      " order by rule_change.id ASC;";
+
+  private final String allUpdates =
+    "select" +
+      "   rule_change.id," +
+      "   rule_change.change_date as " + CREATED_AT + "," +
+      "   users.login as " + USER_LOGIN + "," +
+      "   CONCAT(rule_def.plugin_name,':',rule_def.plugin_rule_key) as " + RULE_KEY + "," +
+      "   CONCAT(profile.name,':',profile.language) as " + PROFILE_KEY + "," +
+      "   rule_change.new_severity as " + SEVERITY + "," +
+      "   rule_def.name as " + RULE_NAME + "," +
+      "   rule_def_param.name as " + PARAM_NAME + "," +
+      "   rule_param_change.new_value as " + PARAM_VALUE +
+      " from active_rule_changes rule_change" +
+      "   left join users on users.name = rule_change.username" +
+      "   left join rules rule_def on rule_def.id = rule_change.rule_id" +
+      "   left join rules_profiles profile on profile.id = rule_change.profile_id" +
+      "   left join active_rule_param_changes rule_param_change on rule_param_change.active_rule_change_id = rule_change.id" +
+      "   left join rules_parameters rule_def_param on rule_def_param.id = rule_param_change.rules_parameter_id" +
+      " WHERE rule_change.enabled is null" +
+      "       AND profile.name is not null" +
+      "       AND profile.language is not null" +
+      "       AND rule_def.plugin_name is not null" +
+      "       AND rule_def.plugin_name is not null" +
+      " order by rule_change.id ASC;";
+
+  private String allDeactivation =
+    "select" +
+      "  rule_change.id as id," +
+      "  rule_change.change_date as " + CREATED_AT + "," +
+      "  users.login as " + USER_LOGIN + "," +
+      "  CONCAT(rule_def.plugin_name,':',rule_def.plugin_rule_key) as " + RULE_KEY + "," +
+      "  CONCAT(profile.name,':',profile.language) as " + PROFILE_KEY +
+      " from active_rule_changes rule_change" +
+      "  left join users on users.name = rule_change.username" +
+      "  left join rules rule_def on rule_def.id = rule_change.rule_id" +
+      "  left join rules_profiles profile on profile.id = rule_change.profile_id" +
+      " WHERE rule_change.enabled is false" +
+      "      AND profile.name is not null" +
+      "      AND profile.language is not null" +
+      "      AND rule_def.plugin_name is not null" +
+      "      AND rule_def.plugin_name is not null" +
+      " order by rule_change.id ASC";
+
+  public ChangeLogMigration(ActivityService service, ActivityDao dao, DbClient db) {
+    this.dao = dao;
+    this.db = db;
+  }
+
+  @Override
+  public void execute() {
+    this.session = db.openSession(false);
+    executeUpsert(ActiveRuleChange.Type.ACTIVATED, allActivation);
+    executeUpsert(ActiveRuleChange.Type.UPDATED, allUpdates);
+    executeUpsert(ActiveRuleChange.Type.DEACTIVATED, allDeactivation);
+    session.commit();
+    session.close();
+  }
+
+  private void executeUpsert(ActiveRuleChange.Type type, String sql) {
+    try {
+      Connection connection = db.database().getDataSource().getConnection();
+      ResultSet result = connection.createStatement().executeQuery(sql);
+
+      //startCase
+      result.next();
+      int currentId = result.getInt("id");
+      Date currentTimeStamp = result.getTimestamp(CREATED_AT);
+      String currentAuthor = getAuthor(result);
+      ActiveRuleChange ruleChange = newActiveRuleChance(type, result);
+      processRuleChange(ruleChange, result);
+
+      while (result.next()) {
+        int id = result.getInt("id");
+        if (id != currentId) {
+          saveActiveRuleChange(ruleChange, currentAuthor, currentTimeStamp);
+          currentId = id;
+          currentTimeStamp = result.getTimestamp(CREATED_AT);
+          currentAuthor = getAuthor(result);
+          ruleChange = newActiveRuleChance(type, result);
+        }
+        processRuleChange(ruleChange, result);
+      }
+      //save the last
+      saveActiveRuleChange(ruleChange, currentAuthor, currentTimeStamp);
+
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+  }
+
+  private String getAuthor(ResultSet result) {
+    try {
+      String author = result.getString(USER_LOGIN);
+      if (StringUtils.isNotEmpty(author) && !author.equals("null")) {
+        return author;
+      } else {
+        return "unknown";
+      }
+    } catch (Exception e) {
+      return "unknown";
+    }
+  }
+
+
+  private void saveActiveRuleChange(ActiveRuleChange ruleChange, String author, Date currentTimeStamp) {
+    ActivityDto activity = ActivityDto.createFor(ruleChange);
+    activity.setType(Activity.Type.ACTIVE_RULE);
+    activity.setAuthor(author);
+    activity.setCreatedAt(currentTimeStamp);
+    dao.insert(session, activity);
+  }
+
+  private void processRuleChange(ActiveRuleChange ruleChange, ResultSet result) throws SQLException {
+
+    try {
+      ruleChange.setSeverity(SeverityUtil.getSeverityFromOrdinal(result.getInt(SEVERITY)));
+    } catch (Exception e) {
+      //System.out.println("e.getMessage() = " + e.getMessage());
+    }
+    try {
+      String param_value = result.getString(PARAM_VALUE);
+      String param_name = result.getString(PARAM_NAME);
+      if (StringUtils.isNotEmpty(param_name) && !param_name.equals("null")) {
+        ruleChange.setParameter(param_name, param_value);
+      }
+    } catch (Exception e) {
+      //System.out.println("e.getMessage() = " + e.getMessage());
+    }
+  }
+
+  private ActiveRuleChange newActiveRuleChance(ActiveRuleChange.Type type, ResultSet result) throws SQLException {
+    return ActiveRuleChange.createFor(
+      type, ActiveRuleKey.of(
+        QualityProfileKey.parse(result.getString(PROFILE_KEY)),
+        RuleKey.parse(result.getString(RULE_KEY))));
+  }
+}
index f783170a5c21eabb41514da00c01ed03ea69f5d1..1239c2f5cf3236717416d4cea4f03c8311165cac 100644 (file)
@@ -32,7 +32,7 @@ import java.util.Map;
 
 public class ActiveRuleChange implements ActivityLog {
 
-  static enum Type {
+  public static enum Type {
     ACTIVATED, DEACTIVATED, UPDATED
   }
 
index 442298809e723212ac7cc197bc3691b7b401fed1..62c06b37bd02ea8c1c38bc25a1734d51e089fef6 100644 (file)
@@ -46,6 +46,7 @@ public class IndexSynchronizer {
     long start = System.currentTimeMillis();
     db.ruleDao().synchronizeAfter(session, 0);
     db.activeRuleDao().synchronizeAfter(session, 0);
+    db.activityDao().synchronizeAfter(session, 0);
     session.commit();
     LOG.info("Synchronization done in {}ms...", System.currentTimeMillis()-start);
     session.close();
diff --git a/sonar-server/src/main/webapp/WEB-INF/db/migrate/548_update_logs_to_activities.rb b/sonar-server/src/main/webapp/WEB-INF/db/migrate/548_update_logs_to_activities.rb
new file mode 100644 (file)
index 0000000..5dc8744
--- /dev/null
@@ -0,0 +1,31 @@
+#
+# SonarQube, open source software quality management tool.
+# Copyright (C) 2008-2014 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.
+#
+
+#
+# SonarQube 4.4
+# SONAR-5218
+#
+class UpdateLogsToActivities < ActiveRecord::Migration
+
+  def self.up
+    Java::OrgSonarServerUi::JRubyFacade.getInstance().databaseMigrator().executeMigration('org.sonar.server.db.migrations.v44.ChangeLogMigration')
+  end
+
+end
diff --git a/sonar-server/src/test/java/org/sonar/server/db/migrations/v44/ChangeLogMigrationTest.java b/sonar-server/src/test/java/org/sonar/server/db/migrations/v44/ChangeLogMigrationTest.java
new file mode 100644 (file)
index 0000000..0fcc7f2
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 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.migrations.v44;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.sonar.api.utils.DateUtils;
+import org.sonar.api.utils.System2;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.TestDatabase;
+import org.sonar.server.activity.db.ActivityDao;
+import org.sonar.server.db.DbClient;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ChangeLogMigrationTest {
+
+  @ClassRule
+  public static TestDatabase db = new TestDatabase();
+
+  @Mock
+  System2 system2;
+
+  DbClient dbClient;
+  ActivityDao dao;
+  ChangeLogMigration migration;
+  DbSession session;
+
+  @Before
+  public void setUp() throws Exception {
+    when(system2.now()).thenReturn(DateUtils.parseDate("2014-03-13").getTime());
+    dao = new ActivityDao(system2);
+    dbClient = new DbClient(db.database(), db.myBatis(), dao);
+    migration = new ChangeLogMigration(null, dao, dbClient);
+    session = dbClient.openSession(false);
+  }
+
+  @After
+  public void tearDown() {
+    session.close();
+  }
+
+  @Test
+  public void migrate() throws Exception {
+    db.prepareDbUnit(getClass(), "active_rules_changes.xml");
+    migration.execute();
+
+    assertThat(dao.findAll(session)).hasSize(5);
+  }
+}
\ No newline at end of file
diff --git a/sonar-server/src/test/resources/org/sonar/server/db/migrations/v44/ChangeLogMigrationTest/active_rules_changes.xml b/sonar-server/src/test/resources/org/sonar/server/db/migrations/v44/ChangeLogMigrationTest/active_rules_changes.xml
new file mode 100644 (file)
index 0000000..56840af
--- /dev/null
@@ -0,0 +1,43 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<dataset>
+
+  <rules_profiles id="10" name="DB_Testing" language="java"/>
+
+  <active_rule_changes id="122" profile_id="10" profile_version="2" rule_id="1" change_date="2011-11-03 20:20:05.158"
+                       enabled="true" old_severity="[null]" new_severity="1" username="Administrator"/>
+
+  <active_rule_changes id="123" profile_id="10" profile_version="2" rule_id="1" change_date="2011-12-04 10:20:05.158"
+                       enabled="[null]" old_severity="1" new_severity="4" username="asdasads"/>
+
+  <active_rule_changes id="126" profile_id="10" profile_version="2" rule_id="1" change_date="2011-12-04 20:20:05.158"
+                       enabled="[null]" old_severity="[null]" new_severity="[null]" username="Administrator"/>
+  <active_rule_param_changes id="1" active_rule_change_id="126" rules_parameter_id="11" old_value="[null]"
+                             new_value="TODO"/>
+  <active_rule_param_changes id="2" active_rule_change_id="126" rules_parameter_id="12" old_value="[null]"
+                             new_value="FIXME"/>
+  <active_rule_param_changes id="3" active_rule_change_id="126" rules_parameter_id="13" old_value="[null]"
+                             new_value="NOSONAR"/>
+
+  <active_rule_changes id="124" profile_id="10" profile_version="2" rule_id="2" change_date="2011-12-05 20:20:05.158"
+                       enabled="true" old_severity="[null]" new_severity="1" username="Administrator"/>
+  <active_rule_param_changes id="4" active_rule_change_id="124" rules_parameter_id="21" old_value="[null]"
+                             new_value="TODO"/>
+  <active_rule_param_changes id="5" active_rule_change_id="124" rules_parameter_id="22" old_value="[null]"
+                             new_value="FIXME"/>
+
+  <active_rule_changes id="125" profile_id="10" profile_version="2" rule_id="2" change_date="2011-12-06 20:20:05.158"
+                       enabled="false" old_severity="1" new_severity="[null]" username="[null]"/>
+
+  <rules id="1" plugin_name="xoo" plugin_rule_key="S001"/>
+  <rules id="2" plugin_name="xoo" plugin_rule_key="S002"/>
+
+  <rules_parameters id="11" rule_id="1" param_type="STRING" name="param1"/>
+  <rules_parameters id="12" rule_id="1" param_type="STRING" name="param2"/>
+  <rules_parameters id="13" rule_id="1" param_type="STRING" name="param3"/>
+
+  <rules_parameters id="21" rule_id="2" param_type="STRING" name="PARAM1"/>
+  <rules_parameters id="22" rule_id="2" param_type="STRING" name="PARAM2"/>
+
+  <users id="1111" name="Administrator" login="admin"/>
+
+</dataset>