From: Julien Lancelot Date: Wed, 9 Apr 2014 12:00:05 +0000 (+0200) Subject: SONAR-5200 When a module has been removed, related issues are not closed during the... X-Git-Tag: 4.3~82 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=fef49730fdf2126edbd1f2414d50426f5e3b73b3;p=sonarqube.git SONAR-5200 When a module has been removed, related issues are not closed during the purge --- diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java b/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java index f6a6dc41922..c09affd1af3 100644 --- a/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java +++ b/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java @@ -33,7 +33,7 @@ import java.util.List; */ public class DatabaseVersion implements BatchComponent, ServerComponent { - public static final int LAST_VERSION = 524; + public static final int LAST_VERSION = 525; public static enum Status { UP_TO_DATE, REQUIRES_UPGRADE, REQUIRES_DOWNGRADE, FRESH_INSTALL diff --git a/sonar-core/src/main/java/org/sonar/core/purge/PurgeConfiguration.java b/sonar-core/src/main/java/org/sonar/core/purge/PurgeConfiguration.java index ac8880c4678..d026ba60612 100644 --- a/sonar-core/src/main/java/org/sonar/core/purge/PurgeConfiguration.java +++ b/sonar-core/src/main/java/org/sonar/core/purge/PurgeConfiguration.java @@ -21,8 +21,10 @@ package org.sonar.core.purge; import com.google.common.annotations.VisibleForTesting; import org.apache.commons.lang.time.DateUtils; +import org.sonar.api.utils.System2; import javax.annotation.CheckForNull; + import java.util.Date; public class PurgeConfiguration { @@ -30,11 +32,18 @@ public class PurgeConfiguration { private final long rootProjectId; private final String[] scopesWithoutHistoricalData; private final int maxAgeInDaysOfClosedIssues; + private final System2 system2; public PurgeConfiguration(long rootProjectId, String[] scopesWithoutHistoricalData, int maxAgeInDaysOfClosedIssues) { + this(rootProjectId, scopesWithoutHistoricalData, maxAgeInDaysOfClosedIssues, System2.INSTANCE); + } + + @VisibleForTesting + PurgeConfiguration(long rootProjectId, String[] scopesWithoutHistoricalData, int maxAgeInDaysOfClosedIssues, System2 system2) { this.rootProjectId = rootProjectId; this.scopesWithoutHistoricalData = scopesWithoutHistoricalData; this.maxAgeInDaysOfClosedIssues = maxAgeInDaysOfClosedIssues; + this.system2 = system2; } public long rootProjectId() { @@ -47,7 +56,7 @@ public class PurgeConfiguration { @CheckForNull public Date maxLiveDateOfClosedIssues() { - return maxLiveDateOfClosedIssues(new Date()); + return maxLiveDateOfClosedIssues(new Date(system2.now())); } @VisibleForTesting diff --git a/sonar-core/src/main/java/org/sonar/core/purge/PurgeDao.java b/sonar-core/src/main/java/org/sonar/core/purge/PurgeDao.java index 73c95d818c4..5777908166b 100644 --- a/sonar-core/src/main/java/org/sonar/core/purge/PurgeDao.java +++ b/sonar-core/src/main/java/org/sonar/core/purge/PurgeDao.java @@ -19,7 +19,6 @@ */ package org.sonar.core.purge; -import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Lists; import org.apache.commons.lang.ArrayUtils; import org.apache.ibatis.session.ResultContext; @@ -83,34 +82,35 @@ public class PurgeDao { if (hasAbortedBuilds(project.getId(), commands)) { LOG.info("<- Delete aborted builds"); PurgeSnapshotQuery query = PurgeSnapshotQuery.create() - .setIslast(false) - .setStatus(new String[] {"U"}) - .setRootProjectId(project.getId()); + .setIslast(false) + .setStatus(new String[]{"U"}) + .setRootProjectId(project.getId()); commands.deleteSnapshots(query); } } private boolean hasAbortedBuilds(Long projectId, PurgeCommands commands) { PurgeSnapshotQuery query = PurgeSnapshotQuery.create() - .setIslast(false) - .setStatus(new String[] {"U"}) - .setResourceId(projectId); + .setIslast(false) + .setStatus(new String[]{"U"}) + .setResourceId(projectId); return !commands.selectSnapshotIds(query).isEmpty(); } private void purge(ResourceDto project, String[] scopesWithoutHistoricalData, PurgeCommands purgeCommands) { List projectSnapshotIds = purgeCommands.selectSnapshotIds( - PurgeSnapshotQuery.create() - .setResourceId(project.getId()) - .setIslast(false) - .setNotPurged(true)); + PurgeSnapshotQuery.create() + .setResourceId(project.getId()) + .setIslast(false) + .setNotPurged(true) + ); for (final Long projectSnapshotId : projectSnapshotIds) { LOG.info("<- Clean snapshot " + projectSnapshotId); if (!ArrayUtils.isEmpty(scopesWithoutHistoricalData)) { PurgeSnapshotQuery query = PurgeSnapshotQuery.create() - .setIslast(false) - .setScopes(scopesWithoutHistoricalData) - .setRootSnapshotId(projectSnapshotId); + .setIslast(false) + .setScopes(scopesWithoutHistoricalData) + .setRootSnapshotId(projectSnapshotId); purgeCommands.deleteSnapshots(query); } @@ -170,11 +170,11 @@ public class PurgeDao { commands.deleteResources(resourceIds); } - @VisibleForTesting - void disableResource(long resourceId, PurgeMapper mapper) { + private void disableResource(long resourceId, PurgeMapper mapper) { mapper.deleteResourceIndex(Arrays.asList(resourceId)); mapper.setSnapshotIsLastToFalse(resourceId); mapper.disableResource(resourceId); + mapper.resolveResourceIssuesNotAlreadyResolved(resourceId); } public PurgeDao deleteSnapshots(PurgeSnapshotQuery query) { diff --git a/sonar-core/src/main/java/org/sonar/core/purge/PurgeMapper.java b/sonar-core/src/main/java/org/sonar/core/purge/PurgeMapper.java index ba596bccef4..ff7d36d2d04 100644 --- a/sonar-core/src/main/java/org/sonar/core/purge/PurgeMapper.java +++ b/sonar-core/src/main/java/org/sonar/core/purge/PurgeMapper.java @@ -58,16 +58,14 @@ public interface PurgeMapper { List selectMetricIdsWithoutHistoricalData(); - List selectCharacteristicIdsToPurge(); - void deleteSnapshotWastedMeasures(@Param("snapshotIds") List snapshotIds, @Param("mids") List metricIds); - void deleteSnapshotMeasuresOnCharacteristics(@Param("snapshotIds") List snapshotIds, @Param("cids") List characteristicIds); - void updatePurgeStatusToOne(long snapshotId); void disableResource(long resourceId); + void resolveResourceIssuesNotAlreadyResolved(long resourceId); + void deleteResourceIndex(@Param("resourceIds") List resourceIds); void deleteEvent(long eventId); diff --git a/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql b/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql index c2427db7198..5c2d3bd0be5 100644 --- a/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql +++ b/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql @@ -223,6 +223,7 @@ INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('521'); INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('522'); INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('523'); INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('524'); +INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('525'); 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; diff --git a/sonar-core/src/main/resources/org/sonar/core/purge/PurgeMapper.xml b/sonar-core/src/main/resources/org/sonar/core/purge/PurgeMapper.xml index a7de12225bb..cd4dc492f89 100644 --- a/sonar-core/src/main/resources/org/sonar/core/purge/PurgeMapper.xml +++ b/sonar-core/src/main/resources/org/sonar/core/purge/PurgeMapper.xml @@ -183,6 +183,10 @@ update projects set enabled=${_false} where id=#{id} + + update issues set status='CLOSED',resolution='REMOVED' where component_id=#{id} AND resolution IS NULL + + delete from resource_index where resource_id in diff --git a/sonar-core/src/test/java/org/sonar/core/purge/PurgeDaoTest.java b/sonar-core/src/test/java/org/sonar/core/purge/PurgeDaoTest.java index a22b5106384..bec255186e0 100644 --- a/sonar-core/src/test/java/org/sonar/core/purge/PurgeDaoTest.java +++ b/sonar-core/src/test/java/org/sonar/core/purge/PurgeDaoTest.java @@ -24,6 +24,8 @@ import org.hamcrest.Description; import org.junit.Before; import org.junit.Test; import org.sonar.api.resources.Scopes; +import org.sonar.api.utils.DateUtils; +import org.sonar.api.utils.System2; import org.sonar.core.persistence.AbstractDaoTestCase; import org.sonar.core.resource.ResourceDao; @@ -32,13 +34,20 @@ import java.util.List; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; import static org.junit.internal.matchers.IsCollectionContaining.hasItem; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class PurgeDaoTest extends AbstractDaoTestCase { - private PurgeDao dao; + System2 system2; + + PurgeDao dao; @Before public void createDao() { + system2 = mock(System2.class); + when(system2.now()).thenReturn(DateUtils.parseDate("2014-04-09").getTime()); + dao = new PurgeDao(getMyBatis(), new ResourceDao(getMyBatis()), new PurgeProfiler()); } @@ -64,10 +73,10 @@ public class PurgeDaoTest extends AbstractDaoTestCase { } @Test - public void shouldDisableResourcesWithoutLastSnapshot() { - setupData("shouldDisableResourcesWithoutLastSnapshot"); - dao.purge(new PurgeConfiguration(1L, new String[0], 30)); - checkTables("shouldDisableResourcesWithoutLastSnapshot", "projects", "snapshots"); + public void disable_resources_without_last_snapshot() { + setupData("disable_resources_without_last_snapshot"); + dao.purge(new PurgeConfiguration(1L, new String[0], 30, system2)); + checkTables("disable_resources_without_last_snapshot", "projects", "snapshots", "issues"); } @Test @@ -109,7 +118,6 @@ public class PurgeDaoTest extends AbstractDaoTestCase { checkTables("should_delete_all_closed_issues", "issues", "issue_changes"); } - static final class SnapshotMatcher extends BaseMatcher { long snapshotId; boolean isLast; diff --git a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/disable_resources_without_last_snapshot-result.xml b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/disable_resources_without_last_snapshot-result.xml new file mode 100644 index 00000000000..9663761342b --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/disable_resources_without_last_snapshot-result.xml @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/disable_resources_without_last_snapshot.xml b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/disable_resources_without_last_snapshot.xml new file mode 100644 index 00000000000..e2cc5f459c9 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/disable_resources_without_last_snapshot.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldDisableResourcesWithoutLastSnapshot-result.xml b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldDisableResourcesWithoutLastSnapshot-result.xml deleted file mode 100644 index 8857dc5ddca..00000000000 --- a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldDisableResourcesWithoutLastSnapshot-result.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldDisableResourcesWithoutLastSnapshot.xml b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldDisableResourcesWithoutLastSnapshot.xml deleted file mode 100644 index fbda7d8a16d..00000000000 --- a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/shouldDisableResourcesWithoutLastSnapshot.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/should_delete_all_closed_issues-result.xml b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/should_delete_all_closed_issues-result.xml index 9eb87fb10c9..4d55fe35f48 100644 --- a/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/should_delete_all_closed_issues-result.xml +++ b/sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/should_delete_all_closed_issues-result.xml @@ -9,6 +9,16 @@ long_name="[null]" scope="PRJ" qualifier="TRK" kee="project" name="project" description="[null]" language="java" copy_resource_id="[null]" person_id="[null]"/> + + + > CLASSES = ImmutableList.of( + // 3.6 ViolationMigration.class, + + // 4.2 + PackageKeysMigration.class, CompleteIssueMessageMigration.class, + + // 4.3 IssueMigration.class, IssueChangelogMigration.class, TechnicalDebtMeasuresMigration.class, DevelopmentCostMeasuresMigration.class, RequirementMeasuresMigration.class, - - // 4.2 - PackageKeysMigration.class, CompleteIssueMessageMigration.class + NotResolvedIssuesOnRemovedComponentsMigration.class ); } diff --git a/sonar-server/src/main/java/org/sonar/server/db/migrations/MassUpdater.java b/sonar-server/src/main/java/org/sonar/server/db/migrations/MassUpdater.java index 31f9e0224d0..a6e861e4202 100644 --- a/sonar-server/src/main/java/org/sonar/server/db/migrations/MassUpdater.java +++ b/sonar-server/src/main/java/org/sonar/server/db/migrations/MassUpdater.java @@ -20,6 +20,7 @@ package org.sonar.server.db.migrations; +import com.google.common.annotations.VisibleForTesting; import org.apache.commons.dbutils.DbUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -81,7 +82,7 @@ public class MassUpdater { } else { stmt.setFetchSize(GROUP_SIZE); } - rs = stmt.executeQuery(inputLoader.selectSql()); + rs = stmt.executeQuery(convertSelectSql(inputLoader.selectSql(), db)); int cursor = 0; while (rs.next()) { @@ -120,4 +121,15 @@ public class MassUpdater { } } + @VisibleForTesting + static String convertSelectSql(String selectSql, Database db){ + // Replace ${_true} + selectSql = selectSql.replace("${_true}", db.getDialect().getTrueSqlValue()); + + // Replace ${_false} + selectSql = selectSql.replace("${_false}", db.getDialect().getFalseSqlValue()); + + return selectSql; + } + } diff --git a/sonar-server/src/main/java/org/sonar/server/db/migrations/v43/NotResolvedIssuesOnRemovedComponentsMigration.java b/sonar-server/src/main/java/org/sonar/server/db/migrations/v43/NotResolvedIssuesOnRemovedComponentsMigration.java index a851125dab7..cfd9cc707b2 100644 --- a/sonar-server/src/main/java/org/sonar/server/db/migrations/v43/NotResolvedIssuesOnRemovedComponentsMigration.java +++ b/sonar-server/src/main/java/org/sonar/server/db/migrations/v43/NotResolvedIssuesOnRemovedComponentsMigration.java @@ -21,7 +21,7 @@ package org.sonar.server.db.migrations.v43; import com.google.common.annotations.VisibleForTesting; -import org.sonar.api.config.Settings; +import org.sonar.api.issue.Issue; import org.sonar.api.utils.System2; import org.sonar.core.persistence.Database; import org.sonar.server.db.migrations.DatabaseMigration; @@ -35,22 +35,21 @@ import java.sql.Timestamp; /** * Used in the Active Record Migration 525 + * * @since 4.3 */ public class NotResolvedIssuesOnRemovedComponentsMigration implements DatabaseMigration { - private final WorkDurationConvertor workDurationConvertor; private final System2 system2; private final Database db; - public NotResolvedIssuesOnRemovedComponentsMigration(Database database, Settings settings) { - this(database, settings, System2.INSTANCE); + public NotResolvedIssuesOnRemovedComponentsMigration(Database database) { + this(database, System2.INSTANCE); } @VisibleForTesting - NotResolvedIssuesOnRemovedComponentsMigration(Database database, Settings settings, System2 system2) { + NotResolvedIssuesOnRemovedComponentsMigration(Database database, System2 system2) { this.db = database; - this.workDurationConvertor = new WorkDurationConvertor(settings); this.system2 = system2; } @@ -60,28 +59,30 @@ public class NotResolvedIssuesOnRemovedComponentsMigration implements DatabaseMi new MassUpdater.InputLoader() { @Override public String selectSql() { - return "SELECT i.id, i.technical_debt FROM issues i WHERE i.technical_debt IS NOT NULL"; + return "SELECT i.id FROM issues i " + + "INNER JOIN projects p on p.id=i.component_id " + + "WHERE p.enabled=${_false} AND i.resolution IS NULL "; } @Override public Row load(ResultSet rs) throws SQLException { Row row = new Row(); row.id = SqlUtil.getLong(rs, 1); - row.debt = SqlUtil.getLong(rs, 2); return row; } }, new MassUpdater.InputConverter() { @Override public String updateSql() { - return "UPDATE issues SET technical_debt=?,updated_at=? WHERE id=?"; + return "UPDATE issues SET status=?,resolution=?,updated_at=? WHERE id=?"; } @Override public boolean convert(Row row, PreparedStatement updateStatement) throws SQLException { - updateStatement.setLong(1, workDurationConvertor.createFromLong(row.debt)); - updateStatement.setTimestamp(2, new Timestamp(system2.now())); - updateStatement.setLong(3, row.id); + updateStatement.setString(1, Issue.STATUS_CLOSED); + updateStatement.setString(2, Issue.RESOLUTION_REMOVED); + updateStatement.setTimestamp(3, new Timestamp(system2.now())); + updateStatement.setLong(4, row.id); return true; } } @@ -90,7 +91,6 @@ public class NotResolvedIssuesOnRemovedComponentsMigration implements DatabaseMi private static class Row { private Long id; - private Long debt; } } diff --git a/sonar-server/src/main/webapp/WEB-INF/db/migrate/525_update_not_resolved_issues_on_removed_components.rb b/sonar-server/src/main/webapp/WEB-INF/db/migrate/525_update_not_resolved_issues_on_removed_components.rb new file mode 100644 index 00000000000..df7f088f8ad --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/db/migrate/525_update_not_resolved_issues_on_removed_components.rb @@ -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.3 +# SONAR-5200 +# +class UpdateNotResolvedIssuesOnRemovedComponents < ActiveRecord::Migration + + def self.up + Java::OrgSonarServerUi::JRubyFacade.getInstance().databaseMigrator().executeMigration('org.sonar.server.db.migrations.v43.NotResolvedIssuesOnRemovedComponentsMigration') + end + +end diff --git a/sonar-server/src/test/java/org/sonar/server/db/migrations/MassUpdaterTest.java b/sonar-server/src/test/java/org/sonar/server/db/migrations/MassUpdaterTest.java new file mode 100644 index 00000000000..208c0d50687 --- /dev/null +++ b/sonar-server/src/test/java/org/sonar/server/db/migrations/MassUpdaterTest.java @@ -0,0 +1,51 @@ +/* + * 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; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.sonar.core.persistence.Database; +import org.sonar.core.persistence.dialect.Dialect; + +import static org.fest.assertions.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class MassUpdaterTest { + + @Mock + Database db; + + @Test + public void convert_select_sql() throws Exception { + Dialect dialect = mock(Dialect.class); + when(dialect.getTrueSqlValue()).thenReturn("true"); + when(dialect.getFalseSqlValue()).thenReturn("false"); + + when(db.getDialect()).thenReturn(dialect); + + String result = MassUpdater.convertSelectSql("SELECT * FROM projects WHERE enabled=${_true} AND used=${_true} AND deleted=${_false}", db); + assertThat(result).isEqualTo("SELECT * FROM projects WHERE enabled=true AND used=true AND deleted=false"); + } +} diff --git a/sonar-server/src/test/java/org/sonar/server/db/migrations/v43/NotResolvedIssuesOnRemovedComponentsMigrationTest.java b/sonar-server/src/test/java/org/sonar/server/db/migrations/v43/NotResolvedIssuesOnRemovedComponentsMigrationTest.java new file mode 100644 index 00000000000..dae4233e37b --- /dev/null +++ b/sonar-server/src/test/java/org/sonar/server/db/migrations/v43/NotResolvedIssuesOnRemovedComponentsMigrationTest.java @@ -0,0 +1,62 @@ +/* + * 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.v43; + +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.TestDatabase; + +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class NotResolvedIssuesOnRemovedComponentsMigrationTest { + + @ClassRule + public static TestDatabase db = new TestDatabase().schema(NotResolvedIssuesOnRemovedComponentsMigrationTest.class, "schema.sql"); + + @Mock + System2 system2; + + NotResolvedIssuesOnRemovedComponentsMigration migration; + + @Before + public void setUp() throws Exception { + when(system2.now()).thenReturn(DateUtils.parseDate("2014-04-09").getTime()); + + migration = new NotResolvedIssuesOnRemovedComponentsMigration(db.database(), system2); + } + + @Test + public void migrate_issues() throws Exception { + db.prepareDbUnit(getClass(), "migrate_issues.xml"); + + migration.execute(); + + db.assertDbUnit(getClass(), "migrate_issues_result.xml", "issues"); + } + +} diff --git a/sonar-server/src/test/resources/org/sonar/server/db/migrations/v43/NotResolvedIssuesOnRemovedComponentsMigrationTest/migrate_issues.xml b/sonar-server/src/test/resources/org/sonar/server/db/migrations/v43/NotResolvedIssuesOnRemovedComponentsMigrationTest/migrate_issues.xml new file mode 100644 index 00000000000..1e7e5ab984c --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/db/migrations/v43/NotResolvedIssuesOnRemovedComponentsMigrationTest/migrate_issues.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + diff --git a/sonar-server/src/test/resources/org/sonar/server/db/migrations/v43/NotResolvedIssuesOnRemovedComponentsMigrationTest/migrate_issues_result.xml b/sonar-server/src/test/resources/org/sonar/server/db/migrations/v43/NotResolvedIssuesOnRemovedComponentsMigrationTest/migrate_issues_result.xml new file mode 100644 index 00000000000..4509c279724 --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/db/migrations/v43/NotResolvedIssuesOnRemovedComponentsMigrationTest/migrate_issues_result.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + diff --git a/sonar-server/src/test/resources/org/sonar/server/db/migrations/v43/NotResolvedIssuesOnRemovedComponentsMigrationTest/schema.sql b/sonar-server/src/test/resources/org/sonar/server/db/migrations/v43/NotResolvedIssuesOnRemovedComponentsMigrationTest/schema.sql new file mode 100644 index 00000000000..c0129aa79f5 --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/db/migrations/v43/NotResolvedIssuesOnRemovedComponentsMigrationTest/schema.sql @@ -0,0 +1,46 @@ +-- 4.3 + +CREATE TABLE "ISSUES" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "KEE" VARCHAR(50) UNIQUE NOT NULL, + "COMPONENT_ID" INTEGER NOT NULL, + "ROOT_COMPONENT_ID" INTEGER, + "RULE_ID" INTEGER, + "SEVERITY" VARCHAR(10), + "MANUAL_SEVERITY" BOOLEAN NOT NULL, + "MESSAGE" VARCHAR(4000), + "LINE" INTEGER, + "EFFORT_TO_FIX" DOUBLE, + "STATUS" VARCHAR(20), + "RESOLUTION" VARCHAR(20), + "CHECKSUM" VARCHAR(1000), + "REPORTER" VARCHAR(40), + "ASSIGNEE" VARCHAR(40), + "AUTHOR_LOGIN" VARCHAR(100), + "ACTION_PLAN_KEY" VARCHAR(50) NULL, + "ISSUE_ATTRIBUTES" VARCHAR(4000), + "ISSUE_CREATION_DATE" TIMESTAMP, + "ISSUE_CLOSE_DATE" TIMESTAMP, + "ISSUE_UPDATE_DATE" TIMESTAMP, + "CREATED_AT" TIMESTAMP, + "UPDATED_AT" TIMESTAMP, + "TECHNICAL_DEBT" INTEGER +); + +CREATE TABLE "PROJECTS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "NAME" VARCHAR(256), + "DESCRIPTION" VARCHAR(2000), + "ENABLED" BOOLEAN NOT NULL DEFAULT TRUE, + "SCOPE" VARCHAR(3), + "QUALIFIER" VARCHAR(10), + "KEE" VARCHAR(400), + "DEPRECATED_KEE" VARCHAR(400), + "PATH" VARCHAR(2000), + "ROOT_ID" INTEGER, + "LANGUAGE" VARCHAR(20), + "COPY_RESOURCE_ID" INTEGER, + "LONG_NAME" VARCHAR(256), + "PERSON_ID" INTEGER, + "CREATED_AT" TIMESTAMP +);