From 181b1bc208d2d49e6ce723e4be1380be16823c54 Mon Sep 17 00:00:00 2001 From: Julien HENRY Date: Wed, 19 Jun 2019 14:19:33 +0200 Subject: [PATCH] SONAR-11320 Update branding from VSTS/TFS to Azure DevOps --- .../db/migration/version/v79/DbVersion79.java | 3 +- .../v79/MigrateVstsProviderToAzureDevOps.java | 65 +++++++++++ .../version/v79/DbVersion79Test.java | 2 +- .../MigrateVstsProviderToAzureDevOpsTest.java | 105 ++++++++++++++++++ .../properties.sql | 12 ++ .../resources/org/sonar/l10n/core.properties | 2 +- 6 files changed, 186 insertions(+), 3 deletions(-) create mode 100644 server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v79/MigrateVstsProviderToAzureDevOps.java create mode 100644 server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v79/MigrateVstsProviderToAzureDevOpsTest.java create mode 100644 server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v79/MigrateVstsProviderToAzureDevOpsTest/properties.sql diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v79/DbVersion79.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v79/DbVersion79.java index ba6201566de..963cc0ffb96 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v79/DbVersion79.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v79/DbVersion79.java @@ -28,6 +28,7 @@ public class DbVersion79 implements DbVersion { registry .add(2800, "Truncate environment variables and system properties from existing scanner reports", TruncateEnvAndSystemVarsFromScannerContext.class) - .add(2801, "populate install version and install date internal properties", PopulateInstallDateAndVersion.class); + .add(2801, "populate install version and install date internal properties", PopulateInstallDateAndVersion.class) + .add(2802, "Migrate property 'sonar.pullrequest.provider' value from VSTS to Azure DevOps", MigrateVstsProviderToAzureDevOps.class); } } diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v79/MigrateVstsProviderToAzureDevOps.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v79/MigrateVstsProviderToAzureDevOps.java new file mode 100644 index 00000000000..4bbe529dc2d --- /dev/null +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v79/MigrateVstsProviderToAzureDevOps.java @@ -0,0 +1,65 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 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.v79; + +import java.sql.SQLException; +import org.sonar.db.Database; +import org.sonar.server.platform.db.migration.SupportsBlueGreen; +import org.sonar.server.platform.db.migration.step.DataChange; +import org.sonar.server.platform.db.migration.step.MassUpdate; + +@SupportsBlueGreen +public class MigrateVstsProviderToAzureDevOps extends DataChange { + + private static final String VSTS = "VSTS"; + private static final String VSTS_TFS = "VSTS / TFS"; + + public MigrateVstsProviderToAzureDevOps(Database db) { + super(db); + } + + @Override + protected void execute(Context context) throws SQLException { + MassUpdate massUpdate = context.prepareMassUpdate(); + massUpdate.select("select id, text_value from properties " + + " where prop_key = 'sonar.pullrequest.provider' and text_value in ('" + VSTS + "', '" + VSTS_TFS + "')"); + massUpdate.update("update properties " + + " set text_value= ?, " + + " clob_value = null " + + " where id = ?"); + massUpdate.rowPluralName("PR provider properties"); + massUpdate.execute((row, update) -> { + update.setString(1, convert(row.getString(2))); + update.setLong(2, row.getLong(1)); + return true; + }); + } + + private static String convert(String oldValue) { + switch (oldValue) { + case VSTS: + return "Azure DevOps Services"; + case VSTS_TFS: + return "Azure DevOps Services/Server"; + default: + throw new IllegalStateException("Unexpected value: " + oldValue); + } + } +} diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v79/DbVersion79Test.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v79/DbVersion79Test.java index ad2680616cc..760504bc02b 100644 --- a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v79/DbVersion79Test.java +++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v79/DbVersion79Test.java @@ -35,7 +35,7 @@ public class DbVersion79Test { @Test public void verify_migration_count() { - verifyMigrationCount(underTest, 2); + verifyMigrationCount(underTest, 3); } } diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v79/MigrateVstsProviderToAzureDevOpsTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v79/MigrateVstsProviderToAzureDevOpsTest.java new file mode 100644 index 00000000000..880f8c085bf --- /dev/null +++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v79/MigrateVstsProviderToAzureDevOpsTest.java @@ -0,0 +1,105 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 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.v79; + +import java.sql.SQLException; +import java.util.HashMap; +import java.util.stream.Collectors; +import javax.annotation.Nullable; +import org.assertj.core.groups.Tuple; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.db.CoreDbTester; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; + +public class MigrateVstsProviderToAzureDevOpsTest { + + private final static String SELECT_PROPERTIES = "SELECT prop_key, is_empty, text_value, clob_value FROM properties"; + + @Rule + public CoreDbTester db = CoreDbTester.createForSchema(MigrateVstsProviderToAzureDevOpsTest.class, "properties.sql"); + + private MigrateVstsProviderToAzureDevOps underTest = new MigrateVstsProviderToAzureDevOps(db.database()); + + @Test + public void migration_must_update_the_database() throws SQLException { + insertProperty("sonar.pullrequest.provider", "any.value_here", null, false); + insertProperty("sonar.pullrequest.provider", "VSTS", null, false); + insertProperty("sonar.pullrequest.provider", "VSTS / TFS", null, false); + insertProperty("whatever.property", "nothingspecial", null, false); + insertProperty("whatever.property", null, "nothing.special", false); + + underTest.execute(); + + assertPropertyContainsInAnyOrder( + tuple("sonar.pullrequest.provider", "any.value_here", null, false), + tuple("sonar.pullrequest.provider", "Azure DevOps Services", null, false), + tuple("sonar.pullrequest.provider", "Azure DevOps Services/Server", null, false), // Single change + tuple("whatever.property", "nothingspecial", null, false), + tuple("whatever.property", null, "nothing.special", false) + ); + } + + @Test + public void migration_must_be_reentrant() throws SQLException { + insertProperty("sonar.pullrequest.provider", "any.value_here", null, false); + insertProperty("sonar.pullrequest.provider", "VSTS", null, false); + insertProperty("sonar.pullrequest.provider", "VSTS / TFS", null, false); + insertProperty("whatever.property", "nothingspecial", null, false); + insertProperty("whatever.property", null, "nothing.special", false); + + underTest.execute(); + underTest.execute(); + + assertPropertyContainsInAnyOrder( + tuple("sonar.pullrequest.provider", "any.value_here", null, false), + tuple("sonar.pullrequest.provider", "Azure DevOps Services", null, false), + tuple("sonar.pullrequest.provider", "Azure DevOps Services/Server", null, false), // Single change + tuple("whatever.property", "nothingspecial", null, false), + tuple("whatever.property", null, "nothing.special", false) + ); + } + + @Test + public void migration_is_doing_nothing_when_no_data() throws SQLException { + assertThat(db.countRowsOfTable("properties")).isEqualTo(0); + underTest.execute(); + assertThat(db.countRowsOfTable("properties")).isEqualTo(0); + } + + private void insertProperty(String propKey, @Nullable String textValue, @Nullable String clobValue, boolean isEmpty) { + HashMap map = new HashMap<>(); + map.put("PROP_KEY", propKey); + map.put("TEXT_VALUE", textValue); + map.put("CLOB_VALUE", clobValue); + map.put("IS_EMPTY", isEmpty); + db.executeInsert("PROPERTIES", map); + } + + private void assertPropertyContainsInAnyOrder(Tuple... tuples) { + assertThat(db.select(SELECT_PROPERTIES) + .stream() + .map(p -> new Tuple(p.get("PROP_KEY"), p.get("TEXT_VALUE"), p.get("CLOB_VALUE"), p.get("IS_EMPTY"))) + .collect(Collectors.toList())) + .containsExactlyInAnyOrder(tuples); + } +} diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v79/MigrateVstsProviderToAzureDevOpsTest/properties.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v79/MigrateVstsProviderToAzureDevOpsTest/properties.sql new file mode 100644 index 00000000000..a81f731fd80 --- /dev/null +++ b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v79/MigrateVstsProviderToAzureDevOpsTest/properties.sql @@ -0,0 +1,12 @@ +CREATE TABLE "PROPERTIES" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "PROP_KEY" VARCHAR(512) NOT NULL, + "RESOURCE_ID" INTEGER, + "USER_ID" INTEGER, + "IS_EMPTY" BOOLEAN NOT NULL, + "TEXT_VALUE" VARCHAR(4000), + "CLOB_VALUE" CLOB, + "CREATED_AT" BIGINT +); +CREATE INDEX "PROPERTIES_KEY" ON "PROPERTIES" ("PROP_KEY"); + diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties index ed4af11f3e5..2d49a5c84f3 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -2807,7 +2807,7 @@ onboarding.project_analysis.description=We initialized your project on {instance onboarding.project_analysis.commands_for_analysis=Below are the commands to use to do an analysis. onboarding.project_analysis.guide_to_integrate_pipelines=follow the guide to integrating with Pipelines onboarding.project_analysis.guide_to_integrate_travis=follow the guide to integrating with Travis CI -onboarding.project_analysis.guide_to_integrate_vsts=follow the guide to integrating with VSTS +onboarding.project_analysis.guide_to_integrate_vsts=follow the guide to integrating with Azure DevOps Services onboarding.project_analysis.simply_link=Simply {link}. onboarding.project_analysis.suggestions.bitbucket=If you are using Bitbucket Cloud Pipelines, the SonarCloud App makes it easier to run these commands with your CI process. onboarding.project_analysis.suggestions.github=If you are using Travis CI, the SonarCloud Travis Add-on makes it easier to run these commands with your CI process. -- 2.39.5