From c36b12d2160dd7c57bb7374345a02ebb91ae31e9 Mon Sep 17 00:00:00 2001 From: Michal Duda Date: Wed, 21 Apr 2021 11:27:25 +0200 Subject: [PATCH] SONAR-14693 fix error when setting a new code period reference branch --- server/sonar-db-dao/src/schema/schema-sq.ddl | 2 +- .../newcodeperiod/NewCodePeriodDaoTest.java | 50 +++++++---- .../db/migration/version/v89/DbVersion89.java | 3 +- ...izeOfValueColumnInNewCodePeriodsTable.java | 45 ++++++++++ ...fValueColumnInNewCodePeriodsTableTest.java | 86 +++++++++++++++++++ .../schema.sql | 13 +++ 6 files changed, 180 insertions(+), 19 deletions(-) create mode 100644 server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v89/IncreaseSizeOfValueColumnInNewCodePeriodsTable.java create mode 100644 server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v89/IncreaseSizeOfValueColumnInNewCodePeriodsTableTest.java create mode 100644 server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v89/IncreaseSizeOfValueColumnInNewCodePeriodsTableTest/schema.sql diff --git a/server/sonar-db-dao/src/schema/schema-sq.ddl b/server/sonar-db-dao/src/schema/schema-sq.ddl index 8e997a27dbb..1ac0160e5f5 100644 --- a/server/sonar-db-dao/src/schema/schema-sq.ddl +++ b/server/sonar-db-dao/src/schema/schema-sq.ddl @@ -485,7 +485,7 @@ CREATE TABLE "NEW_CODE_PERIODS"( "PROJECT_UUID" VARCHAR(40), "BRANCH_UUID" VARCHAR(40), "TYPE" VARCHAR(30) NOT NULL, - "VALUE" VARCHAR(40), + "VALUE" VARCHAR(255), "UPDATED_AT" BIGINT NOT NULL, "CREATED_AT" BIGINT NOT NULL ); diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/newcodeperiod/NewCodePeriodDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/newcodeperiod/NewCodePeriodDaoTest.java index 1a3cac64eb4..02bb92a7c98 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/newcodeperiod/NewCodePeriodDaoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/newcodeperiod/NewCodePeriodDaoTest.java @@ -33,6 +33,7 @@ import org.sonar.db.project.ProjectDto; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.Assertions.tuple; import static org.sonar.db.newcodeperiod.NewCodePeriodType.NUMBER_OF_DAYS; import static org.sonar.db.newcodeperiod.NewCodePeriodType.PREVIOUS_VERSION; import static org.sonar.db.newcodeperiod.NewCodePeriodType.REFERENCE_BRANCH; @@ -46,10 +47,10 @@ public class NewCodePeriodDaoTest { private final DbSession dbSession = db.getSession(); private final UuidFactory uuidFactory = new SequenceUuidFactory(); private final NewCodePeriodDao underTest = new NewCodePeriodDao(System2.INSTANCE, uuidFactory); - + @Test public void insert_new_code_period() { - insert("proj-uuid", "branch-uuid", NUMBER_OF_DAYS, "5"); + insert("1", "proj-uuid", "branch-uuid", NUMBER_OF_DAYS, "5"); Optional resultOpt = underTest.selectByUuid(dbSession, "1"); @@ -69,6 +70,19 @@ public class NewCodePeriodDaoTest { assertNewCodePeriodRowCount(1); } + @Test + public void reference_branch_new_code_period_accepts_branches_with_long_names() { + String branchWithLongName = "abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabc" + + "defghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijab" + + "cdefghijabcdefghijabcdefghijabcdefghijxxxxx"; + + insert("1", "proj-uuid", "branch-uuid", REFERENCE_BRANCH, branchWithLongName); + + assertThat(db.select("select uuid as \"UUID\", value as \"VALUE\" from new_code_periods")) + .extracting(r -> r.get("UUID"), r -> r.get("VALUE")) + .containsExactly(tuple("1", branchWithLongName)); + } + @Test public void select_global_with_no_value() { assertThat(underTest.selectGlobal(dbSession)).isEmpty(); @@ -76,7 +90,7 @@ public class NewCodePeriodDaoTest { @Test public void update_new_code_period() { - insert("proj-uuid", "branch-uuid", NUMBER_OF_DAYS, "5"); + insert("1", "proj-uuid", "branch-uuid", NUMBER_OF_DAYS, "5"); underTest.update(dbSession, new NewCodePeriodDto() .setUuid("1") @@ -105,7 +119,7 @@ public class NewCodePeriodDaoTest { @Test public void insert_with_upsert() { - insert("proj-uuid", "branch-uuid", NUMBER_OF_DAYS, "5"); + insert("1", "proj-uuid", "branch-uuid", NUMBER_OF_DAYS, "5"); Optional resultOpt = underTest.selectByUuid(dbSession, "1"); @@ -128,7 +142,7 @@ public class NewCodePeriodDaoTest { @Test public void update_with_upsert() { - insert("proj-uuid", "branch-uuid", NUMBER_OF_DAYS, "5"); + insert("1", "proj-uuid", "branch-uuid", NUMBER_OF_DAYS, "5"); underTest.upsert(dbSession, new NewCodePeriodDto() .setUuid("1") @@ -158,7 +172,7 @@ public class NewCodePeriodDaoTest { @Test public void select_by_project_and_branch_uuids() { - insert("proj-uuid", "branch-uuid", NUMBER_OF_DAYS, "5"); + insert("1", "proj-uuid", "branch-uuid", NUMBER_OF_DAYS, "5"); Optional resultOpt = underTest.selectByBranch(dbSession, "proj-uuid", "branch-uuid"); assertThat(resultOpt) @@ -183,17 +197,17 @@ public class NewCodePeriodDaoTest { BranchDto branch2 = db.components().insertProjectBranch(project); BranchDto branch3 = db.components().insertProjectBranch(project); - insert(project.getUuid(), null, REFERENCE_BRANCH, mainBranch.getKey()); - insert(project.getUuid(), branch1.getUuid(), REFERENCE_BRANCH, mainBranch.getKey()); - insert(project.getUuid(), branch2.getUuid(), NUMBER_OF_DAYS, "5"); - insert(project.getUuid(), project.getUuid(), PREVIOUS_VERSION, null); + insert("1", project.getUuid(), null, REFERENCE_BRANCH, mainBranch.getKey()); + insert("2", project.getUuid(), branch1.getUuid(), REFERENCE_BRANCH, mainBranch.getKey()); + insert("3", project.getUuid(), branch2.getUuid(), NUMBER_OF_DAYS, "5"); + insert("4", project.getUuid(), project.getUuid(), PREVIOUS_VERSION, null); db.commit(); assertThat(underTest.selectBranchesReferencing(dbSession, project.getUuid(), mainBranch.getKey())).containsOnly(branch1.getUuid(), branch3.getUuid()); } @Test public void select_by_project_uuid() { - insert("proj-uuid", null, NUMBER_OF_DAYS, "5"); + insert("1", "proj-uuid", null, NUMBER_OF_DAYS, "5"); Optional resultOpt = underTest.selectByProject(dbSession, "proj-uuid"); assertThat(resultOpt) @@ -212,7 +226,7 @@ public class NewCodePeriodDaoTest { @Test public void select_global() { - insert(null, null, NUMBER_OF_DAYS, "30"); + insert("1", null, null, NUMBER_OF_DAYS, "30"); Optional newCodePeriodDto = underTest.selectGlobal(dbSession); assertThat(newCodePeriodDto).isNotEmpty(); @@ -229,7 +243,7 @@ public class NewCodePeriodDaoTest { @Test public void exists_by_project_analysis_is_true() { - insert("proj-uuid", "branch-uuid", SPECIFIC_ANALYSIS, "analysis-uuid"); + insert("1", "proj-uuid", "branch-uuid", SPECIFIC_ANALYSIS, "analysis-uuid"); boolean exists = underTest.existsByProjectAnalysisUuid(dbSession, "analysis-uuid"); assertThat(exists).isTrue(); @@ -237,7 +251,7 @@ public class NewCodePeriodDaoTest { @Test public void delete_by_project_uuid_and_branch_uuid() { - insert("proj-uuid", "branch-uuid", SPECIFIC_ANALYSIS, "analysis-uuid"); + insert("1", "proj-uuid", "branch-uuid", SPECIFIC_ANALYSIS, "analysis-uuid"); underTest.delete(dbSession, "proj-uuid", "branch-uuid"); db.commit(); @@ -246,7 +260,7 @@ public class NewCodePeriodDaoTest { @Test public void delete_by_project_uuid() { - insert("proj-uuid", null, SPECIFIC_ANALYSIS, "analysis-uuid"); + insert("1", "proj-uuid", null, SPECIFIC_ANALYSIS, "analysis-uuid"); underTest.delete(dbSession, "proj-uuid", null); db.commit(); @@ -255,7 +269,7 @@ public class NewCodePeriodDaoTest { @Test public void delete_global() { - insert(null, null, SPECIFIC_ANALYSIS, "analysis-uuid"); + insert("1", null, null, SPECIFIC_ANALYSIS, "analysis-uuid"); underTest.delete(dbSession, null, null); db.commit(); @@ -294,11 +308,13 @@ public class NewCodePeriodDaoTest { .isEqualTo(expected); } - private void insert(@Nullable String projectUuid, @Nullable String branchUuid, NewCodePeriodType type, @Nullable String value) { + private void insert(String uuid, @Nullable String projectUuid, @Nullable String branchUuid, NewCodePeriodType type, @Nullable String value) { underTest.insert(dbSession, new NewCodePeriodDto() + .setUuid(uuid) .setProjectUuid(projectUuid) .setBranchUuid(branchUuid) .setType(type) .setValue(value)); + db.commit(); } } diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v89/DbVersion89.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v89/DbVersion89.java index c9685b683b2..54ced6ea0d9 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v89/DbVersion89.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v89/DbVersion89.java @@ -30,6 +30,7 @@ public class DbVersion89 implements DbVersion { .add(4400, "Add indices on columns 'type' and 'value' to 'new_code_periods' table", AddIndicesToNewCodePeriodTable.class) .add(4401, "Drop local webhooks", DropLocalWebhooks.class) .add(4402, "Add Index on column 'main_branch_project_uuid' to 'components' table", AddMainBranchProjectUuidIndexToComponentTable.class) - .add(4403, "Drop Github endpoint on project level setting", DropGithubEndpointOnProjectLevelSetting.class); + .add(4403, "Drop Github endpoint on project level setting", DropGithubEndpointOnProjectLevelSetting.class) + .add(4404, "Increase size of 'value' column in 'new_code_periods' table ", IncreaseSizeOfValueColumnInNewCodePeriodsTable.class); } } diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v89/IncreaseSizeOfValueColumnInNewCodePeriodsTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v89/IncreaseSizeOfValueColumnInNewCodePeriodsTable.java new file mode 100644 index 00000000000..59814056f31 --- /dev/null +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v89/IncreaseSizeOfValueColumnInNewCodePeriodsTable.java @@ -0,0 +1,45 @@ +/* + * SonarQube + * Copyright (C) 2009-2021 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.v89; + +import java.sql.SQLException; +import org.sonar.db.Database; +import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder; +import org.sonar.server.platform.db.migration.step.DdlChange; + +import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder; + +public class IncreaseSizeOfValueColumnInNewCodePeriodsTable extends DdlChange { + private static final String TABLE_NAME = "new_code_periods"; + + public IncreaseSizeOfValueColumnInNewCodePeriodsTable(Database db) { + super(db); + } + + @Override + public void execute(Context context) throws SQLException { + context.execute(new AlterColumnsBuilder(getDialect(), TABLE_NAME) + .updateColumn(newVarcharColumnDefBuilder() + .setColumnName("value") + .setLimit(255) + .build()) + .build()); + } +} diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v89/IncreaseSizeOfValueColumnInNewCodePeriodsTableTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v89/IncreaseSizeOfValueColumnInNewCodePeriodsTableTest.java new file mode 100644 index 00000000000..c6c47e402a1 --- /dev/null +++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v89/IncreaseSizeOfValueColumnInNewCodePeriodsTableTest.java @@ -0,0 +1,86 @@ +/* + * SonarQube + * Copyright (C) 2009-2021 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.v89; + +import java.sql.SQLException; +import javax.annotation.Nullable; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.db.CoreDbTester; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.Assertions.tuple; + +public class IncreaseSizeOfValueColumnInNewCodePeriodsTableTest { + private static final String TABLE_NAME = "new_code_periods"; + private static final String VERY_LONG_BRANCH_NAME = "abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijab" + + "cdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcd" + + "efghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijxxxxx"; + private final System2 system = System2.INSTANCE; + + @Rule + public CoreDbTester db = CoreDbTester.createForSchema(IncreaseSizeOfValueColumnInNewCodePeriodsTableTest.class, "schema.sql"); + + private final IncreaseSizeOfValueColumnInNewCodePeriodsTable underTest = new IncreaseSizeOfValueColumnInNewCodePeriodsTable(db.database()); + + @Test + public void cannot_insert_long_value_before_migration() { + assertThatThrownBy(() -> insertNewCodePeriod("1", VERY_LONG_BRANCH_NAME)) + .isInstanceOf(IllegalStateException.class); + } + + @Test + public void can_insert_long_value_after_migration() throws SQLException { + underTest.execute(); + assertThat(db.countRowsOfTable(TABLE_NAME)).isZero(); + + insertNewCodePeriod("1", VERY_LONG_BRANCH_NAME); + + assertThat(db.countRowsOfTable(TABLE_NAME)).isEqualTo(1); + } + + @Test + public void existing_entries_are_not_affected() throws SQLException { + insertNewCodePeriod("1", "branch1"); + insertNewCodePeriod("2", null); + + underTest.execute(); + + assertThat(db.select("select uuid as \"UUID\", value as \"VALUE\"from new_code_periods")) + .extracting(r -> r.get("UUID"), r -> r.get("VALUE")) + .containsExactlyInAnyOrder( + tuple("1", "branch1"), + tuple("2", null)); + } + + private void insertNewCodePeriod(String uuid, @Nullable String value) { + long now = system.now(); + db.executeInsert("NEW_CODE_PERIODS", + "UUID", uuid, + "PROJECT_UUID", "proj-" + uuid, + "BRANCH_UUID", "branch-1", + "TYPE", "REFERENCE_BRANCH", + "VALUE", value, + "UPDATED_AT", now, + "CREATED_AT", now); + } +} diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v89/IncreaseSizeOfValueColumnInNewCodePeriodsTableTest/schema.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v89/IncreaseSizeOfValueColumnInNewCodePeriodsTableTest/schema.sql new file mode 100644 index 00000000000..b560d20c68a --- /dev/null +++ b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v89/IncreaseSizeOfValueColumnInNewCodePeriodsTableTest/schema.sql @@ -0,0 +1,13 @@ +CREATE TABLE "NEW_CODE_PERIODS"( + "UUID" VARCHAR(40) NOT NULL, + "PROJECT_UUID" VARCHAR(40), + "BRANCH_UUID" VARCHAR(40), + "TYPE" VARCHAR(30) NOT NULL, + "VALUE" VARCHAR(40), + "UPDATED_AT" BIGINT NOT NULL, + "CREATED_AT" BIGINT NOT NULL +); +ALTER TABLE "NEW_CODE_PERIODS" ADD CONSTRAINT "PK_NEW_CODE_PERIODS" PRIMARY KEY("UUID"); +CREATE UNIQUE INDEX "UNIQ_NEW_CODE_PERIODS" ON "NEW_CODE_PERIODS"("PROJECT_UUID", "BRANCH_UUID"); +CREATE INDEX "IDX_NCP_TYPE" ON "NEW_CODE_PERIODS"("TYPE"); +CREATE INDEX "IDX_NCP_VALUE" ON "NEW_CODE_PERIODS"("VALUE"); -- 2.39.5