]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6777 Project cache sync 475/head
authorDuarte Meneses <duarte.meneses@sonarsource.com>
Wed, 12 Aug 2015 12:05:13 +0000 (14:05 +0200)
committerDuarte Meneses <duarte.meneses@sonarsource.com>
Wed, 12 Aug 2015 14:12:50 +0000 (16:12 +0200)
27 files changed:
sonar-batch/src/main/java/org/sonar/batch/bootstrap/AbstractServerLoader.java [deleted file]
sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalMode.java
sonar-batch/src/main/java/org/sonar/batch/cache/ProjectCacheSynchronizer.java
sonar-batch/src/main/java/org/sonar/batch/cache/package-info.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/issue/tracking/DefaultServerLineHashesLoader.java
sonar-batch/src/main/java/org/sonar/batch/issue/tracking/ServerLineHashesLoader.java
sonar-batch/src/main/java/org/sonar/batch/issue/tracking/SourceHashHolder.java
sonar-batch/src/main/java/org/sonar/batch/repository/DefaultGlobalRepositoriesLoader.java
sonar-batch/src/main/java/org/sonar/batch/repository/DefaultProjectRepositoriesLoader.java
sonar-batch/src/main/java/org/sonar/batch/repository/GlobalRepositoriesLoader.java
sonar-batch/src/main/java/org/sonar/batch/repository/GlobalRepositoriesProvider.java
sonar-batch/src/main/java/org/sonar/batch/repository/ProjectRepositoriesLoader.java
sonar-batch/src/main/java/org/sonar/batch/repository/ProjectRepositoriesProvider.java
sonar-batch/src/main/java/org/sonar/batch/repository/user/UserRepositoryLoader.java
sonar-batch/src/main/java/org/sonar/batch/rule/DefaultRulesLoader.java
sonar-batch/src/main/java/org/sonar/batch/rule/RulesLoader.java
sonar-batch/src/main/java/org/sonar/batch/rule/RulesProvider.java
sonar-batch/src/main/java/org/sonar/batch/scan/ProjectAnalysisMode.java
sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java
sonar-batch/src/test/java/org/sonar/batch/cache/ProjectCacheSynchronizerTest.java
sonar-batch/src/test/java/org/sonar/batch/issue/tracking/DefaultServerLineHashesLoaderTest.java
sonar-batch/src/test/java/org/sonar/batch/issue/tracking/SourceHashHolderTest.java
sonar-batch/src/test/java/org/sonar/batch/mediumtest/BatchMediumTester.java
sonar-batch/src/test/java/org/sonar/batch/repository/DefaultProjectRepositoriesLoaderTest.java
sonar-batch/src/test/java/org/sonar/batch/repository/user/UserRepositoryLoaderTest.java
sonar-batch/src/test/java/org/sonar/batch/rule/DefaultRulesLoaderTest.java
sonar-batch/src/test/java/org/sonar/batch/rule/RulesProviderTest.java

diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/AbstractServerLoader.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/AbstractServerLoader.java
deleted file mode 100644 (file)
index d7883e7..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.batch.bootstrap;
-
-public class AbstractServerLoader {
-  protected Boolean loadedFromCache = null;
-
-  public boolean loadedFromCache() {
-    if (loadedFromCache == null) {
-      throw new IllegalStateException("Didn't load");
-    }
-    return loadedFromCache;
-  }
-}
index ee0c94cefd9dcf0d377ca77df1407566d6126e0b..a4341c96fe25cb98aa7dd9c3cea7a339e717f88e 100644 (file)
@@ -49,11 +49,11 @@ public class GlobalMode {
     issues = CoreProperties.ANALYSIS_MODE_ISSUES.equals(mode);
 
     if (preview) {
-      LOG.info("Preview global mode");
+      LOG.debug("Preview global mode");
     } else if (issues) {
-      LOG.info("Issues global mode");
+      LOG.debug("Issues global mode");
     } else {
-      LOG.info("Publish global mode");
+      LOG.debug("Publish global mode");
     }
   }
 
index 9f0c0f4250a8705dec0b3828dceb95a6fe690fdf..47b0d2dfd32379ae607269053ee90b4792ecf7da 100644 (file)
@@ -19,8 +19,9 @@
  */
 package org.sonar.batch.cache;
 
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.mutable.MutableBoolean;
 
