diff options
author | Duarte Meneses <duarte.meneses@sonarsource.com> | 2015-09-21 18:09:30 +0200 |
---|---|---|
committer | Duarte Meneses <duarte.meneses@sonarsource.com> | 2015-09-30 16:27:12 +0200 |
commit | 80b9f52b80c5ae3fcc81b8b8cc3209000a886b7f (patch) | |
tree | 6309fa9d853be81dd6ae47a1e07d7350480b3905 /sonar-batch | |
parent | 0847774db59344316629a7171c3943dbfaa3f52d (diff) | |
download | sonarqube-80b9f52b80c5ae3fcc81b8b8cc3209000a886b7f.tar.gz sonarqube-80b9f52b80c5ae3fcc81b8b8cc3209000a886b7f.zip |
SONAR-6818 Split batch/project WS in several simpler WS
Diffstat (limited to 'sonar-batch')
65 files changed, 1277 insertions, 3112 deletions
diff --git a/sonar-batch/src/main/java/org/sonar/batch/cache/NonAssociatedCacheSynchronizer.java b/sonar-batch/src/main/java/org/sonar/batch/cache/NonAssociatedCacheSynchronizer.java index 44743f5c120..5242184a30f 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/cache/NonAssociatedCacheSynchronizer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/cache/NonAssociatedCacheSynchronizer.java @@ -19,9 +19,9 @@ */ package org.sonar.batch.cache; +import org.sonarqube.ws.QualityProfiles.WsSearchResponse.QualityProfile; import org.sonar.batch.rule.ActiveRulesLoader; import org.sonar.batch.repository.QualityProfileLoader; -import org.sonar.batch.protocol.input.QProfile; import org.sonar.api.utils.log.Loggers; import org.sonar.api.utils.log.Profiler; import org.slf4j.Logger; @@ -61,15 +61,15 @@ public class NonAssociatedCacheSynchronizer { } loadData(); - + cacheStatus.save(); LOG.info("-- Succesfully synchronized cache"); } - private static Collection<String> getKeys(Collection<QProfile> qProfiles) { + private static Collection<String> getKeys(Collection<QualityProfile> qProfiles) { List<String> list = new ArrayList<>(qProfiles.size()); - for (QProfile qp : qProfiles) { - list.add(qp.key()); + for (QualityProfile qp : qProfiles) { + list.add(qp.getKey()); } return list; @@ -79,11 +79,14 @@ public class NonAssociatedCacheSynchronizer { Profiler profiler = Profiler.create(Loggers.get(ProjectCacheSynchronizer.class)); profiler.startInfo("Load default quality profiles"); - Collection<QProfile> qProfiles = qualityProfileLoader.load(null, null); + Collection<QualityProfile> qProfiles = qualityProfileLoader.loadDefault(null); profiler.stopInfo(); profiler.startInfo("Load default active rules"); - activeRulesLoader.load(getKeys(qProfiles), null); + Collection<String> keys = getKeys(qProfiles); + for (String k : keys) { + activeRulesLoader.load(k, null); + } profiler.stopInfo(); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/cache/ProjectCacheSynchronizer.java b/sonar-batch/src/main/java/org/sonar/batch/cache/ProjectCacheSynchronizer.java index 20d16fbaaad..4445eaae606 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/cache/ProjectCacheSynchronizer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/cache/ProjectCacheSynchronizer.java @@ -19,6 +19,9 @@ */ package org.sonar.batch.cache; +import org.sonar.batch.repository.ProjectRepositoriesLoader; + +import org.sonarqube.ws.QualityProfiles.WsSearchResponse.QualityProfile; import com.google.common.base.Function; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; @@ -26,9 +29,7 @@ import org.slf4j.LoggerFactory; import org.sonar.api.utils.log.Loggers; import org.sonar.api.utils.log.Profiler; import org.sonar.batch.protocol.input.BatchInput.ServerIssue; -import org.sonar.batch.protocol.input.QProfile; -import org.sonar.batch.repository.ProjectSettingsLoader; -import org.sonar.batch.repository.ProjectSettingsRepo; +import org.sonar.batch.repository.ProjectRepositories; import org.sonar.batch.repository.QualityProfileLoader; import org.sonar.batch.repository.ServerIssuesLoader; import org.sonar.batch.repository.user.UserRepositoryLoader; @@ -48,14 +49,14 @@ public class ProjectCacheSynchronizer { private final UserRepositoryLoader userRepository; private final ProjectCacheStatus cacheStatus; private final QualityProfileLoader qualityProfileLoader; - private final ProjectSettingsLoader projectSettingsLoader; + private final ProjectRepositoriesLoader projectRepositoriesLoader; private final ActiveRulesLoader activeRulesLoader; - public ProjectCacheSynchronizer(QualityProfileLoader qualityProfileLoader, ProjectSettingsLoader projectSettingsLoader, + public ProjectCacheSynchronizer(QualityProfileLoader qualityProfileLoader, ProjectRepositoriesLoader projectSettingsLoader, ActiveRulesLoader activeRulesLoader, ServerIssuesLoader issuesLoader, UserRepositoryLoader userRepository, ProjectCacheStatus cacheStatus) { this.qualityProfileLoader = qualityProfileLoader; - this.projectSettingsLoader = projectSettingsLoader; + this.projectRepositoriesLoader = projectSettingsLoader; this.activeRulesLoader = activeRulesLoader; this.issuesLoader = issuesLoader; this.userRepository = userRepository; @@ -88,42 +89,51 @@ public class ProjectCacheSynchronizer { private void loadData(String projectKey) { Profiler profiler = Profiler.create(Loggers.get(ProjectCacheSynchronizer.class)); + ProjectRepositories projectRepo = null; profiler.startInfo("Load project settings"); - ProjectSettingsRepo settings = projectSettingsLoader.load(projectKey, null); - profiler.stopInfo(); + projectRepo = projectRepositoriesLoader.load(projectKey, true, null); - if (settings.lastAnalysisDate() == null) { + if (!projectRepo.exists()) { + LOG.debug("Project doesn't exist in the server"); + } else if (projectRepo.lastAnalysisDate() == null) { LOG.debug("No previous analysis found"); - return; } + profiler.stopInfo(); profiler.startInfo("Load project quality profiles"); - Collection<QProfile> qProfiles = qualityProfileLoader.load(projectKey, null); + Collection<QualityProfile> qProfiles; + if (projectRepo.exists()) { + qProfiles = qualityProfileLoader.load(projectKey, null, null); + } else { + qProfiles = qualityProfileLoader.loadDefault(null); + } profiler.stopInfo(); - Collection<String> profileKeys = getKeys(qProfiles); - profiler.startInfo("Load project active rules"); - activeRulesLoader.load(profileKeys, projectKey); - profiler.stopInfo(); + Collection<String> keys = getKeys(qProfiles); + for (String k : keys) { + activeRulesLoader.load(k, null); + } - profiler.startInfo("Load server issues"); - UserLoginAccumulator consumer = new UserLoginAccumulator(); - issuesLoader.load(projectKey, consumer); - profiler.stopInfo(); + if (projectRepo.lastAnalysisDate() != null) { + profiler.startInfo("Load server issues"); + UserLoginAccumulator consumer = new UserLoginAccumulator(); + issuesLoader.load(projectKey, consumer); + profiler.stopInfo(); - profiler.startInfo("Load user information (" + consumer.loginSet.size() + " users)"); - for (String login : consumer.loginSet) { - userRepository.load(login, null); + profiler.startInfo("Load user information (" + consumer.loginSet.size() + " users)"); + for (String login : consumer.loginSet) { + userRepository.load(login, null); + } + profiler.stopInfo("Load user information"); } - profiler.stopInfo("Load user information"); } - private static Collection<String> getKeys(Collection<QProfile> qProfiles) { + private static Collection<String> getKeys(Collection<QualityProfile> qProfiles) { List<String> list = new ArrayList<>(qProfiles.size()); - for (QProfile qp : qProfiles) { - list.add(qp.key()); + for (QualityProfile qp : qProfiles) { + list.add(qp.getKey()); } return list; diff --git a/sonar-batch/src/main/java/org/sonar/batch/cache/ProjectSyncContainer.java b/sonar-batch/src/main/java/org/sonar/batch/cache/ProjectSyncContainer.java index 79be9383f10..2bfc9dd12fa 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/cache/ProjectSyncContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/cache/ProjectSyncContainer.java @@ -21,7 +21,6 @@ package org.sonar.batch.cache; import javax.annotation.Nullable; -import org.sonar.batch.repository.ProjectRepositoriesFactoryProvider; import org.sonar.batch.analysis.DefaultAnalysisMode; import org.sonar.api.CoreProperties; @@ -30,15 +29,13 @@ import java.util.Map; import org.sonar.batch.analysis.AnalysisProperties; import org.sonar.batch.bootstrap.GlobalProperties; -import org.sonar.batch.repository.ProjectSettingsLoader; -import org.sonar.batch.repository.DefaultProjectSettingsLoader; +import org.sonar.batch.repository.DefaultProjectRepositoriesLoader; import org.sonar.batch.rule.ActiveRulesLoader; import org.sonar.batch.rule.DefaultActiveRulesLoader; import org.sonar.batch.repository.QualityProfileLoader; import org.sonar.batch.repository.DefaultQualityProfileLoader; import org.sonar.batch.cache.WSLoader.LoadStrategy; import org.sonar.batch.repository.user.UserRepositoryLoader; -import org.sonar.batch.repository.DefaultProjectRepositoriesLoader; import org.sonar.batch.repository.DefaultServerIssuesLoader; import org.sonar.batch.repository.ProjectRepositoriesLoader; import org.sonar.batch.repository.ServerIssuesLoader; @@ -84,7 +81,6 @@ public class ProjectSyncContainer extends ComponentContainer { new ProjectKeySupplier(projectKey), projectKey != null ? ProjectCacheSynchronizer.class : NonAssociatedCacheSynchronizer.class, UserRepositoryLoader.class, - new ProjectRepositoriesFactoryProvider(projectKey), new ProjectPersistentCacheProvider(), createIssuesAnalysisMode(projectKey)); @@ -93,6 +89,5 @@ public class ProjectSyncContainer extends ComponentContainer { addIfMissing(DefaultServerIssuesLoader.class, ServerIssuesLoader.class); addIfMissing(DefaultQualityProfileLoader.class, QualityProfileLoader.class); addIfMissing(DefaultActiveRulesLoader.class, ActiveRulesLoader.class); - addIfMissing(DefaultProjectSettingsLoader.class, ProjectSettingsLoader.class); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/cache/WSLoader.java b/sonar-batch/src/main/java/org/sonar/batch/cache/WSLoader.java index 96a83811d08..6535e2c6445 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/cache/WSLoader.java +++ b/sonar-batch/src/main/java/org/sonar/batch/cache/WSLoader.java @@ -19,6 +19,8 @@ */ package org.sonar.batch.cache; +import org.sonar.api.utils.HttpDownloader.HttpException; + import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; @@ -27,7 +29,6 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.apache.commons.io.IOUtils; -import org.sonar.api.utils.HttpDownloader; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.batch.bootstrap.ServerClient; @@ -52,9 +53,9 @@ public class WSLoader { } private final LoadStrategy defautLoadStrategy; - private ServerStatus serverStatus; private final ServerClient client; private final PersistentCache cache; + private ServerStatus serverStatus; public WSLoader(LoadStrategy strategy, PersistentCache cache, ServerClient client) { this.defautLoadStrategy = strategy; @@ -65,7 +66,7 @@ public class WSLoader { @Nonnull public WSLoaderResult<InputStream> loadStream(String id) { - return load(id, defautLoadStrategy, createStreamLoaderServer(), createStreamLoaderCache()); + return load(id, defautLoadStrategy, streamServerLoader, streamCacheLoader); } @Nonnull @@ -75,7 +76,7 @@ public class WSLoader { @Nonnull public WSLoaderResult<String> loadString(String id, WSLoader.LoadStrategy strategy) { - return load(id, strategy, createStringLoaderServer(), createStringLoaderCache()); + return load(id, strategy, stringServerLoader, stringCacheLoader); } @Nonnull @@ -149,7 +150,7 @@ public class WSLoader { @Nonnull private <T> WSLoaderResult<T> loadFromCache(String id, DataLoader<T> loader) throws NotAvailableException { T result = null; - + try { result = loader.load(id); } catch (IOException e) { @@ -172,7 +173,7 @@ public class WSLoader { switchToOnline(); return new WSLoaderResult<T>(t, false); } catch (IllegalStateException e) { - if (e.getCause() instanceof HttpDownloader.HttpException) { + if (e.getCause() instanceof HttpException) { // fail fast if it could connect but there was a application-level error throw e; } @@ -184,56 +185,48 @@ public class WSLoader { } } - private DataLoader<String> createStringLoaderServer() { - return new DataLoader<String>() { - @Override - public String load(String id) throws IOException { - InputStream is = client.load(id, REQUEST_METHOD, true, CONNECT_TIMEOUT, READ_TIMEOUT); - String str = IOUtils.toString(is, StandardCharsets.UTF_8); - try { - cache.put(id, str.getBytes(StandardCharsets.UTF_8)); - } catch (IOException e) { - throw new IllegalStateException("Error saving to WS cache", e); - } - return str; + private DataLoader<String> stringServerLoader = new DataLoader<String>() { + @Override + public String load(String id) throws IOException { + InputStream is = client.load(id, REQUEST_METHOD, true, CONNECT_TIMEOUT, READ_TIMEOUT); + String str = IOUtils.toString(is, StandardCharsets.UTF_8); + try { + cache.put(id, str.getBytes(StandardCharsets.UTF_8)); + } catch (IOException e) { + throw new IllegalStateException("Error saving to WS cache", e); } - }; - } + return str; + } + }; - private DataLoader<String> createStringLoaderCache() { - return new DataLoader<String>() { - @Override - public String load(String id) throws IOException { - return cache.getString(id); + private DataLoader<String> stringCacheLoader = new DataLoader<String>() { + @Override + public String load(String id) throws IOException { + return cache.getString(id); + } + }; + + private DataLoader<InputStream> streamServerLoader = new DataLoader<InputStream>() { + @Override + public InputStream load(String id) throws IOException { + InputStream is = client.load(id, REQUEST_METHOD, true, CONNECT_TIMEOUT, READ_TIMEOUT); + try { + cache.put(id, is); + } catch (IOException e) { + throw new IllegalStateException("Error saving to WS cache", e); } - }; - } + is.close(); + return cache.getStream(id); + } + }; - private DataLoader<InputStream> createStreamLoaderServer() { - return new DataLoader<InputStream>() { - @Override - public InputStream load(String id) throws IOException { - InputStream is = client.load(id, REQUEST_METHOD, true, CONNECT_TIMEOUT, READ_TIMEOUT); - try { - cache.put(id, is); - } catch (IOException e) { - throw new IllegalStateException("Error saving to WS cache", e); - } - is.close(); - return cache.getStream(id); - } - }; - } + private DataLoader<InputStream> streamCacheLoader = new DataLoader<InputStream>() { + @Override + public InputStream load(String id) throws IOException { + return cache.getStream(id); + } + }; - private DataLoader<InputStream> createStreamLoaderCache() { - return new DataLoader<InputStream>() { - @Override - public InputStream load(String id) throws IOException { - return cache.getStream(id); - } - }; - } - private class NotAvailableException extends Exception { private static final long serialVersionUID = 1L; diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/LocalIssueTracking.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/LocalIssueTracking.java index 0acf38329c5..19cdeb7f1b5 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/LocalIssueTracking.java +++ b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/LocalIssueTracking.java @@ -19,7 +19,7 @@ */ package org.sonar.batch.issue.tracking; -import org.sonar.batch.repository.ProjectSettingsRepo; +import org.sonar.batch.repository.ProjectRepositories; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Lists; @@ -64,7 +64,7 @@ public class LocalIssueTracking { private boolean hasServerAnalysis; public LocalIssueTracking(BatchComponentCache resourceCache, IssueTracking tracking, ServerLineHashesLoader lastLineHashes, IssueUpdater updater, - ActiveRules activeRules, ServerIssueRepository serverIssueRepository, ProjectSettingsRepo projectRepositories, ReportPublisher reportPublisher) { + ActiveRules activeRules, ServerIssueRepository serverIssueRepository, ProjectRepositories projectRepositories, ReportPublisher reportPublisher) { this.tracking = tracking; this.lastLineHashes = lastLineHashes; this.updater = updater; diff --git a/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultGlobalRepositoriesLoader.java b/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultGlobalRepositoriesLoader.java index 0575d6a2c72..51e7aaa4635 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultGlobalRepositoriesLoader.java +++ b/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultGlobalRepositoriesLoader.java @@ -30,7 +30,7 @@ import org.sonar.batch.protocol.input.GlobalRepositories; public class DefaultGlobalRepositoriesLoader implements GlobalRepositoriesLoader { - private static final String BATCH_GLOBAL_URL = "/scanner/global"; + private static final String BATCH_GLOBAL_URL = "/batch/global"; private final WSLoader wsLoader; diff --git a/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultProjectRepositoriesFactory.java b/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultProjectRepositoriesFactory.java deleted file mode 100644 index 3861684da2e..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultProjectRepositoriesFactory.java +++ /dev/null @@ -1,81 +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.repository; - -import org.sonar.api.batch.bootstrap.ProjectReactor; - -import org.sonar.batch.rule.ModuleQProfiles; -import org.sonar.batch.analysis.AnalysisProperties; -import org.sonar.batch.analysis.DefaultAnalysisMode; -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 org.sonar.batch.protocol.input.ProjectRepositories; - -public class DefaultProjectRepositoriesFactory implements ProjectRepositoriesFactory { - private static final String LOG_MSG = "Load project repositories"; - private static final Logger LOG = Loggers.get(DefaultProjectRepositoriesFactory.class); - private static final String NON_EXISTING = "non1-existing2-project3-key"; - - private final DefaultAnalysisMode analysisMode; - private final ProjectRepositoriesLoader loader; - private final AnalysisProperties props; - private final ProjectReactor projectReactor; - - private ProjectRepositories projectReferentials; - - public DefaultProjectRepositoriesFactory(ProjectReactor projectReactor, DefaultAnalysisMode analysisMode, ProjectRepositoriesLoader loader, AnalysisProperties props) { - this.projectReactor = projectReactor; - this.analysisMode = analysisMode; - this.loader = loader; - this.props = props; - } - - @Override - public ProjectRepositories create() { - if (projectReferentials == null) { - Profiler profiler = Profiler.create(LOG).startInfo(LOG_MSG); - MutableBoolean fromCache = new MutableBoolean(); - projectReferentials = loader.load(getProjectKey(), getSonarProfile(), 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'."); - } - } - return projectReferentials; - } - - private String getProjectKey() { - if (analysisMode.isNotAssociated()) { - return NON_EXISTING; - } - return projectReactor.getRoot().getKeyWithBranch(); - } - - private String getSonarProfile() { - String profile = null; - if (!analysisMode.isIssues()) { - profile = props.property(ModuleQProfiles.SONAR_PROFILE_PROP); - } - return profile; - } -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultProjectRepositoriesLoader.java b/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultProjectRepositoriesLoader.java index ab0f960c6a1..990a6c903f0 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultProjectRepositoriesLoader.java +++ b/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultProjectRepositoriesLoader.java @@ -19,48 +19,88 @@ */ package org.sonar.batch.repository; -import javax.annotation.Nullable; -import org.apache.commons.lang.mutable.MutableBoolean; -import org.sonar.api.utils.log.Logger; -import org.sonar.api.utils.log.Loggers; -import org.sonar.batch.analysis.DefaultAnalysisMode; -import org.sonar.batch.cache.WSLoader; -import org.sonar.batch.cache.WSLoaderResult; -import org.sonar.batch.protocol.input.ProjectRepositories; -import org.sonar.batch.rule.ModuleQProfiles; +import org.apache.commons.io.IOUtils; + import org.sonar.batch.util.BatchUtils; +import org.sonarqube.ws.WsScanner.WsProjectResponse.FileDataByPath; +import org.sonarqube.ws.WsScanner.WsProjectResponse.Settings; +import org.sonarqube.ws.WsScanner.WsProjectResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.google.common.collect.Table; +import com.google.common.collect.HashBasedTable; +import org.sonar.batch.cache.WSLoaderResult; +import org.sonar.batch.cache.WSLoader; +import org.apache.commons.lang.mutable.MutableBoolean; -public class DefaultProjectRepositoriesLoader implements ProjectRepositoriesLoader { +import javax.annotation.Nullable; - private static final Logger LOG = Loggers.get(DefaultProjectRepositoriesLoader.class); - private static final String BATCH_PROJECT_URL = "/scanner/project"; +import java.io.IOException; +import java.io.InputStream; +import java.util.Date; +import java.util.Map; - private final WSLoader wsLoader; - private final DefaultAnalysisMode analysisMode; +public class DefaultProjectRepositoriesLoader implements ProjectRepositoriesLoader { + private static final Logger LOG = LoggerFactory.getLogger(DefaultProjectRepositoriesLoader.class); + private static final String BATCH_PROJECT_URL = "/batch/project"; + private final WSLoader loader; - public DefaultProjectRepositoriesLoader(WSLoader wsLoader, DefaultAnalysisMode analysisMode) { - this.wsLoader = wsLoader; - this.analysisMode = analysisMode; + public DefaultProjectRepositoriesLoader(WSLoader loader) { + this.loader = loader; } @Override - public ProjectRepositories load(String projectKeyWithBranch, @Nullable String sonarProfile, @Nullable MutableBoolean fromCache) { - String url = BATCH_PROJECT_URL + "?key=" + BatchUtils.encodeForUrl(projectKeyWithBranch); - if (sonarProfile != null) { - LOG.warn("Ability to set quality profile from command line using '" + ModuleQProfiles.SONAR_PROFILE_PROP - + "' is deprecated and will be dropped in a future SonarQube version. Please configure quality profile used by your project on SonarQube server."); - url += "&profile=" + BatchUtils.encodeForUrl(sonarProfile); + public ProjectRepositories load(String projectKey, boolean issuesMode, @Nullable MutableBoolean fromCache) { + try { + WSLoaderResult<InputStream> result = loader.loadStream(getUrl(projectKey, issuesMode)); + if (fromCache != null) { + fromCache.setValue(result.isFromCache()); + } + return processStream(result.get(), projectKey); + } catch (IllegalStateException e) { + LOG.debug("Couldn't get project repositories - continuing without it", e); + return new ProjectRepositories(); } - url += "&preview=" + analysisMode.isIssues(); + } - return load(url, fromCache); + private static String getUrl(String projectKey, boolean issuesMode) { + StringBuilder builder = new StringBuilder(); + + builder.append(BATCH_PROJECT_URL) + .append("?key=").append(BatchUtils.encodeForUrl(projectKey)); + if (issuesMode) { + builder.append("&issues=true"); + } + return builder.toString(); } - private ProjectRepositories load(String resource, @Nullable MutableBoolean fromCache) { - WSLoaderResult<String> result = wsLoader.loadString(resource); - if (fromCache != null) { - fromCache.setValue(result.isFromCache()); + private static ProjectRepositories processStream(InputStream is, String projectKey) { + try { + WsProjectResponse response = WsProjectResponse.parseFrom(is); + + Table<String, String, FileData> fileDataTable = HashBasedTable.create(); + Table<String, String, String> settings = HashBasedTable.create(); + + Map<String, Settings> settingsByModule = response.getSettingsByModule(); + for (Map.Entry<String, Settings> e1 : settingsByModule.entrySet()) { + for (Map.Entry<String, String> e2 : e1.getValue().getSettings().entrySet()) { + settings.put(e1.getKey(), e2.getKey(), e2.getValue()); + } + } + + Map<String, FileDataByPath> fileDataByModuleAndPath = response.getFileDataByModuleAndPath(); + for (Map.Entry<String, FileDataByPath> e1 : fileDataByModuleAndPath.entrySet()) { + for (Map.Entry<String, org.sonarqube.ws.WsScanner.WsProjectResponse.FileData> e2 : e1.getValue().getFileDataByPath().entrySet()) { + FileData fd = new FileData(e2.getValue().getHash(), e2.getValue().getRevision()); + fileDataTable.put(e1.getKey(), e2.getKey(), fd); + } + } + + return new ProjectRepositories(settings, fileDataTable, new Date(response.getLastAnalysisDate())); + } catch (IOException e) { + throw new IllegalStateException("Couldn't load project settings for " + projectKey, e); + } finally { + IOUtils.closeQuietly(is); } - return ProjectRepositories.fromJson(result.get()); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultProjectSettingsLoader.java b/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultProjectSettingsLoader.java deleted file mode 100644 index acb23823686..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultProjectSettingsLoader.java +++ /dev/null @@ -1,56 +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.repository; - -import org.apache.commons.lang.mutable.MutableBoolean; - -import javax.annotation.Nullable; - -import java.util.Map; - -import com.google.common.collect.HashBasedTable; -import com.google.common.collect.Table; -import org.sonar.batch.protocol.input.ProjectRepositories; - -public class DefaultProjectSettingsLoader implements ProjectSettingsLoader { - private ProjectRepositoriesFactory projectRepositoryFactory; - - public DefaultProjectSettingsLoader(ProjectRepositoriesFactory projectRepositoryFactory) { - this.projectRepositoryFactory = projectRepositoryFactory; - } - - @Override - public ProjectSettingsRepo load(String projectKey, @Nullable MutableBoolean fromCache) { - ProjectRepositories pr = projectRepositoryFactory.create(); - return new ProjectSettingsRepo(toTable(pr.settings()), toTable(pr.fileDataByModuleAndPath()), pr.lastAnalysisDate()); - } - - private static <T, U, V> Table<T, U, V> toTable(Map<T, Map<U, V>> map) { - Table<T, U, V> table = HashBasedTable.create(); - - for (Map.Entry<T, Map<U, V>> e1 : map.entrySet()) { - for (Map.Entry<U, V> e2 : e1.getValue().entrySet()) { - table.put(e1.getKey(), e2.getKey(), e2.getValue()); - } - } - - return table; - } -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultQualityProfileLoader.java b/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultQualityProfileLoader.java index ab86309f3d5..9e041e1e46e 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultQualityProfileLoader.java +++ b/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultQualityProfileLoader.java @@ -19,32 +19,71 @@ */ package org.sonar.batch.repository; -import javax.annotation.Nullable; +import org.sonarqube.ws.QualityProfiles.WsSearchResponse; + +import org.sonar.batch.util.BatchUtils; +import org.apache.commons.io.IOUtils; +import org.sonarqube.ws.QualityProfiles.WsSearchResponse.QualityProfile; +import org.apache.commons.lang.mutable.MutableBoolean; +import org.sonar.batch.cache.WSLoaderResult; +import org.sonar.batch.cache.WSLoader; -import org.sonar.batch.protocol.input.ProjectRepositories; -import org.sonar.batch.protocol.input.QProfile; +import javax.annotation.Nullable; +import java.io.IOException; +import java.io.InputStream; import java.util.Collection; +import java.util.List; public class DefaultQualityProfileLoader implements QualityProfileLoader { + private static final String WS_URL = "/qualityprofiles/search"; - private ProjectRepositoriesFactory projectRepositoriesFactory; + private WSLoader wsLoader; - public DefaultQualityProfileLoader(ProjectRepositoriesFactory projectRepositoriesFactory) { - this.projectRepositoriesFactory = projectRepositoriesFactory; + public DefaultQualityProfileLoader(WSLoader wsLoader) { + this.wsLoader = wsLoader; } @Override - public Collection<QProfile> load(@Nullable String projectKey, @Nullable String sonarProfile) { - ProjectRepositories pr = projectRepositoriesFactory.create(); - validate(pr.qProfiles()); - return pr.qProfiles(); + public List<QualityProfile> loadDefault(@Nullable MutableBoolean fromCache) { + String url = WS_URL + "?defaults=true"; + return loadResource(url, fromCache); + } + + @Override + public List<QualityProfile> load(String projectKey, @Nullable String profileName, @Nullable MutableBoolean fromCache) { + String url = WS_URL + "?projectKey=" + BatchUtils.encodeForUrl(projectKey); + if (profileName != null) { + url += "&profileName=" + BatchUtils.encodeForUrl(profileName); + } + return loadResource(url, fromCache); } - private static void validate(Collection<QProfile> profiles) { + private static void validate(Collection<QualityProfile> profiles) { if (profiles == null || profiles.isEmpty()) { throw new IllegalStateException("No quality profiles has been found this project, you probably don't have any language plugin suitable for this analysis."); } } + private List<QualityProfile> loadResource(String url, @Nullable MutableBoolean fromCache) { + WSLoaderResult<InputStream> result = wsLoader.loadStream(url); + if (fromCache != null) { + fromCache.setValue(result.isFromCache()); + } + InputStream is = result.get(); + WsSearchResponse profiles = null; + + try { + profiles = WsSearchResponse.parseFrom(is); + } catch (IOException e) { + throw new IllegalStateException("Failed to load quality profiles", e); + } finally { + IOUtils.closeQuietly(is); + } + + List<QualityProfile> profilesList = profiles.getProfilesList(); + validate(profilesList); + return profilesList; + } + } diff --git a/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultServerIssuesLoader.java b/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultServerIssuesLoader.java index 0989cd5e616..bf238c03aed 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultServerIssuesLoader.java +++ b/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultServerIssuesLoader.java @@ -20,7 +20,6 @@ package org.sonar.batch.repository; import com.google.common.base.Function; -import com.google.common.io.ByteSource; import java.io.IOException; import java.io.InputStream; import org.apache.commons.io.IOUtils; @@ -39,7 +38,7 @@ public class DefaultServerIssuesLoader implements ServerIssuesLoader { @Override public boolean load(String componentKey, Function<ServerIssue, Void> consumer) { - WSLoaderResult<ByteSource> result = wsLoader.loadSource("/scanner/issues?key=" + BatchUtils.encodeForUrl(componentKey)); + WSLoaderResult<InputStream> result = wsLoader.loadStream("/batch/issues?key=" + BatchUtils.encodeForUrl(componentKey)); parseIssues(result.get(), consumer); return result.isFromCache(); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/repository/ProjectRepositoriesFactory.java b/sonar-batch/src/main/java/org/sonar/batch/repository/FileData.java index 13ce299d8f9..0c1572c2f80 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/repository/ProjectRepositoriesFactory.java +++ b/sonar-batch/src/main/java/org/sonar/batch/repository/FileData.java @@ -19,10 +19,23 @@ */ package org.sonar.batch.repository; -import org.sonar.batch.protocol.input.ProjectRepositories; +import javax.annotation.concurrent.Immutable; -public interface ProjectRepositoriesFactory { +@Immutable +public class FileData { + private final String hash; + private final String revision; - ProjectRepositories create(); + public FileData(String hash, String revision) { + this.hash = hash; + this.revision = revision; + } + public String hash() { + return hash; + } + + public String revision() { + return revision; + } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/repository/ProjectSettingsRepo.java b/sonar-batch/src/main/java/org/sonar/batch/repository/ProjectRepositories.java index 1e53de437bc..4c12eb40886 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/repository/ProjectSettingsRepo.java +++ b/sonar-batch/src/main/java/org/sonar/batch/repository/ProjectRepositories.java @@ -19,27 +19,38 @@ */ package org.sonar.batch.repository; +import com.google.common.collect.HashBasedTable; import com.google.common.collect.Table; import javax.annotation.CheckForNull; import javax.annotation.Nullable; -import org.sonar.batch.protocol.input.FileData; - import java.util.Date; import java.util.Map; -public class ProjectSettingsRepo { - private Table<String, String, String> settingsByModule = null; - private Table<String, String, FileData> fileDataByModuleAndPath = null; - private Date lastAnalysisDate; +public class ProjectRepositories { + private final Table<String, String, String> settingsByModule; + private final Table<String, String, FileData> fileDataByModuleAndPath; + private final Date lastAnalysisDate; + private final boolean exists; + + public ProjectRepositories() { + this.exists = false; + this.settingsByModule = HashBasedTable.create(); + this.fileDataByModuleAndPath = HashBasedTable.create(); + this.lastAnalysisDate = null; + } - public ProjectSettingsRepo(Table<String, String, String> settingsByModule, Table<String, String, FileData> fileDataByModuleAndPath, + public ProjectRepositories(Table<String, String, String> settingsByModule, Table<String, String, FileData> fileDataByModuleAndPath, @Nullable Date lastAnalysisDate) { - super(); this.settingsByModule = settingsByModule; this.fileDataByModuleAndPath = fileDataByModuleAndPath; this.lastAnalysisDate = lastAnalysisDate; + this.exists = true; + } + + public boolean exists() { + return exists; } public Map<String, FileData> fileDataByPath(String moduleKey) { diff --git a/sonar-batch/src/main/java/org/sonar/batch/repository/ProjectRepositoriesFactoryProvider.java b/sonar-batch/src/main/java/org/sonar/batch/repository/ProjectRepositoriesFactoryProvider.java deleted file mode 100644 index 609d7a73f5d..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/repository/ProjectRepositoriesFactoryProvider.java +++ /dev/null @@ -1,41 +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.repository; - -import org.picocontainer.injectors.ProviderAdapter; - -public class ProjectRepositoriesFactoryProvider extends ProviderAdapter { - - private final String projectKey; - private SyncProjectRepositoriesFactory factory; - - public ProjectRepositoriesFactoryProvider(String projectKey) { - this.projectKey = projectKey; - this.factory = null; - } - - public ProjectRepositoriesFactory provide(ProjectRepositoriesLoader loader) { - if (factory == null) { - factory = new SyncProjectRepositoriesFactory(projectKey, loader); - } - - return factory; - } -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/repository/ProjectRepositoriesLoader.java b/sonar-batch/src/main/java/org/sonar/batch/repository/ProjectRepositoriesLoader.java index d066b488940..acf32cdda32 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/repository/ProjectRepositoriesLoader.java +++ b/sonar-batch/src/main/java/org/sonar/batch/repository/ProjectRepositoriesLoader.java @@ -19,14 +19,10 @@ */ package org.sonar.batch.repository; - import javax.annotation.Nullable; import org.apache.commons.lang.mutable.MutableBoolean; -import org.sonar.batch.protocol.input.ProjectRepositories; public interface ProjectRepositoriesLoader { - - ProjectRepositories load(String projectKeyWithBranch, @Nullable String sonarProfile, @Nullable MutableBoolean fromCache); - + ProjectRepositories load(String projectKeyWithBranch, boolean issuesMode, @Nullable MutableBoolean fromCache); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/repository/SyncProjectRepositoriesFactory.java b/sonar-batch/src/main/java/org/sonar/batch/repository/ProjectRepositoriesProvider.java index f01cce9102b..2006167509e 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/repository/SyncProjectRepositoriesFactory.java +++ b/sonar-batch/src/main/java/org/sonar/batch/repository/ProjectRepositoriesProvider.java @@ -19,56 +19,52 @@ */ package org.sonar.batch.repository; -import javax.annotation.Nullable; +import org.sonar.api.utils.log.Profiler; -import org.apache.commons.lang.mutable.MutableBoolean; +import org.sonar.api.batch.bootstrap.ProjectKey; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; -import org.sonar.api.utils.log.Profiler; -import org.sonar.batch.protocol.input.ProjectRepositories; -public class SyncProjectRepositoriesFactory implements ProjectRepositoriesFactory { - private static final String LOG_MSG = "Load project repositories"; - private static final Logger LOG = Loggers.get(SyncProjectRepositoriesFactory.class); - private static final String NON_EXISTING = "non1-existing2-project3-key"; +import javax.annotation.Nullable; - private final ProjectRepositoriesLoader loader; - private final String projectKey; +import org.sonar.batch.analysis.DefaultAnalysisMode; +import org.apache.commons.lang.mutable.MutableBoolean; +import org.picocontainer.injectors.ProviderAdapter; - private ProjectRepositories projectRepositories; +public class ProjectRepositoriesProvider extends ProviderAdapter { + private static final Logger LOG = Loggers.get(ProjectRepositoriesProvider.class); + private static final String LOG_MSG = "Load project repositories"; + private ProjectRepositories project = null; - public SyncProjectRepositoriesFactory(@Nullable String projectKey, ProjectRepositoriesLoader loader) { - this.projectKey = projectKey; - this.loader = loader; - } + public ProjectRepositories provide(@Nullable ProjectRepositoriesLoader loader, ProjectKey projectKey, DefaultAnalysisMode mode) { + if (project == null) { + MutableBoolean fromCache = new MutableBoolean(false); + Profiler profiler = Profiler.create(LOG).startInfo(LOG_MSG); + if (mode.isNotAssociated()) { + project = createNonAssociatedProjectRepositories(); + profiler.stopInfo(); + } else { + project = loader.load(projectKey.get(), mode.isIssues(), fromCache); + checkProject(mode); + profiler.stopInfo(fromCache.booleanValue()); + } - @Override - public ProjectRepositories create() { - if (projectRepositories == null) { - projectRepositories = newInstance(); } - return projectRepositories; + return project; } - public ProjectRepositories newInstance() { - if (projectRepositories == null) { - Profiler profiler = Profiler.create(LOG).startInfo(LOG_MSG); - MutableBoolean fromCache = new MutableBoolean(); - projectRepositories = loader.load(getProjectKey(projectKey), null, fromCache); - profiler.stopInfo(fromCache.booleanValue()); - - if (projectRepositories.lastAnalysisDate() == null) { + private void checkProject(DefaultAnalysisMode mode) { + if (mode.isIssues()) { + if (!project.exists()) { + LOG.warn("Project doesn't exist on the server. All issues will be marked as 'new'."); + } else if (project.lastAnalysisDate() == null) { LOG.warn("No analysis has been found on the server for this project. All issues will be marked as 'new'."); } } - return projectRepositories; } - private static String getProjectKey(@Nullable String projectKey) { - if (projectKey == null) { - return NON_EXISTING; - } - return projectKey; + private static ProjectRepositories createNonAssociatedProjectRepositories() { + return new ProjectRepositories(); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/repository/ProjectSettingsLoader.java b/sonar-batch/src/main/java/org/sonar/batch/repository/ProjectSettingsLoader.java deleted file mode 100644 index dc0efbcc4e4..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/repository/ProjectSettingsLoader.java +++ /dev/null @@ -1,28 +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.repository; - -import org.apache.commons.lang.mutable.MutableBoolean; - -import javax.annotation.Nullable; - -public interface ProjectSettingsLoader { - ProjectSettingsRepo load(String projectKey, @Nullable MutableBoolean fromCache); -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/repository/ProjectSettingsProvider.java b/sonar-batch/src/main/java/org/sonar/batch/repository/ProjectSettingsProvider.java deleted file mode 100644 index 5fa0db433b5..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/repository/ProjectSettingsProvider.java +++ /dev/null @@ -1,64 +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.repository; - -import org.sonar.api.utils.log.Logger; -import org.sonar.api.utils.log.Loggers; - -import javax.annotation.Nullable; - -import org.sonar.batch.analysis.DefaultAnalysisMode; -import org.sonar.batch.protocol.input.FileData; -import com.google.common.collect.Table; -import com.google.common.collect.ImmutableTable; -import org.apache.commons.lang.mutable.MutableBoolean; -import org.sonar.api.batch.bootstrap.ProjectReactor; -import org.picocontainer.injectors.ProviderAdapter; - -public class ProjectSettingsProvider extends ProviderAdapter { - private static final Logger LOG = Loggers.get(ProjectSettingsProvider.class); - private ProjectSettingsRepo settings = null; - - public ProjectSettingsRepo provide(@Nullable ProjectSettingsLoader loader, ProjectReactor projectReactor, DefaultAnalysisMode mode) { - if (settings == null) { - if (mode.isNotAssociated()) { - settings = createNonAssociatedProjectSettings(); - } else { - MutableBoolean fromCache = new MutableBoolean(); - settings = loader.load(projectReactor.getRoot().getKeyWithBranch(), fromCache); - checkProject(mode); - } - } - - return settings; - } - - private void checkProject(DefaultAnalysisMode mode) { - if (mode.isIssues() && settings.lastAnalysisDate() == null) { - LOG.warn("No analysis has been found on the server for this project. All issues will be marked as 'new'."); - } - } - - private static ProjectSettingsRepo createNonAssociatedProjectSettings() { - Table<String, String, String> emptySettings = ImmutableTable.of(); - Table<String, String, FileData> emptyFileData = ImmutableTable.of(); - return new ProjectSettingsRepo(emptySettings, emptyFileData, null); - } -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/repository/QualityProfileLoader.java b/sonar-batch/src/main/java/org/sonar/batch/repository/QualityProfileLoader.java index 1d41398bff4..1ab61a9e438 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/repository/QualityProfileLoader.java +++ b/sonar-batch/src/main/java/org/sonar/batch/repository/QualityProfileLoader.java @@ -19,12 +19,15 @@ */ package org.sonar.batch.repository; -import javax.annotation.Nullable; +import org.apache.commons.lang.mutable.MutableBoolean; +import org.sonarqube.ws.QualityProfiles.WsSearchResponse.QualityProfile; -import org.sonar.batch.protocol.input.QProfile; +import javax.annotation.Nullable; -import java.util.Collection; +import java.util.List; public interface QualityProfileLoader { - Collection<QProfile> load(@Nullable String projectKey, @Nullable String sonarProfile); + List<QualityProfile> load(String projectKey, @Nullable String profileName, @Nullable MutableBoolean fromCache); + + List<QualityProfile> loadDefault(@Nullable MutableBoolean fromCache); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/repository/QualityProfileProvider.java b/sonar-batch/src/main/java/org/sonar/batch/repository/QualityProfileProvider.java index 6f40ef0c7a8..d35ab28fb6b 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/repository/QualityProfileProvider.java +++ b/sonar-batch/src/main/java/org/sonar/batch/repository/QualityProfileProvider.java @@ -19,30 +19,49 @@ */ package org.sonar.batch.repository; -import org.sonar.batch.protocol.input.QProfile; +import org.sonar.api.utils.log.Profiler; +import org.sonar.api.utils.log.Logger; +import org.sonar.api.utils.log.Loggers; +import org.apache.commons.lang.mutable.MutableBoolean; +import org.sonarqube.ws.QualityProfiles.WsSearchResponse.QualityProfile; +import org.sonar.batch.analysis.DefaultAnalysisMode; +import org.sonar.api.batch.bootstrap.ProjectKey; -import java.util.Collection; +import java.util.List; -import org.sonar.api.batch.AnalysisMode; import org.sonar.batch.analysis.AnalysisProperties; -import org.sonar.api.batch.bootstrap.ProjectReactor; import org.sonar.batch.rule.ModuleQProfiles; import org.picocontainer.injectors.ProviderAdapter; public class QualityProfileProvider extends ProviderAdapter { + private static final Logger LOG = Loggers.get(QualityProfileProvider.class); + private static final String LOG_MSG = "Load quality profiles"; private ModuleQProfiles profiles = null; - public ModuleQProfiles provide(ProjectReactor projectReactor, QualityProfileLoader loader, AnalysisProperties props, AnalysisMode mode) { + public ModuleQProfiles provide(ProjectKey projectKey, QualityProfileLoader loader, ProjectRepositories projectRepositories, AnalysisProperties props, DefaultAnalysisMode mode) { if (this.profiles == null) { - String profile = null; - if (!mode.isIssues()) { - profile = props.property(ModuleQProfiles.SONAR_PROFILE_PROP); + List<QualityProfile> profileList; + MutableBoolean fromCache = new MutableBoolean(); + + Profiler profiler = Profiler.create(LOG).startInfo(LOG_MSG); + if (mode.isNotAssociated() || !projectRepositories.exists()) { + profileList = loader.loadDefault(fromCache); + } else { + profileList = loader.load(projectKey.get(), getSonarProfile(props, mode), fromCache); } - Collection<QProfile> qps = loader.load(projectReactor.getRoot().getKeyWithBranch(), profile); - profiles = new ModuleQProfiles(qps); + profiler.stopInfo(fromCache.booleanValue()); + profiles = new ModuleQProfiles(profileList); } return profiles; } + private static String getSonarProfile(AnalysisProperties props, DefaultAnalysisMode mode) { + String profile = null; + if (!mode.isIssues()) { + profile = props.property(ModuleQProfiles.SONAR_PROFILE_PROP); + } + return profile; + } + } diff --git a/sonar-batch/src/main/java/org/sonar/batch/repository/user/UserRepositoryLoader.java b/sonar-batch/src/main/java/org/sonar/batch/repository/user/UserRepositoryLoader.java index a7b9dc71d4a..cb973bba454 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/repository/user/UserRepositoryLoader.java +++ b/sonar-batch/src/main/java/org/sonar/batch/repository/user/UserRepositoryLoader.java @@ -73,7 +73,7 @@ public class UserRepositoryLoader { } private InputStream loadQuery(String loginsQuery, @Nullable MutableBoolean fromCache) { - WSLoaderResult<InputStream> result = wsLoader.loadStream("/scanner/users?logins=" + loginsQuery); + WSLoaderResult<InputStream> result = wsLoader.loadStream("/batch/users?logins=" + loginsQuery); if (fromCache != null) { fromCache.setValue(result.isFromCache()); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/rule/ActiveRulesLoader.java b/sonar-batch/src/main/java/org/sonar/batch/rule/ActiveRulesLoader.java index bf2ff6d406a..72f33bdb43c 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/rule/ActiveRulesLoader.java +++ b/sonar-batch/src/main/java/org/sonar/batch/rule/ActiveRulesLoader.java @@ -19,10 +19,13 @@ */ package org.sonar.batch.rule; -import org.sonar.batch.protocol.input.ActiveRule; +import org.sonarqube.ws.Rules.Rule; +import org.apache.commons.lang.mutable.MutableBoolean; -import java.util.Collection; +import javax.annotation.Nullable; + +import java.util.List; public interface ActiveRulesLoader { - Collection<ActiveRule> load(Collection<String> qualityProfileKeys, String projectKey); + List<Rule> load(String qualityProfileKey, @Nullable MutableBoolean fromCache); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/rule/ActiveRulesProvider.java b/sonar-batch/src/main/java/org/sonar/batch/rule/ActiveRulesProvider.java index ee2529cadff..5373c36f945 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/rule/ActiveRulesProvider.java +++ b/sonar-batch/src/main/java/org/sonar/batch/rule/ActiveRulesProvider.java @@ -19,47 +19,80 @@ */ package org.sonar.batch.rule; -import org.sonar.api.batch.bootstrap.ProjectReactor; +import org.sonar.api.utils.log.Profiler; + +import org.sonar.api.utils.log.Logger; +import org.sonar.api.utils.log.Loggers; +import org.sonarqube.ws.Rules.Rule.Param; +import org.sonarqube.ws.Rules.Rule; import org.picocontainer.injectors.ProviderAdapter; import org.sonar.api.batch.rule.ActiveRules; import org.sonar.api.batch.rule.internal.ActiveRulesBuilder; import org.sonar.api.batch.rule.internal.NewActiveRule; import org.sonar.api.rule.RuleKey; -import org.sonar.batch.protocol.input.ActiveRule; +import java.io.IOException; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.List; -import java.util.Map.Entry; +import java.util.Map; /** * Loads the rules that are activated on the Quality profiles - * used by the current project and build {@link org.sonar.api.batch.rule.ActiveRules}. + * used by the current project and builds {@link org.sonar.api.batch.rule.ActiveRules}. */ public class ActiveRulesProvider extends ProviderAdapter { - + private static final Logger LOG = Loggers.get(ActiveRulesProvider.class); + private static final String LOG_MSG = "Load active rules"; private ActiveRules singleton = null; - public ActiveRules provide(ActiveRulesLoader ref, ModuleQProfiles qProfiles, ProjectReactor projectReactor) { + public ActiveRules provide(ActiveRulesLoader loader, ModuleQProfiles qProfiles) { if (singleton == null) { - singleton = load(ref, qProfiles, projectReactor); + Profiler profiler = Profiler.create(LOG).startInfo(LOG_MSG); + singleton = load(loader, qProfiles); + profiler.stopInfo(); } return singleton; } - private static ActiveRules load(ActiveRulesLoader loader, ModuleQProfiles qProfiles, ProjectReactor projectReactor) { + private static ActiveRules load(ActiveRulesLoader loader, ModuleQProfiles qProfiles) { + + Collection<String> qProfileKeys = getKeys(qProfiles); + Map<String, Rule> loadedRulesByKey = new HashMap<>(); + + try { + for (String qProfileKey : qProfileKeys) { + Collection<Rule> qProfileRules; + qProfileRules = load(loader, qProfileKey); + + for (Rule r : qProfileRules) { + if (!loadedRulesByKey.containsKey(r.getKey())) { + loadedRulesByKey.put(r.getKey(), r); + } + } + } + } catch (IOException e) { + throw new IllegalStateException("Error loading active rules", e); + } + + return transform(loadedRulesByKey.values()); + } + + private static ActiveRules transform(Collection<Rule> loadedRules) { ActiveRulesBuilder builder = new ActiveRulesBuilder(); - for (ActiveRule activeRule : loader.load(getKeys(qProfiles), projectReactor.getRoot().getKeyWithBranch())) { - NewActiveRule newActiveRule = builder.create(RuleKey.of(activeRule.repositoryKey(), activeRule.ruleKey())); - newActiveRule.setName(activeRule.name()); - newActiveRule.setSeverity(activeRule.severity()); - newActiveRule.setLanguage(activeRule.language()); - newActiveRule.setInternalKey(activeRule.internalKey()); - newActiveRule.setTemplateRuleKey(activeRule.templateRuleKey()); + + for (Rule activeRule : loadedRules) { + NewActiveRule newActiveRule = builder.create(RuleKey.of(activeRule.getRepo(), activeRule.getKey())); + newActiveRule.setName(activeRule.getName()); + newActiveRule.setSeverity(activeRule.getSeverity()); + newActiveRule.setLanguage(activeRule.getLang()); + newActiveRule.setInternalKey(activeRule.getInternalKey()); + newActiveRule.setTemplateRuleKey(activeRule.getTemplateKey()); // load parameters - for (Entry<String, String> param : activeRule.params().entrySet()) { - newActiveRule.setParam(param.getKey(), param.getValue()); + for (Param param : activeRule.getParams().getParamsList()) { + newActiveRule.setParam(param.getKey(), param.getDefaultValue()); } newActiveRule.activate(); @@ -67,6 +100,10 @@ public class ActiveRulesProvider extends ProviderAdapter { return builder.build(); } + private static List<Rule> load(ActiveRulesLoader loader, String qProfileKey) throws IOException { + return loader.load(qProfileKey, null); + } + private static Collection<String> getKeys(ModuleQProfiles qProfiles) { List<String> keys = new ArrayList<>(qProfiles.findAll().size()); diff --git a/sonar-batch/src/main/java/org/sonar/batch/rule/DefaultActiveRulesLoader.java b/sonar-batch/src/main/java/org/sonar/batch/rule/DefaultActiveRulesLoader.java index 05e58846648..112efd60995 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/rule/DefaultActiveRulesLoader.java +++ b/sonar-batch/src/main/java/org/sonar/batch/rule/DefaultActiveRulesLoader.java @@ -19,25 +19,53 @@ */ package org.sonar.batch.rule; -import org.sonar.batch.repository.ProjectRepositoriesFactory; +import org.sonarqube.ws.Rules.SearchResponse; -import org.sonar.batch.protocol.input.ActiveRule; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.mutable.MutableBoolean; +import org.sonar.batch.cache.WSLoader; +import org.sonar.batch.cache.WSLoaderResult; -import java.util.Collection; +import javax.annotation.Nullable; -import org.sonar.batch.protocol.input.ProjectRepositories; +import org.sonarqube.ws.Rules.Rule; + +import java.io.IOException; +import java.io.InputStream; +import java.util.List; public class DefaultActiveRulesLoader implements ActiveRulesLoader { - private final ProjectRepositoriesFactory projectRepositoriesFactory; + private static final String RULES_SEARCH_URL = "/api/rules/search?f=repo,name,severity,lang,internalKey,templateKey"; + + private final WSLoader wsLoader; - public DefaultActiveRulesLoader(ProjectRepositoriesFactory projectRepositoriesFactory) { - this.projectRepositoriesFactory = projectRepositoriesFactory; + public DefaultActiveRulesLoader(WSLoader wsLoader) { + this.wsLoader = wsLoader; } @Override - public Collection<ActiveRule> load(Collection<String> qualityProfileKeys, String projectKey) { - ProjectRepositories pr = projectRepositoriesFactory.create(); - return pr.activeRules(); + public List<Rule> load(String qualityProfileKey, @Nullable MutableBoolean fromCache) { + WSLoaderResult<InputStream> result = wsLoader.loadStream(getUrl(qualityProfileKey)); + List<Rule> ruleList = loadFromStream(result.get()); + if (fromCache != null) { + fromCache.setValue(result.isFromCache()); + } + return ruleList; + } + + private static String getUrl(String qualityProfileKey) { + return RULES_SEARCH_URL + "&qprofile=" + qualityProfileKey; + } + + private static List<Rule> loadFromStream(InputStream is) { + try { + SearchResponse response = SearchResponse.parseFrom(is); + return response.getRulesList(); + } catch (IOException e) { + throw new IllegalStateException("Failed to load quality profiles", e); + } finally { + IOUtils.closeQuietly(is); + } } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/rule/ModuleQProfiles.java b/sonar-batch/src/main/java/org/sonar/batch/rule/ModuleQProfiles.java index 3ac70d83150..3f8d5cdd8ae 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/rule/ModuleQProfiles.java +++ b/sonar-batch/src/main/java/org/sonar/batch/rule/ModuleQProfiles.java @@ -19,6 +19,9 @@ */ package org.sonar.batch.rule; +import org.sonar.api.utils.DateUtils; + +import org.sonarqube.ws.QualityProfiles.WsSearchResponse.QualityProfile; import com.google.common.collect.ImmutableMap; import org.sonar.api.batch.BatchSide; @@ -36,12 +39,16 @@ public class ModuleQProfiles { public static final String SONAR_PROFILE_PROP = "sonar.profile"; private final Map<String, QProfile> byLanguage; - public ModuleQProfiles(Collection<org.sonar.batch.protocol.input.QProfile> profiles) { + public ModuleQProfiles(Collection<QualityProfile> profiles) { ImmutableMap.Builder<String, QProfile> builder = ImmutableMap.builder(); - for (org.sonar.batch.protocol.input.QProfile qProfile : profiles) { - builder.put(qProfile.language(), - new QProfile().setKey(qProfile.key()).setName(qProfile.name()).setLanguage(qProfile.language()).setRulesUpdatedAt(qProfile.rulesUpdatedAt())); + for (QualityProfile qProfile : profiles) { + builder.put(qProfile.getLanguage(), + new QProfile() + .setKey(qProfile.getKey()) + .setName(qProfile.getName()) + .setLanguage(qProfile.getLanguage()) + .setRulesUpdatedAt(DateUtils.parseDateTime(qProfile.getRulesUpdatedAt()))); } byLanguage = builder.build(); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleSettings.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleSettings.java index 43ca0dd6ac1..96f085d76b2 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleSettings.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleSettings.java @@ -28,17 +28,17 @@ import org.sonar.api.utils.MessageException; import org.sonar.batch.analysis.DefaultAnalysisMode; import org.sonar.batch.bootstrap.GlobalSettings; import org.sonar.batch.report.AnalysisContextReportPublisher; -import org.sonar.batch.repository.ProjectSettingsRepo; +import org.sonar.batch.repository.ProjectRepositories; /** * @since 2.12 */ public class ModuleSettings extends Settings { - private final ProjectSettingsRepo projectSettingsRepo; + private final ProjectRepositories projectSettingsRepo; private final DefaultAnalysisMode analysisMode; - public ModuleSettings(GlobalSettings batchSettings, ProjectDefinition moduleDefinition, ProjectSettingsRepo projectSettingsRepo, + public ModuleSettings(GlobalSettings batchSettings, ProjectDefinition moduleDefinition, ProjectRepositories projectSettingsRepo, DefaultAnalysisMode analysisMode, AnalysisContextReportPublisher contextReportPublisher) { super(batchSettings.getDefinitions()); this.projectSettingsRepo = projectSettingsRepo; diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java index 5c7bbb9e026..b882d231243 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java @@ -19,17 +19,15 @@ */ package org.sonar.batch.scan; -import org.sonar.batch.cache.ProjectPersistentCacheProvider; +import org.sonar.batch.repository.ProjectRepositoriesProvider; +import org.sonar.batch.repository.ProjectRepositories; +import org.sonar.batch.cache.ProjectPersistentCacheProvider; import org.sonar.batch.issue.tracking.LocalIssueTracking; import org.sonar.batch.issue.tracking.IssueTransition; -import org.sonar.batch.repository.DefaultProjectRepositoriesFactory; import org.sonar.batch.repository.QualityProfileProvider; import org.sonar.batch.repository.DefaultQualityProfileLoader; import org.sonar.batch.repository.QualityProfileLoader; -import org.sonar.batch.repository.ProjectSettingsLoader; -import org.sonar.batch.repository.DefaultProjectSettingsLoader; -import org.sonar.batch.repository.ProjectSettingsProvider; import org.sonar.batch.rule.DefaultActiveRulesLoader; import org.sonar.batch.rule.ActiveRulesLoader; import org.sonar.batch.analysis.DefaultAnalysisMode; @@ -131,7 +129,6 @@ public class ProjectScanContainer extends ComponentContainer { props, DefaultAnalysisMode.class, ProjectReactorBuilder.class, - DefaultProjectRepositoriesFactory.class, new MutableProjectReactorProvider(), new ImmutableProjectReactorProvider(), ProjectBuildersExecutor.class, @@ -151,7 +148,7 @@ public class ProjectScanContainer extends ComponentContainer { Caches.class, BatchComponentCache.class, DefaultIssueCallback.class, - new ProjectSettingsProvider(), + new ProjectRepositoriesProvider(), new ProjectPersistentCacheProvider(), // temp @@ -211,7 +208,6 @@ public class ProjectScanContainer extends ComponentContainer { addIfMissing(DefaultActiveRulesLoader.class, ActiveRulesLoader.class); addIfMissing(DefaultQualityProfileLoader.class, QualityProfileLoader.class); addIfMissing(DefaultProjectRepositoriesLoader.class, ProjectRepositoriesLoader.class); - addIfMissing(DefaultProjectSettingsLoader.class, ProjectSettingsLoader.class); } private void addIssueTrackingComponents() { @@ -227,7 +223,7 @@ public class ProjectScanContainer extends ComponentContainer { return false; } - return getComponentByType(DefaultProjectRepositoriesFactory.class).create().lastAnalysisDate() != null; + return getComponentByType(ProjectRepositories.class).lastAnalysisDate() != null; } private void addBatchExtensions() { diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectSettings.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectSettings.java index df9b5135100..c022541bd96 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectSettings.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectSettings.java @@ -19,7 +19,7 @@ */ package org.sonar.batch.scan; -import org.sonar.batch.repository.ProjectSettingsRepo; +import org.sonar.batch.repository.ProjectRepositories; import org.sonar.batch.analysis.DefaultAnalysisMode; import com.google.common.collect.ImmutableMap; @@ -45,11 +45,11 @@ public class ProjectSettings extends Settings { ); private final GlobalSettings globalSettings; - private final ProjectSettingsRepo projectRepositories; + private final ProjectRepositories projectRepositories; private final DefaultAnalysisMode mode; public ProjectSettings(ProjectReactor reactor, GlobalSettings globalSettings, PropertyDefinitions propertyDefinitions, - ProjectSettingsRepo projectRepositories, DefaultAnalysisMode mode) { + ProjectRepositories projectRepositories, DefaultAnalysisMode mode) { super(propertyDefinitions); this.mode = mode; getEncryption().setPathToSecretKey(globalSettings.getString(CoreProperties.ENCRYPTION_SECRET_KEY_PATH)); diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/StatusDetection.java b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/StatusDetection.java index 51232ec5701..54270befcca 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/StatusDetection.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/StatusDetection.java @@ -19,17 +19,17 @@ */ package org.sonar.batch.scan.filesystem; -import org.sonar.batch.repository.ProjectSettingsRepo; +import org.sonar.batch.repository.FileData; +import org.sonar.batch.repository.ProjectRepositories; import org.apache.commons.lang.StringUtils; import org.sonar.api.batch.fs.InputFile; -import org.sonar.batch.protocol.input.FileData; class StatusDetection { - private final ProjectSettingsRepo projectSettings; + private final ProjectRepositories projectSettings; - StatusDetection(ProjectSettingsRepo projectSettings) { + StatusDetection(ProjectRepositories projectSettings) { this.projectSettings = projectSettings; } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/StatusDetectionFactory.java b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/StatusDetectionFactory.java index f372b171df2..4ee5057c9ff 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/StatusDetectionFactory.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/StatusDetectionFactory.java @@ -19,16 +19,16 @@ */ package org.sonar.batch.scan.filesystem; -import org.sonar.batch.repository.ProjectSettingsRepo; +import org.sonar.batch.repository.ProjectRepositories; import org.sonar.api.batch.BatchSide; @BatchSide public class StatusDetectionFactory { - private final ProjectSettingsRepo projectReferentials; + private final ProjectRepositories projectReferentials; - public StatusDetectionFactory(ProjectSettingsRepo projectReferentials) { + public StatusDetectionFactory(ProjectRepositories projectReferentials) { this.projectReferentials = projectReferentials; } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scm/ScmSensor.java b/sonar-batch/src/main/java/org/sonar/batch/scm/ScmSensor.java index 7d24836072d..8ff079170e8 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scm/ScmSensor.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scm/ScmSensor.java @@ -19,7 +19,9 @@ */ package org.sonar.batch.scm; -import org.sonar.batch.repository.ProjectSettingsRepo; +import org.sonar.batch.repository.FileData; + +import org.sonar.batch.repository.ProjectRepositories; import java.util.LinkedList; import java.util.List; @@ -35,7 +37,6 @@ import org.sonar.api.batch.sensor.Sensor; import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.batch.sensor.SensorDescriptor; import org.sonar.batch.index.BatchComponentCache; -import org.sonar.batch.protocol.input.FileData; import org.sonar.batch.report.ReportPublisher; import org.sonar.batch.scan.filesystem.InputPathCache; @@ -46,12 +47,12 @@ public final class ScmSensor implements Sensor { private final ProjectDefinition projectDefinition; private final ScmConfiguration configuration; private final FileSystem fs; - private final ProjectSettingsRepo projectSettings; + private final ProjectRepositories projectSettings; private final BatchComponentCache resourceCache; private final ReportPublisher publishReportJob; public ScmSensor(ProjectDefinition projectDefinition, ScmConfiguration configuration, - ProjectSettingsRepo projectSettings, FileSystem fs, InputPathCache inputPathCache, BatchComponentCache resourceCache, + ProjectRepositories projectSettings, FileSystem fs, InputPathCache inputPathCache, BatchComponentCache resourceCache, ReportPublisher publishReportJob) { this.projectDefinition = projectDefinition; this.configuration = configuration; @@ -98,7 +99,7 @@ public final class ScmSensor implements Sensor { addIfNotEmpty(filesToBlame, f); } else { FileData fileData = projectSettings.fileData(projectDefinition.getKeyWithBranch(), f.relativePath()); - if (f.status() != Status.SAME || fileData == null || fileData.needBlame()) { + if (f.status() != Status.SAME || fileData == null || fileData.revision() != null) { addIfNotEmpty(filesToBlame, f); } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/cache/NonAssociatedCacheSynchronizerTest.java b/sonar-batch/src/test/java/org/sonar/batch/cache/NonAssociatedCacheSynchronizerTest.java index 3d58f3d3daa..4181b2f16b2 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/cache/NonAssociatedCacheSynchronizerTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/cache/NonAssociatedCacheSynchronizerTest.java @@ -20,15 +20,15 @@ package org.sonar.batch.cache; import static org.mockito.Mockito.when; -import org.sonar.batch.protocol.input.ActiveRule; + +import org.sonarqube.ws.Rules.Rule; + +import org.sonarqube.ws.QualityProfiles.WsSearchResponse.QualityProfile; import com.google.common.collect.ImmutableList; -import org.sonar.batch.protocol.input.QProfile; import org.junit.Test; import java.util.Date; -import static org.mockito.Mockito.mock; - import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import org.mockito.MockitoAnnotations; @@ -51,11 +51,11 @@ public class NonAssociatedCacheSynchronizerTest { public void setUp() { MockitoAnnotations.initMocks(this); - QProfile pf = new QProfile("profile", "profile", "lang", new Date(1000)); - ActiveRule ar = mock(ActiveRule.class); + QualityProfile pf = QualityProfile.newBuilder().setKey("profile").setName("profile").setLanguage("lang").build(); + Rule ar = Rule.newBuilder().build(); - when(qualityProfileLoader.load(null, null)).thenReturn(ImmutableList.of(pf)); - when(activeRulesLoader.load(ImmutableList.of("profile"), null)).thenReturn(ImmutableList.of(ar)); + when(qualityProfileLoader.loadDefault(null)).thenReturn(ImmutableList.of(pf)); + when(activeRulesLoader.load("profile", null)).thenReturn(ImmutableList.of(ar)); synchronizer = new NonAssociatedCacheSynchronizer(qualityProfileLoader, activeRulesLoader, cacheStatus); } @@ -83,8 +83,8 @@ public class NonAssociatedCacheSynchronizerTest { private void checkSync() { verify(cacheStatus).getSyncStatus(); verify(cacheStatus).save(); - verify(qualityProfileLoader).load(null, null); - verify(activeRulesLoader).load(ImmutableList.of("profile"), null); + verify(qualityProfileLoader).loadDefault(null); + verify(activeRulesLoader).load("profile", null); verifyNoMoreInteractions(qualityProfileLoader, activeRulesLoader); } diff --git a/sonar-batch/src/test/java/org/sonar/batch/cache/ProjectCacheSynchronizerTest.java b/sonar-batch/src/test/java/org/sonar/batch/cache/ProjectCacheSynchronizerTest.java index d91f154ee79..0d46388d01c 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/cache/ProjectCacheSynchronizerTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/cache/ProjectCacheSynchronizerTest.java @@ -19,36 +19,8 @@ */ package org.sonar.batch.cache; -import static org.mockito.Mockito.when; -import org.sonar.batch.repository.ProjectRepositoriesFactory; -import org.sonar.batch.repository.DefaultProjectRepositoriesFactory; -import org.junit.Rule; -import org.junit.rules.ExpectedException; -import org.sonar.batch.repository.ProjectSettingsRepo; import com.google.common.base.Function; import com.google.common.collect.ImmutableList; -import org.sonar.batch.protocol.input.ActiveRule; -import org.sonar.batch.protocol.input.QProfile; -import org.apache.commons.lang.mutable.MutableBoolean; -import org.sonar.batch.repository.DefaultProjectSettingsLoader; -import org.sonar.batch.rule.DefaultActiveRulesLoader; -import org.sonar.batch.repository.DefaultQualityProfileLoader; -import org.sonar.batch.repository.ProjectSettingsLoader; -import org.sonar.batch.rule.ActiveRulesLoader; -import org.sonar.batch.repository.QualityProfileLoader; -import org.sonar.batch.analysis.DefaultAnalysisMode; -import org.sonar.batch.analysis.AnalysisProperties; -import org.sonar.batch.protocol.input.ProjectRepositories; -import org.sonar.batch.repository.DefaultServerIssuesLoader; -import org.sonar.batch.repository.DefaultProjectRepositoriesLoader; -import org.sonar.api.batch.bootstrap.ProjectReactor; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.util.Date; -import java.util.HashMap; import org.apache.commons.lang.mutable.MutableBoolean; import org.junit.Before; import org.junit.Rule; @@ -60,23 +32,23 @@ import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.bootstrap.ProjectReactor; import org.sonar.batch.analysis.AnalysisProperties; import org.sonar.batch.analysis.DefaultAnalysisMode; -import org.sonar.batch.protocol.input.ActiveRule; -import org.sonar.batch.protocol.input.ProjectRepositories; -import org.sonar.batch.protocol.input.QProfile; -import org.sonar.batch.repository.DefaultProjectRepositoriesFactory; import org.sonar.batch.repository.DefaultProjectRepositoriesLoader; -import org.sonar.batch.repository.DefaultProjectSettingsLoader; import org.sonar.batch.repository.DefaultQualityProfileLoader; import org.sonar.batch.repository.DefaultServerIssuesLoader; -import org.sonar.batch.repository.ProjectRepositoriesFactory; +import org.sonar.batch.repository.ProjectRepositories; import org.sonar.batch.repository.ProjectRepositoriesLoader; -import org.sonar.batch.repository.ProjectSettingsLoader; -import org.sonar.batch.repository.ProjectSettingsRepo; import org.sonar.batch.repository.QualityProfileLoader; import org.sonar.batch.repository.ServerIssuesLoader; import org.sonar.batch.repository.user.UserRepositoryLoader; import org.sonar.batch.rule.ActiveRulesLoader; import org.sonar.batch.rule.DefaultActiveRulesLoader; +import org.sonarqube.ws.QualityProfiles.WsSearchResponse.QualityProfile; + +import java.io.IOException; +import java.util.Date; +import java.util.HashMap; + +import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; @@ -87,8 +59,6 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; public class ProjectCacheSynchronizerTest { - private static final String BATCH_PROJECT = "/scanner/project?key=org.codehaus.sonar-plugins%3Asonar-scm-git-plugin&preview=true"; - private static final String ISSUES = "/scanner/issues?key=org.codehaus.sonar-plugins%3Asonar-scm-git-plugin"; private static final String PROJECT_KEY = "org.codehaus.sonar-plugins:sonar-scm-git-plugin"; @Rule @@ -104,135 +74,76 @@ public class ProjectCacheSynchronizerTest { private DefaultAnalysisMode analysisMode; @Mock private AnalysisProperties properties; - @Mock - private WSLoader ws; - private ProjectRepositoriesLoader projectRepositoryLoader; private ServerIssuesLoader issuesLoader; private UserRepositoryLoader userRepositoryLoader; private QualityProfileLoader qualityProfileLoader; private ActiveRulesLoader activeRulesLoader; - private ProjectSettingsLoader projectSettingsLoader; + private ProjectRepositoriesLoader projectRepositoriesLoader; @Before public void setUp() throws IOException { MockitoAnnotations.initMocks(this); - String batchProject = getResourceAsString("batch_project.json"); - InputStream issues = getResourceAsInputStream("batch_issues.protobuf"); - - when(ws.loadString(BATCH_PROJECT)).thenReturn(new WSLoaderResult<>(batchProject, false)); - when(ws.loadStream(ISSUES)).thenReturn(new WSLoaderResult<>(issues, false)); - when(analysisMode.isIssues()).thenReturn(true); when(properties.properties()).thenReturn(new HashMap<String, String>()); } - private ProjectCacheSynchronizer create(ProjectRepositories projectRepositories) { - if (projectRepositories == null) { - projectRepositoryLoader = new DefaultProjectRepositoriesLoader(ws, analysisMode); - } else { - projectRepositoryLoader = mock(ProjectRepositoriesLoader.class); - when(projectRepositoryLoader.load(anyString(), anyString(), any(MutableBoolean.class))).thenReturn(projectRepositories); - } - - ProjectReactor reactor = mock(ProjectReactor.class); - ProjectDefinition root = mock(ProjectDefinition.class); - when(root.getKeyWithBranch()).thenReturn(PROJECT_KEY); - when(reactor.getRoot()).thenReturn(root); - - ProjectRepositoriesFactory projectRepositoriesFactory = new DefaultProjectRepositoriesFactory(reactor, analysisMode, projectRepositoryLoader, properties); - - issuesLoader = new DefaultServerIssuesLoader(ws); - userRepositoryLoader = new UserRepositoryLoader(ws); - qualityProfileLoader = new DefaultQualityProfileLoader(projectRepositoriesFactory); - activeRulesLoader = new DefaultActiveRulesLoader(projectRepositoriesFactory); - projectSettingsLoader = new DefaultProjectSettingsLoader(projectRepositoriesFactory); - - return new ProjectCacheSynchronizer(qualityProfileLoader, projectSettingsLoader, activeRulesLoader, issuesLoader, userRepositoryLoader, cacheStatus); - } - - private ProjectCacheSynchronizer createMockedLoaders(Date lastAnalysisDate) { + private ProjectCacheSynchronizer createMockedLoaders(boolean projectExists, Date lastAnalysisDate) { issuesLoader = mock(DefaultServerIssuesLoader.class); userRepositoryLoader = mock(UserRepositoryLoader.class); qualityProfileLoader = mock(DefaultQualityProfileLoader.class); activeRulesLoader = mock(DefaultActiveRulesLoader.class); - projectSettingsLoader = mock(DefaultProjectSettingsLoader.class); + projectRepositoriesLoader = mock(DefaultProjectRepositoriesLoader.class); - QProfile pf = new QProfile("profile", "profile", "lang", new Date(1000)); - ActiveRule ar = mock(ActiveRule.class); - ProjectSettingsRepo repo = mock(ProjectSettingsRepo.class); + QualityProfile pf = QualityProfile.newBuilder().setKey("profile").setName("profile").setLanguage("lang").build(); + org.sonarqube.ws.Rules.Rule ar = org.sonarqube.ws.Rules.Rule.newBuilder().build(); + ProjectRepositories repo = mock(ProjectRepositories.class); - when(qualityProfileLoader.load(PROJECT_KEY, null)).thenReturn(ImmutableList.of(pf)); - when(activeRulesLoader.load(ImmutableList.of("profile"), PROJECT_KEY)).thenReturn(ImmutableList.of(ar)); + when(qualityProfileLoader.load(PROJECT_KEY, null, null)).thenReturn(ImmutableList.of(pf)); + when(qualityProfileLoader.loadDefault(null)).thenReturn(ImmutableList.of(pf)); + when(activeRulesLoader.load("profile", null)).thenReturn(ImmutableList.of(ar)); when(repo.lastAnalysisDate()).thenReturn(lastAnalysisDate); - when(projectSettingsLoader.load(anyString(), any(MutableBoolean.class))).thenReturn(repo); - - return new ProjectCacheSynchronizer(qualityProfileLoader, projectSettingsLoader, activeRulesLoader, issuesLoader, userRepositoryLoader, cacheStatus); - } - - @Test - public void testSync() { - ProjectCacheSynchronizer sync = create(null); - - sync.load(PROJECT_KEY, false); - - verify(ws).loadString(BATCH_PROJECT); - verify(ws).loadStream(ISSUES); - verifyNoMoreInteractions(ws); + when(repo.exists()).thenReturn(projectExists); + when(projectRepositoriesLoader.load(anyString(), anyBoolean(), any(MutableBoolean.class))).thenReturn(repo); - verify(cacheStatus).save(); + return new ProjectCacheSynchronizer(qualityProfileLoader, projectRepositoriesLoader, activeRulesLoader, issuesLoader, userRepositoryLoader, cacheStatus); } @Test public void testLoadersUsage() { - ProjectCacheSynchronizer synchronizer = createMockedLoaders(new Date()); + ProjectCacheSynchronizer synchronizer = createMockedLoaders(true, new Date()); synchronizer.load(PROJECT_KEY, false); verify(issuesLoader).load(eq(PROJECT_KEY), any(Function.class)); - verify(qualityProfileLoader).load(PROJECT_KEY, null); - verify(activeRulesLoader).load(ImmutableList.of("profile"), PROJECT_KEY); - verify(projectSettingsLoader).load(eq(PROJECT_KEY), any(MutableBoolean.class)); + verify(qualityProfileLoader).load(PROJECT_KEY, null, null); + verify(activeRulesLoader).load("profile", null); + verify(projectRepositoriesLoader).load(eq(PROJECT_KEY), eq(true), any(MutableBoolean.class)); - verifyNoMoreInteractions(issuesLoader, userRepositoryLoader, qualityProfileLoader, activeRulesLoader, projectSettingsLoader); + verifyNoMoreInteractions(issuesLoader, userRepositoryLoader, qualityProfileLoader, activeRulesLoader, projectRepositoriesLoader); } @Test public void testLoadersUsage_NoLastAnalysis() { - ProjectCacheSynchronizer synchronizer = createMockedLoaders(null); + ProjectCacheSynchronizer synchronizer = createMockedLoaders(true, null); synchronizer.load(PROJECT_KEY, false); - verify(projectSettingsLoader).load(eq(PROJECT_KEY), any(MutableBoolean.class)); + verify(projectRepositoriesLoader).load(eq(PROJECT_KEY), eq(true), any(MutableBoolean.class)); + verify(qualityProfileLoader).load(PROJECT_KEY, null, null); + verify(activeRulesLoader).load("profile", null); - verifyNoMoreInteractions(issuesLoader, userRepositoryLoader, qualityProfileLoader, activeRulesLoader, projectSettingsLoader); + verifyNoMoreInteractions(issuesLoader, userRepositoryLoader, qualityProfileLoader, activeRulesLoader, projectRepositoriesLoader); } @Test - public void testSyncNoLastAnalysis() { - ProjectRepositories mockedProjectRepositories = mock(ProjectRepositories.class); - when(mockedProjectRepositories.lastAnalysisDate()).thenReturn(null); - - ProjectCacheSynchronizer sync = create(mockedProjectRepositories); - sync.load(PROJECT_KEY, true); - verify(cacheStatus).save(); - } - - @Test - public void testDontSyncIfNotForce() { - when(cacheStatus.getSyncStatus()).thenReturn(new Date()); - ProjectCacheSynchronizer sync = create(null); - sync.load(PROJECT_KEY, false); - - verifyNoMoreInteractions(ws); - } + public void testLoadersUsage_ProjectDoesntExist() { + ProjectCacheSynchronizer synchronizer = createMockedLoaders(false, null); + synchronizer.load(PROJECT_KEY, false); - private String getResourceAsString(String name) throws IOException { - URL resource = this.getClass().getResource(getClass().getSimpleName() + "/" + name); - return Resources.toString(resource, StandardCharsets.UTF_8); - } + verify(projectRepositoriesLoader).load(eq(PROJECT_KEY), eq(true), any(MutableBoolean.class)); + verify(qualityProfileLoader).loadDefault(null); + verify(activeRulesLoader).load("profile", null); - private InputStream getResourceAsInputStream(String name) throws IOException { - URL resource = this.getClass().getResource(getClass().getSimpleName() + "/" + name); - return Resources.asByteSource(resource).openBufferedStream(); + verifyNoMoreInteractions(issuesLoader, userRepositoryLoader, qualityProfileLoader, activeRulesLoader, projectRepositoriesLoader); } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/BatchMediumTester.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/BatchMediumTester.java index 9016442b345..ef508dcb553 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/BatchMediumTester.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/BatchMediumTester.java @@ -19,6 +19,15 @@ */ package org.sonar.batch.mediumtest; +import org.sonar.batch.repository.FileData; + +import org.sonar.api.utils.DateUtils; +import com.google.common.collect.Table; +import com.google.common.collect.HashBasedTable; +import org.sonar.batch.repository.ProjectRepositories; +import org.sonar.batch.rule.ActiveRulesLoader; +import org.sonarqube.ws.QualityProfiles.WsSearchResponse.QualityProfile; +import org.sonar.batch.repository.QualityProfileLoader; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.mutable.MutableBoolean; @@ -56,11 +65,8 @@ import org.sonar.batch.bootstrapper.Batch; import org.sonar.batch.bootstrapper.EnvironmentInformation; import org.sonar.batch.bootstrapper.LogOutput; import org.sonar.batch.issue.tracking.ServerLineHashesLoader; -import org.sonar.batch.protocol.input.ActiveRule; import org.sonar.batch.protocol.input.BatchInput.ServerIssue; -import org.sonar.batch.protocol.input.FileData; import org.sonar.batch.protocol.input.GlobalRepositories; -import org.sonar.batch.protocol.input.ProjectRepositories; import org.sonar.batch.report.ReportPublisher; import org.sonar.batch.repository.GlobalRepositoriesLoader; import org.sonar.batch.repository.ProjectRepositoriesLoader; @@ -108,7 +114,7 @@ public class BatchMediumTester { builder.bootstrapProperties.put(MEDIUM_TEST_ENABLED, "true"); builder.bootstrapProperties.put(ReportPublisher.KEEP_REPORT_PROP_KEY, "true"); builder.bootstrapProperties.put(CoreProperties.WORKING_DIRECTORY, workingDir.toString()); - builder.bootstrapProperties.put(CoreProperties.GLOBAL_WORKING_DIRECTORY, globalWorkingDir.toString()); + builder.bootstrapProperties.put("sonar.userHome", globalWorkingDir.toString()); return builder; } @@ -120,7 +126,8 @@ public class BatchMediumTester { private final FakeServerLineHashesLoader serverLineHashes = new FakeServerLineHashesLoader(); private final Map<String, String> bootstrapProperties = new HashMap<>(); private final FakeRulesLoader rulesLoader = new FakeRulesLoader(); - private final FakeProjectCacheStatus projectCacheStatus = new FakeProjectCacheStatus(); + private final FakeQualityProfileLoader qualityProfiles = new FakeQualityProfileLoader(); + private final FakeActiveRulesLoader activeRules = new FakeActiveRulesLoader(); private boolean associated = true; private LogOutput logOutput = null; @@ -161,7 +168,7 @@ public class BatchMediumTester { } public BatchMediumTesterBuilder addQProfile(String language, String name) { - projectRefProvider.addQProfile(language, name); + qualityProfiles.add(language, name); return this; } @@ -202,7 +209,7 @@ public class BatchMediumTester { } public BatchMediumTesterBuilder setPreviousAnalysisDate(Date previousAnalysis) { - projectRefProvider.ref.setLastAnalysisDate(previousAnalysis); + projectRefProvider.setLastAnalysisDate(previousAnalysis); return this; } @@ -211,8 +218,33 @@ public class BatchMediumTester { return this; } - public BatchMediumTesterBuilder activateRule(ActiveRule activeRule) { - projectRefProvider.addActiveRule(activeRule); + public BatchMediumTesterBuilder activateRule(org.sonarqube.ws.Rules.Rule activeRule) { + activeRules.addActiveRule(activeRule); + return this; + } + + public BatchMediumTesterBuilder addActiveRule(String repositoryKey, String ruleKey, @Nullable String templateRuleKey, String name, @Nullable String severity, + @Nullable String internalKey, @Nullable String languag) { + + org.sonarqube.ws.Rules.Rule.Builder builder = org.sonarqube.ws.Rules.Rule.newBuilder(); + builder.setRepo(repositoryKey); + builder.setKey(ruleKey); + builder.setName(name); + + if (templateRuleKey != null) { + builder.setTemplateKey(templateRuleKey); + } + if (languag != null) { + builder.setLang(languag); + } + if (internalKey != null) { + builder.setInternalKey(internalKey); + } + if (severity != null) { + builder.setSeverity(severity); + } + + activeRules.addActiveRule(builder.build()); return this; } @@ -262,9 +294,10 @@ public class BatchMediumTester { new EnvironmentInformation("mediumTest", "1.0"), builder.pluginInstaller, builder.globalRefProvider, + builder.qualityProfiles, builder.rulesLoader, - builder.projectCacheStatus, builder.projectRefProvider, + builder.activeRules, new DefaultDebtModel()) .setBootstrapProperties(builder.bootstrapProperties) .setLogOutput(builder.logOutput); @@ -346,6 +379,19 @@ public class BatchMediumTester { } } + private static class FakeActiveRulesLoader implements ActiveRulesLoader { + private List<org.sonarqube.ws.Rules.Rule> activeRules = new LinkedList<>(); + + public void addActiveRule(org.sonarqube.ws.Rules.Rule activeRule) { + this.activeRules.add(activeRule); + } + + @Override + public List<org.sonarqube.ws.Rules.Rule> load(String qualityProfileKey, MutableBoolean fromCache) { + return activeRules; + } + } + private static class FakeGlobalRepositoriesLoader implements GlobalRepositoriesLoader { private int metricId = 1; @@ -382,34 +428,49 @@ public class BatchMediumTester { private static class FakeProjectRepositoriesLoader implements ProjectRepositoriesLoader { - private ProjectRepositories ref = new ProjectRepositories(); + private Table<String, String, FileData> fileDataTable = HashBasedTable.create(); + private Date lastAnalysisDate; @Override - public ProjectRepositories load(String projectKey, @Nullable String sonarProfile, @Nullable MutableBoolean fromCache) { - return ref; + public ProjectRepositories load(String projectKey, boolean isIssuesMode, @Nullable MutableBoolean fromCache) { + Table<String, String, String> settings = HashBasedTable.create(); + return new ProjectRepositories(settings, fileDataTable, lastAnalysisDate); } - public FakeProjectRepositoriesLoader addQProfile(String language, String name) { - // Use a fixed date to allow assertions - ref.addQProfile(new org.sonar.batch.protocol.input.QProfile(name, name, language, new Date(1234567891212L))); + public FakeProjectRepositoriesLoader addFileData(String moduleKey, String path, FileData fileData) { + fileDataTable.put(moduleKey, path, fileData); return this; } - public FakeProjectRepositoriesLoader addActiveRule(ActiveRule activeRule) { - ref.addActiveRule(activeRule); + public FakeProjectRepositoriesLoader setLastAnalysisDate(Date d) { + lastAnalysisDate = d; return this; } - public FakeProjectRepositoriesLoader addFileData(String moduleKey, String path, FileData fileData) { - ref.addFileData(moduleKey, path, fileData); - return this; + } + + private static class FakeQualityProfileLoader implements QualityProfileLoader { + + private List<QualityProfile> qualityProfiles = new LinkedList<>(); + + public void add(String language, String name) { + qualityProfiles.add(QualityProfile.newBuilder() + .setLanguage(language) + .setKey(name) + .setName(name) + .setRulesUpdatedAt(DateUtils.formatDateTime(new Date(1234567891212L))) + .build()); } - public FakeProjectRepositoriesLoader setLastAnalysisDate(Date d) { - ref.setLastAnalysisDate(d); - return this; + @Override + public List<QualityProfile> load(String projectKey, String profileName, MutableBoolean fromCache) { + return qualityProfiles; } + @Override + public List<QualityProfile> loadDefault(MutableBoolean fromCache) { + return qualityProfiles; + } } private static class FakeServerIssuesLoader implements ServerIssuesLoader { @@ -429,23 +490,6 @@ public class BatchMediumTester { } } - private static class FakeProjectCacheStatus implements ProjectCacheStatus { - - @Override - public void save() { - } - - @Override - public void delete() { - } - - @Override - public Date getSyncStatus() { - return new Date(); - } - - } - private static class FakeServerLineHashesLoader implements ServerLineHashesLoader { private Map<String, String[]> byKey = new HashMap<>(); diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/LogOutputRecorder.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/LogOutputRecorder.java new file mode 100644 index 00000000000..bcc2ab4611a --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/LogOutputRecorder.java @@ -0,0 +1,54 @@ +/* + * 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.mediumtest; + +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; + +import com.google.common.collect.Multimap; +import com.google.common.collect.HashMultimap; +import org.sonar.batch.bootstrapper.LogOutput; + +public class LogOutputRecorder implements LogOutput { + private Multimap<String, String> recordedByLevel = HashMultimap.create(); + private List<String> recorded = new LinkedList<>(); + private StringBuffer asString = new StringBuffer(); + + @Override + public void log(String formattedMessage, Level level) { + recordedByLevel.put(level.toString(), formattedMessage); + recorded.add(formattedMessage); + asString.append(formattedMessage).append("\n"); + } + + public Collection<String> getAll() { + return recorded; + } + + public Collection<String> get(String level) { + return recordedByLevel.get(level); + } + + public String getAsString() { + return asString.toString(); + } + +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/cache/CacheSyncTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/cache/CacheSyncTest.java index 0e20b4eed9f..41c5eda71cf 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/cache/CacheSyncTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/cache/CacheSyncTest.java @@ -19,16 +19,23 @@ */ package org.sonar.batch.mediumtest.cache; +import org.junit.rules.TemporaryFolder; + +import org.sonar.batch.mediumtest.TaskResult; +import org.sonar.batch.mediumtest.BatchMediumTester.TaskBuilder; +import org.sonar.batch.mediumtest.LogOutputRecorder; +import org.sonar.batch.repository.FileData; import com.google.common.collect.ImmutableMap; + import java.util.Date; + +import static org.assertj.core.api.Assertions.assertThat; import org.junit.After; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.sonar.api.CoreProperties; import org.sonar.batch.mediumtest.BatchMediumTester; -import org.sonar.batch.protocol.input.ActiveRule; -import org.sonar.batch.protocol.input.FileData; import org.sonar.xoo.XooPlugin; import org.sonar.xoo.rule.XooRulesDefinition; @@ -36,6 +43,9 @@ public class CacheSyncTest { @Rule public ExpectedException exception = ExpectedException.none(); + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + private BatchMediumTester tester; @After @@ -47,59 +57,99 @@ public class CacheSyncTest { } @Test + public void testExecuteTask() { + LogOutputRecorder logOutput = new LogOutputRecorder(); + + tester = BatchMediumTester.builder() + .bootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_ISSUES, + "sonar.verbose", "true")) + .registerPlugin("xoo", new XooPlugin()) + .addRules(new XooRulesDefinition()) + .addQProfile("lang", "name") + .addActiveRule("xoo", "OneIssuePerLine", null, "One issue per line", "MAJOR", "my/internal/key", "xoo") + .setPreviousAnalysisDate(new Date()) + .addFileData("test-project", "file1", new FileData("hash", "123456789")) + .setLogOutput(logOutput) + .build(); + + tester.start(); + executeTask(tester.newTask()); + assertThat(logOutput.getAsString()).contains("Cache for project [key] not found, synchronizing"); + } + + @Test public void testSyncFirstTime() { - FileData file1 = new FileData("hash", "123456789"); + LogOutputRecorder logOutput = new LogOutputRecorder(); tester = BatchMediumTester.builder() - .bootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_ISSUES)) + .bootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_ISSUES, + "sonar.verbose", "true")) .registerPlugin("xoo", new XooPlugin()) .addRules(new XooRulesDefinition()) .addQProfile("lang", "name") - .activateRule(new ActiveRule("xoo", "OneIssuePerLine", null, "One issue per line", "MAJOR", "my/internal/key", "xoo")) + .addActiveRule("xoo", "OneIssuePerLine", null, "One issue per line", "MAJOR", "my/internal/key", "xoo") .setPreviousAnalysisDate(new Date()) - .addFileData("test-project", "file1", file1) + .addFileData("test-project", "file1", new FileData("hash", "123456789")) + .setLogOutput(logOutput) .build(); tester.start(); tester.syncProject("test-project"); + assertThat(logOutput.getAsString()).contains("Cache for project [test-project] not found"); } @Test - public void testNonAssociated() { - FileData file1 = new FileData("hash", "123456789"); + public void testSyncTwice() { + LogOutputRecorder logOutput = new LogOutputRecorder(); tester = BatchMediumTester.builder() - .bootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_ISSUES)) + .bootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_ISSUES, + "sonar.verbose", "true")) .registerPlugin("xoo", new XooPlugin()) .addRules(new XooRulesDefinition()) .addQProfile("lang", "name") - .activateRule(new ActiveRule("xoo", "OneIssuePerLine", null, "One issue per line", "MAJOR", "my/internal/key", "xoo")) + .addActiveRule("xoo", "OneIssuePerLine", null, "One issue per line", "MAJOR", "my/internal/key", "xoo") .setPreviousAnalysisDate(new Date()) - .addFileData("test-project", "file1", file1) + .addFileData("test-project", "file1", new FileData("hash", "123456789")) + .setLogOutput(logOutput) .build(); tester.start(); - tester.syncProject(null); + tester.syncProject("test-project"); + tester.syncProject("test-project"); + assertThat(logOutput.getAsString()).contains("-- Found project [test-project]"); + assertThat(logOutput.getAsString()).contains("not found, synchronizing data"); + assertThat(logOutput.getAsString()).contains("], synchronizing data.."); } @Test - public void testNoQProfile() { - FileData file1 = new FileData("hash", "123456789"); + public void testNonAssociated() { + LogOutputRecorder logOutput = new LogOutputRecorder(); tester = BatchMediumTester.builder() .bootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_ISSUES)) .registerPlugin("xoo", new XooPlugin()) .addRules(new XooRulesDefinition()) - .activateRule(new ActiveRule("xoo", "OneIssuePerLine", null, "One issue per line", "MAJOR", "my/internal/key", "xoo")) + .addQProfile("lang", "name") + .addActiveRule("xoo", "OneIssuePerLine", null, "One issue per line", "MAJOR", "my/internal/key", "xoo") .setPreviousAnalysisDate(new Date()) - .addFileData("test-project", "file1", file1) + .addFileData("test-project", "file1", new FileData("hash", "123456789")) + .setLogOutput(logOutput) .build(); tester.start(); + tester.syncProject(null); - exception.expect(IllegalStateException.class); - exception.expectMessage("No quality"); - tester.syncProject("test-project"); + assertThat(logOutput.getAsString()).contains("Cache not found, synchronizing data"); + } + + private TaskResult executeTask(TaskBuilder builder) { + builder.property("sonar.projectKey", "key"); + builder.property("sonar.projectVersion", "1.0"); + builder.property("sonar.projectName", "key"); + builder.property("sonar.projectBaseDir", temp.getRoot().getAbsolutePath()); + builder.property("sonar.sources", temp.getRoot().getAbsolutePath()); + return builder.start(); } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/deprecated/DeprecatedApiMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/deprecated/DeprecatedApiMediumTest.java index a84b0bda342..7e8cdbcaf95 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/deprecated/DeprecatedApiMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/deprecated/DeprecatedApiMediumTest.java @@ -29,7 +29,6 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.batch.mediumtest.BatchMediumTester; import org.sonar.batch.mediumtest.TaskResult; -import org.sonar.batch.protocol.input.ActiveRule; import org.sonar.xoo.XooPlugin; import org.sonar.xoo.rule.XooRulesDefinition; @@ -45,7 +44,7 @@ public class DeprecatedApiMediumTest { .registerPlugin("xoo", new XooPlugin()) .addRules(new XooRulesDefinition()) .addDefaultQProfile("xoo", "Sonar Way") - .activateRule(new ActiveRule("xoo", "DeprecatedResourceApi", null, "One issue per line", "MAJOR", null, "xoo")) + .addActiveRule("xoo", "DeprecatedResourceApi", null, "One issue per line", "MAJOR", null, "xoo") .build(); @Before diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/fs/ProjectBuilderMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/fs/ProjectBuilderMediumTest.java index 917ac570c77..119aa973416 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/fs/ProjectBuilderMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/fs/ProjectBuilderMediumTest.java @@ -31,7 +31,6 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.batch.mediumtest.BatchMediumTester; import org.sonar.batch.mediumtest.TaskResult; -import org.sonar.batch.protocol.input.ActiveRule; import org.sonar.batch.protocol.output.BatchReport.Issue; import org.sonar.xoo.XooPlugin; import org.sonar.xoo.rule.XooRulesDefinition; @@ -48,7 +47,7 @@ public class ProjectBuilderMediumTest { .addRules(new XooRulesDefinition()) .addDefaultQProfile("xoo", "Sonar Way") .setPreviousAnalysisDate(new Date()) - .activateRule(new ActiveRule("xoo", "OneIssuePerLine", null, "One issue per line", "MAJOR", "OneIssuePerLine.internal", "xoo")) + .addActiveRule("xoo", "OneIssuePerLine", null, "One issue per line", "MAJOR", "OneIssuePerLine.internal", "xoo") .build(); @Before diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/fs/RandomFsAccessMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/fs/RandomFsAccessMediumTest.java index 7fcc91ecaac..92f7257d19e 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/fs/RandomFsAccessMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/fs/RandomFsAccessMediumTest.java @@ -33,7 +33,6 @@ import org.junit.rules.TemporaryFolder; import org.sonar.batch.mediumtest.BatchMediumTester; import org.sonar.batch.mediumtest.Benchmark; import org.sonar.batch.mediumtest.TaskResult; -import org.sonar.batch.protocol.input.ActiveRule; import org.sonar.batch.protocol.output.BatchReport.Issue; import org.sonar.xoo.XooPlugin; import org.sonar.xoo.rule.XooRulesDefinition; @@ -52,7 +51,7 @@ public class RandomFsAccessMediumTest { .registerPlugin("xoo", new XooPlugin()) .addDefaultQProfile("xoo", "Sonar Way") .addRules(new XooRulesDefinition()) - .activateRule(new ActiveRule("xoo", "RandomAccessIssue", null, "One issue per line", "MAJOR", null, "xoo")) + .addActiveRule("xoo", "RandomAccessIssue", null, "One issue per line", "MAJOR", null, "xoo") .build(); @Before diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/ChecksMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/ChecksMediumTest.java index 6b43beeb609..488c56ae7bc 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/ChecksMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/ChecksMediumTest.java @@ -19,10 +19,18 @@ */ package org.sonar.batch.mediumtest.issues; +import org.sonarqube.ws.Rules.Rule.Param; + +import org.sonarqube.ws.Rules.Rule.Params; + +import javax.annotation.Nullable; + import com.google.common.collect.ImmutableMap; + import java.io.File; import java.io.IOException; import java.util.List; + import org.apache.commons.io.FileUtils; import org.junit.After; import org.junit.Before; @@ -30,11 +38,9 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.batch.mediumtest.BatchMediumTester; import org.sonar.batch.mediumtest.TaskResult; -import org.sonar.batch.protocol.input.ActiveRule; import org.sonar.batch.protocol.output.BatchReport.Issue; import org.sonar.xoo.XooPlugin; import org.sonar.xoo.rule.XooRulesDefinition; - import static org.assertj.core.api.Assertions.assertThat; public class ChecksMediumTest { @@ -48,8 +54,8 @@ public class ChecksMediumTest { .addDefaultQProfile("xoo", "Sonar Way") .addRule("TemplateRule_1234", "xoo", "TemplateRule_1234", "A template rule") .addRule("TemplateRule_1235", "xoo", "TemplateRule_1235", "Another template rule") - .activateRule(new ActiveRule("xoo", "TemplateRule_1234", "TemplateRule", "A template rule", "MAJOR", null, "xoo").addParam("line", "1")) - .activateRule(new ActiveRule("xoo", "TemplateRule_1235", "TemplateRule", "Another template rule", "MAJOR", null, "xoo").addParam("line", "2")) + .activateRule(createActiveRuleWithParam("xoo", "TemplateRule_1234", "TemplateRule", "A template rule", "MAJOR", null, "xoo", "line", "1")) + .activateRule(createActiveRuleWithParam("xoo", "TemplateRule_1235", "TemplateRule", "Another template rule", "MAJOR", null, "xoo", "line", "2")) .build(); @Before @@ -103,4 +109,29 @@ public class ChecksMediumTest { assertThat(foundIssueAtLine2).isTrue(); } + private org.sonarqube.ws.Rules.Rule createActiveRuleWithParam(String repositoryKey, String ruleKey, @Nullable String templateRuleKey, String name, @Nullable String severity, + @Nullable String internalKey, @Nullable String languag, String paramKey, String paramValue) { + org.sonarqube.ws.Rules.Rule.Builder builder = org.sonarqube.ws.Rules.Rule.newBuilder(); + builder.setRepo(repositoryKey); + builder.setKey(ruleKey); + if (templateRuleKey != null) { + builder.setTemplateKey(templateRuleKey); + } + if (languag != null) { + builder.setLang(languag); + } + if (internalKey != null) { + builder.setInternalKey(internalKey); + } + if (severity != null) { + builder.setSeverity(severity); + } + builder.setName(name); + + Param param = Param.newBuilder().setKey(paramKey).setDefaultValue(paramValue).build(); + Params params = Params.newBuilder().addParams(param).build(); + builder.setParams(params); + return builder.build(); + } + } diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesIssuesModeMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesIssuesModeMediumTest.java index e21eea304c4..24734b1ba06 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesIssuesModeMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesIssuesModeMediumTest.java @@ -26,7 +26,6 @@ import org.junit.Before; import com.google.common.collect.ImmutableMap; import org.sonar.api.CoreProperties; import org.sonar.batch.mediumtest.BatchMediumTester; -import org.sonar.batch.protocol.input.ActiveRule; import org.sonar.xoo.XooPlugin; import org.sonar.xoo.rule.XooRulesDefinition; import org.apache.commons.io.FileUtils; @@ -49,7 +48,7 @@ public class IssuesIssuesModeMediumTest { .addDefaultQProfile("xoo", "Sonar Way") .addRules(new XooRulesDefinition()) .bootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_ISSUES)) - .activateRule(new ActiveRule("xoo", "OneIssuePerLine", null, "One issue per line", "MAJOR", "OneIssuePerLine.internal", "xoo")) + .addActiveRule("xoo", "OneIssuePerLine", null, "One issue per line", "MAJOR", "OneIssuePerLine.internal", "xoo") .setLastBuildDate(new Date()) .build(); diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java index 97b7d3fe52e..2226796cc40 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java @@ -32,7 +32,6 @@ import org.junit.rules.TemporaryFolder; import org.sonar.batch.bootstrapper.IssueListener; import org.sonar.batch.mediumtest.BatchMediumTester; import org.sonar.batch.mediumtest.TaskResult; -import org.sonar.batch.protocol.input.ActiveRule; import org.sonar.batch.protocol.output.BatchReport.Issue; import org.sonar.xoo.XooPlugin; import org.sonar.xoo.rule.XooRulesDefinition; @@ -48,7 +47,7 @@ public class IssuesMediumTest { .registerPlugin("xoo", new XooPlugin()) .addDefaultQProfile("xoo", "Sonar Way") .addRules(new XooRulesDefinition()) - .activateRule(new ActiveRule("xoo", "OneIssuePerLine", null, "One issue per line", "MAJOR", "OneIssuePerLine.internal", "xoo")) + .addActiveRule("xoo", "OneIssuePerLine", null, "One issue per line", "MAJOR", "OneIssuePerLine.internal", "xoo") .build(); @Before diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesOnDirMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesOnDirMediumTest.java index a5cb1e212aa..4fad08a8c99 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesOnDirMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesOnDirMediumTest.java @@ -29,7 +29,6 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.batch.mediumtest.BatchMediumTester; import org.sonar.batch.mediumtest.TaskResult; -import org.sonar.batch.protocol.input.ActiveRule; import org.sonar.xoo.XooPlugin; import org.sonar.xoo.rule.XooRulesDefinition; @@ -44,7 +43,7 @@ public class IssuesOnDirMediumTest { .registerPlugin("xoo", new XooPlugin()) .addDefaultQProfile("xoo", "Sonar Way") .addRules(new XooRulesDefinition()) - .activateRule(new ActiveRule("xoo", "OneIssueOnDirPerFile", null, "One issue per line", "MINOR", "xoo", "xoo")) + .addActiveRule("xoo", "OneIssueOnDirPerFile", null, "One issue per line", "MINOR", "xoo", "xoo") .build(); @Before diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/MultilineIssuesMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/MultilineIssuesMediumTest.java index 3c452e5f53c..d02f0c4e813 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/MultilineIssuesMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/MultilineIssuesMediumTest.java @@ -28,7 +28,6 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.batch.mediumtest.BatchMediumTester; import org.sonar.batch.mediumtest.TaskResult; -import org.sonar.batch.protocol.input.ActiveRule; import org.sonar.batch.protocol.output.BatchReport.Flow; import org.sonar.batch.protocol.output.BatchReport.Issue; import org.sonar.batch.protocol.output.BatchReport.IssueLocation; @@ -46,7 +45,7 @@ public class MultilineIssuesMediumTest { .registerPlugin("xoo", new XooPlugin()) .addRules(new XooRulesDefinition()) .addDefaultQProfile("xoo", "Sonar Way") - .activateRule(new ActiveRule("xoo", "MultilineIssue", null, "Multinile Issue", "MAJOR", null, "xoo")) + .addActiveRule("xoo", "MultilineIssue", null, "Multinile Issue", "MAJOR", null, "xoo") .build(); private TaskResult result; diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issuesmode/EmptyFileTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issuesmode/EmptyFileTest.java index 03e11861bd0..586bba47896 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issuesmode/EmptyFileTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issuesmode/EmptyFileTest.java @@ -33,7 +33,6 @@ import org.sonar.api.CoreProperties; import org.sonar.api.utils.log.LogTester; import org.sonar.batch.mediumtest.BatchMediumTester; import org.sonar.batch.mediumtest.TaskResult; -import org.sonar.batch.protocol.input.ActiveRule; import org.sonar.xoo.XooPlugin; import java.io.File; @@ -54,7 +53,7 @@ public class EmptyFileTest { .registerPlugin("xoo", new XooPlugin()) .addRules(new XooRulesDefinition()) .addDefaultQProfile("xoo", "Sonar Way") - .activateRule(new ActiveRule("xoo", "OneIssuePerLine", null, "One issue per line", "MAJOR", "my/internal/key", "xoo")) + .addActiveRule("xoo", "OneIssuePerLine", null, "One issue per line", "MAJOR", "my/internal/key", "xoo") .setPreviousAnalysisDate(new Date()) .build(); diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issuesmode/IssueModeAndReportsMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issuesmode/IssueModeAndReportsMediumTest.java index 47d0589c0c3..0e0ee39b9e3 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issuesmode/IssueModeAndReportsMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issuesmode/IssueModeAndReportsMediumTest.java @@ -41,7 +41,6 @@ import org.sonar.batch.bootstrapper.IssueListener; import org.sonar.batch.mediumtest.BatchMediumTester; import org.sonar.batch.mediumtest.TaskResult; import org.sonar.batch.protocol.Constants.Severity; -import org.sonar.batch.protocol.input.ActiveRule; import org.sonar.batch.protocol.input.BatchInput.ServerIssue; import org.sonar.batch.scan.report.ConsoleReport; import org.sonar.xoo.XooPlugin; @@ -74,10 +73,10 @@ public class IssueModeAndReportsMediumTest { .addRules(new XooRulesDefinition()) .addRule("manual:MyManualIssue", "manual", "MyManualIssue", "My manual issue") .addRule("manual:MyManualIssueDup", "manual", "MyManualIssue", "My manual issue") - .activateRule(new ActiveRule("xoo", "OneIssuePerLine", null, "One issue per line", "MAJOR", null, "xoo")) - .activateRule(new ActiveRule("xoo", "OneIssueOnDirPerFile", null, "OneIssueOnDirPerFile", "MAJOR", null, "xoo")) - .activateRule(new ActiveRule("xoo", "OneIssuePerModule", null, "OneIssuePerModule", "MAJOR", null, "xoo")) - .activateRule(new ActiveRule("manual", "MyManualIssue", null, "My manual issue", "MAJOR", null, null)) + .addActiveRule("xoo", "OneIssuePerLine", null, "One issue per line", "MAJOR", null, "xoo") + .addActiveRule("xoo", "OneIssueOnDirPerFile", null, "OneIssueOnDirPerFile", "MAJOR", null, "xoo") + .addActiveRule("xoo", "OneIssuePerModule", null, "OneIssuePerModule", "MAJOR", null, "xoo") + .addActiveRule("manual", "MyManualIssue", null, "My manual issue", "MAJOR", null, null) .setPreviousAnalysisDate(new Date()) // Existing issue that is still detected .mockServerIssue(ServerIssue.newBuilder().setKey("xyz") diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issuesmode/NonAssociatedProject.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issuesmode/NonAssociatedProject.java index 6b2ae4c342c..2071dcfe2c6 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issuesmode/NonAssociatedProject.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issuesmode/NonAssociatedProject.java @@ -30,7 +30,6 @@ import org.sonar.api.CoreProperties; import org.sonar.api.utils.log.LogTester; import org.sonar.batch.mediumtest.BatchMediumTester; import org.sonar.batch.mediumtest.TaskResult; -import org.sonar.batch.protocol.input.ActiveRule; import org.sonar.xoo.XooPlugin; import org.sonar.xoo.rule.XooRulesDefinition; @@ -57,10 +56,10 @@ public class NonAssociatedProject { .addRules(new XooRulesDefinition()) .addRule("manual:MyManualIssue", "manual", "MyManualIssue", "My manual issue") .addRule("manual:MyManualIssueDup", "manual", "MyManualIssue", "My manual issue") - .activateRule(new ActiveRule("xoo", "OneIssuePerLine", null, "One issue per line", "MAJOR", null, "xoo")) - .activateRule(new ActiveRule("xoo", "OneIssueOnDirPerFile", null, "OneIssueOnDirPerFile", "MAJOR", null, "xoo")) - .activateRule(new ActiveRule("xoo", "OneIssuePerModule", null, "OneIssuePerModule", "MAJOR", null, "xoo")) - .activateRule(new ActiveRule("manual", "MyManualIssue", null, "My manual issue", "MAJOR", null, null)) + .addActiveRule("xoo", "OneIssuePerLine", null, "One issue per line", "MAJOR", null, "xoo") + .addActiveRule("xoo", "OneIssueOnDirPerFile", null, "OneIssueOnDirPerFile", "MAJOR", null, "xoo") + .addActiveRule("xoo", "OneIssuePerModule", null, "OneIssuePerModule", "MAJOR", null, "xoo") + .addActiveRule("manual", "MyManualIssue", null, "My manual issue", "MAJOR", null, null) .setAssociated(false) .build(); tester.start(); diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/scm/ScmMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/scm/ScmMediumTest.java index 28a13a38d55..d7a4af92705 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/scm/ScmMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/scm/ScmMediumTest.java @@ -19,6 +19,8 @@ */ package org.sonar.batch.mediumtest.scm; +import org.sonar.batch.repository.FileData; + import com.google.common.collect.ImmutableMap; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.io.FileUtils; @@ -30,7 +32,6 @@ import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; import org.sonar.batch.mediumtest.BatchMediumTester; import org.sonar.batch.mediumtest.BatchMediumTester.TaskBuilder; -import org.sonar.batch.protocol.input.FileData; import org.sonar.batch.protocol.output.BatchReport; import org.sonar.batch.protocol.output.BatchReport.Changesets.Changeset; import org.sonar.batch.protocol.output.BatchReport.Component; diff --git a/sonar-batch/src/test/java/org/sonar/batch/repository/DefaultGlobalRepositoriesLoaderTest.java b/sonar-batch/src/test/java/org/sonar/batch/repository/DefaultGlobalRepositoriesLoaderTest.java index df13b2ae6a7..ac9f309532b 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/repository/DefaultGlobalRepositoriesLoaderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/repository/DefaultGlobalRepositoriesLoaderTest.java @@ -33,7 +33,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; public class DefaultGlobalRepositoriesLoaderTest { - private static final String BATCH_GLOBAL_URL = "/scanner/global"; + private static final String BATCH_GLOBAL_URL = "/batch/global"; private WSLoader wsLoader; private WSLoaderResult<String> result; private DefaultGlobalRepositoriesLoader globalRepositoryLoader; diff --git a/sonar-batch/src/test/java/org/sonar/batch/repository/DefaultProjectRepositoriesLoaderTest.java b/sonar-batch/src/test/java/org/sonar/batch/repository/DefaultProjectRepositoriesLoaderTest.java index 19be82675cc..3a0a4b892f9 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/repository/DefaultProjectRepositoriesLoaderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/repository/DefaultProjectRepositoriesLoaderTest.java @@ -19,107 +19,78 @@ */ package org.sonar.batch.repository; -import java.io.IOException; -import java.util.Date; -import org.apache.commons.io.IOUtils; +import org.sonarqube.ws.WsScanner.WsProjectResponse; +import org.sonar.batch.cache.WSLoaderResult; +import org.sonar.batch.cache.WSLoader; import org.apache.commons.lang.mutable.MutableBoolean; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; + +import static org.assertj.core.api.Assertions.assertThat; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; -import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.utils.MessageException; -import org.sonar.batch.analysis.DefaultAnalysisMode; -import org.sonar.batch.cache.WSLoader; -import org.sonar.batch.cache.WSLoaderResult; -import org.sonar.batch.protocol.input.ProjectRepositories; -import org.sonar.batch.protocol.input.QProfile; - -import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; public class DefaultProjectRepositoriesLoaderTest { - + private final static String PROJECT_KEY = "foo?"; @Rule public ExpectedException thrown = ExpectedException.none(); private DefaultProjectRepositoriesLoader loader; private WSLoader wsLoader; - private DefaultAnalysisMode analysisMode; - private ProjectDefinition project; @Before - public void prepare() { + public void prepare() throws IOException { wsLoader = mock(WSLoader.class); - analysisMode = mock(DefaultAnalysisMode.class); - loader = new DefaultProjectRepositoriesLoader(wsLoader, analysisMode); - loader = spy(loader); - when(wsLoader.loadString(anyString())).thenReturn(new WSLoaderResult<>("{}", true)); + InputStream is = mockData(); + when(wsLoader.loadStream(anyString())).thenReturn(new WSLoaderResult<InputStream>(is, true)); + loader = new DefaultProjectRepositoriesLoader(wsLoader); } @Test - public void passPreviewParameter() { - addQualityProfile(); - project = ProjectDefinition.create().setKey("foo"); - when(analysisMode.isIssues()).thenReturn(false); - loader.load(project.getKeyWithBranch(), null, null); - verify(wsLoader).loadString("/scanner/project?key=foo&preview=false"); + public void continueOnError() { + when(wsLoader.loadStream(anyString())).thenThrow(IllegalStateException.class); + ProjectRepositories proj = loader.load(PROJECT_KEY, false, null); + assertThat(proj.exists()).isEqualTo(false); + } + + @Test + public void passIssuesModeParameter() { + loader.load(PROJECT_KEY, false, null); + verify(wsLoader).loadStream("/batch/project?key=foo%3F"); - when(analysisMode.isIssues()).thenReturn(true); - loader.load(project.getKeyWithBranch(), null, null); - verify(wsLoader).loadString("/scanner/project?key=foo&preview=true"); + loader.load(PROJECT_KEY, true, null); + verify(wsLoader).loadStream("/batch/project?key=foo%3F&issues=true"); } @Test 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, true)); - project = ProjectDefinition.create().setKey("foo"); MutableBoolean fromCache = new MutableBoolean(); - ProjectRepositories projectRepo = loader.load(project.getKeyWithBranch(), null, fromCache); - + loader.load(PROJECT_KEY, false, fromCache); assertThat(fromCache.booleanValue()).isTrue(); - assertThat(projectRepo.activeRules().size()).isEqualTo(221); - assertThat(projectRepo.fileDataByPath("my:project").size()).isEqualTo(11); - } @Test public void passAndEncodeProjectKeyParameter() { - addQualityProfile(); - project = ProjectDefinition.create().setKey("foo bà r"); - loader.load(project.getKeyWithBranch(), null, null); - verify(wsLoader).loadString("/scanner/project?key=foo+b%C3%A0r&preview=false"); - } - - @Test - public void passAndEncodeProfileParameter() { - addQualityProfile(); - project = ProjectDefinition.create().setKey("foo"); - loader.load(project.getKeyWithBranch(), "my-profile#2", null); - verify(wsLoader).loadString("/scanner/project?key=foo&profile=my-profile%232&preview=false"); + loader.load(PROJECT_KEY, false, null); + verify(wsLoader).loadStream("/batch/project?key=foo%3F"); } - @Test - public void fail_with_message_exception_when_no_quality_profile() throws Exception { - thrown.expect(MessageException.class); - thrown.expectMessage("No quality profiles has been found this project, you probably don't have any language plugin suitable for this analysis."); - - project = ProjectDefinition.create().setKey("foo"); - when(wsLoader.loadString(anyString())).thenReturn(new WSLoaderResult<>(new ProjectRepositories().toJson(), true)); - - loader.load(project.getKeyWithBranch(), null, null); - } + private InputStream mockData() throws IOException { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + WsProjectResponse.Builder projectResponseBuilder = WsProjectResponse.newBuilder(); + WsProjectResponse response = projectResponseBuilder.build(); + response.writeTo(os); - private void addQualityProfile() { - ProjectRepositories projectRepositories = new ProjectRepositories(); - projectRepositories.addQProfile(new QProfile("key", "name", "language", new Date())); - when(wsLoader.loadString(anyString())).thenReturn(new WSLoaderResult<>(projectRepositories.toJson(), true)); + return new ByteArrayInputStream(os.toByteArray()); } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/repository/DefaultProjectSettingsLoaderTest.java b/sonar-batch/src/test/java/org/sonar/batch/repository/DefaultProjectSettingsLoaderTest.java deleted file mode 100644 index 0a4b7b7b340..00000000000 --- a/sonar-batch/src/test/java/org/sonar/batch/repository/DefaultProjectSettingsLoaderTest.java +++ /dev/null @@ -1,77 +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.repository; - -import com.google.common.collect.ImmutableMap; - -import org.sonar.batch.protocol.input.FileData; -import org.junit.Before; -import org.junit.Test; -import org.sonar.batch.protocol.input.ProjectRepositories; - -import java.util.Date; - -import static org.assertj.core.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; - -public class DefaultProjectSettingsLoaderTest { - private DefaultProjectSettingsLoader loader; - private DefaultProjectRepositoriesFactory factory; - private ProjectRepositories projectRepositories; - - private FileData f1; - private FileData f2; - - @Before - public void setUp() { - createProjectRepo(); - factory = mock(DefaultProjectRepositoriesFactory.class); - when(factory.create()).thenReturn(projectRepositories); - loader = new DefaultProjectSettingsLoader(factory); - } - - private void createProjectRepo() { - projectRepositories = new ProjectRepositories(); - projectRepositories.setLastAnalysisDate(new Date(1000)); - - f1 = new FileData("hash1", "123456789"); - f2 = new FileData("hash2", "123456789"); - projectRepositories.addFileData("module1", "file1", f1); - projectRepositories.addFileData("module1", "file2", f2); - - projectRepositories.addSettings("module1", ImmutableMap.of("key", "value")); - } - - @Test - public void test() { - ProjectSettingsRepo loaded = loader.load("project", null); - - assertThat(loaded.fileData("module1", "file1")).isEqualTo(f1); - assertThat(loaded.fileData("module1", "file2")).isEqualTo(f2); - assertThat(loaded.settings("module1")).isEqualTo(ImmutableMap.of("key", "value")); - assertThat(loaded.lastAnalysisDate()).isEqualTo(new Date(1000)); - - verify(factory).create(); - verifyNoMoreInteractions(factory); - } -} diff --git a/sonar-batch/src/test/java/org/sonar/batch/repository/DefaultQualityProfileLoaderTest.java b/sonar-batch/src/test/java/org/sonar/batch/repository/DefaultQualityProfileLoaderTest.java index 06de84fc400..33b053b74a2 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/repository/DefaultQualityProfileLoaderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/repository/DefaultQualityProfileLoaderTest.java @@ -19,18 +19,25 @@ */ package org.sonar.batch.repository; +import org.sonarqube.ws.QualityProfiles.WsSearchResponse; + +import com.google.common.io.Resources; +import org.sonarqube.ws.QualityProfiles.WsSearchResponse.QualityProfile; +import org.sonar.batch.cache.WSLoaderResult; +import org.sonar.batch.cache.WSLoader; import org.junit.Rule; import org.junit.rules.ExpectedException; - import org.junit.Before; import org.junit.Test; -import org.sonar.batch.protocol.input.ProjectRepositories; -import org.sonar.batch.protocol.input.QProfile; -import java.util.Collection; -import java.util.Date; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.mock; @@ -41,37 +48,68 @@ public class DefaultQualityProfileLoaderTest { public ExpectedException exception = ExpectedException.none(); private DefaultQualityProfileLoader qpLoader; - private DefaultProjectRepositoriesFactory factory; - private ProjectRepositories projectRepositories; + private WSLoader ws; + private InputStream is; @Before - public void setUp() { - projectRepositories = new ProjectRepositories(); - projectRepositories.addQProfile(new QProfile("profile", "name", "lang", new Date())); - - factory = mock(DefaultProjectRepositoriesFactory.class); - when(factory.create()).thenReturn(projectRepositories); - qpLoader = new DefaultQualityProfileLoader(factory); + public void setUp() throws IOException { + ws = mock(WSLoader.class); + is = mock(InputStream.class); + when(is.read()).thenReturn(-1); + WSLoaderResult<InputStream> result = new WSLoaderResult<>(is, false); + when(ws.loadStream(anyString())).thenReturn(result); + qpLoader = new DefaultQualityProfileLoader(ws); } @Test - public void test() { - Collection<QProfile> loaded = qpLoader.load("project", null); + public void testEncoding() throws IOException { + WSLoaderResult<InputStream> result = new WSLoaderResult<>(createEncodedQP("qp"), false); + when(ws.loadStream(anyString())).thenReturn(result); + List<QualityProfile> loaded = qpLoader.load("foo#2", "my-profile#2", null); + verify(ws).loadStream("/qualityprofiles/search?projectKey=foo%232&profileName=my-profile%232"); + verifyNoMoreInteractions(ws); assertThat(loaded).hasSize(1); - assertThat(loaded.iterator().next().key()).isEqualTo("profile"); - verify(factory).create(); - verifyNoMoreInteractions(factory); } @Test - public void testNoProfile() { - projectRepositories = new ProjectRepositories(); - when(factory.create()).thenReturn(projectRepositories); + public void testNoProfile() throws IOException { + InputStream is = createEncodedQP(); + when(ws.loadStream(anyString())).thenReturn(new WSLoaderResult<InputStream>(is, false)); exception.expect(IllegalStateException.class); exception.expectMessage("No quality profiles"); - qpLoader.load("project", null); + qpLoader.load("project", null, null); + verifyNoMoreInteractions(ws); + } + + @Test + public void use_real_response() throws IOException { + InputStream is = getTestResource("quality_profile_search_default"); + when(ws.loadStream(anyString())).thenReturn(new WSLoaderResult<InputStream>(is, false)); + + List<QualityProfile> loaded = qpLoader.loadDefault(null); + verify(ws).loadStream("/qualityprofiles/search?defaults=true"); + verifyNoMoreInteractions(ws); + assertThat(loaded).hasSize(1); + } + + private InputStream getTestResource(String name) throws IOException { + return Resources.asByteSource(this.getClass().getResource(this.getClass().getSimpleName() + "/" + name)) + .openBufferedStream(); + } + + private static InputStream createEncodedQP(String... names) throws IOException { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + WsSearchResponse.Builder responseBuilder = WsSearchResponse.newBuilder(); + + for (String n : names) { + QualityProfile qp = QualityProfile.newBuilder().setKey(n).setName(n).setLanguage("lang").build(); + responseBuilder.addProfiles(qp); + } + + responseBuilder.build().writeTo(os); + return new ByteArrayInputStream(os.toByteArray()); } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/repository/DefaultServerIssuesLoaderTest.java b/sonar-batch/src/test/java/org/sonar/batch/repository/DefaultServerIssuesLoaderTest.java index 0bcde52323b..1801b62e95f 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/repository/DefaultServerIssuesLoaderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/repository/DefaultServerIssuesLoaderTest.java @@ -58,7 +58,7 @@ public class DefaultServerIssuesLoaderTest { .writeDelimitedTo(bos); InputStream is = new ByteArrayInputStream(bos.toByteArray()); - when(wsLoader.loadStream("/scanner/issues?key=foo")).thenReturn(new WSLoaderResult<>(is, true)); + when(wsLoader.loadStream("/batch/issues?key=foo")).thenReturn(new WSLoaderResult<>(is, true)); final List<ServerIssue> result = new ArrayList<>(); loader.load("foo", new Function<BatchInput.ServerIssue, Void>() { @@ -75,15 +75,9 @@ public class DefaultServerIssuesLoaderTest { @Test(expected = IllegalStateException.class) public void testError() throws IOException { -<<<<<<< HEAD - ByteSource source = mock(ByteSource.class); - when(source.openBufferedStream()).thenThrow(IOException.class); - when(wsLoader.loadSource("/scanner/issues?key=foo")).thenReturn(new WSLoaderResult<ByteSource>(source, true)); -======= InputStream is = mock(InputStream.class); when(is.read()).thenThrow(IOException.class); when(wsLoader.loadStream("/batch/issues?key=foo")).thenReturn(new WSLoaderResult<InputStream>(is, true)); ->>>>>>> SONAR-6777 Project cache sync loader.load("foo", mock(Function.class)); } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/repository/ProjectRepositoriesProviderTest.java b/sonar-batch/src/test/java/org/sonar/batch/repository/ProjectRepositoriesProviderTest.java new file mode 100644 index 00000000000..916bfaf79d4 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/repository/ProjectRepositoriesProviderTest.java @@ -0,0 +1,115 @@ +/* + * 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.repository; + +import java.util.Date; + +import org.sonar.batch.repository.FileData; +import com.google.common.collect.Table; +import com.google.common.collect.HashBasedTable; +import org.apache.commons.lang.mutable.MutableBoolean; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.sonar.api.batch.bootstrap.ProjectKey; +import org.sonar.batch.analysis.DefaultAnalysisMode; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +public class ProjectRepositoriesProviderTest { + private ProjectRepositoriesProvider provider; + private ProjectRepositories project; + + @Mock + private ProjectRepositoriesLoader loader; + @Mock + private ProjectKey projectKey; + @Mock + private DefaultAnalysisMode mode; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + Table<String, String, String> t1 = HashBasedTable.create(); + Table<String, String, FileData> t2 = HashBasedTable.create(); + + project = new ProjectRepositories(t1, t2, new Date()); + provider = new ProjectRepositoriesProvider(); + + when(projectKey.get()).thenReturn("key"); + } + + @Test + public void testNonAssociated() { + when(mode.isNotAssociated()).thenReturn(true); + ProjectRepositories repo = provider.provide(loader, projectKey, mode); + + assertThat(repo.exists()).isEqualTo(false); + verify(mode).isNotAssociated(); + verifyNoMoreInteractions(loader, projectKey, mode); + } + + @Test + public void singleton() { + when(mode.isNotAssociated()).thenReturn(true); + ProjectRepositories repo = provider.provide(loader, projectKey, mode); + + assertThat(repo.exists()).isEqualTo(false); + verify(mode).isNotAssociated(); + verifyNoMoreInteractions(loader, projectKey, mode); + + repo = provider.provide(loader, projectKey, mode); + verifyNoMoreInteractions(loader, projectKey, mode); + } + + @Test + public void testValidation() { + when(mode.isNotAssociated()).thenReturn(false); + when(mode.isIssues()).thenReturn(true); + when(loader.load(eq("key"), eq(true), any(MutableBoolean.class))).thenReturn(project); + + provider.provide(loader, projectKey, mode); + } + + @Test + public void testAssociated() { + when(mode.isNotAssociated()).thenReturn(false); + when(mode.isIssues()).thenReturn(false); + when(loader.load(eq("key"), eq(false), any(MutableBoolean.class))).thenReturn(project); + + ProjectRepositories repo = provider.provide(loader, projectKey, mode); + + assertThat(repo.exists()).isEqualTo(true); + assertThat(repo.lastAnalysisDate()).isNotNull(); + + verify(mode).isNotAssociated(); + verify(mode, times(2)).isIssues(); + verify(projectKey).get(); + verify(loader).load(eq("key"), eq(false), any(MutableBoolean.class)); + verifyNoMoreInteractions(loader, projectKey, mode); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/repository/QualityProfileProviderTest.java b/sonar-batch/src/test/java/org/sonar/batch/repository/QualityProfileProviderTest.java index 357f0bcdcc5..361d147ac0d 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/repository/QualityProfileProviderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/repository/QualityProfileProviderTest.java @@ -19,24 +19,26 @@ */ package org.sonar.batch.repository; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; - -import org.sonar.batch.protocol.input.QProfile; +import org.apache.commons.lang.mutable.MutableBoolean; +import org.sonar.api.batch.bootstrap.ProjectKey; +import org.sonar.batch.analysis.DefaultAnalysisMode; +import org.sonarqube.ws.QualityProfiles.WsSearchResponse.QualityProfile; import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; +import java.util.List; + +import static org.mockito.Matchers.isNull; +import static org.mockito.Matchers.eq; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verify; import static org.assertj.core.api.Assertions.assertThat; import org.sonar.batch.rule.ModuleQProfiles; -import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.junit.Test; import org.sonar.batch.analysis.AnalysisProperties; import org.mockito.MockitoAnnotations; -import org.sonar.api.batch.AnalysisMode; -import org.sonar.api.batch.bootstrap.ProjectReactor; import org.mockito.Mock; import org.junit.Before; @@ -46,49 +48,78 @@ public class QualityProfileProviderTest { @Mock private QualityProfileLoader loader; @Mock - private ProjectReactor projectReactor; - @Mock - private AnalysisMode mode; + private DefaultAnalysisMode mode; @Mock private AnalysisProperties props; + @Mock + private ProjectKey key; + @Mock + private ProjectRepositories projectRepo; - private Collection<QProfile> response; + private List<QualityProfile> response; @Before public void setUp() { MockitoAnnotations.initMocks(this); qualityProfileProvider = new QualityProfileProvider(); - ProjectDefinition root = mock(ProjectDefinition.class); - when(root.getKeyWithBranch()).thenReturn("project"); - when(projectReactor.getRoot()).thenReturn(root); + when(key.get()).thenReturn("project"); + when(projectRepo.exists()).thenReturn(true); - response = new ArrayList<QProfile>(1); - response.add(new QProfile("profile", "name", "lang", new Date())); + response = new ArrayList<QualityProfile>(1); + response.add(QualityProfile.newBuilder().setKey("profile").setName("profile").setLanguage("lang").build()); } @Test public void testProvide() { - when(loader.load("project", null)).thenReturn(response); - ModuleQProfiles qps = qualityProfileProvider.provide(projectReactor, loader, props, mode); + when(mode.isNotAssociated()).thenReturn(false); + when(loader.load(eq("project"), isNull(String.class), any(MutableBoolean.class))).thenReturn(response); + ModuleQProfiles qps = qualityProfileProvider.provide(key, loader, projectRepo, props, mode); + assertResponse(qps); + + verify(loader).load(eq("project"), isNull(String.class), any(MutableBoolean.class)); + verifyNoMoreInteractions(loader); + } + + @Test + public void testNonAssociated() { + when(mode.isNotAssociated()).thenReturn(true); + when(loader.loadDefault(any(MutableBoolean.class))).thenReturn(response); + ModuleQProfiles qps = qualityProfileProvider.provide(key, loader, projectRepo, props, mode); + assertResponse(qps); + + verify(loader).loadDefault(any(MutableBoolean.class)); + verifyNoMoreInteractions(loader); + } + + @Test + public void testProjectDoesntExist() { + when(mode.isNotAssociated()).thenReturn(false); + when(projectRepo.exists()).thenReturn(false); + when(loader.loadDefault(any(MutableBoolean.class))).thenReturn(response); + ModuleQProfiles qps = qualityProfileProvider.provide(key, loader, projectRepo, props, mode); assertResponse(qps); - verify(loader).load("project", null); + verify(loader).loadDefault(any(MutableBoolean.class)); + verifyNoMoreInteractions(loader); } @Test public void testProfileProp() { - when(loader.load("project", "custom")).thenReturn(response); + when(mode.isNotAssociated()).thenReturn(false); + when(loader.load(eq("project"), eq("custom"), any(MutableBoolean.class))).thenReturn(response); when(props.property(ModuleQProfiles.SONAR_PROFILE_PROP)).thenReturn("custom"); - ModuleQProfiles qps = qualityProfileProvider.provide(projectReactor, loader, props, mode); + ModuleQProfiles qps = qualityProfileProvider.provide(key, loader, projectRepo, props, mode); assertResponse(qps); - verify(loader).load("project", "custom"); + verify(loader).load(eq("project"), eq("custom"), any(MutableBoolean.class)); + verifyNoMoreInteractions(loader); } private void assertResponse(ModuleQProfiles qps) { assertThat(qps.findAll()).hasSize(1); assertThat(qps.findAll()).extracting("key").containsExactly("profile"); + } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/repository/user/UserRepositoryLoaderTest.java b/sonar-batch/src/test/java/org/sonar/batch/repository/user/UserRepositoryLoaderTest.java index 16ee8a426f2..d2443bf1219 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/repository/user/UserRepositoryLoaderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/repository/user/UserRepositoryLoaderTest.java @@ -68,7 +68,7 @@ public class UserRepositoryLoaderTest { public void testLoad() throws IOException { Map<String, String> userMap = ImmutableMap.of("fmallet", "Freddy Mallet", "sbrandhof", "Simon"); WSLoaderResult<InputStream> res = new WSLoaderResult<>(createUsersMock(userMap), true); - when(wsLoader.loadStream("/scanner/users?logins=fmallet,sbrandhof")).thenReturn(res); + when(wsLoader.loadStream("/batch/users?logins=fmallet,sbrandhof")).thenReturn(res); assertThat(userRepo.load(Arrays.asList("fmallet", "sbrandhof"))).extracting("login", "name").containsOnly(tuple("fmallet", "Freddy Mallet"), tuple("sbrandhof", "Simon")); } @@ -88,13 +88,8 @@ public class UserRepositoryLoaderTest { @Test public void testLoadSingleUser() throws IOException { -<<<<<<< HEAD - WSLoaderResult<ByteSource> res = new WSLoaderResult<>(createUsersMock(ImmutableMap.of("fmallet", "Freddy Mallet")), true); - when(wsLoader.loadSource("/scanner/users?logins=fmallet")).thenReturn(res); -======= WSLoaderResult<InputStream> res = new WSLoaderResult<>(createUsersMock(ImmutableMap.of("fmallet", "Freddy Mallet")), true); when(wsLoader.loadStream("/batch/users?logins=fmallet")).thenReturn(res); ->>>>>>> SONAR-6777 Project cache sync assertThat(userRepo.load("fmallet").getName()).isEqualTo("Freddy Mallet"); } @@ -111,17 +106,9 @@ public class UserRepositoryLoaderTest { @Test public void testInputStreamError() throws IOException { -<<<<<<< HEAD - ByteSource source = mock(ByteSource.class); - - WSLoaderResult<ByteSource> res = new WSLoaderResult<>(source, true); - - when(wsLoader.loadSource("/scanner/users?logins=fmallet,sbrandhof")).thenReturn(res); -======= InputStream is = mock(InputStream.class); Mockito.doThrow(IOException.class).when(is).read(); WSLoaderResult<InputStream> res = new WSLoaderResult<>(is, true); ->>>>>>> SONAR-6777 Project cache sync when(wsLoader.loadStream("/batch/users?logins=fmallet,sbrandhof")).thenReturn(res); diff --git a/sonar-batch/src/test/java/org/sonar/batch/rule/ActiveRulesProviderTest.java b/sonar-batch/src/test/java/org/sonar/batch/rule/ActiveRulesProviderTest.java new file mode 100644 index 00000000000..a4f9b56aa3e --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/rule/ActiveRulesProviderTest.java @@ -0,0 +1,94 @@ +/* + * 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.rule; + +import org.sonarqube.ws.QualityProfiles.WsSearchResponse.QualityProfile; + +import com.google.common.collect.ImmutableList; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.sonar.api.batch.rule.ActiveRules; +import org.sonar.api.rule.RuleKey; +import org.sonarqube.ws.Rules.Rule; + +import java.util.LinkedList; +import java.util.List; + +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.verify; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +public class ActiveRulesProviderTest { + private ActiveRulesProvider provider; + + @Mock + private DefaultActiveRulesLoader loader; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + provider = new ActiveRulesProvider(); + } + + @Test + public void testCombinationOfRules() { + Rule r1 = mockRule("rule1"); + Rule r2 = mockRule("rule2"); + Rule r3 = mockRule("rule3"); + + List<Rule> qp1Rules = ImmutableList.of(r1, r2); + List<Rule> qp2Rules = ImmutableList.of(r2, r3); + List<Rule> qp3Rules = ImmutableList.of(r1, r3); + + when(loader.load("qp1", null)).thenReturn(qp1Rules); + when(loader.load("qp2", null)).thenReturn(qp2Rules); + when(loader.load("qp3", null)).thenReturn(qp3Rules); + + ModuleQProfiles profiles = mockProfiles("qp1", "qp2", "qp3"); + ActiveRules activeRules = provider.provide(loader, profiles); + + assertThat(activeRules.findAll()).hasSize(3); + assertThat(activeRules.findAll()).extracting("ruleKey").containsOnly( + RuleKey.of("rule1", "rule1"), RuleKey.of("rule2", "rule2"), RuleKey.of("rule3", "rule3")); + + verify(loader).load("qp1", null); + verify(loader).load("qp2", null); + verify(loader).load("qp3", null); + verifyNoMoreInteractions(loader); + } + + private static ModuleQProfiles mockProfiles(String... keys) { + List<QualityProfile> profiles = new LinkedList<>(); + + for (String k : keys) { + QualityProfile p = QualityProfile.newBuilder().setKey(k).setLanguage(k).build(); + profiles.add(p); + } + + return new ModuleQProfiles(profiles); + } + + private static Rule mockRule(String name) { + return Rule.newBuilder().setName(name).setRepo(name).setKey(name).build(); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/rule/DefaultActiveRulesLoaderTest.java b/sonar-batch/src/test/java/org/sonar/batch/rule/DefaultActiveRulesLoaderTest.java index 7c3f2e118b1..d9cd09d2838 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/rule/DefaultActiveRulesLoaderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/rule/DefaultActiveRulesLoaderTest.java @@ -19,52 +19,50 @@ */ package org.sonar.batch.rule; -import org.sonar.batch.repository.DefaultProjectRepositoriesFactory; - -import com.google.common.collect.ImmutableList; -import org.sonar.batch.protocol.input.ActiveRule; +import org.sonarqube.ws.Rules.Rule; +import org.sonar.batch.cache.WSLoaderResult; +import org.sonar.batch.cache.WSLoader; +import com.google.common.io.Resources; import org.junit.Test; -import org.sonar.batch.protocol.input.ProjectRepositories; +import java.io.IOException; +import java.io.InputStream; import java.util.Collection; +import static org.mockito.Mockito.verify; + +import static org.mockito.Matchers.anyString; import static org.assertj.core.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 org.junit.Before; public class DefaultActiveRulesLoaderTest { private DefaultActiveRulesLoader loader; - private DefaultProjectRepositoriesFactory factory; - private ProjectRepositories projectRepositories; - - private ActiveRule response; + private WSLoader ws; @Before public void setUp() { - response = mock(ActiveRule.class); - when(response.ruleKey()).thenReturn("rule"); - - projectRepositories = new ProjectRepositories(); - projectRepositories.addActiveRule(response); - - factory = mock(DefaultProjectRepositoriesFactory.class); - when(factory.create()).thenReturn(projectRepositories); - loader = new DefaultActiveRulesLoader(factory); + ws = mock(WSLoader.class); + loader = new DefaultActiveRulesLoader(ws); } @Test - public void test() { - Collection<String> profiles = ImmutableList.of("profile1"); - Collection<ActiveRule> activeRules = loader.load(profiles, "project"); + public void feed_real_response() throws IOException { + InputStream response = loadResource("active_rule_search.protobuf"); + when(ws.loadStream(anyString())).thenReturn(new WSLoaderResult<InputStream>(response, false)); + Collection<Rule> activeRules = loader.load("java-sonar-way-26368", null); + assertThat(activeRules).hasSize(100); - assertThat(activeRules).hasSize(1); - assertThat(activeRules.iterator().next().ruleKey()).isEqualTo("rule"); + verify(ws).loadStream("/api/rules/search?f=repo,name,severity,lang,internalKey,templateKey&qprofile=java-sonar-way-26368"); + verifyNoMoreInteractions(ws); + + } - verify(factory).create(); - verifyNoMoreInteractions(factory); + private InputStream loadResource(String name) throws IOException { + return Resources.asByteSource(this.getClass().getResource("DefaultActiveRulesLoaderTest/" + name)) + .openBufferedStream(); } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/ModuleSettingsTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/ModuleSettingsTest.java index 336cf7a2a85..ab85aa3e5c7 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/ModuleSettingsTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/ModuleSettingsTest.java @@ -19,12 +19,16 @@ */ package org.sonar.batch.scan; +import org.sonar.batch.repository.FileData; + import com.google.common.collect.HashBasedTable; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableTable; import com.google.common.collect.Table; + import java.util.List; import java.util.Map; + import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -34,10 +38,8 @@ import org.sonar.api.config.PropertyDefinitions; import org.sonar.api.utils.MessageException; import org.sonar.batch.analysis.DefaultAnalysisMode; import org.sonar.batch.bootstrap.GlobalSettings; -import org.sonar.batch.protocol.input.FileData; import org.sonar.batch.report.AnalysisContextReportPublisher; -import org.sonar.batch.repository.ProjectSettingsRepo; - +import org.sonar.batch.repository.ProjectRepositories; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -54,14 +56,14 @@ public class ModuleSettingsTest { mode = mock(DefaultAnalysisMode.class); } - private ProjectSettingsRepo createSettings(String module, Map<String, String> settingsMap) { + private ProjectRepositories createSettings(String module, Map<String, String> settingsMap) { Table<String, String, FileData> fileData = ImmutableTable.of(); Table<String, String, String> settings = HashBasedTable.create(); for (Map.Entry<String, String> e : settingsMap.entrySet()) { settings.put(module, e.getKey(), e.getValue()); } - return new ProjectSettingsRepo(settings, fileData, null); + return new ProjectRepositories(settings, fileData, null); } @Test @@ -86,7 +88,7 @@ public class ModuleSettingsTest { "overridding", "batch", "on-batch", "true")); - ProjectSettingsRepo projSettingsRepo = createSettings("struts-core", ImmutableMap.of("on-module", "true", "overridding", "module")); + ProjectRepositories projSettingsRepo = createSettings("struts-core", ImmutableMap.of("on-module", "true", "overridding", "module")); ProjectDefinition module = ProjectDefinition.create().setKey("struts-core"); @@ -105,7 +107,7 @@ public class ModuleSettingsTest { when(batchSettings.getProperties()).thenReturn(ImmutableMap.of( "sonar.foo.secured", "bar")); - ProjectSettingsRepo projSettingsRepo = createSettings("struts-core", ImmutableMap.of("sonar.foo.license.secured", "bar2")); + ProjectRepositories projSettingsRepo = createSettings("struts-core", ImmutableMap.of("sonar.foo.license.secured", "bar2")); ProjectDefinition module = ProjectDefinition.create().setKey("struts-core"); @@ -122,7 +124,7 @@ public class ModuleSettingsTest { when(batchSettings.getProperties()).thenReturn(ImmutableMap.of( "sonar.foo.secured", "bar")); - ProjectSettingsRepo projSettingsRepo = createSettings("struts-core", ImmutableMap.of("sonar.foo.license.secured", "bar2")); + ProjectRepositories projSettingsRepo = createSettings("struts-core", ImmutableMap.of("sonar.foo.license.secured", "bar2")); when(mode.isIssues()).thenReturn(true); @@ -135,7 +137,7 @@ public class ModuleSettingsTest { thrown.expect(MessageException.class); thrown .expectMessage( - "Access to the secured property 'sonar.foo.secured' is not possible in issues mode. The SonarQube plugin which requires this property must be deactivated in issues mode."); + "Access to the secured property 'sonar.foo.secured' is not possible in issues mode. The SonarQube plugin which requires this property must be deactivated in issues mode."); moduleSettings.getString("sonar.foo.secured"); } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectSettingsTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectSettingsTest.java index 412b563e2ac..0a2583325a9 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectSettingsTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectSettingsTest.java @@ -19,12 +19,12 @@ */ package org.sonar.batch.scan; -import org.sonar.batch.protocol.input.FileData; +import org.sonar.batch.repository.FileData; import com.google.common.collect.HashBasedTable; import com.google.common.collect.Table; import com.google.common.collect.ImmutableTable; -import org.sonar.batch.repository.ProjectSettingsRepo; +import org.sonar.batch.repository.ProjectRepositories; import org.sonar.batch.analysis.DefaultAnalysisMode; import org.sonar.batch.bootstrap.GlobalMode; import com.google.common.collect.ImmutableMap; @@ -56,7 +56,7 @@ public class ProjectSettingsTest { @Rule public LogTester logTester = new LogTester(); - private ProjectSettingsRepo projectRef; + private ProjectRepositories projectRef; private ProjectDefinition project; private GlobalSettings bootstrapProps; private Table<String, String, FileData> emptyFileData; @@ -79,7 +79,7 @@ public class ProjectSettingsTest { public void should_load_project_props() { project.setProperty("project.prop", "project"); - projectRef = new ProjectSettingsRepo(emptySettings, emptyFileData, null); + projectRef = new ProjectRepositories(emptySettings, emptyFileData, null); ProjectSettings batchSettings = new ProjectSettings(new ProjectReactor(project), bootstrapProps, new PropertyDefinitions(), projectRef, mode); assertThat(batchSettings.getString("project.prop")).isEqualTo("project"); @@ -91,7 +91,7 @@ public class ProjectSettingsTest { settings.put("struts", "sonar.cpd.cross", "true"); settings.put("struts", "sonar.java.coveragePlugin", "jacoco"); - projectRef = new ProjectSettingsRepo(settings, emptyFileData, null); + projectRef = new ProjectRepositories(settings, emptyFileData, null); ProjectSettings batchSettings = new ProjectSettings(new ProjectReactor(project), bootstrapProps, new PropertyDefinitions(), projectRef, mode); assertThat(batchSettings.getString("sonar.java.coveragePlugin")).isEqualTo("jacoco"); } @@ -104,7 +104,7 @@ public class ProjectSettingsTest { settings.put("struts:mybranch", "sonar.cpd.cross", "true"); settings.put("struts:mybranch", "sonar.java.coveragePlugin", "jacoco"); - projectRef = new ProjectSettingsRepo(settings, emptyFileData, null); + projectRef = new ProjectRepositories(settings, emptyFileData, null); ProjectSettings batchSettings = new ProjectSettings(new ProjectReactor(project), bootstrapProps, new PropertyDefinitions(), projectRef, mode); @@ -117,7 +117,7 @@ public class ProjectSettingsTest { settings.put("struts", "sonar.foo.secured", "bar"); settings.put("struts", "sonar.foo.license.secured", "bar2"); - projectRef = new ProjectSettingsRepo(settings, emptyFileData, null); + projectRef = new ProjectRepositories(settings, emptyFileData, null); ProjectSettings batchSettings = new ProjectSettings(new ProjectReactor(project), bootstrapProps, new PropertyDefinitions(), projectRef, mode); assertThat(batchSettings.getString("sonar.foo.license.secured")).isEqualTo("bar2"); @@ -132,7 +132,7 @@ public class ProjectSettingsTest { when(mode.isIssues()).thenReturn(true); - projectRef = new ProjectSettingsRepo(settings, emptyFileData, null); + projectRef = new ProjectRepositories(settings, emptyFileData, null); ProjectSettings batchSettings = new ProjectSettings(new ProjectReactor(project), bootstrapProps, new PropertyDefinitions(), projectRef, mode); assertThat(batchSettings.getString("sonar.foo.license.secured")).isEqualTo("bar2"); @@ -146,7 +146,7 @@ public class ProjectSettingsTest { public void should_log_a_warning_when_a_dropper_property_is_present() { GlobalSettings settings = new GlobalSettings(new GlobalProperties(ImmutableMap.of("sonar.qualitygate", "somevalue")), new PropertyDefinitions(), new GlobalRepositories(), globalMode); - projectRef = new ProjectSettingsRepo(emptySettings, emptyFileData, null); + projectRef = new ProjectRepositories(emptySettings, emptyFileData, null); new ProjectSettings(new ProjectReactor(project), settings, new PropertyDefinitions(), projectRef, mode); assertThat(logTester.logs(LoggerLevel.WARN)).containsOnly("Property 'sonar.qualitygate' is not supported any more. It will be ignored."); diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/StatusDetectionFactoryTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/StatusDetectionFactoryTest.java index 1e2f3ac3620..ff51f74f739 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/StatusDetectionFactoryTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/StatusDetectionFactoryTest.java @@ -19,7 +19,7 @@ */ package org.sonar.batch.scan.filesystem; -import org.sonar.batch.repository.ProjectSettingsRepo; +import org.sonar.batch.repository.ProjectRepositories; import org.junit.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -28,7 +28,7 @@ import static org.mockito.Mockito.mock; public class StatusDetectionFactoryTest { @Test public void testCreate() throws Exception { - StatusDetectionFactory factory = new StatusDetectionFactory(mock(ProjectSettingsRepo.class)); + StatusDetectionFactory factory = new StatusDetectionFactory(mock(ProjectRepositories.class)); StatusDetection detection = factory.create(); assertThat(detection).isNotNull(); } diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/StatusDetectionTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/StatusDetectionTest.java index 98b17dd6a56..8ae4fd41269 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/StatusDetectionTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/StatusDetectionTest.java @@ -19,21 +19,21 @@ */ package org.sonar.batch.scan.filesystem; +import org.sonar.batch.repository.FileData; + import com.google.common.collect.HashBasedTable; import com.google.common.collect.ImmutableTable; import com.google.common.collect.Table; import org.junit.Test; import org.sonar.api.batch.fs.InputFile; -import org.sonar.batch.protocol.input.FileData; -import org.sonar.batch.repository.ProjectSettingsRepo; - +import org.sonar.batch.repository.ProjectRepositories; import static org.assertj.core.api.Assertions.assertThat; public class StatusDetectionTest { @Test public void detect_status() { Table<String, String, String> t = ImmutableTable.of(); - ProjectSettingsRepo ref = new ProjectSettingsRepo(t, createTable(), null); + ProjectRepositories ref = new ProjectRepositories(t, createTable(), null); StatusDetection statusDetection = new StatusDetection(ref); assertThat(statusDetection.status("foo", "src/Foo.java", "ABCDE")).isEqualTo(InputFile.Status.SAME); diff --git a/sonar-batch/src/test/resources/org/sonar/batch/repository/DefaultProjectRepositoriesLoaderTest/sample_response.json b/sonar-batch/src/test/resources/org/sonar/batch/repository/DefaultProjectRepositoriesLoaderTest/sample_response.json deleted file mode 100644 index 24522c42e15..00000000000 --- a/sonar-batch/src/test/resources/org/sonar/batch/repository/DefaultProjectRepositoriesLoaderTest/sample_response.json +++ /dev/null @@ -1,2093 +0,0 @@ -{ - "timestamp": 0, - "qprofilesByLanguage": { - "java": { - "key": "java-sonar-way-95117", - "name": "Sonar way", - "language": "java", - "rulesUpdatedAt": "2015-08-06T17:02:00+0200" - } - }, - "activeRules": [ - { - "repositoryKey": "common-java", - "ruleKey": "DuplicatedBlocks", - "name": "Source files should not have any duplicated blocks", - "severity": "MAJOR", - "language": "java", - "params": {} - }, - { - "repositoryKey": "common-java", - "ruleKey": "InsufficientBranchCoverage", - "name": "Branches should have sufficient coverage by unit tests", - "severity": "MAJOR", - "language": "java", - "params": { - "minimumBranchCoverageRatio": "65.0" - } - }, - { - "repositoryKey": "squid", - "ruleKey": "S00105", - "name": "Tabulation characters should not be used", - "severity": "MINOR", - "internalKey": "S00105", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "MethodCyclomaticComplexity", - "name": "Methods should not be too complex", - "severity": "MAJOR", - "internalKey": "MethodCyclomaticComplexity", - "language": "java", - "params": { - "Threshold": "10" - } - }, - { - "repositoryKey": "squid", - "ruleKey": "ClassCyclomaticComplexity", - "name": "Classes should not be too complex", - "severity": "MAJOR", - "internalKey": "ClassCyclomaticComplexity", - "language": "java", - "params": { - "max": "200" - } - }, - { - "repositoryKey": "squid", - "ruleKey": "CommentedOutCodeLine", - "name": "Sections of code should not be \"commented out\"", - "severity": "MAJOR", - "internalKey": "CommentedOutCodeLine", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S00108", - "name": "Nested blocks of code should not be left empty", - "severity": "MAJOR", - "internalKey": "S00108", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S00107", - "name": "Methods should not have too many parameters", - "severity": "MAJOR", - "internalKey": "S00107", - "language": "java", - "params": { - "max": "7", - "constructorMax": "7" - } - }, - { - "repositoryKey": "squid", - "ruleKey": "S00112", - "name": "Generic exceptions should never be thrown", - "severity": "MAJOR", - "internalKey": "S00112", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S00100", - "name": "Method names should comply with a naming convention", - "severity": "MINOR", - "internalKey": "S00100", - "language": "java", - "params": { - "format": "^[a-z][a-zA-Z0-9]*$" - } - }, - { - "repositoryKey": "squid", - "ruleKey": "S00101", - "name": "Class names should comply with a naming convention", - "severity": "MINOR", - "internalKey": "S00101", - "language": "java", - "params": { - "format": "^[A-Z][a-zA-Z0-9]*$" - } - }, - { - "repositoryKey": "squid", - "ruleKey": "S00114", - "name": "Interface names should comply with a naming convention", - "severity": "MINOR", - "internalKey": "S00114", - "language": "java", - "params": { - "format": "^[A-Z][a-zA-Z0-9]*$" - } - }, - { - "repositoryKey": "squid", - "ruleKey": "S00115", - "name": "Constant names should comply with a naming convention", - "severity": "MINOR", - "internalKey": "S00115", - "language": "java", - "params": { - "format": "^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$" - } - }, - { - "repositoryKey": "squid", - "ruleKey": "S00116", - "name": "Field names should comply with a naming convention", - "severity": "MINOR", - "internalKey": "S00116", - "language": "java", - "params": { - "format": "^[a-z][a-zA-Z0-9]*$" - } - }, - { - "repositoryKey": "squid", - "ruleKey": "S3008", - "name": "Static non-final field names should comply with a naming convention", - "severity": "MINOR", - "internalKey": "S3008", - "language": "java", - "params": { - "format": "^[a-z][a-zA-Z0-9]*$" - } - }, - { - "repositoryKey": "squid", - "ruleKey": "S00117", - "name": "Local variable and method parameter names should comply with a naming convention", - "severity": "MINOR", - "internalKey": "S00117", - "language": "java", - "params": { - "format": "^[a-z][a-zA-Z0-9]*$" - } - }, - { - "repositoryKey": "squid", - "ruleKey": "S00119", - "name": "Type parameter names should comply with a naming convention", - "severity": "MINOR", - "internalKey": "S00119", - "language": "java", - "params": { - "format": "^[A-Z][0-9]?$" - } - }, - { - "repositoryKey": "squid", - "ruleKey": "S00120", - "name": "Package names should comply with a naming convention", - "severity": "MINOR", - "internalKey": "S00120", - "language": "java", - "params": { - "format": "^[a-z]+(\\.[a-z][a-z0-9]*)*$" - } - }, - { - "repositoryKey": "squid", - "ruleKey": "S00122", - "name": "Statements should be on separate lines", - "severity": "MINOR", - "internalKey": "S00122", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "RightCurlyBraceStartLineCheck", - "name": "A close curly brace should be located at the beginning of a line", - "severity": "MINOR", - "internalKey": "RightCurlyBraceStartLineCheck", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "UselessParenthesesCheck", - "name": "Useless parentheses around expressions should be removed to prevent any misunderstanding", - "severity": "MAJOR", - "internalKey": "UselessParenthesesCheck", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "ObjectFinalizeCheck", - "name": "The Object.finalize() method should not be called", - "severity": "CRITICAL", - "internalKey": "ObjectFinalizeCheck", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "ObjectFinalizeOverridenCheck", - "name": "The Object.finalize() method should not be overriden", - "severity": "CRITICAL", - "internalKey": "ObjectFinalizeOverridenCheck", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "ObjectFinalizeOverridenCallsSuperFinalizeCheck", - "name": "super.finalize() should be called at the end of Object.finalize() implementations", - "severity": "BLOCKER", - "internalKey": "ObjectFinalizeOverridenCallsSuperFinalizeCheck", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "ClassVariableVisibilityCheck", - "name": "Class variable fields should not have public accessibility", - "severity": "MAJOR", - "internalKey": "ClassVariableVisibilityCheck", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "ForLoopCounterChangedCheck", - "name": "\"for\" loop stop conditions should be invariant", - "severity": "MAJOR", - "internalKey": "ForLoopCounterChangedCheck", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "LabelsShouldNotBeUsedCheck", - "name": "Labels should not be used", - "severity": "MAJOR", - "internalKey": "LabelsShouldNotBeUsedCheck", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "SwitchLastCaseIsDefaultCheck", - "name": "\"switch\" statements should end with a \"default\" clause", - "severity": "MAJOR", - "internalKey": "SwitchLastCaseIsDefaultCheck", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "EmptyStatementUsageCheck", - "name": "Empty statements should be removed", - "severity": "MINOR", - "internalKey": "EmptyStatementUsageCheck", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "ModifiersOrderCheck", - "name": "Modifiers should be declared in the correct order", - "severity": "MINOR", - "internalKey": "ModifiersOrderCheck", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "AssignmentInSubExpressionCheck", - "name": "Assignments should not be made from within sub-expressions", - "severity": "MAJOR", - "internalKey": "AssignmentInSubExpressionCheck", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "UselessImportCheck", - "name": "Useless imports should be removed", - "severity": "MINOR", - "internalKey": "UselessImportCheck", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "LowerCaseLongSuffixCheck", - "name": "Long suffix \"L\" should be upper case", - "severity": "MINOR", - "internalKey": "LowerCaseLongSuffixCheck", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "MissingDeprecatedCheck", - "name": "Deprecated elements should have both the annotation and the Javadoc tag", - "severity": "MAJOR", - "internalKey": "MissingDeprecatedCheck", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "HiddenFieldCheck", - "name": "Local variables should not shadow class fields", - "severity": "MAJOR", - "internalKey": "HiddenFieldCheck", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1133", - "name": "Deprecated code should be removed eventually", - "severity": "INFO", - "internalKey": "S1133", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1134", - "name": "\"FIXME\" tags should be handled", - "severity": "MAJOR", - "internalKey": "S1134", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1135", - "name": "\"TODO\" tags should be handled", - "severity": "INFO", - "internalKey": "S1135", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1118", - "name": "Utility classes should not have public constructors", - "severity": "MAJOR", - "internalKey": "S1118", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1132", - "name": "Strings literals should be placed on the left side when checking for equality", - "severity": "MAJOR", - "internalKey": "S1132", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1126", - "name": "Return of boolean expressions should not be wrapped into an \"if-then-else\" statement", - "severity": "MINOR", - "internalKey": "S1126", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1125", - "name": "Literal boolean values should not be used in condition expressions", - "severity": "MINOR", - "internalKey": "S1125", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1067", - "name": "Expressions should not be too complex", - "severity": "MAJOR", - "internalKey": "S1067", - "language": "java", - "params": { - "max": "3" - } - }, - { - "repositoryKey": "squid", - "ruleKey": "S1141", - "name": "Try-catch blocks should not be nested", - "severity": "MAJOR", - "internalKey": "S1141", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1147", - "name": "Exit methods should not be called", - "severity": "CRITICAL", - "internalKey": "S1147", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1143", - "name": "\"return\" statements should not occur in \"finally\" blocks", - "severity": "BLOCKER", - "internalKey": "S1143", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1157", - "name": "Case insensitive string comparisons should be made without intermediate upper or lower casing", - "severity": "MAJOR", - "internalKey": "S1157", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1155", - "name": "Collection.isEmpty() should be used to test for emptiness", - "severity": "MAJOR", - "internalKey": "S1155", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1149", - "name": "Synchronized classes Vector, Hashtable, Stack and StringBuffer should not be used", - "severity": "MAJOR", - "internalKey": "S1149", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1171", - "name": "Only static class initializers should be used", - "severity": "MAJOR", - "internalKey": "S1171", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1168", - "name": "Empty arrays and collections should be returned instead of null", - "severity": "MAJOR", - "internalKey": "S1168", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1170", - "name": "Public constants and fields initialized at declaration should be \"static final\" rather than merely \"final\"", - "severity": "MINOR", - "internalKey": "S1170", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1163", - "name": "Exceptions should not be thrown in finally blocks", - "severity": "MAJOR", - "internalKey": "S1163", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S106", - "name": "Standard ouputs should not be used directly to log anything", - "severity": "MAJOR", - "internalKey": "S106", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1165", - "name": "Exception classes should be immutable", - "severity": "MAJOR", - "internalKey": "S1165", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1066", - "name": "Collapsible \"if\" statements should be merged", - "severity": "MAJOR", - "internalKey": "S1066", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S134", - "name": "Control flow statements \"if\", \"for\", \"while\", \"switch\" and \"try\" should not be nested too deeply", - "severity": "MAJOR", - "internalKey": "S134", - "language": "java", - "params": { - "max": "3" - } - }, - { - "repositoryKey": "squid", - "ruleKey": "S1181", - "name": "Throwable and Error should not be caught", - "severity": "BLOCKER", - "internalKey": "S1181", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1150", - "name": "Enumeration should not be implemented", - "severity": "MAJOR", - "internalKey": "S1150", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1182", - "name": "Classes that override \"clone\" should be \"Cloneable\" and call \"super.clone()\"", - "severity": "MAJOR", - "internalKey": "S1182", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1151", - "name": "\"switch case\" clauses should not have too many lines", - "severity": "MAJOR", - "internalKey": "S1151", - "language": "java", - "params": { - "max": "5" - } - }, - { - "repositoryKey": "squid", - "ruleKey": "S128", - "name": "Switch cases should end with an unconditional \"break\" statement", - "severity": "CRITICAL", - "internalKey": "S128", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1166", - "name": "Exception handlers should preserve the original exception", - "severity": "CRITICAL", - "internalKey": "S1166", - "language": "java", - "params": { - "exceptions": "java.lang.InterruptedException, java.lang.NumberFormatException, java.text.ParseException, java.net.MalformedURLException" - } - }, - { - "repositoryKey": "squid", - "ruleKey": "S1190", - "name": "Future keywords should not be used as names", - "severity": "MAJOR", - "internalKey": "S1190", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1188", - "name": "Lambdas and anonymous classes should not have too many lines", - "severity": "MAJOR", - "internalKey": "S1188", - "language": "java", - "params": { - "Max": "20" - } - }, - { - "repositoryKey": "squid", - "ruleKey": "S1191", - "name": "Classes from \"sun.*\" packages should not be used", - "severity": "MAJOR", - "internalKey": "S1191", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S135", - "name": "Loops should not contain more than a single \"break\" or \"continue\" statement", - "severity": "MAJOR", - "internalKey": "S135", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1186", - "name": "Methods should not be empty", - "severity": "MAJOR", - "internalKey": "S1186", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1185", - "name": "Overriding methods should do more than simply call the same method in the super class", - "severity": "MINOR", - "internalKey": "S1185", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1174", - "name": "\"Object.finalize()\" should remain protected (versus public) when overriding", - "severity": "MAJOR", - "internalKey": "S1174", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1175", - "name": "The signature of \"finalize()\" should match that of \"Object.finalize()\"", - "severity": "MAJOR", - "internalKey": "S1175", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1153", - "name": "String.valueOf() should not be appended to a String", - "severity": "MINOR", - "internalKey": "S1153", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1148", - "name": "Throwable.printStackTrace(...) should not be called", - "severity": "CRITICAL", - "internalKey": "S1148", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1195", - "name": "Array designators \"[]\" should be located after the type in method signatures", - "severity": "MINOR", - "internalKey": "S1195", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1194", - "name": "\"java.lang.Error\" should not be extended", - "severity": "MAJOR", - "internalKey": "S1194", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1193", - "name": "Exception types should not be tested using \"instanceof\" in catch blocks", - "severity": "MAJOR", - "internalKey": "S1193", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1192", - "name": "String literals should not be duplicated", - "severity": "MINOR", - "internalKey": "S1192", - "language": "java", - "params": { - "threshold": "3" - } - }, - { - "repositoryKey": "squid", - "ruleKey": "S1158", - "name": "Primitive wrappers should not be instantiated only for \"toString\" or \"compareTo\" calls", - "severity": "MAJOR", - "internalKey": "S1158", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1215", - "name": "Execution of the Garbage Collector should be triggered only by the JVM", - "severity": "CRITICAL", - "internalKey": "S1215", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1197", - "name": "Array designators \"[]\" should be on the type, not the variable", - "severity": "MINOR", - "internalKey": "S1197", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1220", - "name": "The default unnamed package should not be used", - "severity": "MINOR", - "internalKey": "S1220", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1221", - "name": "Methods should not be named \"hashcode\" or \"equal\"", - "severity": "CRITICAL", - "internalKey": "S1221", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1199", - "name": "Nested code blocks should not be used", - "severity": "MAJOR", - "internalKey": "S1199", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1214", - "name": "Constants should not be defined in interfaces", - "severity": "MINOR", - "internalKey": "S1214", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1201", - "name": "Methods named \"equals\" should override Object.equals(Object)", - "severity": "CRITICAL", - "internalKey": "S1201", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1210", - "name": "\"equals(Object obj)\" should be overridden along with the \"compareTo(T obj)\" method", - "severity": "CRITICAL", - "internalKey": "S1210", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1206", - "name": "\"equals(Object obj)\" and \"hashCode()\" should be overridden in pairs", - "severity": "BLOCKER", - "internalKey": "S1206", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1219", - "name": "\"switch\" statements should not contain non-case labels", - "severity": "CRITICAL", - "internalKey": "S1219", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1301", - "name": "\"switch\" statements should have at least 3 \"case\" clauses", - "severity": "MINOR", - "internalKey": "S1301", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1314", - "name": "Octal values should not be used", - "severity": "MAJOR", - "internalKey": "S1314", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1226", - "name": "Method parameters, caught exceptions and foreach variables should not be reassigned", - "severity": "MAJOR", - "internalKey": "S1226", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1313", - "name": "IP addresses should not be hardcoded", - "severity": "MAJOR", - "internalKey": "S1313", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1312", - "name": "Loggers should be \"private static final\" and should share a naming convention", - "severity": "MINOR", - "internalKey": "S1312", - "language": "java", - "params": { - "format": "LOG(?:GER)?" - } - }, - { - "repositoryKey": "squid", - "ruleKey": "S1223", - "name": "Non-constructor methods should not have the same name as the enclosing class", - "severity": "MAJOR", - "internalKey": "S1223", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1319", - "name": "Declarations should use Java collection interfaces such as \"List\" rather than specific implementation classes such as \"LinkedList\"", - "severity": "MAJOR", - "internalKey": "S1319", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1213", - "name": "The members of an interface declaration or class should appear in a pre-defined order", - "severity": "MINOR", - "internalKey": "S1213", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1444", - "name": ":", - "severity": "CRITICAL", - "internalKey": "S1444", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1452", - "name": "Generic wildcard types should not be used in return parameters", - "severity": "MAJOR", - "internalKey": "S1452", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1481", - "name": "Unused local variables should be removed", - "severity": "MAJOR", - "internalKey": "S1481", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1068", - "name": "Unused private fields should be removed", - "severity": "MAJOR", - "internalKey": "S1068", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1317", - "name": "\"StringBuilder\" and \"StringBuffer\" should not be instantiated with a character", - "severity": "MAJOR", - "internalKey": "S1317", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1596", - "name": "Collections.emptyList(), emptyMap() and emptySet() should be used instead of Collections.EMPTY_LIST, EMPTY_MAP and EMPTY_SET", - "severity": "MAJOR", - "internalKey": "S1596", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "UnusedPrivateMethod", - "name": "Unused private method should be removed", - "severity": "MAJOR", - "internalKey": "UnusedPrivateMethod", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "RedundantThrowsDeclarationCheck", - "name": "Throws declarations should not be superfluous", - "severity": "MINOR", - "internalKey": "RedundantThrowsDeclarationCheck", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1160", - "name": "Public methods should throw at most one checked exception", - "severity": "MAJOR", - "internalKey": "S1160", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1217", - "name": "Thread.run() and Runnable.run() should not be called directly", - "severity": "CRITICAL", - "internalKey": "S1217", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1862", - "name": "Related \"if/else if\" statements should not have the same condition", - "severity": "CRITICAL", - "internalKey": "S1862", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1488", - "name": "Local Variables should not be declared and then immediately returned or thrown", - "severity": "MINOR", - "internalKey": "S1488", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1602", - "name": "Lamdbas containing only one statement should not nest this statement in a block", - "severity": "MAJOR", - "internalKey": "S1602", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1611", - "name": "Parentheses should be removed from a single lambda input parameter when its type is inferred", - "severity": "MINOR", - "internalKey": "S1611", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1700", - "name": "A field should not duplicate the name of its containing class", - "severity": "MAJOR", - "internalKey": "S1700", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1172", - "name": "Unused method parameters should be removed", - "severity": "MAJOR", - "internalKey": "S1172", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1598", - "name": "Package declaration should match source file directory", - "severity": "MAJOR", - "internalKey": "S1598", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1873", - "name": "\"static final\" arrays should be \"private\"", - "severity": "CRITICAL", - "internalKey": "S1873", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1948", - "name": "Fields in a \"Serializable\" class should either be transient or serializable", - "severity": "CRITICAL", - "internalKey": "S1948", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1479", - "name": "\"switch\" statements should not have too many \"case\" clauses", - "severity": "MAJOR", - "internalKey": "S1479", - "language": "java", - "params": { - "maximum": "30" - } - }, - { - "repositoryKey": "squid", - "ruleKey": "S1764", - "name": "Identical expressions should not be used on both sides of a binary operator", - "severity": "CRITICAL", - "internalKey": "S1764", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1244", - "name": "Floating point numbers should not be tested for equality", - "severity": "CRITICAL", - "internalKey": "S1244", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2077", - "name": "Values passed to SQL commands should be sanitized", - "severity": "CRITICAL", - "internalKey": "S2077", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1161", - "name": "\"@Override\" annotation should be used on any method overriding (since Java 5) or implementing (since Java 6) another one", - "severity": "MAJOR", - "internalKey": "S1161", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1994", - "name": "\"for\" loop incrementers should modify the variable being tested in the loop\u0027s stop condition", - "severity": "CRITICAL", - "internalKey": "S1994", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2094", - "name": "Classes should not be empty", - "severity": "MAJOR", - "internalKey": "S2094", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1850", - "name": "\"instanceof\" operators that always return \"true\" or \"false\" should be removed", - "severity": "MAJOR", - "internalKey": "S1850", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1905", - "name": "Redundant casts should not be used", - "severity": "MINOR", - "internalKey": "S1905", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2114", - "name": "Collections should not be passed as arguments to their own methods", - "severity": "CRITICAL", - "internalKey": "S2114", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1065", - "name": "Unused labels should be removed", - "severity": "MAJOR", - "internalKey": "S1065", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2184", - "name": "Math operands should be cast before assignment", - "severity": "MAJOR", - "internalKey": "S2184", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2225", - "name": "\"toString()\" and \"clone()\" methods should not return null", - "severity": "CRITICAL", - "internalKey": "S2225", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2230", - "name": "Non-public methods should not be \"@Transactional\"", - "severity": "CRITICAL", - "internalKey": "S2230", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2200", - "name": "\"compareTo\" results should not be checked for specific values", - "severity": "MAJOR", - "internalKey": "S2200", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2092", - "name": "Cookies should be \"secure\"", - "severity": "CRITICAL", - "internalKey": "S2092", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1848", - "name": "Objects should not be created to be dropped immediately without being used", - "severity": "CRITICAL", - "internalKey": "S1848", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2235", - "name": "IllegalMonitorStateException should not be caught", - "severity": "CRITICAL", - "internalKey": "S2235", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S888", - "name": "Relational operators should be used in \"for\" loop termination conditions", - "severity": "CRITICAL", - "internalKey": "S888", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2068", - "name": "Credentials should not be hard-coded", - "severity": "CRITICAL", - "internalKey": "S2068", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2232", - "name": "\"ResultSet.isLast()\" should not be used", - "severity": "CRITICAL", - "internalKey": "S2232", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1849", - "name": "\"Iterator.hasNext()\" should not call \"Iterator.next()\"", - "severity": "BLOCKER", - "internalKey": "S1849", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2236", - "name": "Methods \"wait(...)\", \"notify()\" and \"notifyAll()\" should never be called on Thread instances", - "severity": "BLOCKER", - "internalKey": "S2236", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1844", - "name": "\"Object.wait(...)\" should never be called on objects that implement \"java.util.concurrent.locks.Condition\"", - "severity": "BLOCKER", - "internalKey": "S1844", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2251", - "name": "A \"for\" loop update clause should move the counter in the right direction", - "severity": "BLOCKER", - "internalKey": "S2251", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2252", - "name": "Loop conditions should be true at least once", - "severity": "CRITICAL", - "internalKey": "S2252", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2254", - "name": "\"HttpServletRequest.getRequestedSessionId()\" should not be used", - "severity": "CRITICAL", - "internalKey": "S2254", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2250", - "name": "\"ConcurrentLinkedQueue.size()\" should not be used", - "severity": "CRITICAL", - "internalKey": "S2250", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2226", - "name": "Servlets should never have mutable instance fields", - "severity": "CRITICAL", - "internalKey": "S2226", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2111", - "name": "\"BigDecimal(double)\" should not be used", - "severity": "CRITICAL", - "internalKey": "S2111", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2109", - "name": "Reflection should not be used to check non-runtime annotations", - "severity": "BLOCKER", - "internalKey": "S2109", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2273", - "name": "\"wait(...)\", \"notify()\" and \"notifyAll()\" methods should only be called when a lock is obviously held on an object", - "severity": "CRITICAL", - "internalKey": "S2273", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2276", - "name": "\"wait(...)\" should be used instead of \"Thread.sleep(...)\" when a lock is held", - "severity": "CRITICAL", - "internalKey": "S2276", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2274", - "name": "\"Object.wait(...)\" and \"Condition.await(...)\" should be called inside a \"while\" loop", - "severity": "CRITICAL", - "internalKey": "S2274", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2272", - "name": "\"Iterator.next()\" methods should throw \"NoSuchElementException\"", - "severity": "MAJOR", - "internalKey": "S2272", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2277", - "name": "Cryptographic RSA algorithms should always incorporate OAEP (Optimal Asymmetric Encryption Padding)", - "severity": "CRITICAL", - "internalKey": "S2277", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2204", - "name": "\".equals()\" should not be used to test the values of \"Atomic\" classes", - "severity": "BLOCKER", - "internalKey": "S2204", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2178", - "name": "Short-circuit logic should be used in boolean contexts", - "severity": "CRITICAL", - "internalKey": "S2178", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2116", - "name": "\"hashCode\" and \"toString\" should not be called on array instances", - "severity": "CRITICAL", - "internalKey": "S2116", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2157", - "name": "\"Cloneables\" should implement \"clone\"", - "severity": "CRITICAL", - "internalKey": "S2157", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2275", - "name": "Printf-style format strings should not lead to unexpected behavior at runtime", - "severity": "CRITICAL", - "internalKey": "S2275", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2151", - "name": "\"runFinalizersOnExit\" should not be called", - "severity": "BLOCKER", - "internalKey": "S2151", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2127", - "name": "\"Double.longBitsToDouble\" should not be used for \"int\"", - "severity": "BLOCKER", - "internalKey": "S2127", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1860", - "name": "Synchronization should not be based on Strings or boxed primitives", - "severity": "BLOCKER", - "internalKey": "S1860", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2055", - "name": "The non-serializable super class of a \"Serializable\" class must have a no-argument constructor", - "severity": "CRITICAL", - "internalKey": "S2055", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2118", - "name": "Non-serializable classes should not be written", - "severity": "CRITICAL", - "internalKey": "S2118", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2066", - "name": "\"Serializable\" inner classes of non-serializable classes should be \"static\"", - "severity": "CRITICAL", - "internalKey": "S2066", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2065", - "name": "Fields in non-serializable classes should not be \"transient\"", - "severity": "MINOR", - "internalKey": "S2065", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2061", - "name": "Custom serialization method signatures should meet requirements", - "severity": "CRITICAL", - "internalKey": "S2061", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2176", - "name": "Class names should not shadow interfaces or superclasses", - "severity": "MAJOR", - "internalKey": "S2176", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2130", - "name": "Parsing should be used to convert \"Strings\" to primitives", - "severity": "MAJOR", - "internalKey": "S2130", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2166", - "name": "Classes named like \"Exception\" should extend \"Exception\" or a subclass", - "severity": "MAJOR", - "internalKey": "S2166", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2153", - "name": "Boxing and unboxing should not be immediately reversed", - "severity": "MAJOR", - "internalKey": "S2153", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2326", - "name": "Unused type parameters should be removed", - "severity": "MAJOR", - "internalKey": "S2326", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2386", - "name": "Interfaces should not have \"public static\" mutable fields", - "severity": "CRITICAL", - "internalKey": "S2386", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2183", - "name": "Ints and longs should not be shifted by more than their number of bits-1", - "severity": "CRITICAL", - "internalKey": "S2183", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2167", - "name": "\"compareTo\" should not return \"Integer.MIN_VALUE\"", - "severity": "CRITICAL", - "internalKey": "S2167", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2165", - "name": "\"finalize\" should not set fields to \"null\"", - "severity": "MAJOR", - "internalKey": "S2165", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2122", - "name": "\"ScheduledThreadPoolExecutor\" should not have 0 core threads", - "severity": "BLOCKER", - "internalKey": "S2122", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2134", - "name": "Classes extending java.lang.Thread should override the \"run\" method", - "severity": "MAJOR", - "internalKey": "S2134", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2175", - "name": "Inappropriate \"Collection\" calls should not be made", - "severity": "CRITICAL", - "internalKey": "S2175", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2447", - "name": "Null should not be returned from a \"Boolean\" method", - "severity": "CRITICAL", - "internalKey": "S2447", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2131", - "name": "Primitives should not be boxed just for \"String\" conversion", - "severity": "MAJOR", - "internalKey": "S2131", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2437", - "name": "Silly bit operations should not be performed", - "severity": "MAJOR", - "internalKey": "S2437", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2110", - "name": "Invalid \"Date\" values should not be used", - "severity": "CRITICAL", - "internalKey": "S2110", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2160", - "name": "Subclasses that add fields should override \"equals\"", - "severity": "MAJOR", - "internalKey": "S2160", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1872", - "name": "Classes should not be compared by name", - "severity": "CRITICAL", - "internalKey": "S1872", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2440", - "name": "Classes with only \"static\" methods should not be instantiated", - "severity": "MAJOR", - "internalKey": "S2440", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2441", - "name": "Non-serializable objects should not be stored in \"HttpSessions\"", - "severity": "CRITICAL", - "internalKey": "S2441", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2123", - "name": "Values should not be uselessly incremented", - "severity": "CRITICAL", - "internalKey": "S2123", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2133", - "name": "Objects should not be created only to \"getClass\"", - "severity": "MAJOR", - "internalKey": "S2133", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2154", - "name": "Dissimilar primitive wrappers should not be used with the ternary operator without explicit casting", - "severity": "CRITICAL", - "internalKey": "S2154", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2442", - "name": "\"Lock\" objects should not be \"synchronized\"", - "severity": "BLOCKER", - "internalKey": "S2442", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2388", - "name": "Inner class calls to super class methods should be unambiguous", - "severity": "MAJOR", - "internalKey": "S2388", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2438", - "name": "\"Threads\" should not be used where \"Runnables\" are expected", - "severity": "CRITICAL", - "internalKey": "S2438", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2259", - "name": "Null pointers should not be dereferenced", - "severity": "BLOCKER", - "internalKey": "S2259", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2583", - "name": "Conditions should not unconditionally evaluate to \"TRUE\" or to \"FALSE\"", - "severity": "BLOCKER", - "internalKey": "S2583", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2696", - "name": "Instance methods should not write to \"static\" fields", - "severity": "CRITICAL", - "internalKey": "S2696", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2674", - "name": "The value returned from a stream read should be checked", - "severity": "CRITICAL", - "internalKey": "S2674", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2695", - "name": "\"PreparedStatement\" and \"ResultSet\" methods should be called with valid indices", - "severity": "BLOCKER", - "internalKey": "S2695", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2112", - "name": "\"URL.hashCode\" and \"URL.equals\" should be avoided", - "severity": "CRITICAL", - "internalKey": "S2112", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2387", - "name": "Child class members should not shadow parent class members", - "severity": "MAJOR", - "internalKey": "S2387", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2786", - "name": "Nested \"enum\"s should not be declared static", - "severity": "MAJOR", - "internalKey": "S2786", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2095", - "name": "Resources should be closed", - "severity": "BLOCKER", - "internalKey": "S2095", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2677", - "name": "\"read\" and \"readLine\" return values should be used", - "severity": "BLOCKER", - "internalKey": "S2677", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1858", - "name": "\"toString()\" should never be called on a String object", - "severity": "MAJOR", - "internalKey": "S1858", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2864", - "name": "\"entrySet()\" should be iterated when both the key and value are needed", - "severity": "MAJOR", - "internalKey": "S2864", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2692", - "name": "\"indexOf\" checks should not be for positive numbers", - "severity": "CRITICAL", - "internalKey": "S2692", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2675", - "name": "\"readObject\" should not be \"synchronized\"", - "severity": "MAJOR", - "internalKey": "S2675", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2676", - "name": "Neither \"Math.abs\" nor negation should be used on numbers that could be \"MIN_VALUE\"", - "severity": "CRITICAL", - "internalKey": "S2676", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2885", - "name": "\"Calendars\" and \"DateFormats\" should not be static", - "severity": "CRITICAL", - "internalKey": "S2885", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2222", - "name": "Locks should be released", - "severity": "CRITICAL", - "internalKey": "S2222", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2097", - "name": "\"equals(Object obj)\" should test argument type", - "severity": "BLOCKER", - "internalKey": "S2097", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2185", - "name": "Silly math should not be performed", - "severity": "MAJOR", - "internalKey": "S2185", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2159", - "name": "Silly equality checks should not be made", - "severity": "MAJOR", - "internalKey": "S2159", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2912", - "name": "\"indexOf\" checks should use a start position", - "severity": "MAJOR", - "internalKey": "S2912", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2325", - "name": "\"private\" methods that don\u0027t access instance data should be \"static\"", - "severity": "MINOR", - "internalKey": "S2325", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1264", - "name": "A \"while\" loop should be used instead of a \"for\" loop", - "severity": "MINOR", - "internalKey": "S1264", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2681", - "name": "Multiline blocks should be enclosed in curly braces", - "severity": "CRITICAL", - "internalKey": "S2681", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S1640", - "name": "Maps with keys that are enum values should be replaced with EnumMap", - "severity": "MAJOR", - "internalKey": "S1640", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2976", - "name": "\"File.createTempFile\" should not be used to create a directory", - "severity": "CRITICAL", - "internalKey": "S2976", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2188", - "name": "JUnit test cases should call super methods", - "severity": "CRITICAL", - "internalKey": "S2188", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2186", - "name": "JUnit assertions should not be used in \"run\" methods", - "severity": "CRITICAL", - "internalKey": "S2186", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2187", - "name": "TestCases should contain tests", - "severity": "MAJOR", - "internalKey": "S2187", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2391", - "name": "JUnit framework methods should be declared properly", - "severity": "CRITICAL", - "internalKey": "S2391", - "language": "java", - "params": {} - }, - { - "repositoryKey": "squid", - "ruleKey": "S2970", - "name": "Assertions should be complete", - "severity": "CRITICAL", - "internalKey": "S2970", - "language": "java", - "params": {} - } - ], - "settingsByModule": {}, - "fileDataByModuleAndPath": { - "my:project": { - "src/test/java/org/sonar/plugins/scm/jazzrtc/UTCRule.java": { - "hash": "e80b5df219bc78ed5c498988d9f23d37", - "needBlame": true - }, - "src/test/java/org/sonar/plugins/scm/jazzrtc/JazzRtcScmProviderTest.java": { - "hash": "6f4f93e1016714869a2008de7df3d207", - "needBlame": true - }, - "src/test/java/org/sonar/plugins/scm/jazzrtc/JazzRtcBlameCommandTest.java": { - "hash": "0ab25adb0ae40d826ea23998a362a7ef", - "needBlame": true - }, - "src/main/java/org/sonar/plugins/scm/jazzrtc/JazzRtcConfiguration.java": { - "hash": "23961c33f6388248ae3530dbc8988e72", - "needBlame": true - }, - "src/main/java/org/sonar/plugins/scm/jazzrtc/package-info.java": { - "hash": "afdb44120bc13f6fd36be27040408ac0", - "needBlame": true - }, - "src/test/java/org/sonar/plugins/scm/jazzrtc/JazzRtcBlameConsumerTest.java": { - "hash": "cd9f105580a53c702e0b721899314348", - "needBlame": true - }, - "src/main/java/org/sonar/plugins/scm/jazzrtc/JazzRtcBlameConsumer.java": { - "hash": "fff6441cd4193c275f12221355658883", - "needBlame": true - }, - "src/main/java/org/sonar/plugins/scm/jazzrtc/JazzRtcScmProvider.java": { - "hash": "f047b734b6653a5126f8c278dc6aa1a5", - "needBlame": true - }, - "src/test/java/org/sonar/plugins/scm/jazzrtc/JazzRtcPluginTest.java": { - "hash": "688b065dcf12a55b363acf7901f9a6de", - "needBlame": true - }, - "src/main/java/org/sonar/plugins/scm/jazzrtc/JazzRtcBlameCommand.java": { - "hash": "9646e0be0c460017af98505e8ab5578a", - "needBlame": true - }, - "src/main/java/org/sonar/plugins/scm/jazzrtc/JazzRtcPlugin.java": { - "hash": "c9fd9a67b28d610165edbb29d8975d00", - "needBlame": true - } - } - }, - "lastAnalysisDate": "2015-08-06T17:06:58+0200" -}
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/repository/DefaultQualityProfileLoaderTest/quality_profile_search_default b/sonar-batch/src/test/resources/org/sonar/batch/repository/DefaultQualityProfileLoaderTest/quality_profile_search_default Binary files differnew file mode 100644 index 00000000000..6780d7338a1 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/repository/DefaultQualityProfileLoaderTest/quality_profile_search_default diff --git a/sonar-batch/src/test/resources/org/sonar/batch/rule/DefaultActiveRulesLoaderTest/active_rule_search.protobuf b/sonar-batch/src/test/resources/org/sonar/batch/rule/DefaultActiveRulesLoaderTest/active_rule_search.protobuf new file mode 100644 index 00000000000..18d0a1284a8 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/rule/DefaultActiveRulesLoaderTest/active_rule_search.protobuf @@ -0,0 +1,105 @@ +¾d"Z +squid:S1194squid("java.lang.Error" should not be extendedRMAJORbS1194šjava¢Java"× +4squid:ObjectFinalizeOverridenCallsSuperFinalizeChecksquidQsuper.finalize() should be called at the end of Object.finalize() implementationsRBLOCKERb.ObjectFinalizeOverridenCallsSuperFinalizeCheckšjava¢Java"f +squid:S2078squid1Values passed to LDAP queries should be sanitizedRCRITICALbS2078šjava¢Java"~ +squid:S1195squidLArray designators "[]" should be located after the type in method signaturesRMINORbS1195šjava¢Java"k + +squid:S106squid;Standard ouputs should not be used directly to log anythingRMAJORbS106šjava¢Java"Z +squid:S1192squid(String literals should not be duplicatedRMINORbS1192šjava¢Java"P + +squid:S109squid Magic numbers should not be usedRMINORbS109šjava¢Java"f +squid:S2077squid1Values passed to SQL commands should be sanitizedRCRITICALbS2077šjava¢Java"e +squid:S2076squid0Values passed to OS commands should be sanitizedRCRITICALbS2076šjava¢Java"y +squid:S1193squidGException types should not be tested using "instanceof" in catch blocksRMAJORbS1193šjava¢Java"] +squid:S1190squid+Future keywords should not be used as namesRMAJORbS1190šjava¢Java"b +squid:S1191squid0Classes from "sun.*" packages should not be usedRMAJORbS1191šjava¢Java"6 +squid:S1444squid:RCRITICALbS1444šjava¢Java"x +squid:S2864squidF"entrySet()" should be iterated when both the key and value are neededRMAJORbS2864šjava¢Java"¢ +#squid:RightCurlyBraceStartLineChecksquid@A close curly brace should be located at the beginning of a lineRMINORbRightCurlyBraceStartLineCheckšjava¢Java"p +squid:S2070squid;SHA-1 and Message-Digest hash algorithms should not be usedRCRITICALbS2070šjava¢Java"j +squid:S1849squid6"Iterator.hasNext()" should not call "Iterator.next()"RBLOCKERbS1849šjava¢Java"f +squid:S2301squid4Public methods should not contain selector argumentsRMAJORbS2301šjava¢Java" +squid:S1848squidJObjects should not be created to be dropped immediately without being usedRCRITICALbS1848šjava¢Java"W +squid:S1199squid%Nested code blocks should not be usedRMAJORbS1199šjava¢Java"ž +squid:S1844squidj"Object.wait(...)" should never be called on objects that implement "java.util.concurrent.locks.Condition"RBLOCKERbS1844šjava¢Java"p +squid:S1197squid>Array designators "[]" should be on the type, not the variableRMINORbS1197šjava¢Java"€ +squid:S2066squidK"Serializable" inner classes of non-serializable classes should be "static"RCRITICALbS2066šjava¢Java"n +squid:S2065squid<Fields in non-serializable classes should not be "transient"RMINORbS2065šjava¢Java"R +squid:S2970squidAssertions should be completeRCRITICALbS2970šjava¢Java"Y +squid:S2068squid$Credentials should not be hard-codedRCRITICALbS2068šjava¢Java"i +squid:S2974squid7Classes without "public" constructors should be "final"RMAJORbS2974šjava¢Java"s +squid:S2976squid>"File.createTempFile" should not be used to create a directoryRCRITICALbS2976šjava¢Java"Y +squid:S1068squid'Unused private fields should be removedRMAJORbS1068šjava¢Java"Q +squid:S1065squidUnused labels should be removedRMAJORbS1065šjava¢Java"} + squid:MethodCyclomaticComplexitysquid!Methods should not be too complexRMAJORbMethodCyclomaticComplexityšjava¢Java"z +squid:EmptyStatementUsageChecksquid"Empty statements should be removedRMINORbEmptyStatementUsageCheckšjava¢Java"W +squid:S1067squid%Expressions should not be too complexRMAJORbS1067šjava¢Java"^ +squid:S1066squid,Collapsible "if" statements should be mergedRMAJORbS1066šjava¢Java"t +squid:S2061squid?Custom serialization method signatures should meet requirementsRCRITICALbS2061šjava¢Java"Þ +-squid:RightCurlyBraceSameLineAsNextBlockChecksquidhClose curly brace and the next "else", "catch" and "finally" keywords should be located on the same lineRMINORb'RightCurlyBraceSameLineAsNextBlockCheckšjava¢Java"V +squid:S2063squid$Comparators should be "Serializable"RMAJORbS2063šjava¢Java"i +squid:S2701squid7Literal boolean values should not be used in assertionsRMAJORbS2701šjava¢Java"y +squid:S2059squidG"Serializable" inner classes of "Serializable" classes should be staticRMAJORbS2059šjava¢Java"a +squid:S2057squid/"Serializable" classes should have a version idRMAJORbS2057šjava¢Java"® +squid:S1596squid|Collections.emptyList(), emptyMap() and emptySet() should be used instead of Collections.EMPTY_LIST, EMPTY_MAP and EMPTY_SETRMAJORbS1596šjava¢Java"“ +squid:S2055squid^The non-serializable super class of a "Serializable" class must have a no-argument constructorRCRITICALbS2055šjava¢Java"h +squid:S1598squid6Package declaration should match source file directoryRMAJORbS1598šjava¢Java"S +squid:ParsingErrorsquidJava parser failureRMAJORbParsingErroršjava¢Java"• + +squid:S881squideIncrement (++) and decrement (--) operators should not be mixed with other operators in an expressionRMAJORbS881šjava¢Java"v +squid:S1724squidDDeprecated classes and interfaces should not be extended/implementedRMAJORbS1724šjava¢Java"w +squid:S1862squidBRelated "if/else if" statements should not have the same conditionRCRITICALbS1862šjava¢Java"v +squid:S1860squidBSynchronization should not be based on Strings or boxed primitivesRBLOCKERbS1860šjava¢Java"€ +squid:S1317squidN"StringBuilder" and "StringBuffer" should not be instantiated with a characterRMAJORbS1317šjava¢Java"Q +squid:S1314squidOctal values should not be usedRMAJORbS1314šjava¢Java"j +squid:S1315squid8"CHECKSTYLE:OFF" suppression comments should not be usedRMINORbS1315šjava¢Java"} +squid:S2718squidH"DateUtils.truncate" from Apache Commons Lang library should not be usedRCRITICALbS2718šjava¢Java"s +squid:IndentationChecksquid+Source code should be indented consistentlyRMINORbIndentationCheckšjava¢Java"c +squid:S1451squid/Copyright and license headers should be definedRBLOCKERbS1451šjava¢Java"p +squid:S1452squid>Generic wildcard types should not be used in return parametersRMAJORbS1452šjava¢Java"u +squid:S1318squid@"object == null" should be used instead of "object.equals(null)"RCRITICALbS1318šjava¢Java"µ +squid:S1319squid‚Declarations should use Java collection interfaces such as "List" rather than specific implementation classes such as "LinkedList"RMAJORbS1319šjava¢Java" +squid:S1312squidMLoggers should be "private static final" and should share a naming conventionRMINORbS1312šjava¢Java"V +squid:S1313squid$IP addresses should not be hardcodedRMAJORbS1313šjava¢Java" + +squid:S864squidOLimited dependence should be placed on operator precedence rules in expressionsRMAJORbS864šjava¢Java"a +squid:S1310squid/"NOPMD" suppression comments should not be usedRMINORbS1310šjava¢Java"h +squid:S2447squid3Null should not be returned from a "Boolean" methodRCRITICALbS2447šjava¢Java" +squid:S1850squidM"instanceof" operators that always return "true" or "false" should be removedRMAJORbS1850šjava¢Java"z +squid:S2583squidFConditions should not unconditionally evaluate to "TRUE" or to "FALSE"RBLOCKERbS2583šjava¢Java"^ +squid:S1710squid,Annotation repetitions should not be wrappedRMAJORbS1710šjava¢Java"o +squid:S2440squid=Classes with only "static" methods should not be instantiatedRMAJORbS2440šjava¢Java"t +squid:S2441squid?Non-serializable objects should not be stored in "HttpSessions"RCRITICALbS2441šjava¢Java"_ +squid:S2442squid+"Lock" objects should not be "synchronized"RBLOCKERbS2442šjava¢Java"— +"squid:ObjectFinalizeOverridenChecksquid4The Object.finalize() method should not be overridenRCRITICALbObjectFinalizeOverridenCheckšjava¢Java"h +squid:S1858squid6"toString()" should never be called on a String objectRMAJORbS1858šjava¢Java"t +squid:S2444squid?Lazy initialization of "static" fields should be "synchronized"RCRITICALbS2444šjava¢Java" +squid:S2445squid[Blocks synchronized on fields should not contain assignments of new objects to those fieldsRBLOCKERbS2445šjava¢Java"O +squid:S2446squid"notifyAll" should be usedRCRITICALbS2446šjava¢Java"k +squid:S1301squid9"switch" statements should have at least 3 "case" clausesRMINORbS1301šjava¢Java"f +squid:S1607squid4Skipped unit tests should be either removed or fixedRMAJORbS1607šjava¢Java"d +squid:S1309squid3The @SuppressWarnings annotation should not be usedRINFObS1309šjava¢Java"z +squid:S1604squidHAnonymous inner classes containing only one method should become lambdasRMAJORbS1604šjava¢Java" +squid:S1602squidOLamdbas containing only one statement should not nest this statement in a blockRMAJORbS1602šjava¢Java"{ +squid:ClassCyclomaticComplexitysquid!Classes should not be too complexRMAJORbClassCyclomaticComplexityšjava¢Java"‹ +squid:S1200squidYClasses should not be coupled to too many other classes (Single Responsibility Principle)RMAJORbS1200šjava¢Java"q +squid:S1201squid<Methods named "equals" should override Object.equals(Object)RCRITICALbS1201šjava¢Java"f +squid:S1701squid4Fields and methods should not have conflicting namesRMAJORbS1701šjava¢Java"w +squid:S1206squidC"equals(Object obj)" and "hashCode()" should be overridden in pairsRBLOCKERbS1206šjava¢Java"o +squid:S1700squid=A field should not duplicate the name of its containing classRMAJORbS1700šjava¢Java"k +squid:S2178squid6Short-circuit logic should be used in boolean contextsRCRITICALbS2178šjava¢Java"j +squid:S2176squid8Class names should not shadow interfaces or superclassesRMAJORbS2176šjava¢Java"Š + squid:ForLoopCounterChangedChecksquid."for" loop stop conditions should be invariantRMAJORbForLoopCounterChangedCheckšjava¢Java"h +squid:S2175squid3Inappropriate "Collection" calls should not be madeRCRITICALbS2175šjava¢Java"e +squid:S2160squid3Subclasses that add fields should override "equals"RMAJORbS2160šjava¢Java"q +squid:S2162squid<"equals" methods should be symmetric and work for subclassesRCRITICALbS2162šjava¢Java"“ +%squid:RedundantThrowsDeclarationChecksquid-Throws declarations should not be superfluousRMINORbRedundantThrowsDeclarationCheckšjava¢Java"‘ +squid:S1994squid\"for" loop incrementers should modify the variable being tested in the loop's stop conditionRCRITICALbS1994šjava¢Java"\ +squid:S2165squid*"finalize" should not set fields to "null"RMAJORbS2165šjava¢Java"[ +squid:S2164squid&Math should not be performed on floatsRCRITICALbS2164šjava¢Java"f +squid:S2167squid1"compareTo" should not return "Integer.MIN_VALUE"RCRITICALbS2167šjava¢Java"x +squid:S2166squidFClasses named like "Exception" should extend "Exception" or a subclassRMAJORbS2166šjava¢Java"g +squid:S2885squid2"Calendars" and "DateFormats" should not be staticRCRITICALbS2885šjava¢Java"~ +squid:S2694squidLInner classes which do not reference their owning classes should be "static"RMAJORbS2694šjava¢Java"ƒ +squid:S2695squidO"PreparedStatement" and "ResultSet" methods should be called with valid indicesRBLOCKERbS2695šjava¢Java"h +squid:S2692squid3"indexOf" checks should not be for positive numbersRCRITICALbS2692šjava¢Java
\ No newline at end of file |