diff options
author | Léo Geoffroy <leo.geoffroy@sonarsource.com> | 2024-11-21 15:46:50 +0100 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2024-11-26 20:02:50 +0000 |
commit | b8f2672802b7196253b5ca60f220933b6ffe8da5 (patch) | |
tree | 851c214276111e6fe849f4d0064029848719f5ad /server/sonar-server-common | |
parent | bbadf94575df13966c7f28281160e88528464774 (diff) | |
download | sonarqube-b8f2672802b7196253b5ca60f220933b6ffe8da5.tar.gz sonarqube-b8f2672802b7196253b5ca60f220933b6ffe8da5.zip |
SONAR-23651 Trigger conditions mismatch notification when mode is changed
Diffstat (limited to 'server/sonar-server-common')
6 files changed, 135 insertions, 84 deletions
diff --git a/server/sonar-server-common/src/it/java/org/sonar/server/qualitygate/QualityGateConditionsValidatorIT.java b/server/sonar-server-common/src/it/java/org/sonar/server/qualitygate/QualityGateConditionsValidatorIT.java new file mode 100644 index 00000000000..c5290328376 --- /dev/null +++ b/server/sonar-server-common/src/it/java/org/sonar/server/qualitygate/QualityGateConditionsValidatorIT.java @@ -0,0 +1,68 @@ +/* + * SonarQube + * Copyright (C) 2009-2024 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.qualitygate; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.utils.System2; +import org.sonar.core.metric.SoftwareQualitiesMetrics; +import org.sonar.db.DbTester; +import org.sonar.db.metric.MetricDto; +import org.sonar.db.qualitygate.QualityGateDto; + +class QualityGateConditionsValidatorIT { + + @RegisterExtension + public DbTester db = DbTester.create(System2.INSTANCE); + + public QualityGateConditionsValidator underTest = new QualityGateConditionsValidator(db.getDbClient()); + + @Test + void hasConditionsMismatch_hasMismatchForStandardMode_shouldReturnExpectedValue() { + QualityGateDto qualityGateDto = db.qualityGates().insertQualityGate(); + MetricDto mqrMetric = db.measures().insertMetric(m -> m.setKey(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RELIABILITY_ISSUES_KEY)); + db.qualityGates().addCondition(qualityGateDto, mqrMetric); + + Assertions.assertThat(underTest.hasConditionsMismatch(false)).isTrue(); + Assertions.assertThat(underTest.hasConditionsMismatch(true)).isFalse(); + } + + @Test + void hasConditionsMismatch_hasMismatchForMQRMode_shouldReturnExpectedValue() { + QualityGateDto qualityGateDto = db.qualityGates().insertQualityGate(); + MetricDto mqrMetric = db.measures().insertMetric(m -> m.setKey(CoreMetrics.CODE_SMELLS_KEY)); + db.qualityGates().addCondition(qualityGateDto, mqrMetric); + + Assertions.assertThat(underTest.hasConditionsMismatch(true)).isTrue(); + Assertions.assertThat(underTest.hasConditionsMismatch(false)).isFalse(); + } + + @Test + void hasConditionsMismatch_hasNoMismatchFromAnyModes_shouldReturnExpectedValue() { + QualityGateDto qualityGateDto = db.qualityGates().insertQualityGate(); + MetricDto mqrMetric = db.measures().insertMetric(m -> m.setKey(CoreMetrics.COVERAGE_KEY)); + db.qualityGates().addCondition(qualityGateDto, mqrMetric); + + Assertions.assertThat(underTest.hasConditionsMismatch(true)).isFalse(); + Assertions.assertThat(underTest.hasConditionsMismatch(false)).isFalse(); + } +} diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/NewModesNotificationsModule.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/NewModesNotificationsModule.java index 14ecc81a5f2..bda5ac1df76 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/NewModesNotificationsModule.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/NewModesNotificationsModule.java @@ -20,13 +20,14 @@ package org.sonar.server.issue.notification; import org.sonar.core.platform.Module; +import org.sonar.server.qualitygate.QualityGateConditionsValidator; public class NewModesNotificationsModule extends Module { @Override protected void configureModule() { add( NewModesNotificationsSender.class, - + QualityGateConditionsValidator.class, MQRAndStandardModesExistNotification.class, MQRAndStandardModesExistNotificationHandler.class, MQRAndStandardModesExistTemplate.class, diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/NewModesNotificationsSender.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/NewModesNotificationsSender.java index 6fc280561ed..357827bc578 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/NewModesNotificationsSender.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/NewModesNotificationsSender.java @@ -19,16 +19,11 @@ */ package org.sonar.server.issue.notification; -import java.util.Map; -import java.util.stream.Collectors; import org.sonar.api.Startable; import org.sonar.api.config.Configuration; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.metric.MetricDto; -import org.sonar.server.metric.StandardToMQRMetrics; import org.sonar.server.notification.NotificationManager; import org.sonar.server.platform.db.migration.history.MigrationHistory; +import org.sonar.server.qualitygate.QualityGateConditionsValidator; import static org.sonar.core.config.MQRModeConstants.MULTI_QUALITY_MODE_DEFAULT_VALUE; import static org.sonar.core.config.MQRModeConstants.MULTI_QUALITY_MODE_ENABLED; @@ -39,44 +34,27 @@ public class NewModesNotificationsSender implements Startable { private final NotificationManager notificationManager; private final Configuration configuration; private final MigrationHistory migrationHistory; - private final DbClient dbClient; + private final QualityGateConditionsValidator qualityGateConditionsValidator; - public NewModesNotificationsSender(NotificationManager notificationManager, Configuration configuration, MigrationHistory migrationHistory, DbClient dbClient) { + public NewModesNotificationsSender(NotificationManager notificationManager, Configuration configuration, MigrationHistory migrationHistory, + QualityGateConditionsValidator qualityGateConditionsValidator) { this.notificationManager = notificationManager; this.configuration = configuration; this.migrationHistory = migrationHistory; - this.dbClient = dbClient; + this.qualityGateConditionsValidator = qualityGateConditionsValidator; } @Override public void start() { if (migrationHistory.getInitialDbVersion() != -1 && migrationHistory.getInitialDbVersion() < NEW_MODES_SQ_VERSION) { boolean isMQRModeEnabled = configuration.getBoolean(MULTI_QUALITY_MODE_ENABLED).orElse(MULTI_QUALITY_MODE_DEFAULT_VALUE); - sendNewModesNotification(isMQRModeEnabled); - sendQualityGateMetricsUpdateNotification(isMQRModeEnabled); - } - } - - private void sendQualityGateMetricsUpdateNotification(boolean isMQRModeEnabled) { - try (DbSession dbSession = dbClient.openSession(false)) { - - Map<String, String> metricKeysByUuids = dbClient.metricDao().selectAll(dbSession).stream() - .collect(Collectors.toMap(MetricDto::getUuid, MetricDto::getKey)); - - boolean hasConditionsFromOtherMode = dbClient.gateConditionDao().selectAll(dbSession).stream() - .anyMatch(c -> isMQRModeEnabled ? StandardToMQRMetrics.isStandardMetric(metricKeysByUuids.get(c.getMetricUuid())) - : StandardToMQRMetrics.isMQRMetric(metricKeysByUuids.get(c.getMetricUuid()))); - - if (hasConditionsFromOtherMode) { + notificationManager.scheduleForSending(new MQRAndStandardModesExistNotification(isMQRModeEnabled)); + if (qualityGateConditionsValidator.hasConditionsMismatch(isMQRModeEnabled)) { notificationManager.scheduleForSending(new QualityGateMetricsUpdateNotification(isMQRModeEnabled)); } } } - private void sendNewModesNotification(boolean isMQRModeEnabled) { - notificationManager.scheduleForSending(new MQRAndStandardModesExistNotification(isMQRModeEnabled)); - } - @Override public void stop() { // Nothing to do diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/qualitygate/QualityGateConditionsValidator.java b/server/sonar-server-common/src/main/java/org/sonar/server/qualitygate/QualityGateConditionsValidator.java new file mode 100644 index 00000000000..f47481131c0 --- /dev/null +++ b/server/sonar-server-common/src/main/java/org/sonar/server/qualitygate/QualityGateConditionsValidator.java @@ -0,0 +1,48 @@ +/* + * SonarQube + * Copyright (C) 2009-2024 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.qualitygate; + +import java.util.Map; +import java.util.stream.Collectors; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.metric.MetricDto; +import org.sonar.server.metric.StandardToMQRMetrics; + +public class QualityGateConditionsValidator { + + private final DbClient dbClient; + + public QualityGateConditionsValidator(DbClient dbClient) { + this.dbClient = dbClient; + } + + public boolean hasConditionsMismatch(boolean isMQRModeEnabled) { + try (DbSession dbSession = dbClient.openSession(false)) { + Map<String, String> metricKeysByUuids = dbClient.metricDao().selectAll(dbSession).stream() + .collect(Collectors.toMap(MetricDto::getUuid, MetricDto::getKey)); + + return dbClient.gateConditionDao().selectAll(dbSession).stream() + .anyMatch(c -> isMQRModeEnabled ? StandardToMQRMetrics.isStandardMetric(metricKeysByUuids.get(c.getMetricUuid())) + : StandardToMQRMetrics.isMQRMetric(metricKeysByUuids.get(c.getMetricUuid()))); + } + } + +} diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/NewModesNotificationsModuleTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/NewModesNotificationsModuleTest.java index b8fa479f8fd..d049248f06c 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/NewModesNotificationsModuleTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/NewModesNotificationsModuleTest.java @@ -30,6 +30,6 @@ class NewModesNotificationsModuleTest { void configure_shouldReturnExpectedNumberOfComponents() { ListContainer container = new ListContainer(); new NewModesNotificationsModule().configure(container); - assertThat(container.getAddedObjects()).hasSize(8); + assertThat(container.getAddedObjects()).hasSize(9); } } diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/NewModesNotificationsSenderTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/NewModesNotificationsSenderTest.java index 6583ff25599..13306e2fd4a 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/NewModesNotificationsSenderTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/NewModesNotificationsSenderTest.java @@ -21,21 +21,13 @@ package org.sonar.server.issue.notification; import java.util.List; import java.util.Optional; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import org.sonar.api.config.Configuration; -import org.sonar.api.measures.CoreMetrics; import org.sonar.api.notifications.Notification; -import org.sonar.core.metric.SoftwareQualitiesMetrics; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.metric.MetricDao; -import org.sonar.db.metric.MetricDto; -import org.sonar.db.qualitygate.QualityGateConditionDao; -import org.sonar.db.qualitygate.QualityGateConditionDto; import org.sonar.server.notification.NotificationManager; import org.sonar.server.platform.db.migration.history.MigrationHistory; +import org.sonar.server.qualitygate.QualityGateConditionsValidator; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -46,23 +38,12 @@ import static org.mockito.Mockito.when; import static org.sonar.core.config.MQRModeConstants.MULTI_QUALITY_MODE_ENABLED; class NewModesNotificationsSenderTest { - private static final String METRIC_UUID = "metricUuid"; - private static final String METRIC_UUID_2 = "metricUuid2"; private final NotificationManager notificationManager = mock(NotificationManager.class); private final Configuration configuration = mock(Configuration.class); private final MigrationHistory migrationHistory = mock(MigrationHistory.class); - private final DbClient dbClient = mock(DbClient.class); - private final MetricDao metricDao = mock(MetricDao.class); - private final QualityGateConditionDao qualityGateConditionDao = mock(QualityGateConditionDao.class); - private final NewModesNotificationsSender underTest = new NewModesNotificationsSender(notificationManager, configuration, migrationHistory, dbClient); - private final DbSession dbSession = mock(DbSession.class); - - @BeforeEach - void setUp() { - when(dbClient.metricDao()).thenReturn(metricDao); - when(dbClient.gateConditionDao()).thenReturn(qualityGateConditionDao); - when(dbClient.openSession(false)).thenReturn(dbSession); - } + + private final QualityGateConditionsValidator qualityGateConditionsValidator = mock(QualityGateConditionsValidator.class); + private final NewModesNotificationsSender underTest = new NewModesNotificationsSender(notificationManager, configuration, migrationHistory, qualityGateConditionsValidator); @Test void start_whenOldInstanceAndStandardMode_shouldSendNewModesNotification() { @@ -99,11 +80,10 @@ class NewModesNotificationsSenderTest { } @Test - void start_whenOldInstanceInStandardModeWithMQRConditions_shouldSendQualityGateUpdateNotification() { + void start_whenOldInstanceAndConditionsMismatch_shouldSendQualityGateUpdateNotification() { when(configuration.getBoolean(MULTI_QUALITY_MODE_ENABLED)).thenReturn(Optional.of(false)); when(migrationHistory.getInitialDbVersion()).thenReturn(9999L); // 9.9 - when(metricDao.selectAll(dbSession)).thenReturn(List.of(new MetricDto().setKey(SoftwareQualitiesMetrics.SOFTWARE_QUALITY_RELIABILITY_ISSUES_KEY).setUuid(METRIC_UUID))); - when(qualityGateConditionDao.selectAll(dbSession)).thenReturn(List.of(new QualityGateConditionDto().setMetricUuid(METRIC_UUID))); + when(qualityGateConditionsValidator.hasConditionsMismatch(false)).thenReturn(true); underTest.start(); @@ -115,37 +95,13 @@ class NewModesNotificationsSenderTest { .map(notification -> (QualityGateMetricsUpdateNotification) notification) .hasSize(1) .extracting(QualityGateMetricsUpdateNotification::isMQRModeEnabled).isEqualTo(List.of(false)); - - } - - @Test - void start_whenOldInstanceInMQRModeWithStandardConditions_shouldSendQualityGateUpdateNotification() { - when(configuration.getBoolean(MULTI_QUALITY_MODE_ENABLED)).thenReturn(Optional.of(true)); - when(migrationHistory.getInitialDbVersion()).thenReturn(9999L); // 9.9 - when(metricDao.selectAll(dbSession)).thenReturn(List.of(new MetricDto().setKey(CoreMetrics.CODE_SMELLS_KEY).setUuid(METRIC_UUID))); - when(qualityGateConditionDao.selectAll(dbSession)).thenReturn(List.of(new QualityGateConditionDto().setMetricUuid(METRIC_UUID))); - - underTest.start(); - - ArgumentCaptor<Notification> captor = ArgumentCaptor.forClass(Notification.class); - verify(notificationManager, times(2)).scheduleForSending(captor.capture()); - - assertThat(captor.getAllValues()) - .filteredOn(notification -> notification instanceof QualityGateMetricsUpdateNotification) - .map(notification -> (QualityGateMetricsUpdateNotification) notification) - .hasSize(1) - .extracting(QualityGateMetricsUpdateNotification::isMQRModeEnabled).isEqualTo(List.of(true)); } @Test - void start_whenOldInstanceInMQRModeWithOtherConditions_shouldNotSendNotification() { - when(configuration.getBoolean(MULTI_QUALITY_MODE_ENABLED)).thenReturn(Optional.of(true)); + void start_whenOldInstanceAndNoConditionsMismatch_shouldNotSendQualityGateUpdateNotification() { + when(configuration.getBoolean(MULTI_QUALITY_MODE_ENABLED)).thenReturn(Optional.of(false)); when(migrationHistory.getInitialDbVersion()).thenReturn(9999L); // 9.9 - when(metricDao.selectAll(dbSession)).thenReturn(List.of( - new MetricDto().setKey(CoreMetrics.COVERAGE_KEY).setUuid(METRIC_UUID), - new MetricDto().setKey(CoreMetrics.SECURITY_HOTSPOTS_TO_REVIEW_STATUS_KEY).setUuid(METRIC_UUID_2))); - when(qualityGateConditionDao.selectAll(dbSession)).thenReturn(List.of(new QualityGateConditionDto().setMetricUuid(METRIC_UUID), - new QualityGateConditionDto().setMetricUuid(METRIC_UUID_2))); + when(qualityGateConditionsValidator.hasConditionsMismatch(false)).thenReturn(false); underTest.start(); |