From e8269de796a95fb90380f74cc71ffb07db322175 Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=A9bastien=20Lesaint?= Date: Thu, 2 Jan 2020 14:26:22 +0100 Subject: [PATCH] SONAR-12717 default status of hotspot is TO_REVIEW --- .../db/migration/version/v82/DbVersion82.java | 3 +- .../EnsureHotspotDefaultStatusIsToReview.java | 50 ++++++++ .../version/v82/DbVersion82Test.java | 2 +- ...ureHotspotDefaultStatusIsToReviewTest.java | 121 ++++++++++++++++++ .../issues.sql | 39 ++++++ 5 files changed, 213 insertions(+), 2 deletions(-) create mode 100644 server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v82/EnsureHotspotDefaultStatusIsToReview.java create mode 100644 server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v82/EnsureHotspotDefaultStatusIsToReviewTest.java create mode 100644 server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v82/EnsureHotspotDefaultStatusIsToReviewTest/issues.sql diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v82/DbVersion82.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v82/DbVersion82.java index ccaa809ef80..ba11ce14797 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v82/DbVersion82.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v82/DbVersion82.java @@ -28,6 +28,7 @@ public class DbVersion82 implements DbVersion { registry .add(3200, "Drop 'In Review' Security Hotspots status ", DropSecurityHotSpotsInReviewStatus.class) .add(3201, "Migrate Manual Vulnerabilities to Security Hotspots ", MigrateManualVulnerabilitiesToSecurityHotSpots.class) - .add(3202, "Remove 'newsbox.dismiss.hotspots' user property", RemoveNewsboxDismissHotspotsProperty.class); + .add(3202, "Remove 'newsbox.dismiss.hotspots' user property", RemoveNewsboxDismissHotspotsProperty.class) + .add(3203, "Ensure Security Hotspots have status TO_REVIEW", EnsureHotspotDefaultStatusIsToReview.class); } } diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v82/EnsureHotspotDefaultStatusIsToReview.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v82/EnsureHotspotDefaultStatusIsToReview.java new file mode 100644 index 00000000000..9753bd83f11 --- /dev/null +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v82/EnsureHotspotDefaultStatusIsToReview.java @@ -0,0 +1,50 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 SonarSource SA + * mailto:info 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.version.v82; + +import java.sql.SQLException; +import org.sonar.api.rules.RuleType; +import org.sonar.db.Database; +import org.sonar.server.platform.db.migration.step.DataChange; +import org.sonar.server.platform.db.migration.step.MassUpdate; + +import static org.sonar.api.issue.Issue.STATUS_OPEN; +import static org.sonar.api.issue.Issue.STATUS_TO_REVIEW; + +public class EnsureHotspotDefaultStatusIsToReview extends DataChange { + public EnsureHotspotDefaultStatusIsToReview(Database db) { + super(db); + } + + @Override + protected void execute(Context context) throws SQLException { + MassUpdate massUpdate = context.prepareMassUpdate(); + massUpdate.select("select id from issues where issue_type = ? and status = ?") + .setInt(1, RuleType.SECURITY_HOTSPOT.getDbConstant()) + .setString(2, STATUS_OPEN); + massUpdate.update("update issues set status = ? where id = ?"); + massUpdate.execute((row, update) -> { + long id = row.getLong(1); + update.setString(1, STATUS_TO_REVIEW); + update.setLong(2, id); + return true; + }); + } +} diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v82/DbVersion82Test.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v82/DbVersion82Test.java index 0776c6275e6..9baea99797f 100644 --- a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v82/DbVersion82Test.java +++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v82/DbVersion82Test.java @@ -36,7 +36,7 @@ public class DbVersion82Test { @Test public void verify_migration_count() { - verifyMigrationCount(underTest, 3); + verifyMigrationCount(underTest, 4); } } diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v82/EnsureHotspotDefaultStatusIsToReviewTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v82/EnsureHotspotDefaultStatusIsToReviewTest.java new file mode 100644 index 00000000000..c753636a229 --- /dev/null +++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v82/EnsureHotspotDefaultStatusIsToReviewTest.java @@ -0,0 +1,121 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 SonarSource SA + * mailto:info 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.version.v82; + +import com.tngtech.java.junit.dataprovider.DataProvider; +import com.tngtech.java.junit.dataprovider.DataProviderRunner; +import com.tngtech.java.junit.dataprovider.UseDataProvider; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.Random; +import javax.annotation.Nullable; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.sonar.api.issue.Issue; +import org.sonar.api.rules.RuleType; +import org.sonar.db.CoreDbTester; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.api.issue.Issue.STATUS_OPEN; +import static org.sonar.api.issue.Issue.STATUS_TO_REVIEW; +import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT; + +@RunWith(DataProviderRunner.class) +public class EnsureHotspotDefaultStatusIsToReviewTest { + + @Rule + public CoreDbTester db = CoreDbTester.createForSchema(EnsureHotspotDefaultStatusIsToReviewTest.class, "issues.sql"); + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + private Random random = new Random(); + + private EnsureHotspotDefaultStatusIsToReview underTest = new EnsureHotspotDefaultStatusIsToReview(db.database()); + + @Test + public void does_not_fail_if_table_is_empty() throws SQLException { + underTest.execute(); + + assertThat(db.countRowsOfTable("issues")).isEqualTo(0); + } + + @Test + public void changes_OPEN_security_hotspot_to_TO_REVIEW_whatever_resolution() throws SQLException { + insertIssue("Kee_none", SECURITY_HOTSPOT, STATUS_OPEN, null); + Issue.RESOLUTIONS.forEach(resolution -> insertIssue("Kee_" + resolution, SECURITY_HOTSPOT, STATUS_OPEN, resolution)); + + underTest.execute(); + + assertThat(db.select("select distinct STATUS from issues").stream().map(t -> t.get("STATUS"))) + .containsExactly(STATUS_TO_REVIEW); + } + + @Test + @UseDataProvider("allStatusesButOpen") + public void changes_non_OPEN_security_hotspot_to_TO_REVIEW_whatever_resolution(String status) throws SQLException { + insertIssue("Kee_none", SECURITY_HOTSPOT, status, null); + Issue.RESOLUTIONS.forEach(resolution -> insertIssue("Kee_" + resolution, SECURITY_HOTSPOT, status, resolution)); + + underTest.execute(); + + assertThat(db.select("select distinct STATUS from issues").stream().map(t -> t.get("STATUS"))) + .containsExactly(status); + } + + @DataProvider + public static Object[][] allStatusesButOpen() { + return Issue.STATUSES.stream() + .filter(t -> !STATUS_OPEN.equals(t)) + .map(t -> new Object[] {t}) + .toArray(Object[][]::new); + } + + @Test + @UseDataProvider("allRuleTypeButHotspot") + public void does_not_change_OPEN_issues_to_TO_REVIEW_whatever_resolution(RuleType ruleType) throws SQLException { + insertIssue("Kee_none", ruleType, STATUS_OPEN, null); + Issue.RESOLUTIONS.forEach(resolution -> insertIssue("Kee_" + resolution, ruleType, STATUS_OPEN, resolution)); + + underTest.execute(); + + assertThat(db.select("select distinct STATUS from issues").stream().map(t -> t.get("STATUS"))) + .containsExactly(STATUS_OPEN); + } + + @DataProvider + public static Object[][] allRuleTypeButHotspot() { + return Arrays.stream(RuleType.values()) + .filter(t -> t != SECURITY_HOTSPOT) + .map(t -> new Object[] {t}) + .toArray(Object[][]::new); + } + + private void insertIssue(String kee, RuleType ruleType, String status, @Nullable String resolution) { + db.executeInsert( + "ISSUES", + "KEE", kee, + "MANUAL_SEVERITY", random.nextBoolean(), + "ISSUE_TYPE", ruleType.getDbConstant(), + "STATUS", status, + "RESOLUTION", resolution); + } +} diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v82/EnsureHotspotDefaultStatusIsToReviewTest/issues.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v82/EnsureHotspotDefaultStatusIsToReviewTest/issues.sql new file mode 100644 index 00000000000..cf65bc42c84 --- /dev/null +++ b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v82/EnsureHotspotDefaultStatusIsToReviewTest/issues.sql @@ -0,0 +1,39 @@ +CREATE TABLE "ISSUES"( + "ID" BIGINT NOT NULL AUTO_INCREMENT (1,1), + "KEE" VARCHAR(50) NOT NULL, + "RULE_ID" INTEGER, + "SEVERITY" VARCHAR(10), + "MANUAL_SEVERITY" BOOLEAN NOT NULL, + "MESSAGE" VARCHAR(4000), + "LINE" INTEGER, + "GAP" DOUBLE, + "STATUS" VARCHAR(20), + "RESOLUTION" VARCHAR(20), + "CHECKSUM" VARCHAR(1000), + "REPORTER" VARCHAR(255), + "ASSIGNEE" VARCHAR(255), + "AUTHOR_LOGIN" VARCHAR(255), + "ACTION_PLAN_KEY" VARCHAR(50), + "ISSUE_ATTRIBUTES" VARCHAR(4000), + "EFFORT" INTEGER, + "CREATED_AT" BIGINT, + "UPDATED_AT" BIGINT, + "ISSUE_CREATION_DATE" BIGINT, + "ISSUE_UPDATE_DATE" BIGINT, + "ISSUE_CLOSE_DATE" BIGINT, + "TAGS" VARCHAR(4000), + "COMPONENT_UUID" VARCHAR(50), + "PROJECT_UUID" VARCHAR(50), + "LOCATIONS" BLOB, + "ISSUE_TYPE" TINYINT, + "FROM_HOTSPOT" BOOLEAN +); +ALTER TABLE "ISSUES" ADD CONSTRAINT "PK_ISSUES" PRIMARY KEY("ID"); +CREATE INDEX "ISSUES_ASSIGNEE" ON "ISSUES"("ASSIGNEE"); +CREATE INDEX "ISSUES_COMPONENT_UUID" ON "ISSUES"("COMPONENT_UUID"); +CREATE INDEX "ISSUES_CREATION_DATE" ON "ISSUES"("ISSUE_CREATION_DATE"); +CREATE UNIQUE INDEX "ISSUES_KEE" ON "ISSUES"("KEE"); +CREATE INDEX "ISSUES_PROJECT_UUID" ON "ISSUES"("PROJECT_UUID"); +CREATE INDEX "ISSUES_RESOLUTION" ON "ISSUES"("RESOLUTION"); +CREATE INDEX "ISSUES_RULE_ID" ON "ISSUES"("RULE_ID"); +CREATE INDEX "ISSUES_UPDATED_AT" ON "ISSUES"("UPDATED_AT"); -- 2.39.5