+import org.apache.commons.lang.StringUtils;
 import org.sonar.api.utils.log.Loggers;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -66,7 +67,6 @@ public class ProjectCacheSynchronizer {
   }
 
   public void load(boolean force) {
-    Profiler profiler = Profiler.create(Loggers.get(ProjectCacheSynchronizer.class));
     Date lastSync = cacheStatus.getSyncStatus(project.getKeyWithBranch());
 
     if (lastSync != null) {
@@ -74,43 +74,50 @@ public class ProjectCacheSynchronizer {
         LOG.info("Found project [{}] cache [{}]", project.getKeyWithBranch(), lastSync);
         return;
       } else {
-        LOG.info("Found project [{}] cache [{}], refreshing data..", project.getKeyWithBranch(), lastSync);
+        LOG.info("-- Found project [{}] cache [{}], synchronizing data..", project.getKeyWithBranch(), lastSync);
       }
       cacheStatus.delete(project.getKeyWithBranch());
     } else {
-      LOG.info("Cache for project [{}] not found, fetching data..", project.getKeyWithBranch());
+      LOG.info("-- Cache for project [{}] not found, synchronizing data..", project.getKeyWithBranch());
     }
 
+    loadData();
+    saveStatus();
+  }
+
+  private void saveStatus() {
+    cacheStatus.save(project.getKeyWithBranch());
+    LOG.info("-- Succesfully synchronized project cache");
+  }
+
+  private static String getComponentKey(String moduleKey, String filePath) {
+    return moduleKey + ":" + filePath;
+  }
+
+  private void loadData() {
+    Profiler profiler = Profiler.create(Loggers.get(ProjectCacheSynchronizer.class));
     profiler.startInfo("Load project repository");
-    ProjectRepositories projectRepo = projectRepositoryLoader.load(project, properties);
-    profiler.stopInfo(projectRepositoryLoader.loadedFromCache());
+    MutableBoolean fromCache = new MutableBoolean();
+    ProjectRepositories projectRepo = projectRepositoryLoader.load(project, properties, fromCache);
+    profiler.stopInfo(fromCache.booleanValue());
 
     if (projectRepo.lastAnalysisDate() == null) {
       LOG.debug("No previous analysis found");
-      LOG.info("Succesfully synchronized project cache");
       return;
     }
 
     profiler.startInfo("Load server issues");
     UserLoginAccumulator consumer = new UserLoginAccumulator();
-    boolean fromCache = issuesLoader.load(project.getKeyWithBranch(), consumer);
-    profiler.stopInfo(fromCache);
+    boolean isFromCache = issuesLoader.load(project.getKeyWithBranch(), consumer);
+    profiler.stopInfo(isFromCache);
 
     profiler.startInfo("Load user information (" + consumer.loginSet.size() + " users)");
     for (String login : consumer.loginSet) {
-      userRepository.load(login);
+      userRepository.load(login, null);
     }
-    stopInfo(profiler, "Load user information", fromCache);
+    stopInfo(profiler, "Load user information", isFromCache);
 
     loadLineHashes(projectRepo.fileDataByModuleAndPath(), profiler);
-    
-    cacheStatus.save(project.getKeyWithBranch());
-
-    LOG.info("Succesfully synchronized project cache");
-  }
-
-  private String getComponentKey(String moduleKey, String filePath) {
-    return moduleKey + ":" + filePath;
   }
 
   private void loadLineHashes(Map<String, Map<String, FileData>> fileDataByModuleAndPath, Profiler profiler) {
@@ -127,7 +134,7 @@ public class ProjectCacheSynchronizer {
 
       for (Entry<String, FileData> e2 : e1.getValue().entrySet()) {
         String filePath = e2.getKey();
-        lineHashesLoader.getLineHashes(getComponentKey(moduleKey, filePath));
+        lineHashesLoader.getLineHashes(getComponentKey(moduleKey, filePath), null);
       }
     }
 
diff --git a/sonar-batch/src/main/java/org/sonar/batch/cache/package-info.java b/sonar-batch/src/main/java/org/sonar/batch/cache/package-info.java
new file mode 100644 (file)
index 0000000..1efcd13
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.batch.cache;
+
+import javax.annotation.ParametersAreNonnullByDefault;
\ No newline at end of file
index c6a405d0d36ac67e74d398259a06e90ced244cf9..411651dc990f5e53006f0683a05e4901aa7fc554 100644 (file)
  */
 package org.sonar.batch.issue.tracking;
 
-import org.sonar.batch.bootstrap.WSLoaderResult;
+import org.apache.commons.lang.mutable.MutableBoolean;
+
+import javax.annotation.Nullable;
 
+import org.sonar.batch.bootstrap.WSLoaderResult;
 import org.sonar.batch.util.BatchUtils;
 import org.sonar.batch.bootstrap.WSLoader;
 import com.google.common.base.Splitter;
@@ -37,17 +40,20 @@ public class DefaultServerLineHashesLoader implements ServerLineHashesLoader {
   }
 
   @Override
-  public String[] getLineHashes(String fileKey) {
-    String hashesFromWs = loadHashesFromWs(fileKey);
+  public String[] getLineHashes(String fileKey, @Nullable MutableBoolean fromCache) {
+    String hashesFromWs = loadHashesFromWs(fileKey, fromCache);
     return Iterators.toArray(Splitter.on('\n').split(hashesFromWs).iterator(), String.class);
   }
 
-  private String loadHashesFromWs(String fileKey) {
+  private String loadHashesFromWs(String fileKey, @Nullable MutableBoolean fromCache) {
     Profiler profiler = Profiler.createIfDebug(Loggers.get(getClass()))
       .addContext("file", fileKey)
       .startDebug("Load line hashes");
     WSLoaderResult<String> result = wsLoader.loadString("/api/sources/hash?key=" + BatchUtils.encodeForUrl(fileKey));
     try {
+      if (fromCache != null) {
+        fromCache.setValue(result.isFromCache());
+      }
       return result.get();
     } finally {
       if (result.isFromCache()) {
index f3a69222c797ecfc8324323da09ef8191e801c69..0928755d76dbac386697e8b3f8ecf08584d0131a 100644 (file)
  */
 package org.sonar.batch.issue.tracking;
 
+import org.apache.commons.lang.mutable.MutableBoolean;
+
+import javax.annotation.Nullable;
+
 import org.sonar.api.batch.BatchSide;
 
 @BatchSide
 public interface ServerLineHashesLoader {
 
-  String[] getLineHashes(String fileKey);
+  String[] getLineHashes(String fileKey, @Nullable MutableBoolean fromCache);
 }
index 28ed758d9d9c8bc2b6f225266d683f10012e2a7e..724dd0dde91625e81bee30f2b77d3ef7b5c01934 100644 (file)
@@ -49,7 +49,7 @@ public class SourceHashHolder {
       } else if (status == Status.SAME) {
         hashedReference = hashedSource;
       } else {
-        String[] lineHashes = lastSnapshots.getLineHashes(inputFile.key());
+        String[] lineHashes = lastSnapshots.getLineHashes(inputFile.key(), null);
         hashedReference = lineHashes != null ? FileHashes.create(lineHashes) : null;
       }
     }
index 4d0a24c772f71a10ccbc7b52bd63258e09b38236..a26d110646f01fda7ea0ff63b47b6c2afb8ac101 100644 (file)
  */
 package org.sonar.batch.repository;
 
-import org.sonar.batch.bootstrap.AbstractServerLoader;
+import javax.annotation.Nullable;
 
+import org.apache.commons.lang.mutable.MutableBoolean;
 import org.sonar.batch.bootstrap.WSLoaderResult;
 import org.sonar.batch.bootstrap.WSLoader;
 import org.sonar.batch.protocol.input.GlobalRepositories;
 
-public class DefaultGlobalRepositoriesLoader extends AbstractServerLoader implements GlobalRepositoriesLoader {
+public class DefaultGlobalRepositoriesLoader implements GlobalRepositoriesLoader {
 
   private static final String BATCH_GLOBAL_URL = "/batch/global";
 
@@ -36,10 +37,11 @@ public class DefaultGlobalRepositoriesLoader extends AbstractServerLoader implem
   }
 
   @Override
-  public GlobalRepositories load() {
+  public GlobalRepositories load(@Nullable MutableBoolean fromCache) {
     WSLoaderResult<String> result = wsLoader.loadString(BATCH_GLOBAL_URL);
-    super.loadedFromCache = result.isFromCache();
+    if (fromCache != null) {
+      fromCache.setValue(result.isFromCache());
+    }
     return GlobalRepositories.fromJson(result.get());
   }
-
 }
index 45b85452929cd6a91e0cb39cef0e3e65c0d9c5d8..4481de42aec7e06d7dfd53ab104d9aafb20caaf3 100644 (file)
  */
 package org.sonar.batch.repository;
 
-import org.sonar.batch.scan.ProjectAnalysisMode;
+import javax.annotation.Nullable;
 
+import org.apache.commons.lang.mutable.MutableBoolean;
+import org.sonar.batch.scan.ProjectAnalysisMode;
 import org.sonar.api.batch.bootstrap.ProjectDefinition;
-import org.sonar.batch.bootstrap.AbstractServerLoader;
 import org.sonar.batch.bootstrap.WSLoaderResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -33,7 +34,7 @@ import org.sonar.batch.protocol.input.ProjectRepositories;
 import org.sonar.batch.rule.ModuleQProfiles;
 import org.sonar.batch.util.BatchUtils;
 
-public class DefaultProjectRepositoriesLoader extends AbstractServerLoader implements ProjectRepositoriesLoader {
+public class DefaultProjectRepositoriesLoader implements ProjectRepositoriesLoader {
 
   private static final Logger LOG = LoggerFactory.getLogger(DefaultProjectRepositoriesLoader.class);
   private static final String BATCH_PROJECT_URL = "/batch/project";
@@ -47,7 +48,7 @@ public class DefaultProjectRepositoriesLoader extends AbstractServerLoader imple
   }
 
   @Override
-  public ProjectRepositories load(ProjectDefinition projectDefinition, AnalysisProperties taskProperties) {
+  public ProjectRepositories load(ProjectDefinition projectDefinition, AnalysisProperties taskProperties, @Nullable MutableBoolean fromCache) {
     String projectKey = projectDefinition.getKeyWithBranch();
     String url = BATCH_PROJECT_URL + "?key=" + BatchUtils.encodeForUrl(projectKey);
     if (taskProperties.properties().containsKey(ModuleQProfiles.SONAR_PROFILE_PROP)) {
@@ -56,15 +57,18 @@ public class DefaultProjectRepositoriesLoader extends AbstractServerLoader imple
       url += "&profile=" + BatchUtils.encodeForUrl(taskProperties.properties().get(ModuleQProfiles.SONAR_PROFILE_PROP));
     }
     url += "&preview=" + analysisMode.isIssues();
-    ProjectRepositories projectRepositories = ProjectRepositories.fromJson(load(url));
+
+    ProjectRepositories projectRepositories = load(url, fromCache);
     validateProjectRepositories(projectRepositories);
     return projectRepositories;
   }
 
-  private String load(String resource) {
+  private ProjectRepositories load(String resource, @Nullable MutableBoolean fromCache) {
     WSLoaderResult<String> result = wsLoader.loadString(resource);
-    super.loadedFromCache = result.isFromCache();
-    return result.get();
+    if(fromCache != null) {
+      fromCache.setValue(result.isFromCache());
+    }
+    return ProjectRepositories.fromJson(result.get());
   }
 
   private static void validateProjectRepositories(ProjectRepositories projectRepositories) {
index d0d88161c45bf7f5d2777b777c8bb97c2cd35c94..98ec5bbc18cf9d8cc65f5a239058642be1ab6087 100644 (file)
  */
 package org.sonar.batch.repository;
 
+import org.apache.commons.lang.mutable.MutableBoolean;
+
+import javax.annotation.Nullable;
+
 import org.sonar.batch.protocol.input.GlobalRepositories;
 
 public interface GlobalRepositoriesLoader {
 
-  GlobalRepositories load();
-
-  boolean loadedFromCache();
+  GlobalRepositories load(@Nullable MutableBoolean fromCache);
 
 }
index bad8be3dcde9ee2dc6ead37467ae0bf3ad30d427..a8ba268f98c9b8daeb88d0d488af2f5075853519 100644 (file)
@@ -19,6 +19,8 @@
  */
 package org.sonar.batch.repository;
 
+import org.apache.commons.lang.mutable.MutableBoolean;
+
 import org.picocontainer.injectors.ProviderAdapter;
 import org.sonar.api.utils.log.Logger;
 import org.sonar.api.utils.log.Loggers;
@@ -34,8 +36,9 @@ public class GlobalRepositoriesProvider extends ProviderAdapter {
   public GlobalRepositories provide(GlobalRepositoriesLoader loader) {
     if (globalReferentials == null) {
       Profiler profiler = Profiler.create(LOG).startInfo(LOG_MSG);
-      globalReferentials = loader.load();
-      profiler.stopInfo(loader.loadedFromCache());
+      MutableBoolean fromCache = new MutableBoolean();
+      globalReferentials = loader.load(fromCache);
+      profiler.stopInfo(fromCache.booleanValue());
     }
     return globalReferentials;
   }
index dfb3b7412026180f50412a24896332a214c77e84..e0f120f503c333817a3f2c9b4b71bcecadca272d 100644 (file)
  */
 package org.sonar.batch.repository;
 
-import org.sonar.api.batch.bootstrap.ProjectDefinition;
+import javax.annotation.Nullable;
 
+import org.apache.commons.lang.mutable.MutableBoolean;
+import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.batch.bootstrap.AnalysisProperties;
 import org.sonar.batch.protocol.input.ProjectRepositories;
 
 public interface ProjectRepositoriesLoader {
 
-  ProjectRepositories load(ProjectDefinition projectDefinition, AnalysisProperties taskProperties);
-  
-  boolean loadedFromCache();
+  ProjectRepositories load(ProjectDefinition projectDefinition, AnalysisProperties taskProperties, @Nullable MutableBoolean fromCache);
 
 }
index adf4e8b1d301230ae8e640422712cbb7c0cffb11..34c4f14f0e0b2d45245ff04dba6302cc5ec7f076 100644 (file)
@@ -19,6 +19,8 @@
  */
 package org.sonar.batch.repository;
 
+import org.apache.commons.lang.mutable.MutableBoolean;
+
 import org.picocontainer.injectors.ProviderAdapter;
 import org.sonar.api.batch.AnalysisMode;
 import org.sonar.api.batch.bootstrap.ProjectReactor;
@@ -38,8 +40,9 @@ public class ProjectRepositoriesProvider extends ProviderAdapter {
   public ProjectRepositories provide(ProjectRepositoriesLoader loader, ProjectReactor reactor, AnalysisProperties taskProps, AnalysisMode analysisMode) {
     if (projectReferentials == null) {
       Profiler profiler = Profiler.create(LOG).startInfo(LOG_MSG);
-      projectReferentials = loader.load(reactor.getRoot(), taskProps);
-      profiler.stopInfo(loader.loadedFromCache());
+      MutableBoolean fromCache = new MutableBoolean();
+      projectReferentials = loader.load(reactor.getRoot(), taskProps, fromCache);
+      profiler.stopInfo(fromCache.booleanValue());
 
       if (analysisMode.isIssues() && projectReferentials.lastAnalysisDate() == null) {
         LOG.warn("No analysis has been found on the server for this project. All issues will be marked as 'new'.");
index a6193dc278a26ec7627b21dec6fc054e10f747e7..82e8ec1b9914169d19b7c19f63aa553470bed1be 100644 (file)
  */
 package org.sonar.batch.repository.user;
 
-import com.google.common.collect.Lists;
+import javax.annotation.Nullable;
 
+import org.apache.commons.lang.mutable.MutableBoolean;
+import com.google.common.collect.Lists;
 import com.google.common.base.Joiner;
-import org.sonar.batch.bootstrap.AbstractServerLoader;
 import org.sonar.batch.bootstrap.WSLoaderResult;
 import org.sonar.batch.util.BatchUtils;
 import org.sonar.batch.bootstrap.WSLoader;
@@ -37,7 +38,7 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 
-public class UserRepositoryLoader extends AbstractServerLoader {
+public class UserRepositoryLoader {
   private final WSLoader wsLoader;
 
   public UserRepositoryLoader(WSLoader wsLoader) {
@@ -45,25 +46,35 @@ public class UserRepositoryLoader extends AbstractServerLoader {
   }
 
   public BatchInput.User load(String userLogin) {
-    ByteSource byteSource = loadQuery(new UserEncodingFunction().apply(userLogin));
+    return load(userLogin, null);
+  }
+  
+  public BatchInput.User load(String userLogin, @Nullable MutableBoolean fromCache) {
+    ByteSource byteSource = loadQuery(new UserEncodingFunction().apply(userLogin), fromCache);
     return parseUser(byteSource);
   }
 
+  public Collection<BatchInput.User> load(List<String> userLogins) {
+    return load(userLogins, null);
+  }
+  
   /**
    * Not cache friendly. Should not be used if a cache hit is expected.
    */
-  public Collection<BatchInput.User> load(List<String> userLogins) {
+  public Collection<BatchInput.User> load(List<String> userLogins, @Nullable MutableBoolean fromCache) {
     if (userLogins.isEmpty()) {
       return Collections.emptyList();
     }
-    ByteSource byteSource = loadQuery(Joiner.on(',').join(Lists.transform(userLogins, new UserEncodingFunction())));
+    ByteSource byteSource = loadQuery(Joiner.on(',').join(Lists.transform(userLogins, new UserEncodingFunction())), fromCache);
 
     return parseUsers(byteSource);
   }
 
-  private ByteSource loadQuery(String loginsQuery) {
+  private ByteSource loadQuery(String loginsQuery, @Nullable MutableBoolean fromCache) {
     WSLoaderResult<ByteSource> result = wsLoader.loadSource("/batch/users?logins=" + loginsQuery);
-    super.loadedFromCache = result.isFromCache();
+    if (fromCache != null) {
+      fromCache.setValue(result.isFromCache());
+    }
     return result.get();
   }
 
index ae4492bed7ba3322f12014a59486c304c5b79410..8837e326946088c75713cf3e3b1922254a8a3279 100644 (file)
@@ -19,8 +19,9 @@
  */
 package org.sonar.batch.rule;
 
-import org.sonar.batch.bootstrap.AbstractServerLoader;
+import javax.annotation.Nullable;
 
+import org.apache.commons.lang.mutable.MutableBoolean;
 import org.sonar.batch.bootstrap.WSLoaderResult;
 import org.sonarqube.ws.Rules.ListResponse.Rule;
 import com.google.common.io.ByteSource;
@@ -32,7 +33,7 @@ import java.util.List;
 
 import org.sonar.batch.bootstrap.WSLoader;
 
-public class DefaultRulesLoader extends AbstractServerLoader implements RulesLoader {
+public class DefaultRulesLoader implements RulesLoader {
   private static final String RULES_SEARCH_URL = "/api/rules/list";
 
   private final WSLoader wsLoader;
@@ -42,10 +43,12 @@ public class DefaultRulesLoader extends AbstractServerLoader implements RulesLoa
   }
 
   @Override
-  public List<Rule> load() {
+  public List<Rule> load(@Nullable MutableBoolean fromCache) {
     WSLoaderResult<ByteSource> result = wsLoader.loadSource(RULES_SEARCH_URL);
     ListResponse list = loadFromSource(result.get());
-    super.loadedFromCache = result.isFromCache();
+    if (fromCache != null) {
+      fromCache.setValue(result.isFromCache());
+    }
     return list.getRulesList();
   }
 
index 1e0c5df7cff5f221b724f9e0ef6421267408adce..e470ce72b8ebd57ad5eef797ae0f3ca5e24e0a97 100644 (file)
  */
 package org.sonar.batch.rule;
 
+import org.apache.commons.lang.mutable.MutableBoolean;
+
 import java.util.List;
 
 import org.sonarqube.ws.Rules.ListResponse.Rule;
 
 public interface RulesLoader {
-  List<Rule> load();
-
-  boolean loadedFromCache();
+  List<Rule> load(MutableBoolean fromCache);
 }
index 866bcdcb73ba187737031c70187ea1e4bd06730a..068eb06c416ed057079d4b761bf09c4f3332180b 100644 (file)
  */
 package org.sonar.batch.rule;
 
+import org.apache.commons.lang.mutable.MutableBoolean;
+
 import org.sonar.api.utils.log.Logger;
 import org.sonar.api.utils.log.Loggers;
-
 import org.sonar.api.utils.log.Profiler;
 
 import java.util.List;
@@ -47,7 +48,8 @@ public class RulesProvider extends ProviderAdapter {
 
   private static Rules load(RulesLoader ref) {
     Profiler profiler = Profiler.create(LOG).startInfo(LOG_MSG);
-    List<Rule> loadedRules = ref.load();
+    MutableBoolean fromCache = new MutableBoolean();
+    List<Rule> loadedRules = ref.load(fromCache);
     RulesBuilder builder = new RulesBuilder();
 
     for (Rule r : loadedRules) {
@@ -56,7 +58,7 @@ public class RulesProvider extends ProviderAdapter {
       newRule.setInternalKey(r.getInternalKey());
     }
 
-    profiler.stopInfo(ref.loadedFromCache());
+    profiler.stopInfo(fromCache.booleanValue());
 
     return builder.build();
   }
index 4c66441218b97f042e76058e607566f10f04a042..58f9b1ccc1d6eb66660b2b6a5f068a6ff8674b1a 100644 (file)
@@ -83,7 +83,9 @@ public class ProjectAnalysisMode implements AnalysisMode {
     preview = CoreProperties.ANALYSIS_MODE_PREVIEW.equals(mode);
     issues = CoreProperties.ANALYSIS_MODE_ISSUES.equals(mode);
     mediumTestMode = "true".equals(getPropertyWithFallback(analysisProps, globalProps, FakePluginInstaller.MEDIUM_TEST_ENABLED));
-
+  }
+  
+  public void printMode() {
     if (preview) {
       LOG.info("Preview mode");
     } else if (issues) {
index 6ab4474292af37ac98864915b2abb8c3f1ff8343..508af5d6b52790c20778641021a76f58533b62ba 100644 (file)
@@ -19,8 +19,6 @@
  */
 package org.sonar.batch.scan;
 
-import org.sonar.batch.cache.ProjectSyncContainer;
-
 import org.sonar.batch.repository.user.UserRepositoryLoader;
 import org.sonar.batch.issue.tracking.DefaultServerLineHashesLoader;
 import org.sonar.batch.issue.tracking.ServerLineHashesLoader;
@@ -126,13 +124,6 @@ public class ProjectScanContainer extends ComponentContainer {
     return env != null && "SonarRunner".equals(env.getKey());
   }
 
-  private void doProjectSync() {
-    ProjectAnalysisMode mode = getComponentByType(ProjectAnalysisMode.class);
-    if (mode.isIssues()) {
-      new ProjectSyncContainer(getParent(), props, false).execute();
-    }
-  }
-
   private void addBatchComponents() {
     add(
       props,
@@ -223,10 +214,12 @@ public class ProjectScanContainer extends ComponentContainer {
 
   @Override
   protected void doAfterStart() {
+    ProjectAnalysisMode analysisMode = getComponentByType(ProjectAnalysisMode.class);
+    analysisMode.printMode();
     LOG.debug("Start recursive analysis of project modules");
     DefaultProjectTree tree = getComponentByType(DefaultProjectTree.class);
     scanRecursively(tree.getRootProject());
-    if (getComponentByType(ProjectAnalysisMode.class).isMediumTest()) {
+    if (analysisMode.isMediumTest()) {
       getComponentByType(ScanTaskObservers.class).notifyEndOfScanTask();
     }
   }
index 3cf688897f0b14c877d594e02180ca6d96a3276c..e6bf23eb04e85d66cd16547306fb18962eddcc41 100644 (file)
 package org.sonar.batch.cache;
 
 import static org.mockito.Mockito.when;
+
+import org.sonar.batch.protocol.input.ProjectRepositories;
+
+import org.apache.commons.lang.mutable.MutableBoolean;
 import org.sonar.batch.issue.tracking.DefaultServerLineHashesLoader;
 import org.sonar.batch.repository.DefaultServerIssuesLoader;
 import org.sonar.batch.scan.ProjectAnalysisMode;
@@ -35,8 +39,9 @@ import java.nio.charset.StandardCharsets;
 import java.util.Date;
 import java.util.HashMap;
 
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Matchers.anyString;
-
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 import com.google.common.io.Resources;
@@ -75,6 +80,8 @@ public class ProjectCacheSynchronizerTest {
   private ServerLineHashesLoader lineHashesLoader;
   private UserRepositoryLoader userRepositoryLoader;
 
+  private ProjectCacheSynchronizer sync;
+
   @Before
   public void setUp() throws IOException {
     MockitoAnnotations.initMocks(this);
@@ -98,12 +105,13 @@ public class ProjectCacheSynchronizerTest {
     issuesLoader = new DefaultServerIssuesLoader(ws);
     lineHashesLoader = new DefaultServerLineHashesLoader(ws);
     userRepositoryLoader = new UserRepositoryLoader(ws);
+
+    sync = new ProjectCacheSynchronizer(projectReactor, projectRepositoryLoader, properties, issuesLoader, lineHashesLoader, userRepositoryLoader,
+      cacheStatus);
   }
 
   @Test
   public void testSync() {
-    ProjectCacheSynchronizer sync = new ProjectCacheSynchronizer(projectReactor, projectRepositoryLoader, properties, issuesLoader, lineHashesLoader, userRepositoryLoader,
-      cacheStatus);
     sync.load(false);
 
     verify(ws).loadString(BATCH_PROJECT);
@@ -115,6 +123,20 @@ public class ProjectCacheSynchronizerTest {
     verify(cacheStatus).save(anyString());
   }
 
+  @Test
+  public void testSyncNoLastAnalysis() {
+    projectRepositoryLoader = mock(DefaultProjectRepositoriesLoader.class);
+    ProjectRepositories mockedProjectRepositories = mock(ProjectRepositories.class);
+    when(mockedProjectRepositories.lastAnalysisDate()).thenReturn(null);
+    when(projectRepositoryLoader.load(any(ProjectDefinition.class), any(AnalysisProperties.class), any(MutableBoolean.class))).thenReturn(mockedProjectRepositories);
+
+    sync = new ProjectCacheSynchronizer(projectReactor, projectRepositoryLoader, properties, issuesLoader, lineHashesLoader, userRepositoryLoader,
+      cacheStatus);
+    sync.load(true);
+
+    verify(cacheStatus).save("org.codehaus.sonar-plugins:sonar-scm-git-plugin");
+  }
+
   @Test
   public void testDontSyncIfNotForce() {
     when(cacheStatus.getSyncStatus("org.codehaus.sonar-plugins:sonar-scm-git-plugin")).thenReturn(new Date());
index c7e2a40c04ef6ea5f36acbc5284dca3afd032638..f788788fef1f8e5e17652efa9f42d61915c64f8b 100644 (file)
@@ -19,8 +19,9 @@
  */
 package org.sonar.batch.issue.tracking;
 
-import org.sonar.batch.bootstrap.WSLoaderResult;
+import org.apache.commons.lang.mutable.MutableBoolean;
 
+import org.sonar.batch.bootstrap.WSLoaderResult;
 import org.sonar.batch.bootstrap.WSLoader;
 import org.junit.Before;
 import org.junit.Rule;
@@ -53,7 +54,7 @@ public class DefaultServerLineHashesLoaderTest {
 
     ServerLineHashesLoader lastSnapshots = new DefaultServerLineHashesLoader(wsLoader);
 
-    String[] hashes = lastSnapshots.getLineHashes("myproject:org/foo/Bar.c");
+    String[] hashes = lastSnapshots.getLineHashes("myproject:org/foo/Bar.c", null);
     assertThat(hashes).containsOnly("ae12", "", "43fb");
     verify(wsLoader).loadString("/api/sources/hash?key=myproject%3Aorg%2Ffoo%2FBar.c");
   }
@@ -65,7 +66,9 @@ public class DefaultServerLineHashesLoaderTest {
 
     ServerLineHashesLoader lastSnapshots = new DefaultServerLineHashesLoader(server);
 
-    String[] hashes = lastSnapshots.getLineHashes("myproject:org/foo/Foo Bar.c");
+    MutableBoolean fromCache = new MutableBoolean();
+    String[] hashes = lastSnapshots.getLineHashes("myproject:org/foo/Foo Bar.c", fromCache);
+    assertThat(fromCache.booleanValue()).isTrue();
     assertThat(hashes).containsOnly("ae12", "", "43fb");
     verify(server).loadString("/api/sources/hash?key=myproject%3Aorg%2Ffoo%2FFoo+Bar.c");
   }
@@ -78,7 +81,7 @@ public class DefaultServerLineHashesLoaderTest {
     ServerLineHashesLoader lastSnapshots = new DefaultServerLineHashesLoader(server);
 
     thrown.expect(HttpDownloader.HttpException.class);
-    lastSnapshots.getLineHashes("foo");
+    lastSnapshots.getLineHashes("foo", null);
   }
 
 }
index cdb7324ae2aa9bac868646bec1442a9cfa15d926..ed62cd0ee95f8dd7b4665bf635ef6314f4c0aec4 100644 (file)
@@ -83,10 +83,10 @@ public class SourceHashHolderTest {
     FileUtils.write(ioFile, source, StandardCharsets.UTF_8);
     when(file.key()).thenReturn(key);
     when(file.status()).thenReturn(InputFile.Status.CHANGED);
-    when(lastSnapshots.getLineHashes(key)).thenReturn(new String[] {md5Hex(source)});
+    when(lastSnapshots.getLineHashes(key, null)).thenReturn(new String[] {md5Hex(source)});
 
     assertThat(sourceHashHolder.getHashedReference().getHash(1)).isEqualTo(md5Hex(source));
-    verify(lastSnapshots).getLineHashes(key);
+    verify(lastSnapshots).getLineHashes(key, null);
 
     assertThat(sourceHashHolder.getHashedReference().getHash(1)).isEqualTo(md5Hex(source));
     Mockito.verifyNoMoreInteractions(lastSnapshots);
index b4a80af70dbb18da7ab5fb5de437d613c5c2aace..9ff6e0a55d77cda570db1926f22d1205d7558a95 100644 (file)
  */
 package org.sonar.batch.mediumtest;
 
+import org.apache.commons.lang.mutable.MutableBoolean;
+
+import javax.annotation.Nullable;
+
 import org.sonar.batch.cache.ProjectCacheStatus;
 import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonarqube.ws.Rules.ListResponse.Rule;
@@ -294,14 +298,9 @@ public class BatchMediumTester {
     }
 
     @Override
-    public List<Rule> load() {
+    public List<Rule> load(@Nullable MutableBoolean fromCache) {
       return rules;
     }
-
-    @Override
-    public boolean loadedFromCache() {
-      return false;
-    }
   }
 
   private static class FakeGlobalRepositoriesLoader implements GlobalRepositoriesLoader {
@@ -311,7 +310,7 @@ public class BatchMediumTester {
     private GlobalRepositories ref = new GlobalRepositories();
 
     @Override
-    public GlobalRepositories load() {
+    public GlobalRepositories load(@Nullable MutableBoolean fromCache) {
       return ref;
     }
 
@@ -336,10 +335,6 @@ public class BatchMediumTester {
       return this;
     }
 
-    @Override
-    public boolean loadedFromCache() {
-      return false;
-    }
   }
 
   private static class FakeProjectRepositoriesLoader implements ProjectRepositoriesLoader {
@@ -347,7 +342,7 @@ public class BatchMediumTester {
     private ProjectRepositories ref = new ProjectRepositories();
 
     @Override
-    public ProjectRepositories load(ProjectDefinition projDefinition, AnalysisProperties taskProperties) {
+    public ProjectRepositories load(ProjectDefinition projDefinition, AnalysisProperties taskProperties, @Nullable MutableBoolean fromCache) {
       return ref;
     }
 
@@ -372,10 +367,6 @@ public class BatchMediumTester {
       return this;
     }
 
-    @Override
-    public boolean loadedFromCache() {
-      return true;
-    }
   }
 
   private static class FakeServerIssuesLoader implements ServerIssuesLoader {
@@ -417,7 +408,7 @@ public class BatchMediumTester {
     private Map<String, String[]> byKey = new HashMap<>();
 
     @Override
-    public String[] getLineHashes(String fileKey) {
+    public String[] getLineHashes(String fileKey, @Nullable MutableBoolean fromCache) {
       if (byKey.containsKey(fileKey)) {
         return byKey.get(fileKey);
       } else {
index 5e846897aa4287a6626d362a09bda65688d4e82d..9a1f8abea4630bf6778b58fb649069ba0362e159 100644 (file)
@@ -19,8 +19,9 @@
  */
 package org.sonar.batch.repository;
 
-import org.sonar.batch.scan.ProjectAnalysisMode;
+import org.apache.commons.lang.mutable.MutableBoolean;
 
+import org.sonar.batch.scan.ProjectAnalysisMode;
 import org.apache.commons.io.IOUtils;
 import org.sonar.batch.bootstrap.WSLoaderResult;
 import com.google.common.collect.Maps;
@@ -72,11 +73,11 @@ public class DefaultProjectRepositoriesLoaderTest {
     addQualityProfile();
     project = ProjectDefinition.create().setKey("foo");
     when(analysisMode.isIssues()).thenReturn(false);
-    loader.load(project, taskProperties);
+    loader.load(project, taskProperties, null);
     verify(wsLoader).loadString("/batch/project?key=foo&preview=false");
 
     when(analysisMode.isIssues()).thenReturn(true);
-    loader.load(project, taskProperties);
+    loader.load(project, taskProperties, null);
     verify(wsLoader).loadString("/batch/project?key=foo&preview=true");
   }
 
@@ -84,10 +85,12 @@ public class DefaultProjectRepositoriesLoaderTest {
   public void deserializeResponse() throws IOException {
     String resourceName = this.getClass().getSimpleName() + "/sample_response.json";
     String response = IOUtils.toString(this.getClass().getResourceAsStream(resourceName));
-    when(wsLoader.loadString(anyString())).thenReturn(new WSLoaderResult<>(response, false));
+    when(wsLoader.loadString(anyString())).thenReturn(new WSLoaderResult<>(response, true));
     project = ProjectDefinition.create().setKey("foo");
-    ProjectRepositories projectRepo = loader.load(project, taskProperties);
+    MutableBoolean fromCache = new MutableBoolean();
+    ProjectRepositories projectRepo = loader.load(project, taskProperties, fromCache);
 
+    assertThat(fromCache.booleanValue()).isTrue();
     assertThat(projectRepo.activeRules().size()).isEqualTo(221);
     assertThat(projectRepo.fileDataByPath("my:project").size()).isEqualTo(11);
 
@@ -97,7 +100,7 @@ public class DefaultProjectRepositoriesLoaderTest {
   public void passAndEncodeProjectKeyParameter() {
     addQualityProfile();
     project = ProjectDefinition.create().setKey("foo bàr");
-    loader.load(project, taskProperties);
+    loader.load(project, taskProperties, null);
     verify(wsLoader).loadString("/batch/project?key=foo+b%C3%A0r&preview=false");
   }
 
@@ -106,7 +109,7 @@ public class DefaultProjectRepositoriesLoaderTest {
     addQualityProfile();
     project = ProjectDefinition.create().setKey("foo");
     taskProperties.properties().put(ModuleQProfiles.SONAR_PROFILE_PROP, "my-profile#2");
-    loader.load(project, taskProperties);
+    loader.load(project, taskProperties, null);
     verify(wsLoader).loadString("/batch/project?key=foo&profile=my-profile%232&preview=false");
   }
 
@@ -118,7 +121,7 @@ public class DefaultProjectRepositoriesLoaderTest {
     project = ProjectDefinition.create().setKey("foo");
     when(wsLoader.loadString(anyString())).thenReturn(new WSLoaderResult<>(new ProjectRepositories().toJson(), true));
 
-    loader.load(project, taskProperties);
+    loader.load(project, taskProperties, null);
   }
 
   private void addQualityProfile() {
index 8f583afba41a1e895791e66dba2a295549743b31..1b17e6445c6059489c3064042866ff8745b71539 100644 (file)
  */
 package org.sonar.batch.repository.user;
 
-import com.google.common.collect.ImmutableMap;
+import org.junit.Before;
 
+import com.google.common.collect.ImmutableList;
+import org.apache.commons.lang.mutable.MutableBoolean;
+import com.google.common.collect.ImmutableMap;
 import org.junit.rules.ExpectedException;
 import org.junit.Rule;
 import org.mockito.Mockito;
@@ -37,6 +40,7 @@ import java.io.InputStream;
 import java.util.Arrays;
 import java.util.Map;
 
+import static org.mockito.Matchers.anyString;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.tuple;
 import static org.mockito.Mockito.mock;
@@ -46,11 +50,17 @@ public class UserRepositoryLoaderTest {
   @Rule
   public final ExpectedException exception = ExpectedException.none();
 
+  private WSLoader wsLoader;
+  private UserRepositoryLoader userRepo;
+
+  @Before
+  public void setUp() {
+    wsLoader = mock(WSLoader.class);
+    userRepo = new UserRepositoryLoader(wsLoader);
+  }
+
   @Test
   public void testLoad() throws IOException {
-    WSLoader wsLoader = mock(WSLoader.class);
-    UserRepositoryLoader userRepo = new UserRepositoryLoader(wsLoader);
-
     Map<String, String> userMap = ImmutableMap.of("fmallet", "Freddy Mallet", "sbrandhof", "Simon");
     WSLoaderResult<ByteSource> res = new WSLoaderResult<>(createUsersMock(userMap), true);
     when(wsLoader.loadSource("/batch/users?logins=fmallet,sbrandhof")).thenReturn(res);
@@ -59,10 +69,20 @@ public class UserRepositoryLoaderTest {
   }
 
   @Test
-  public void testLoadSingleUser() throws IOException {
-    WSLoader wsLoader = mock(WSLoader.class);
-    UserRepositoryLoader userRepo = new UserRepositoryLoader(wsLoader);
+  public void testFromCache() throws IOException {
+    WSLoaderResult<ByteSource> res = new WSLoaderResult<>(createUsersMock(ImmutableMap.of("fmallet", "Freddy Mallet")), true);
+    when(wsLoader.loadSource(anyString())).thenReturn(res);
+    MutableBoolean fromCache = new MutableBoolean();
+    userRepo.load("", fromCache);
+    assertThat(fromCache.booleanValue()).isTrue();
+
+    fromCache.setValue(false);
+    userRepo.load(ImmutableList.of("user"), fromCache);
+    assertThat(fromCache.booleanValue()).isTrue();
+  }
 
+  @Test
+  public void testLoadSingleUser() throws IOException {
     WSLoaderResult<ByteSource> res = new WSLoaderResult<>(createUsersMock(ImmutableMap.of("fmallet", "Freddy Mallet")), true);
     when(wsLoader.loadSource("/batch/users?logins=fmallet")).thenReturn(res);
 
@@ -83,8 +103,6 @@ public class UserRepositoryLoaderTest {
 
   @Test
   public void testInputStreamError() throws IOException {
-    WSLoader wsLoader = mock(WSLoader.class);
-    UserRepositoryLoader userRepo = new UserRepositoryLoader(wsLoader);
     ByteSource source = mock(ByteSource.class);
 
     WSLoaderResult<ByteSource> res = new WSLoaderResult<>(source, true);
index bd1a2e65da993f8937c5f885eb5f03bbfe9cc124..4456d5b3cb0943dc77e83f8a2d27a87dae6b1131 100644 (file)
@@ -22,8 +22,9 @@ package org.sonar.batch.rule;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-import org.sonar.batch.bootstrap.WSLoaderResult;
+import org.apache.commons.lang.mutable.MutableBoolean;
 
+import org.sonar.batch.bootstrap.WSLoaderResult;
 import org.sonarqube.ws.Rules.ListResponse.Rule;
 import com.google.common.io.ByteSource;
 import com.google.common.io.Resources;
@@ -43,7 +44,7 @@ public class DefaultRulesLoaderTest {
     ByteSource source = Resources.asByteSource(this.getClass().getResource("DefaultRulesLoader/response.protobuf"));
     when(wsLoader.loadSource(anyString())).thenReturn(new WSLoaderResult<>(source, true));
     DefaultRulesLoader loader = new DefaultRulesLoader(wsLoader);
-    List<Rule> ruleList = loader.load();
+    List<Rule> ruleList = loader.load(null);
     assertThat(ruleList).hasSize(318);
   }
 
@@ -53,14 +54,10 @@ public class DefaultRulesLoaderTest {
     ByteSource source = Resources.asByteSource(this.getClass().getResource("DefaultRulesLoader/response.protobuf"));
     when(wsLoader.loadSource(anyString())).thenReturn(new WSLoaderResult<>(source, true));
     DefaultRulesLoader loader = new DefaultRulesLoader(wsLoader);
-    loader.load();
+    MutableBoolean fromCache = new MutableBoolean();
+    loader.load(fromCache);
 
-    assertThat(loader.loadedFromCache()).isTrue();
+    assertThat(fromCache.booleanValue()).isTrue();
   }
 
-  @Test(expected = IllegalStateException.class)
-  public void testGetLoadedFromCacheBefore() {
-    DefaultRulesLoader loader = new DefaultRulesLoader(mock(WSLoader.class));
-    loader.loadedFromCache();
-  }
 }
index 3e43363d5f90b7787561e3b3d25bb4b2e62fcae7..cf48e62aafc1408188b8577452eb69dcf1f2646f 100644 (file)
  */
 package org.sonar.batch.rule;
 
-import com.google.common.collect.Lists;
+import static org.mockito.Matchers.any;
 
-import org.sonar.api.batch.rule.Rules;
+import org.apache.commons.lang.mutable.MutableBoolean;
 
+import com.google.common.collect.Lists;
+import org.sonar.api.batch.rule.Rules;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.when;
 import static org.mockito.Mockito.mock;
@@ -33,7 +35,7 @@ public class RulesProviderTest {
   @Test
   public void testRuleTranslation() {
     RulesLoader loader = mock(RulesLoader.class);
-    when(loader.load()).thenReturn(Lists.newArrayList(getTestRule()));
+    when(loader.load(any(MutableBoolean.class))).thenReturn(Lists.newArrayList(getTestRule()));
 
     RulesProvider provider = new RulesProvider();