From bc413ee3db73258a22059816bd4766bcea66a9ca Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Wed, 23 Sep 2020 12:12:44 +0200 Subject: SONAR-13869 Add a flag in telemetry to know if there's some c/c++ unanalyzed code * SONAR-13869 Compute number of unanalyzed C and C++ files measures * SONAR-13869 Send unanalyzed C and C++ flags in Telemetry --- .../language/HandleUnanalyzedLanguagesStep.java | 138 ++++++++++++++ .../step/PerformNotAnalyzedFilesCheckStep.java | 111 ------------ .../step/ReportComputationSteps.java | 4 +- .../HandleUnanalyzedLanguagesStepTest.java | 200 +++++++++++++++++++++ .../step/PerformNotAnalyzedFilesCheckStepTest.java | 164 ----------------- 5 files changed, 341 insertions(+), 276 deletions(-) create mode 100644 server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/language/HandleUnanalyzedLanguagesStep.java delete mode 100644 server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PerformNotAnalyzedFilesCheckStep.java create mode 100644 server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/language/HandleUnanalyzedLanguagesStepTest.java delete mode 100644 server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/PerformNotAnalyzedFilesCheckStepTest.java (limited to 'server/sonar-ce-task-projectanalysis') diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/language/HandleUnanalyzedLanguagesStep.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/language/HandleUnanalyzedLanguagesStep.java new file mode 100644 index 00000000000..d5c78acab54 --- /dev/null +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/language/HandleUnanalyzedLanguagesStep.java @@ -0,0 +1,138 @@ +/* + * 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.ce.task.projectanalysis.language; + +import java.util.Iterator; +import java.util.Map; +import java.util.SortedMap; +import java.util.TreeMap; +import java.util.stream.Collectors; +import org.sonar.api.utils.System2; +import org.sonar.ce.task.log.CeTaskMessages; +import org.sonar.ce.task.projectanalysis.batch.BatchReportReader; +import org.sonar.ce.task.projectanalysis.component.Component; +import org.sonar.ce.task.projectanalysis.component.TreeRootHolder; +import org.sonar.ce.task.projectanalysis.measure.Measure; +import org.sonar.ce.task.projectanalysis.measure.MeasureRepository; +import org.sonar.ce.task.projectanalysis.metric.Metric; +import org.sonar.ce.task.projectanalysis.metric.MetricRepository; +import org.sonar.ce.task.step.ComputationStep; +import org.sonar.core.platform.EditionProvider; +import org.sonar.core.platform.PlatformEditionProvider; + +import static java.lang.String.format; +import static org.sonar.core.language.UnanalyzedLanguages.C; +import static org.sonar.core.language.UnanalyzedLanguages.CPP; +import static org.sonar.server.metric.UnanalyzedLanguageMetrics.UNANALYZED_CPP_KEY; +import static org.sonar.server.metric.UnanalyzedLanguageMetrics.UNANALYZED_C_KEY; + +/** + * Check if there are files that could be analyzed with a higher SQ edition. + */ +public class HandleUnanalyzedLanguagesStep implements ComputationStep { + + static final String DESCRIPTION = "Check upgrade possibility for not analyzed code files."; + + private static final String LANGUAGE_UPGRADE_MESSAGE = "%s file(s) detected during the last analysis. %s code cannot be analyzed with SonarQube " + + "community edition. Please consider upgrading to " + + "the Developer Edition to analyze this language."; + + private final BatchReportReader reportReader; + private final CeTaskMessages ceTaskMessages; + private final PlatformEditionProvider editionProvider; + private final System2 system; + private final TreeRootHolder treeRootHolder; + private final MeasureRepository measureRepository; + private final Metric unanalyzedCMetric; + private final Metric unanalyzedCppMetric; + + public HandleUnanalyzedLanguagesStep(BatchReportReader reportReader, CeTaskMessages ceTaskMessages, PlatformEditionProvider editionProvider, + System2 system, TreeRootHolder treeRootHolder, MetricRepository metricRepository, MeasureRepository measureRepository) { + this.reportReader = reportReader; + this.ceTaskMessages = ceTaskMessages; + this.editionProvider = editionProvider; + this.system = system; + this.treeRootHolder = treeRootHolder; + this.measureRepository = measureRepository; + this.unanalyzedCMetric = metricRepository.getByKey(UNANALYZED_C_KEY); + this.unanalyzedCppMetric = metricRepository.getByKey(UNANALYZED_CPP_KEY); + } + + @Override + public void execute(Context context) { + editionProvider.get().ifPresent(edition -> { + if (!edition.equals(EditionProvider.Edition.COMMUNITY)) { + return; + } + + Map filesPerLanguage = reportReader.readMetadata().getNotAnalyzedFilesByLanguageMap() + .entrySet() + .stream() + .filter(entry -> entry.getValue() > 0) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + + if (filesPerLanguage.isEmpty()) { + return; + } + + ceTaskMessages.add(constructMessage(filesPerLanguage)); + computeMeasures(filesPerLanguage); + }); + } + + private CeTaskMessages.Message constructMessage(Map filesPerLanguage) { + SortedMap sortedLanguageMap = new TreeMap<>(filesPerLanguage); + Iterator> iterator = sortedLanguageMap.entrySet().iterator(); + Map.Entry firstLanguage = iterator.next(); + StringBuilder languageLabel = new StringBuilder(firstLanguage.getKey()); + StringBuilder fileCountLabel = new StringBuilder(format("%s %s", firstLanguage.getValue(), firstLanguage.getKey())); + while (iterator.hasNext()) { + Map.Entry nextLanguage = iterator.next(); + if (iterator.hasNext()) { + languageLabel.append(", "); + fileCountLabel.append(", "); + } else { + languageLabel.append(" and "); + fileCountLabel.append(" and "); + } + languageLabel.append(nextLanguage.getKey()); + fileCountLabel.append(format("%s %s", nextLanguage.getValue(), nextLanguage.getKey())); + } + + return new CeTaskMessages.Message(format(LANGUAGE_UPGRADE_MESSAGE, fileCountLabel, languageLabel), system.now(), true); + } + + private void computeMeasures(Map filesPerLanguage) { + Component project = treeRootHolder.getRoot(); + Integer unanalyzedCFiles = filesPerLanguage.getOrDefault(C.toString(), 0); + if (unanalyzedCFiles > 0) { + measureRepository.add(project, unanalyzedCMetric, Measure.newMeasureBuilder().create(unanalyzedCFiles)); + } + Integer unanalyzedCppFiles = filesPerLanguage.getOrDefault(CPP.toString(), 0); + if (unanalyzedCppFiles > 0) { + measureRepository.add(project, unanalyzedCppMetric, Measure.newMeasureBuilder().create(unanalyzedCppFiles)); + } + } + + @Override + public String getDescription() { + return DESCRIPTION; + } +} diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PerformNotAnalyzedFilesCheckStep.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PerformNotAnalyzedFilesCheckStep.java deleted file mode 100644 index 67154fc4c74..00000000000 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PerformNotAnalyzedFilesCheckStep.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * 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.ce.task.projectanalysis.step; - -import java.util.Iterator; -import java.util.Map; -import java.util.SortedMap; -import java.util.TreeMap; -import java.util.stream.Collectors; -import org.sonar.api.utils.System2; -import org.sonar.ce.task.log.CeTaskMessages; -import org.sonar.ce.task.projectanalysis.batch.BatchReportReader; -import org.sonar.ce.task.step.ComputationStep; -import org.sonar.core.platform.EditionProvider; -import org.sonar.core.platform.PlatformEditionProvider; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static java.lang.String.format; - -/** - * Check if there are files that could be analyzed with a higher SQ edition. - */ -public class PerformNotAnalyzedFilesCheckStep implements ComputationStep { - static final String DESCRIPTION = "Check upgrade possibility for not analyzed code files."; - - private static final String LANGUAGE_UPGRADE_MESSAGE = "%s file(s) detected during the last analysis. %s code cannot be analyzed with SonarQube " + - "community edition. Please consider upgrading to " + - "the Developer Edition to analyze this language."; - - private final BatchReportReader reportReader; - private final CeTaskMessages ceTaskMessages; - private final PlatformEditionProvider editionProvider; - private final System2 system; - - public PerformNotAnalyzedFilesCheckStep(BatchReportReader reportReader, CeTaskMessages ceTaskMessages, PlatformEditionProvider editionProvider, - System2 system) { - this.reportReader = reportReader; - this.ceTaskMessages = ceTaskMessages; - this.editionProvider = editionProvider; - this.system = system; - } - - @Override - public void execute(Context context) { - editionProvider.get().ifPresent(edition -> { - if (!edition.equals(EditionProvider.Edition.COMMUNITY)) { - return; - } - - Map filesPerLanguage = reportReader.readMetadata().getNotAnalyzedFilesByLanguageMap() - .entrySet() - .stream() - .filter(entry -> entry.getValue() > 0) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); - - if (filesPerLanguage.isEmpty()) { - return; - } - - ceTaskMessages.add(constructMessage(filesPerLanguage)); - }); - } - - private CeTaskMessages.Message constructMessage(Map filesPerLanguage) { - checkNotNull(filesPerLanguage); - checkArgument(filesPerLanguage.size() > 0); - - SortedMap sortedLanguageMap = new TreeMap<>(filesPerLanguage); - Iterator> iterator = sortedLanguageMap.entrySet().iterator(); - Map.Entry firstLanguage = iterator.next(); - StringBuilder languageLabel = new StringBuilder(firstLanguage.getKey()); - StringBuilder fileCountLabel = new StringBuilder(format("%s %s", firstLanguage.getValue(), firstLanguage.getKey())); - while (iterator.hasNext()) { - Map.Entry nextLanguage = iterator.next(); - if (iterator.hasNext()) { - languageLabel.append(", "); - fileCountLabel.append(", "); - } else { - languageLabel.append(" and "); - fileCountLabel.append(" and "); - } - languageLabel.append(nextLanguage.getKey()); - fileCountLabel.append(format("%s %s", nextLanguage.getValue(), nextLanguage.getKey())); - } - - return new CeTaskMessages.Message(format(LANGUAGE_UPGRADE_MESSAGE, fileCountLabel, languageLabel), system.now(), true); - } - - @Override - public String getDescription() { - return DESCRIPTION; - } -} diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/ReportComputationSteps.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/ReportComputationSteps.java index cd708269303..1860cec78f4 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/ReportComputationSteps.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/ReportComputationSteps.java @@ -23,6 +23,7 @@ import java.util.Arrays; import java.util.List; import org.sonar.ce.task.container.TaskContainer; import org.sonar.ce.task.projectanalysis.filemove.FileMoveDetectionStep; +import org.sonar.ce.task.projectanalysis.language.HandleUnanalyzedLanguagesStep; import org.sonar.ce.task.projectanalysis.measure.PostMeasuresComputationChecksStep; import org.sonar.ce.task.projectanalysis.purge.PurgeDatastoresStep; import org.sonar.ce.task.projectanalysis.qualityprofile.RegisterQualityProfileStatusStep; @@ -38,7 +39,6 @@ public class ReportComputationSteps extends AbstractComputationSteps { private static final List> STEPS = Arrays.asList( ExtractReportStep.class, PersistScannerContextStep.class, - PerformNotAnalyzedFilesCheckStep.class, PersistAnalysisWarningsStep.class, GenerateAnalysisUuid.class, @@ -87,6 +87,8 @@ public class ReportComputationSteps extends AbstractComputationSteps { // Must be executed after computation of quality gate measure QualityGateEventsStep.class, + HandleUnanalyzedLanguagesStep.class, + // Persist data PersistComponentsStep.class, PersistAnalysisStep.class, diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/language/HandleUnanalyzedLanguagesStepTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/language/HandleUnanalyzedLanguagesStepTest.java new file mode 100644 index 00000000000..6aba65c5494 --- /dev/null +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/language/HandleUnanalyzedLanguagesStepTest.java @@ -0,0 +1,200 @@ +/* + * 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.ce.task.projectanalysis.language; + +import com.google.common.collect.ImmutableList; +import java.util.List; +import java.util.Optional; +import org.junit.Rule; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.sonar.api.utils.System2; +import org.sonar.ce.task.log.CeTaskMessages; +import org.sonar.ce.task.log.CeTaskMessages.Message; +import org.sonar.ce.task.projectanalysis.batch.BatchReportReaderRule; +import org.sonar.ce.task.projectanalysis.component.Component; +import org.sonar.ce.task.projectanalysis.component.ReportComponent; +import org.sonar.ce.task.projectanalysis.component.TreeRootHolderRule; +import org.sonar.ce.task.projectanalysis.measure.MeasureRepositoryRule; +import org.sonar.ce.task.projectanalysis.metric.MetricRepositoryRule; +import org.sonar.ce.task.step.TestComputationStepContext; +import org.sonar.core.platform.EditionProvider; +import org.sonar.core.platform.PlatformEditionProvider; +import org.sonar.scanner.protocol.output.ScannerReport; + +import static com.google.common.collect.ImmutableList.of; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.sonar.ce.task.projectanalysis.component.Component.Type.PROJECT; +import static org.sonar.server.metric.UnanalyzedLanguageMetrics.UNANALYZED_C; +import static org.sonar.server.metric.UnanalyzedLanguageMetrics.UNANALYZED_CPP; +import static org.sonar.server.metric.UnanalyzedLanguageMetrics.UNANALYZED_CPP_KEY; +import static org.sonar.server.metric.UnanalyzedLanguageMetrics.UNANALYZED_C_KEY; + +public class HandleUnanalyzedLanguagesStepTest { + + private static final int PROJECT_REF = 1; + private static final Component ROOT_PROJECT = ReportComponent.builder(PROJECT, PROJECT_REF).build(); + + @Rule + public BatchReportReaderRule reportReader = new BatchReportReaderRule(); + @Rule + public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule().setRoot(ROOT_PROJECT); + @Rule + public MetricRepositoryRule metricRepository = new MetricRepositoryRule() + .add(UNANALYZED_C) + .add(UNANALYZED_CPP); + @Rule + public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository); + + private final PlatformEditionProvider editionProvider = mock(PlatformEditionProvider.class); + private final CeTaskMessages ceTaskMessages = mock(CeTaskMessages.class); + + private final HandleUnanalyzedLanguagesStep underTest = new HandleUnanalyzedLanguagesStep(reportReader, ceTaskMessages, editionProvider, System2.INSTANCE, treeRootHolder, + metricRepository, measureRepository); + + @Test + public void getDescription() { + assertThat(underTest.getDescription()).isEqualTo(HandleUnanalyzedLanguagesStep.DESCRIPTION); + } + + @Test + public void add_warning_and_measures_in_SQ_community_edition_if_there_are_c_or_cpp_files() { + when(editionProvider.get()).thenReturn(Optional.of(EditionProvider.Edition.COMMUNITY)); + ScannerReport.AnalysisWarning warning1 = ScannerReport.AnalysisWarning.newBuilder().setText("warning 1").build(); + ScannerReport.AnalysisWarning warning2 = ScannerReport.AnalysisWarning.newBuilder().setText("warning 2").build(); + ImmutableList warnings = of(warning1, warning2); + reportReader.setAnalysisWarnings(warnings); + reportReader.setMetadata(ScannerReport.Metadata.newBuilder() + .putNotAnalyzedFilesByLanguage("C++", 20) + .putNotAnalyzedFilesByLanguage("C", 10) + .putNotAnalyzedFilesByLanguage("SomeLang", 1000) + .build()); + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Message.class); + + underTest.execute(new TestComputationStepContext()); + + verify(ceTaskMessages, times(1)).add(argumentCaptor.capture()); + assertThat(argumentCaptor.getAllValues()) + .extracting(Message::getText, Message::isDismissible) + .containsExactly(tuple( + "10 C, 20 C++ and 1000 SomeLang file(s) detected during the last analysis. C, C++ and SomeLang code cannot be analyzed with SonarQube community " + + "edition. Please consider upgrading to the Developer " + + "Edition to analyze this language.", + true)); + assertThat(measureRepository.getAddedRawMeasure(PROJECT_REF, UNANALYZED_C_KEY).get().getIntValue()).isEqualTo(10); + assertThat(measureRepository.getAddedRawMeasure(PROJECT_REF, UNANALYZED_CPP_KEY).get().getIntValue()).isEqualTo(20); + } + + @Test + public void adds_warning_and_measures_in_SQ_community_edition_if_there_are_c_files() { + when(editionProvider.get()).thenReturn(Optional.of(EditionProvider.Edition.COMMUNITY)); + reportReader.setMetadata(ScannerReport.Metadata.newBuilder() + .putNotAnalyzedFilesByLanguage("C", 10) + .build()); + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(CeTaskMessages.Message.class); + + underTest.execute(new TestComputationStepContext()); + + verify(ceTaskMessages, times(1)).add(argumentCaptor.capture()); + List messages = argumentCaptor.getAllValues(); + assertThat(messages).extracting(CeTaskMessages.Message::getText).containsExactly( + "10 C file(s) detected during the last analysis. C code cannot be analyzed with SonarQube community " + + "edition. Please consider upgrading to the Developer " + + "Edition to analyze this language."); + assertThat(measureRepository.getAddedRawMeasure(PROJECT_REF, UNANALYZED_C_KEY).get().getIntValue()).isEqualTo(10); + assertThat(measureRepository.getAddedRawMeasure(PROJECT_REF, UNANALYZED_CPP_KEY)).isEmpty(); + } + + @Test + public void adds_warning_in_SQ_community_edition_if_there_are_cpp_files() { + when(editionProvider.get()).thenReturn(Optional.of(EditionProvider.Edition.COMMUNITY)); + reportReader.setMetadata(ScannerReport.Metadata.newBuilder() + .putNotAnalyzedFilesByLanguage("C++", 9) + .build()); + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(CeTaskMessages.Message.class); + + underTest.execute(new TestComputationStepContext()); + + verify(ceTaskMessages, times(1)).add(argumentCaptor.capture()); + List messages = argumentCaptor.getAllValues(); + assertThat(messages).extracting(CeTaskMessages.Message::getText).containsExactly( + "9 C++ file(s) detected during the last analysis. C++ code cannot be analyzed with SonarQube community " + + "edition. Please consider upgrading to the Developer " + + "Edition to analyze this language."); + assertThat(measureRepository.getAddedRawMeasure(PROJECT_REF, UNANALYZED_CPP_KEY).get().getIntValue()).isEqualTo(9); + assertThat(measureRepository.getAddedRawMeasure(PROJECT_REF, UNANALYZED_C_KEY)).isEmpty(); + } + + @Test + public void do_nothing_SQ_community_edition_if_cpp_files_in_report_is_zero() { + when(editionProvider.get()).thenReturn(Optional.of(EditionProvider.Edition.COMMUNITY)); + ScannerReport.AnalysisWarning warning1 = ScannerReport.AnalysisWarning.newBuilder().setText("warning 1").build(); + ScannerReport.AnalysisWarning warning2 = ScannerReport.AnalysisWarning.newBuilder().setText("warning 2").build(); + ImmutableList warnings = of(warning1, warning2); + reportReader.setAnalysisWarnings(warnings); + reportReader.setMetadata(ScannerReport.Metadata.newBuilder().putNotAnalyzedFilesByLanguage("C++", 0).build()); + + underTest.execute(new TestComputationStepContext()); + + verify(ceTaskMessages, never()).add(any()); + + assertThat(measureRepository.getAddedRawMeasure(PROJECT_REF, UNANALYZED_C_KEY)).isEmpty(); + assertThat(measureRepository.getAddedRawMeasure(PROJECT_REF, UNANALYZED_CPP_KEY)).isEmpty(); + } + + @Test + public void execute_does_not_add_a_warning_in_SQ_community_edition_if_no_c_or_cpp_files() { + when(editionProvider.get()).thenReturn(Optional.of(EditionProvider.Edition.COMMUNITY)); + ScannerReport.AnalysisWarning warning1 = ScannerReport.AnalysisWarning.newBuilder().setText("warning 1").build(); + ScannerReport.AnalysisWarning warning2 = ScannerReport.AnalysisWarning.newBuilder().setText("warning 2").build(); + ImmutableList warnings = of(warning1, warning2); + reportReader.setAnalysisWarnings(warnings); + reportReader.setMetadata(ScannerReport.Metadata.newBuilder().build()); + + underTest.execute(new TestComputationStepContext()); + + verify(ceTaskMessages, never()).add(any()); + assertThat(measureRepository.getAddedRawMeasure(PROJECT_REF, UNANALYZED_C_KEY)).isEmpty(); + assertThat(measureRepository.getAddedRawMeasure(PROJECT_REF, UNANALYZED_CPP_KEY)).isEmpty(); + } + + @Test + public void execute_does_not_add_a_warning_in_SQ_non_community_edition() { + when(editionProvider.get()).thenReturn(Optional.of(EditionProvider.Edition.ENTERPRISE)); + ScannerReport.AnalysisWarning warning1 = ScannerReport.AnalysisWarning.newBuilder().setText("warning 1").build(); + ScannerReport.AnalysisWarning warning2 = ScannerReport.AnalysisWarning.newBuilder().setText("warning 2").build(); + ImmutableList warnings = of(warning1, warning2); + reportReader.setAnalysisWarnings(warnings); + reportReader.setMetadata(ScannerReport.Metadata.newBuilder().putNotAnalyzedFilesByLanguage("C++", 20).build()); + + underTest.execute(new TestComputationStepContext()); + + verify(ceTaskMessages, never()).add(any()); + assertThat(measureRepository.getAddedRawMeasure(PROJECT_REF, UNANALYZED_C_KEY)).isEmpty(); + assertThat(measureRepository.getAddedRawMeasure(PROJECT_REF, UNANALYZED_CPP_KEY)).isEmpty(); + } +} diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/PerformNotAnalyzedFilesCheckStepTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/PerformNotAnalyzedFilesCheckStepTest.java deleted file mode 100644 index ef05b274ed6..00000000000 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/PerformNotAnalyzedFilesCheckStepTest.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * 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.ce.task.projectanalysis.step; - -import com.google.common.collect.ImmutableList; -import java.util.List; -import java.util.Optional; -import org.junit.Rule; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.sonar.api.utils.System2; -import org.sonar.ce.task.log.CeTaskMessages; -import org.sonar.ce.task.log.CeTaskMessages.Message; -import org.sonar.ce.task.projectanalysis.batch.BatchReportReaderRule; -import org.sonar.ce.task.step.TestComputationStepContext; -import org.sonar.core.platform.EditionProvider; -import org.sonar.core.platform.PlatformEditionProvider; -import org.sonar.scanner.protocol.output.ScannerReport; - -import static com.google.common.collect.ImmutableList.of; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.tuple; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class PerformNotAnalyzedFilesCheckStepTest { - - @Rule - public BatchReportReaderRule reportReader = new BatchReportReaderRule(); - - private final PlatformEditionProvider editionProvider = mock(PlatformEditionProvider.class); - private final CeTaskMessages ceTaskMessages = mock(CeTaskMessages.class); - private final PerformNotAnalyzedFilesCheckStep underTest = new PerformNotAnalyzedFilesCheckStep(reportReader, ceTaskMessages, editionProvider, System2.INSTANCE); - - @Test - public void getDescription() { - assertThat(underTest.getDescription()).isEqualTo(PerformNotAnalyzedFilesCheckStep.DESCRIPTION); - } - - @Test - public void execute_adds_warning_in_SQ_community_edition_if_there_are_c_or_cpp_files() { - when(editionProvider.get()).thenReturn(Optional.of(EditionProvider.Edition.COMMUNITY)); - ScannerReport.AnalysisWarning warning1 = ScannerReport.AnalysisWarning.newBuilder().setText("warning 1").build(); - ScannerReport.AnalysisWarning warning2 = ScannerReport.AnalysisWarning.newBuilder().setText("warning 2").build(); - ImmutableList warnings = of(warning1, warning2); - reportReader.setAnalysisWarnings(warnings); - reportReader.setMetadata(ScannerReport.Metadata.newBuilder() - .putNotAnalyzedFilesByLanguage("C++", 20) - .putNotAnalyzedFilesByLanguage("C", 10) - .putNotAnalyzedFilesByLanguage("SomeLang", 1000) - .build()); - ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Message.class); - - underTest.execute(new TestComputationStepContext()); - - verify(ceTaskMessages, times(1)).add(argumentCaptor.capture()); - assertThat(argumentCaptor.getAllValues()) - .extracting(Message::getText, Message::isDismissible) - .containsExactly(tuple( - "10 C, 20 C++ and 1000 SomeLang file(s) detected during the last analysis. C, C++ and SomeLang code cannot be analyzed with SonarQube community " + - "edition. Please consider upgrading to the Developer " + - "Edition to analyze this language.", - true)); - } - - @Test - public void execute_adds_warning_in_SQ_community_edition_if_there_are_c_files() { - when(editionProvider.get()).thenReturn(Optional.of(EditionProvider.Edition.COMMUNITY)); - reportReader.setMetadata(ScannerReport.Metadata.newBuilder() - .putNotAnalyzedFilesByLanguage("C", 10) - .build()); - ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(CeTaskMessages.Message.class); - - underTest.execute(new TestComputationStepContext()); - - verify(ceTaskMessages, times(1)).add(argumentCaptor.capture()); - List messages = argumentCaptor.getAllValues(); - assertThat(messages).extracting(CeTaskMessages.Message::getText).containsExactly( - "10 C file(s) detected during the last analysis. C code cannot be analyzed with SonarQube community " + - "edition. Please consider upgrading to the Developer " + - "Edition to analyze this language."); - } - - @Test - public void execute_adds_warning_in_SQ_community_edition_if_there_are_cpp_files() { - when(editionProvider.get()).thenReturn(Optional.of(EditionProvider.Edition.COMMUNITY)); - reportReader.setMetadata(ScannerReport.Metadata.newBuilder() - .putNotAnalyzedFilesByLanguage("C++", 9) - .build()); - ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(CeTaskMessages.Message.class); - - underTest.execute(new TestComputationStepContext()); - - verify(ceTaskMessages, times(1)).add(argumentCaptor.capture()); - List messages = argumentCaptor.getAllValues(); - assertThat(messages).extracting(CeTaskMessages.Message::getText).containsExactly( - "9 C++ file(s) detected during the last analysis. C++ code cannot be analyzed with SonarQube community " + - "edition. Please consider upgrading to the Developer " + - "Edition to analyze this language."); - } - - @Test - public void execute_does_not_add_a_warning_in_SQ_community_edition_if_cpp_files_in_report_is_zero() { - when(editionProvider.get()).thenReturn(Optional.of(EditionProvider.Edition.COMMUNITY)); - ScannerReport.AnalysisWarning warning1 = ScannerReport.AnalysisWarning.newBuilder().setText("warning 1").build(); - ScannerReport.AnalysisWarning warning2 = ScannerReport.AnalysisWarning.newBuilder().setText("warning 2").build(); - ImmutableList warnings = of(warning1, warning2); - reportReader.setAnalysisWarnings(warnings); - reportReader.setMetadata(ScannerReport.Metadata.newBuilder().putNotAnalyzedFilesByLanguage("C++", 0).build()); - - underTest.execute(new TestComputationStepContext()); - - verify(ceTaskMessages, never()).add(any()); - } - - @Test - public void execute_does_not_add_a_warning_in_SQ_community_edition_if_no_c_or_cpp_files_2() { - when(editionProvider.get()).thenReturn(Optional.of(EditionProvider.Edition.COMMUNITY)); - ScannerReport.AnalysisWarning warning1 = ScannerReport.AnalysisWarning.newBuilder().setText("warning 1").build(); - ScannerReport.AnalysisWarning warning2 = ScannerReport.AnalysisWarning.newBuilder().setText("warning 2").build(); - ImmutableList warnings = of(warning1, warning2); - reportReader.setAnalysisWarnings(warnings); - reportReader.setMetadata(ScannerReport.Metadata.newBuilder().build()); - - underTest.execute(new TestComputationStepContext()); - - verify(ceTaskMessages, never()).add(any()); - } - - @Test - public void execute_does_not_add_a_warning_in_SQ_non_community_edition() { - when(editionProvider.get()).thenReturn(Optional.of(EditionProvider.Edition.ENTERPRISE)); - ScannerReport.AnalysisWarning warning1 = ScannerReport.AnalysisWarning.newBuilder().setText("warning 1").build(); - ScannerReport.AnalysisWarning warning2 = ScannerReport.AnalysisWarning.newBuilder().setText("warning 2").build(); - ImmutableList warnings = of(warning1, warning2); - reportReader.setAnalysisWarnings(warnings); - reportReader.setMetadata(ScannerReport.Metadata.newBuilder().putNotAnalyzedFilesByLanguage("C++", 20).build()); - - underTest.execute(new TestComputationStepContext()); - - verify(ceTaskMessages, never()).add(any()); - } -} -- cgit v1.2.3