aboutsummaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
authorFabrice Bellingard <bellingard@gmail.com>2012-07-05 18:00:16 +0200
committerFabrice Bellingard <bellingard@gmail.com>2012-07-05 18:00:59 +0200
commit8dc62acc9f20e1400af64f8073fd4cb77d78cc14 (patch)
tree9135b1433367903975feac25f26485b2b7cdd7d2 /plugins
parent0c4f2bbafbe616e95d73b983c3e7b5be29644720 (diff)
downloadsonarqube-8dc62acc9f20e1400af64f8073fd4cb77d78cc14.tar.gz
sonarqube-8dc62acc9f20e1400af64f8073fd4cb77d78cc14.zip
SONAR-3543 Fail analysis if a project has no files
=> The Sonar analysis must fail when a project has been analysed but the measure 'files' is 0.
Diffstat (limited to 'plugins')
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/FilesDecorator.java12
-rw-r--r--plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/FilesDecoratorTest.java146
2 files changed, 158 insertions, 0 deletions
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/FilesDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/FilesDecorator.java
index 2b6fc1a9a04..7f3b1097cdd 100644
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/FilesDecorator.java
+++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/FilesDecorator.java
@@ -28,6 +28,8 @@ import org.sonar.api.measures.MeasureUtils;
import org.sonar.api.measures.Metric;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.Resource;
+import org.sonar.api.resources.ResourceUtils;
+import org.sonar.api.utils.SonarException;
import java.util.Collection;
@@ -45,8 +47,10 @@ public final class FilesDecorator implements Decorator {
return CoreMetrics.FILES;
}
+ @SuppressWarnings("rawtypes")
public void decorate(Resource resource, DecoratorContext context) {
if (MeasureUtils.hasValue(context.getMeasure(CoreMetrics.FILES))) {
+ checkRootProjectHasFiles(resource, context.getMeasure(CoreMetrics.FILES).getValue());
return;
}
@@ -56,9 +60,17 @@ public final class FilesDecorator implements Decorator {
} else {
Collection<Measure> childrenMeasures = context.getChildrenMeasures(CoreMetrics.FILES);
Double sum = MeasureUtils.sum(false, childrenMeasures);
+ checkRootProjectHasFiles(resource, sum);
if (sum != null) {
context.saveMeasure(CoreMetrics.FILES, sum);
}
}
}
+
+ @SuppressWarnings("rawtypes")
+ private void checkRootProjectHasFiles(Resource resource, Double sum) {
+ if (ResourceUtils.isRootProject(resource) && (sum == null || sum.doubleValue() == 0)) {
+ throw new SonarException("Project \"" + resource.getName() + "\" does not contain any file. Please check your project configuration.");
+ }
+ }
}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/FilesDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/FilesDecoratorTest.java
new file mode 100644
index 00000000000..c6bfd2bde3f
--- /dev/null
+++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/FilesDecoratorTest.java
@@ -0,0 +1,146 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.plugins.core.sensors;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.resources.Resource;
+import org.sonar.api.utils.SonarException;
+
+import java.util.Arrays;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Matchers.anyDouble;
+import static org.mockito.Matchers.eq;
+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 FilesDecoratorTest {
+
+ private FilesDecorator decorator;
+
+ @Mock
+ private DecoratorContext context;
+
+ @Mock
+ private Resource<?> resource;
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ decorator = new FilesDecorator();
+ }
+
+ @Test
+ public void generatesMetrics() {
+ assertThat(decorator.generateDirectoriesMetric()).isEqualTo(CoreMetrics.FILES);
+ }
+
+ @Test
+ public void shouldExecute() {
+ assertThat(decorator.shouldExecuteOnProject(mock(Project.class))).isEqualTo(true);
+ }
+
+ @Test
+ public void shouldNotSaveIfMeasureAlreadyExists() {
+ when(context.getMeasure(CoreMetrics.FILES)).thenReturn(new Measure(CoreMetrics.FILES, 1.0));
+
+ decorator.decorate(resource, context);
+
+ verify(context, never()).saveMeasure(eq(CoreMetrics.FILES), anyDouble());
+ }
+
+ @Test
+ public void shouldSaveOneForFile() {
+ when(resource.getQualifier()).thenReturn(Qualifiers.FILE);
+
+ decorator.decorate(resource, context);
+
+ verify(context, times(1)).saveMeasure(eq(CoreMetrics.FILES), eq(1d));
+ }
+
+ @Test
+ public void shouldSaveOneForClass() {
+ when(resource.getQualifier()).thenReturn(Qualifiers.CLASS);
+
+ decorator.decorate(resource, context);
+
+ verify(context, times(1)).saveMeasure(eq(CoreMetrics.FILES), eq(1d));
+ }
+
+ @Test
+ public void shouldSumChildren() {
+ when(context.getChildrenMeasures(CoreMetrics.FILES)).thenReturn(Arrays.asList(new Measure(CoreMetrics.FILES, 2.0), new Measure(CoreMetrics.FILES, 3.0)));
+
+ decorator.decorate(resource, context);
+
+ verify(context).saveMeasure(eq(CoreMetrics.FILES), eq(5.0));
+ }
+
+ @Test
+ public void shouldFailOnRootProjectIfNoFile() {
+ when(resource.getQualifier()).thenReturn(Qualifiers.PROJECT);
+ when(resource.getName()).thenReturn("Foo");
+ when(context.getChildrenMeasures(CoreMetrics.FILES)).thenReturn(Arrays.asList(new Measure(CoreMetrics.FILES, 0.0)));
+
+ thrown.expect(SonarException.class);
+ thrown.expectMessage("Project \"Foo\" does not contain any file. Please check your project configuration.");
+
+ decorator.decorate(resource, context);
+ }
+
+ @Test
+ public void shouldFailOnRootProjectIfNoFileMeasure() {
+ when(resource.getQualifier()).thenReturn(Qualifiers.PROJECT);
+ when(resource.getName()).thenReturn("Foo");
+
+ thrown.expect(SonarException.class);
+ thrown.expectMessage("Project \"Foo\" does not contain any file. Please check your project configuration.");
+
+ decorator.decorate(resource, context);
+ }
+
+ @Test
+ public void shouldNotFailOnModuleIfNoFile() {
+ when(resource.getQualifier()).thenReturn(Qualifiers.MODULE);
+ when(context.getChildrenMeasures(CoreMetrics.FILES)).thenReturn(Arrays.asList(new Measure(CoreMetrics.FILES, 0.0)));
+
+ decorator.decorate(resource, context);
+
+ verify(context).saveMeasure(eq(CoreMetrics.FILES), eq(0.0));
+ }
+
+}