]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-3543 Fail analysis if a project has no files
authorFabrice Bellingard <bellingard@gmail.com>
Thu, 5 Jul 2012 16:00:16 +0000 (18:00 +0200)
committerFabrice Bellingard <bellingard@gmail.com>
Thu, 5 Jul 2012 16:00:59 +0000 (18:00 +0200)
=> The Sonar analysis must fail when a project has been analysed
   but the measure 'files' is 0.

plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/FilesDecorator.java
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/FilesDecoratorTest.java [new file with mode: 0644]

index 2b6fc1a9a047ed8565f58850ae00e283556c5ca0..7f3b1097cdd7452406447aa88ff00f501312d065 100644 (file)
@@ -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 (file)
index 0000000..c6bfd2b
--- /dev/null
@@ -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));
+  }
+
+}