]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-9701 Skip unchanged components
authorDuarte Meneses <duarte.meneses@sonarsource.com>
Wed, 9 Aug 2017 14:10:02 +0000 (16:10 +0200)
committerJanos Gyerik <janos.gyerik@sonarsource.com>
Tue, 12 Sep 2017 08:55:10 +0000 (10:55 +0200)
14 files changed:
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/analysis/AnalysisMetadataHolder.java
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/analysis/AnalysisMetadataHolderImpl.java
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/component/ComponentTreeBuilder.java
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/IssueTrackingDelegator.java
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/BuildComponentTreeStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/LoadQualityGateStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/PersistComponentsStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/SizeMeasuresStep.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/analysis/AnalysisMetadataHolderImplTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/analysis/AnalysisMetadataHolderRule.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/analysis/MutableAnalysisMetadataHolderRule.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/component/ComponentTreeBuilderTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/IssueTrackingDelegatorTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/LoadQualityGateStepTest.java

index e86d1a7501ced28403463c7865e7cb93553ddc77..8334cc14b0e3be05ce17e28e9c48472356201fe4 100644 (file)
@@ -69,6 +69,13 @@ public interface AnalysisMetadataHolder {
   @CheckForNull
   Analysis getBaseAnalysis();
 
+  /**
+   * Convenience method equivalent to do the check using {@link #getBranch()}
+   *
+   * @throws IllegalStateException if branch has not been set
+   */
+  boolean isShortLivingBranch();
+
   /**
    * @throws IllegalStateException if cross project duplication flag has not been set
    */
index 7b0a9dcbec0fa2520d39759c2e0135e5e9175b4c..5a6b5dd74b2ea01feceb67427df2991fe56ff3ea 100644 (file)
@@ -24,6 +24,8 @@ import java.util.Map;
 import java.util.Optional;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
+
+import org.sonar.db.component.BranchType;
 import org.sonar.server.computation.util.InitializedProperty;
 import org.sonar.server.qualityprofile.QualityProfile;
 
@@ -163,6 +165,7 @@ public class AnalysisMetadataHolderImpl implements MutableAnalysisMetadataHolder
 
   @Override
   public MutableAnalysisMetadataHolder setRootComponentRef(int rootComponentRef) {
+
     checkState(!this.rootComponentRef.isInitialized(), "Root component ref has already been set");
     this.rootComponentRef.setProperty(rootComponentRef);
     return this;
@@ -200,4 +203,10 @@ public class AnalysisMetadataHolderImpl implements MutableAnalysisMetadataHolder
     return pluginsByKey.getProperty();
   }
 
+  public boolean isShortLivingBranch() {
+    checkState(this.branch.isInitialized(), "Branch has not been set");
+    Branch prop = branch.getProperty();
+    return prop != null && prop.getType() == BranchType.SHORT;
+  }
+
 }
index 7627811ee374a04c490446a1a0122a929a83a43c..e20815be0cba25fd30720d76c1cc25dcd0d2335c 100644 (file)
@@ -58,19 +58,22 @@ public class ComponentTreeBuilder {
 
   @Nullable
   private final SnapshotDto baseAnalysis;
+  private final boolean skipUnchangedFiles;
 
   public ComponentTreeBuilder(
     ComponentKeyGenerator keyGenerator,
     Function<String, String> uuidSupplier,
     Function<Integer, ScannerReport.Component> scannerComponentSupplier,
     Project project,
-    @Nullable SnapshotDto baseAnalysis) {
+    @Nullable SnapshotDto baseAnalysis,
+    boolean skipUnchangedFiles) {
 
     this.keyGenerator = keyGenerator;
     this.uuidSupplier = uuidSupplier;
     this.scannerComponentSupplier = scannerComponentSupplier;
     this.project = project;
     this.baseAnalysis = baseAnalysis;
+    this.skipUnchangedFiles = skipUnchangedFiles;
   }
 
   public Component buildProject(ScannerReport.Component project) {
@@ -80,7 +83,9 @@ public class ComponentTreeBuilder {
   private Component[] buildChildren(ScannerReport.Component component, ScannerReport.Component parentModule) {
     return component.getChildRefList()
       .stream()
-      .map(componentRef -> buildComponent(scannerComponentSupplier.apply(componentRef), parentModule))
+      .map(scannerComponentSupplier::apply)
+      .filter(c -> !skipUnchangedFiles || c.getStatus() != FileStatus.SAME)
+      .map(c -> buildComponent(c, parentModule))
       .toArray(Component[]::new);
   }
 
index 5e51c6c6982276299d2aba3eb424b4bdee001fdf..c8ce36312841870c8afc6108dfc681f19be11333 100644 (file)
  */
 package org.sonar.server.computation.task.projectanalysis.issue;
 
+
 import org.sonar.core.issue.DefaultIssue;
 import org.sonar.core.issue.tracking.Tracking;
-import org.sonar.db.component.BranchType;
 import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolder;
-import org.sonar.server.computation.task.projectanalysis.analysis.Branch;
 import org.sonar.server.computation.task.projectanalysis.component.Component;
 
 public class IssueTrackingDelegator {
@@ -37,13 +36,8 @@ public class IssueTrackingDelegator {
     this.analysisMetadataHolder = analysisMetadataHolder;
   }
 
-  private boolean isShortLivingBranch() {
-    java.util.Optional<Branch> branch = analysisMetadataHolder.getBranch();
-    return branch.isPresent() && branch.get().getType() == BranchType.SHORT;
-  }
-
   public Tracking<DefaultIssue, DefaultIssue> track(Component component) {
-    if (isShortLivingBranch()) {
+    if (analysisMetadataHolder.isShortLivingBranch()) {
       return shortBranchTracker.track(component);
     } else {
       return tracker.track(component);
index edc9921eb6fb1938928fef35149763162d57bb5f..9a487a160b151dcc602c0be760d41261708fc8dd 100644 (file)
@@ -79,12 +79,14 @@ public class BuildComponentTreeStep implements ComputationStep {
 
       String rootUuid = componentUuidFactory.getOrCreateForKey(rootKey);
       SnapshotDto baseAnalysis = loadBaseAnalysis(dbSession, rootUuid);
+      boolean skipUnchangedFiles = analysisMetadataHolder.isShortLivingBranch();
 
       ComponentTreeBuilder builder = new ComponentTreeBuilder(keyGenerator,
         componentUuidFactory::getOrCreateForKey,
         reportReader::readComponent,
         analysisMetadataHolder.getProject(),
-        baseAnalysis);
+        baseAnalysis,
+        skipUnchangedFiles);
       Component project = builder.buildProject(reportProject);
 
       treeRootHolder.setRoot(project);
index 3248e2c780478c616a041e32e41a9552f8167a95..6eb92f179d448f4849cd21981551f2874ee78b4c 100644 (file)
  */
 package org.sonar.server.computation.task.projectanalysis.step;
 
-import com.google.common.base.Optional;
+import static org.apache.commons.lang.StringUtils.isBlank;
+
 import org.sonar.api.config.Configuration;
 import org.sonar.api.utils.log.Logger;
 import org.sonar.api.utils.log.Loggers;
+import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolder;
 import org.sonar.server.computation.task.projectanalysis.component.ConfigurationRepository;
 import org.sonar.server.computation.task.projectanalysis.qualitygate.MutableQualityGateHolder;
 import org.sonar.server.computation.task.projectanalysis.qualitygate.QualityGate;
 import org.sonar.server.computation.task.projectanalysis.qualitygate.QualityGateService;
 import org.sonar.server.computation.task.step.ComputationStep;
 
-import static org.apache.commons.lang.StringUtils.isBlank;
+import com.google.common.base.Optional;
 
 /**
  * This step retrieves the QualityGate and stores it in
@@ -43,16 +45,22 @@ public class LoadQualityGateStep implements ComputationStep {
   private final ConfigurationRepository configRepository;
   private final QualityGateService qualityGateService;
   private final MutableQualityGateHolder qualityGateHolder;
+  private final AnalysisMetadataHolder analysisMetadataHolder;
 
-  public LoadQualityGateStep(ConfigurationRepository settingsRepository,
-    QualityGateService qualityGateService, MutableQualityGateHolder qualityGateHolder) {
+  public LoadQualityGateStep(ConfigurationRepository settingsRepository, QualityGateService qualityGateService, MutableQualityGateHolder qualityGateHolder,
+    AnalysisMetadataHolder analysisMetadataHolder) {
     this.configRepository = settingsRepository;
     this.qualityGateService = qualityGateService;
     this.qualityGateHolder = qualityGateHolder;
+    this.analysisMetadataHolder = analysisMetadataHolder;
   }
 
   @Override
   public void execute() {
+    if (analysisMetadataHolder.isShortLivingBranch()) {
+      qualityGateHolder.setNoQualityGate();
+      return;
+    }
     Configuration config = configRepository.getConfiguration();
     String qualityGateSetting = config.get(PROPERTY_QUALITY_GATE).orElse(null);
 
index 7961ca9f41077be838115eaa234ac3fd04caba01..9e84defc794ee56094dc7cb56695867dfc1598b0 100644 (file)
  */
 package org.sonar.server.computation.task.projectanalysis.step;
 
-import com.google.common.base.Predicate;
+import static com.google.common.collect.FluentIterable.from;
+import static java.util.Optional.ofNullable;
+import static org.sonar.db.component.ComponentDto.UUID_PATH_OF_ROOT;
+import static org.sonar.db.component.ComponentDto.UUID_PATH_SEPARATOR;
+import static org.sonar.db.component.ComponentDto.formatUuidPathFromParent;
+import static org.sonar.server.computation.task.projectanalysis.component.ComponentVisitor.Order.PRE_ORDER;
+
 import java.util.Collection;
 import java.util.Date;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 import java.util.function.Function;
+import java.util.stream.Collectors;
+
 import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
+
 import org.apache.commons.io.FilenameUtils;
 import org.apache.commons.lang.StringUtils;
 import org.sonar.api.resources.Qualifiers;
@@ -53,12 +62,7 @@ import org.sonar.server.computation.task.projectanalysis.component.PathAwareVisi
 import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolder;
 import org.sonar.server.computation.task.step.ComputationStep;
 
-import static com.google.common.collect.FluentIterable.from;
-import static java.util.Optional.ofNullable;
-import static org.sonar.db.component.ComponentDto.UUID_PATH_OF_ROOT;
-import static org.sonar.db.component.ComponentDto.UUID_PATH_SEPARATOR;
-import static org.sonar.db.component.ComponentDto.formatUuidPathFromParent;
-import static org.sonar.server.computation.task.projectanalysis.component.ComponentVisitor.Order.PRE_ORDER;
+import com.google.common.base.Predicate;
 
 /**
  * Persist report components
@@ -169,7 +173,7 @@ public class PersistComponentsStep implements ComputationStep {
   private Map<String, ComponentDto> indexExistingDtosByKey(DbSession session) {
     return dbClient.componentDao().selectAllComponentsFromProjectKey(session, treeRootHolder.getRoot().getKey())
       .stream()
-      .collect(java.util.stream.Collectors.toMap(ComponentDto::getDbKey, Function.identity()));
+      .collect(Collectors.toMap(ComponentDto::getDbKey, Function.identity()));
   }
 
   private class PersistComponentStepsVisitor extends PathAwareVisitorAdapter<ComponentDtoHolder> {
index 2e7c4996bfbf20041d531b410da66cac5f3c2869..0ee54d5d7f966053eea32c9ad7fe321944c9f819 100644 (file)
  */
 package org.sonar.server.computation.task.projectanalysis.step;
 
-import com.google.common.base.Optional;
-import com.google.common.collect.ImmutableList;
+import static org.sonar.api.measures.CoreMetrics.ACCESSORS_KEY;
+import static org.sonar.api.measures.CoreMetrics.CLASSES_KEY;
+import static org.sonar.api.measures.CoreMetrics.DIRECTORIES_KEY;
+import static org.sonar.api.measures.CoreMetrics.FILES_KEY;
+import static org.sonar.api.measures.CoreMetrics.FUNCTIONS_KEY;
+import static org.sonar.api.measures.CoreMetrics.GENERATED_LINES_KEY;
+import static org.sonar.api.measures.CoreMetrics.GENERATED_NCLOC_KEY;
+import static org.sonar.api.measures.CoreMetrics.LINES_KEY;
+import static org.sonar.api.measures.CoreMetrics.NCLOC_KEY;
+import static org.sonar.api.measures.CoreMetrics.STATEMENTS_KEY;
+import static org.sonar.server.computation.task.projectanalysis.component.ComponentVisitor.Order.POST_ORDER;
+import static org.sonar.server.computation.task.projectanalysis.formula.SumFormula.createIntSumFormula;
+import static org.sonar.server.computation.task.projectanalysis.measure.Measure.newMeasureBuilder;
+
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
+
 import org.sonar.server.computation.task.projectanalysis.component.Component;
 import org.sonar.server.computation.task.projectanalysis.component.CrawlerDepthLimit;
 import org.sonar.server.computation.task.projectanalysis.component.PathAwareCrawler;
@@ -35,33 +50,21 @@ import org.sonar.server.computation.task.projectanalysis.metric.Metric;
 import org.sonar.server.computation.task.projectanalysis.metric.MetricRepository;
 import org.sonar.server.computation.task.step.ComputationStep;
 
-import static org.sonar.api.measures.CoreMetrics.ACCESSORS_KEY;
-import static org.sonar.api.measures.CoreMetrics.CLASSES_KEY;
-import static org.sonar.api.measures.CoreMetrics.DIRECTORIES_KEY;
-import static org.sonar.api.measures.CoreMetrics.FILES_KEY;
-import static org.sonar.api.measures.CoreMetrics.FUNCTIONS_KEY;
-import static org.sonar.api.measures.CoreMetrics.GENERATED_LINES_KEY;
-import static org.sonar.api.measures.CoreMetrics.GENERATED_NCLOC_KEY;
-import static org.sonar.api.measures.CoreMetrics.LINES_KEY;
-import static org.sonar.api.measures.CoreMetrics.NCLOC_KEY;
-import static org.sonar.api.measures.CoreMetrics.STATEMENTS_KEY;
-import static org.sonar.server.computation.task.projectanalysis.component.ComponentVisitor.Order.POST_ORDER;
-import static org.sonar.server.computation.task.projectanalysis.formula.SumFormula.createIntSumFormula;
-import static org.sonar.server.computation.task.projectanalysis.measure.Measure.newMeasureBuilder;
+import com.google.common.base.Optional;
 
 /**
  * Compute size measures
  */
 public class SizeMeasuresStep implements ComputationStep {
   private static final CounterStackElementFactory COUNTER_STACK_ELEMENT_FACTORY = new CounterStackElementFactory();
-  private static final List<Formula> AGGREGATED_SIZE_MEASURE_FORMULAS = ImmutableList.<Formula>of(
+  private static final List<Formula> AGGREGATED_SIZE_MEASURE_FORMULAS = Collections.unmodifiableList(Arrays.asList(
     createIntSumFormula(GENERATED_LINES_KEY),
     createIntSumFormula(NCLOC_KEY),
     createIntSumFormula(GENERATED_NCLOC_KEY),
     createIntSumFormula(FUNCTIONS_KEY),
     createIntSumFormula(STATEMENTS_KEY),
     createIntSumFormula(CLASSES_KEY),
-    createIntSumFormula(ACCESSORS_KEY));
+    createIntSumFormula(ACCESSORS_KEY)));
 
   private final TreeRootHolder treeRootHolder;
   private final MetricRepository metricRepository;
index 313c4eed3c15da9d1de3cd5d90ffecbffb5c598b..b3f2b9a023605fbbcceeadb018e18a8d203c372a 100644 (file)
@@ -22,10 +22,13 @@ package org.sonar.server.computation.task.projectanalysis.analysis;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
+import org.sonar.db.component.BranchType;
 import org.sonar.db.organization.OrganizationDto;
 import org.sonar.server.computation.task.projectanalysis.component.DefaultBranchImpl;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 public class AnalysisMetadataHolderImplTest {
 
@@ -200,7 +203,7 @@ public class AnalysisMetadataHolderImplTest {
 
     new AnalysisMetadataHolderImpl().isCrossProjectDuplicationEnabled();
   }
-  
+
   @Test
   public void setIsCrossProjectDuplicationEnabled_throws_ISE_when_called_twice() {
     AnalysisMetadataHolderImpl underTest = new AnalysisMetadataHolderImpl();
@@ -220,7 +223,7 @@ public class AnalysisMetadataHolderImplTest {
     expectedException.expectMessage("Incremental analysis flag has already been set");
     underTest.setIncrementalAnalysis(false);
   }
-  
+
   @Test
   public void isIncrementalAnalysis_return_true() {
     AnalysisMetadataHolderImpl underTest = new AnalysisMetadataHolderImpl();
@@ -338,4 +341,24 @@ public class AnalysisMetadataHolderImplTest {
     expectedException.expectMessage("Root component ref has already been set");
     underTest.setRootComponentRef(9);
   }
+
+  @Test
+  public void getIsShortLivingBranch_throws_ISE_when_holder_is_not_initialized() {
+    expectedException.expect(IllegalStateException.class);
+    expectedException.expectMessage("Branch has not been set");
+
+    AnalysisMetadataHolderImpl underTest = new AnalysisMetadataHolderImpl();
+    underTest.isShortLivingBranch();
+  }
+
+  @Test
+  public void getIsShortLivingBranch_returns_true() {
+    Branch branch = mock(Branch.class);
+    when(branch.getType()).thenReturn(BranchType.SHORT);
+
+    AnalysisMetadataHolderImpl underTest = new AnalysisMetadataHolderImpl();
+    underTest.setBranch(branch);
+
+    assertThat(underTest.isShortLivingBranch()).isTrue();
+  }
 }
index 05977dbbd112f8a0aba04ea2fa6ae5c257685f46..8f310b303314fb8c0790d9314b80a8ce0641b4cf 100644 (file)
@@ -25,6 +25,7 @@ import java.util.Optional;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
 import org.junit.rules.ExternalResource;
+import org.sonar.db.component.BranchType;
 import org.sonar.db.organization.OrganizationDto;
 import org.sonar.server.computation.util.InitializedProperty;
 import org.sonar.server.qualityprofile.QualityProfile;
@@ -214,4 +215,10 @@ public class AnalysisMetadataHolderRule extends ExternalResource implements Muta
     this.incremental.setProperty(isIncrementalAnalysis);
     return this;
   }
+
+  @Override
+  public boolean isShortLivingBranch() {
+    Branch property = this.branch.getProperty();
+    return property != null && property.getType() == BranchType.SHORT;
+  }
 }
index b425b7ce3840da65532f22f4e0eaf1721bc0f811..32d7cdbe5c960952f0e3d5eab2e2461cba6e777a 100644 (file)
@@ -164,4 +164,9 @@ public class MutableAnalysisMetadataHolderRule extends ExternalResource implemen
     delegate.setIncrementalAnalysis(isIncrementalAnalysis);
     return this;
   }
+
+  @Override
+  public boolean isShortLivingBranch() {
+    return delegate.isShortLivingBranch();
+  }
 }
index 6697a44b2666d3fc99afc49de9919efe50a32e96..32ebce8ce454975505e8861730ed5f6da71cd48c 100644 (file)
@@ -718,7 +718,7 @@ public class ComponentTreeBuilderTest {
   }
 
   private ComponentTreeBuilder newUnderTest(@Nullable SnapshotDto baseAnalysis) {
-    return new ComponentTreeBuilder(KEY_GENERATOR, UUID_SUPPLIER, scannerComponentProvider, projectInDb, baseAnalysis);
+    return new ComponentTreeBuilder(KEY_GENERATOR, UUID_SUPPLIER, scannerComponentProvider, projectInDb, baseAnalysis, false);
   }
 
   private static Map<Integer, Component> indexComponentByRef(Component root) {
index e484c69fb4abd5afef20e26b2e4461528508a747..4eede37eb18a62553be0d14f4a0adec356d8e3f3 100644 (file)
@@ -24,8 +24,6 @@ import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 
-import java.util.Optional;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
@@ -55,7 +53,7 @@ public class IssueTrackingDelegatorTest {
 
   @Test
   public void delegate_regular_tracker() {
-    when(analysisMetadataHolder.getBranch()).thenReturn(Optional.empty());
+    when(analysisMetadataHolder.isShortLivingBranch()).thenReturn(false);
 
     underTest.track(component);
 
@@ -67,7 +65,7 @@ public class IssueTrackingDelegatorTest {
   public void delegate_short_branch_tracker() {
     Branch branch = mock(Branch.class);
     when(branch.getType()).thenReturn(BranchType.SHORT);
-    when(analysisMetadataHolder.getBranch()).thenReturn(Optional.of(branch));
+    when(analysisMetadataHolder.isShortLivingBranch()).thenReturn(true);
 
     underTest.track(component);
 
index 0cce63f085d9b3b615143fb99dc2399b8a25b022..eb3a4720bc339d73358ba3f7aba69a0608908b4a 100644 (file)
  */
 package org.sonar.server.computation.task.projectanalysis.step;
 
-import com.google.common.base.Optional;
+import static java.lang.String.format;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.guava.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
 import java.util.Collections;
+
+import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.sonar.api.config.internal.MapSettings;
+import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolder;
 import org.sonar.server.computation.task.projectanalysis.component.ConfigurationRepository;
 import org.sonar.server.computation.task.projectanalysis.qualitygate.MutableQualityGateHolderRule;
 import org.sonar.server.computation.task.projectanalysis.qualitygate.QualityGate;
 import org.sonar.server.computation.task.projectanalysis.qualitygate.QualityGateService;
 
-import static java.lang.String.format;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.guava.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
+import com.google.common.base.Optional;
 
 public class LoadQualityGateStepTest {
 
@@ -45,10 +49,23 @@ public class LoadQualityGateStepTest {
   @Rule
   public MutableQualityGateHolderRule mutableQualityGateHolder = new MutableQualityGateHolderRule();
 
+  private AnalysisMetadataHolder analysisMetadataHolder = mock(AnalysisMetadataHolder.class);
   private ConfigurationRepository settingsRepository = mock(ConfigurationRepository.class);
   private QualityGateService qualityGateService = mock(QualityGateService.class);
 
-  private LoadQualityGateStep underTest = new LoadQualityGateStep(settingsRepository, qualityGateService, mutableQualityGateHolder);
+  private LoadQualityGateStep underTest = new LoadQualityGateStep(settingsRepository, qualityGateService, mutableQualityGateHolder, analysisMetadataHolder);
+
+  @Before
+  public void setUp() {
+    when(analysisMetadataHolder.isShortLivingBranch()).thenReturn(false);
+  }
+
+  @Test
+  public void skip_in_short_living_branches() {
+    when(analysisMetadataHolder.isShortLivingBranch()).thenReturn(true);
+    underTest.execute();
+    verifyNoQualityGate();
+  }
 
   @Test
   public void execute_sets_default_QualityGate_when_project_has_no_settings() {