diff options
author | Duarte Meneses <duarte.meneses@sonarsource.com> | 2015-08-06 14:38:53 +0200 |
---|---|---|
committer | Duarte Meneses <duarte.meneses@sonarsource.com> | 2015-08-12 16:12:50 +0200 |
commit | da0e7d2eb596eeed136301cdaa38523ff8c86d54 (patch) | |
tree | 4e0dcbc4ea5ab12f48c9f807319cef76977b0d8f /sonar-batch/src/test/java | |
parent | 4dc9282453526c25504570caae011283b053ed98 (diff) | |
download | sonarqube-da0e7d2eb596eeed136301cdaa38523ff8c86d54.tar.gz sonarqube-da0e7d2eb596eeed136301cdaa38523ff8c86d54.zip |
SONAR-6777 Project cache sync
Diffstat (limited to 'sonar-batch/src/test/java')
14 files changed, 643 insertions, 116 deletions
diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/WSLoaderGlobalProviderTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/GlobalWSLoaderProviderTest.java index 81a5fdb563f..1ae0c36ab2f 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/WSLoaderGlobalProviderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/GlobalWSLoaderProviderTest.java @@ -24,8 +24,6 @@ import static org.assertj.core.api.Assertions.assertThat; import java.util.HashMap; import java.util.Map; -import static org.mockito.Mockito.when; - import org.sonar.batch.bootstrap.WSLoader.LoadStrategy; import org.junit.Test; import org.junit.Before; @@ -33,7 +31,7 @@ import org.sonar.home.cache.PersistentCache; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -public class WSLoaderGlobalProviderTest { +public class GlobalWSLoaderProviderTest { @Mock private PersistentCache cache; @@ -43,14 +41,14 @@ public class WSLoaderGlobalProviderTest { @Mock private GlobalMode mode; - private WSLoaderGlobalProvider loaderProvider; + private GlobalWSLoaderProvider loaderProvider; private Map<String, String> propMap; private BootstrapProperties props; @Before public void setUp() { MockitoAnnotations.initMocks(this); - loaderProvider = new WSLoaderGlobalProvider(); + loaderProvider = new GlobalWSLoaderProvider(); } @Test @@ -59,18 +57,7 @@ public class WSLoaderGlobalProviderTest { props = new BootstrapProperties(propMap); WSLoader wsLoader = loaderProvider.provide(props, mode, cache, client); - assertThat(wsLoader.getStrategy()).isEqualTo(LoadStrategy.SERVER_FIRST); - assertThat(wsLoader.isCacheEnabled()).isEqualTo(false); + assertThat(wsLoader.getStrategy()).isEqualTo(LoadStrategy.SERVER_ONLY); } - @Test - public void testOffline() { - propMap = new HashMap<>(); - propMap.put("sonar.enableOffline", "true"); - when(mode.isIssues()).thenReturn(true); - props = new BootstrapProperties(propMap); - - WSLoader wsLoader = loaderProvider.provide(props, mode, cache, client); - assertThat(wsLoader.isCacheEnabled()).isEqualTo(true); - } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/WSLoaderTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/WSLoaderTest.java index 31c70e85d4b..781c1ad255c 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/WSLoaderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/WSLoaderTest.java @@ -70,10 +70,9 @@ public class WSLoaderTest { } @Test - public void dont_retry_server() throws IOException { - when(client.load(anyString(), anyString(), anyBoolean(), anyInt(), anyInt())).thenThrow(new IllegalStateException()); - WSLoader loader = new WSLoader(true, cache, client); - loader.setStrategy(LoadStrategy.SERVER_FIRST); + public void dont_retry_server_offline() throws IOException { + turnServerOffline(); + WSLoader loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client); assertResult(loader.loadString(ID), cacheValue, true); assertResult(loader.loadString(ID), cacheValue, true); @@ -86,8 +85,7 @@ public class WSLoaderTest { @Test public void test_cache_strategy_fallback() throws IOException { when(cache.get(ID, null)).thenReturn(null); - WSLoader loader = new WSLoader(true, cache, client); - loader.setStrategy(LoadStrategy.CACHE_FIRST); + WSLoader loader = new WSLoader(LoadStrategy.CACHE_FIRST, cache, client); assertResult(loader.load(ID), serverValue.getBytes(), false); @@ -98,9 +96,8 @@ public class WSLoaderTest { @Test public void test_server_strategy_fallback() throws IOException { - when(client.load(anyString(), anyString(), anyBoolean(), anyInt(), anyInt())).thenThrow(new IllegalStateException()); - WSLoader loader = new WSLoader(true, cache, client); - loader.setStrategy(LoadStrategy.SERVER_FIRST); + turnServerOffline(); + WSLoader loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client); assertResult(loader.loadString(ID), cacheValue, true); @@ -111,20 +108,16 @@ public class WSLoaderTest { @Test public void test_put_cache() throws IOException { - WSLoader loader = new WSLoader(true, cache, client); - loader.setStrategy(LoadStrategy.SERVER_FIRST); + WSLoader loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client); loader.load(ID); verify(cache).put(ID, serverValue.getBytes()); } @Test(expected = NullPointerException.class) public void test_throw_cache_exception_fallback() throws IOException { - when(client.load(anyString(), anyString(), anyBoolean(), anyInt(), anyInt())).thenThrow(new IllegalStateException()); + turnServerOffline(); when(cache.get(ID, null)).thenThrow(new NullPointerException()); - - WSLoader loader = new WSLoader(true, cache, client); - loader.setStrategy(LoadStrategy.SERVER_FIRST); - + WSLoader loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client); loader.load(ID); } @@ -132,9 +125,7 @@ public class WSLoaderTest { public void test_throw_cache_exception() throws IOException { when(cache.get(ID, null)).thenThrow(new IllegalStateException()); - WSLoader loader = new WSLoader(true, cache, client); - loader.setStrategy(LoadStrategy.CACHE_FIRST); - + WSLoader loader = new WSLoader(LoadStrategy.CACHE_FIRST, cache, client); loader.load(ID); } @@ -145,8 +136,7 @@ public class WSLoaderTest { when(client.load(anyString(), anyString(), anyBoolean(), anyInt(), anyInt())).thenThrow(wrapperException); - WSLoader loader = new WSLoader(true, cache, client); - loader.setStrategy(LoadStrategy.SERVER_FIRST); + WSLoader loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client); try { loader.load(ID); @@ -158,23 +148,8 @@ public class WSLoaderTest { } @Test - public void test_change_strategy() throws IOException { - WSLoader loader = new WSLoader(true, cache, client); - loader.setStrategy(LoadStrategy.CACHE_FIRST); - test_cache_strategy_fallback(); - } - - @Test - public void test_enable_cache() throws IOException { - WSLoader loader = new WSLoader(true, cache, client); - loader.setCacheEnabled(false); - test_cache_disabled(); - } - - @Test public void test_server_strategy() throws IOException { - WSLoader loader = new WSLoader(true, cache, client); - loader.setStrategy(LoadStrategy.SERVER_FIRST); + WSLoader loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client); assertResult(loader.load(ID), serverValue.getBytes(), false); // should not fetch from cache @@ -182,18 +157,16 @@ public class WSLoaderTest { verifyNoMoreInteractions(cache); } - @Test - public void test_cache_disabled() throws IOException { - WSLoader loader = new WSLoader(cache, client); + @Test(expected = IllegalStateException.class) + public void test_server_only() throws IOException { + turnServerOffline(); + WSLoader loader = new WSLoader(LoadStrategy.SERVER_ONLY, cache, client); loader.load(ID); - - // should not even put - verifyNoMoreInteractions(cache); } @Test public void test_string() { - WSLoader loader = new WSLoader(cache, client); + WSLoader loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client); assertResult(loader.loadString(ID), serverValue, false); } @@ -202,4 +175,8 @@ public class WSLoaderTest { assertThat(result.get()).isEqualTo(expected); assertThat(result.isFromCache()).isEqualTo(fromCache); } + + private void turnServerOffline() { + when(client.load(anyString(), anyString(), anyBoolean(), anyInt(), anyInt())).thenThrow(new IllegalStateException()); + } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/WSLoaderTestWithServer.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/WSLoaderTestWithServer.java index b99d851d321..b6582883ebc 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/WSLoaderTestWithServer.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/WSLoaderTestWithServer.java @@ -52,7 +52,6 @@ public class WSLoaderTestWithServer { client = new ServerClient(bootstrapProps, new EnvironmentInformation("Junit", "4")); cache = new PersistentCache(temp.getRoot().toPath(), 1000 * 60, new Slf4jLogger(), null); - loader = new WSLoader(cache, client); } @After @@ -63,50 +62,41 @@ public class WSLoaderTestWithServer { } @Test - public void testServer() { - loader.setCacheEnabled(false); - loader.setStrategy(LoadStrategy.SERVER_FIRST); - server.setMockResponseData(RESPONSE_STRING); - assertThat(loader.loadString("/foo")).isEqualTo(RESPONSE_STRING); - } + public void testCacheOnly() { + loader = new WSLoader(LoadStrategy.SERVER_ONLY, cache, client); + makeRequests(); - @Test - public void testCacheDisabled() { - loader.setCacheEnabled(false); - loader.setStrategy(LoadStrategy.CACHE_FIRST); + loader = new WSLoader(LoadStrategy.CACHE_ONLY, cache, client); makeRequests(); assertThat(server.getNumberRequests()).isEqualTo(3); } @Test - public void testCacheEnabled() { - loader.setCacheEnabled(true); - loader.setStrategy(LoadStrategy.CACHE_FIRST); + public void testCacheFirst() { + loader = new WSLoader(LoadStrategy.CACHE_FIRST, cache, client); makeRequests(); assertThat(server.getNumberRequests()).isEqualTo(1); } @Test - public void testServerStrategy() { - loader.setCacheEnabled(true); - loader.setStrategy(LoadStrategy.SERVER_FIRST); + public void testServerFirst() { + loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client); makeRequests(); assertThat(server.getNumberRequests()).isEqualTo(3); } @Test public void testCacheStrategyDisabled() { - loader.setCacheEnabled(false); - loader.setStrategy(LoadStrategy.CACHE_FIRST); + loader = new WSLoader(LoadStrategy.SERVER_ONLY, cache, client); makeRequests(); assertThat(server.getNumberRequests()).isEqualTo(3); } private void makeRequests() { server.setMockResponseData(RESPONSE_STRING); - assertThat(loader.loadString("/foo")).isEqualTo(RESPONSE_STRING); - assertThat(loader.loadString("/foo")).isEqualTo(RESPONSE_STRING); - assertThat(loader.loadString("/foo")).isEqualTo(RESPONSE_STRING); + assertThat(loader.loadString("/foo").get()).isEqualTo(RESPONSE_STRING); + assertThat(loader.loadString("/foo").get()).isEqualTo(RESPONSE_STRING); + assertThat(loader.loadString("/foo").get()).isEqualTo(RESPONSE_STRING); } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/cache/ProjectCacheStatusTest.java b/sonar-batch/src/test/java/org/sonar/batch/cache/ProjectCacheStatusTest.java new file mode 100644 index 00000000000..2b6c4491f62 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/cache/ProjectCacheStatusTest.java @@ -0,0 +1,71 @@ +/* + * 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.cache; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Date; + +import org.junit.Test; +import org.sonar.home.cache.Logger; +import org.junit.rules.TemporaryFolder; +import org.junit.Rule; +import org.junit.Before; +import org.sonar.batch.bootstrap.ServerClient; +import org.sonar.home.cache.PersistentCache; + +public class ProjectCacheStatusTest { + private static final String PROJ_KEY = "project1"; + @Rule + public TemporaryFolder tmp = new TemporaryFolder(); + + ProjectCacheStatus cacheStatus; + PersistentCache cache; + ServerClient client; + + @Before + public void setUp() { + cache = new PersistentCache(tmp.getRoot().toPath(), Long.MAX_VALUE, mock(Logger.class), null); + client = mock(ServerClient.class); + when(client.getURL()).thenReturn("localhost"); + cacheStatus = new ProjectCacheStatus(cache, client); + } + + @Test + public void testSave() { + cacheStatus.save(PROJ_KEY); + assertThat(cacheStatus.getSyncStatus(PROJ_KEY)).isNotNull(); + assertThat(age(cacheStatus.getSyncStatus(PROJ_KEY))).isLessThan(2000); + assertThat(cacheStatus.getSyncStatus(PROJ_KEY+"1")).isNull(); + } + + @Test + public void testDelete() { + cacheStatus.save(PROJ_KEY); + cacheStatus.delete(PROJ_KEY); + assertThat(cacheStatus.getSyncStatus(PROJ_KEY)).isNull(); + } + + private long age(Date date) { + return (new Date().getTime()) - date.getTime(); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/DefaultIssueCallbackTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/DefaultIssueCallbackTest.java index 1ecf5353fab..41d5bddfbca 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/issue/DefaultIssueCallbackTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/issue/DefaultIssueCallbackTest.java @@ -28,7 +28,7 @@ import org.sonar.batch.protocol.input.BatchInput; import org.mockito.MockitoAnnotations; import org.mockito.Mock; import org.sonar.api.batch.rule.Rules; -import org.sonar.batch.repository.user.UserRepository; +import org.sonar.batch.repository.user.UserRepositoryLoader; import org.sonar.batch.bootstrapper.IssueListener; import org.junit.Before; import com.google.common.collect.ImmutableList; @@ -47,7 +47,7 @@ public class DefaultIssueCallbackTest { @Mock private IssueCache issueCache; @Mock - private UserRepository userRepository; + private UserRepositoryLoader userRepository; @Mock private Rules rules; @@ -68,7 +68,7 @@ public class DefaultIssueCallbackTest { BatchInput.User.Builder userBuilder = BatchInput.User.newBuilder(); userBuilder.setLogin("user"); userBuilder.setName("name"); - when(userRepository.loadFromWs(anyListOf(String.class))).thenReturn(ImmutableList.of(userBuilder.build())); + when(userRepository.load(anyListOf(String.class))).thenReturn(ImmutableList.of(userBuilder.build())); Rule r = mock(Rule.class); when(r.name()).thenReturn("rule name"); @@ -128,7 +128,7 @@ public class DefaultIssueCallbackTest { } }; - when(userRepository.loadFromWs(anyListOf(String.class))).thenReturn(new LinkedList<BatchInput.User>()); + when(userRepository.load(anyListOf(String.class))).thenReturn(new LinkedList<BatchInput.User>()); when(rules.find(any(RuleKey.class))).thenReturn(null); DefaultIssueCallback issueCallback = new DefaultIssueCallback(issueCache, listener, userRepository, rules); diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/DefaultServerLineHashesLoaderTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/DefaultServerLineHashesLoaderTest.java index d1880ef7d3c..c7e2a40c04e 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/DefaultServerLineHashesLoaderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/DefaultServerLineHashesLoaderTest.java @@ -49,7 +49,7 @@ public class DefaultServerLineHashesLoaderTest { @Test public void should_download_source_from_ws_if_preview_mode() { WSLoader wsLoader = mock(WSLoader.class); - when(wsLoader.loadString(anyString())).thenReturn(new WSLoaderResult("ae12\n\n43fb", true)); + when(wsLoader.loadString(anyString())).thenReturn(new WSLoaderResult<>("ae12\n\n43fb", true)); ServerLineHashesLoader lastSnapshots = new DefaultServerLineHashesLoader(wsLoader); @@ -61,7 +61,7 @@ public class DefaultServerLineHashesLoaderTest { @Test public void should_download_source_with_space_from_ws_if_preview_mode() { WSLoader server = mock(WSLoader.class); - when(server.loadString(anyString())).thenReturn(new WSLoaderResult("ae12\n\n43fb", true)); + when(server.loadString(anyString())).thenReturn(new WSLoaderResult<>("ae12\n\n43fb", true)); ServerLineHashesLoader lastSnapshots = new DefaultServerLineHashesLoader(server); 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 new file mode 100644 index 00000000000..522d8b5fa1a --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/BatchMediumTester.java @@ -0,0 +1,412 @@ +/* + * 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 org.sonar.api.batch.bootstrap.ProjectDefinition; +import org.sonarqube.ws.Rules.ListResponse.Rule; +import org.sonar.batch.bootstrapper.IssueListener; +import org.sonar.api.server.rule.RulesDefinition.Repository; +import org.sonar.api.server.rule.RulesDefinition; +import org.sonar.batch.rule.RulesLoader; +import com.google.common.base.Function; +import com.google.common.io.Files; + +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.sonar.api.CoreProperties; +import org.sonar.api.SonarPlugin; +import org.sonar.api.batch.debt.internal.DefaultDebtModel; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Metric; +import org.sonar.batch.bootstrap.AnalysisProperties; +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; +import org.sonar.batch.repository.ServerIssuesLoader; +import org.sonar.core.component.ComponentKeys; + +/** + * Main utility class for writing batch medium tests. + * + */ +public class BatchMediumTester { + + public static final String MEDIUM_TEST_ENABLED = "sonar.mediumTest.enabled"; + private Batch batch; + + public static BatchMediumTesterBuilder builder() { + BatchMediumTesterBuilder builder = new BatchMediumTesterBuilder().registerCoreMetrics(); + builder.bootstrapProperties.put(MEDIUM_TEST_ENABLED, "true"); + builder.bootstrapProperties.put(ReportPublisher.KEEP_REPORT_PROP_KEY, "true"); + builder.bootstrapProperties.put(CoreProperties.WORKING_DIRECTORY, Files.createTempDir().getAbsolutePath()); + return builder; + } + + public static class BatchMediumTesterBuilder { + private final FakeGlobalRepositoriesLoader globalRefProvider = new FakeGlobalRepositoriesLoader(); + private final FakeProjectRepositoriesLoader projectRefProvider = new FakeProjectRepositoriesLoader(); + private final FakePluginInstaller pluginInstaller = new FakePluginInstaller(); + private final FakeServerIssuesLoader serverIssues = new FakeServerIssuesLoader(); + private final FakeServerLineHashesLoader serverLineHashes = new FakeServerLineHashesLoader(); + private final Map<String, String> bootstrapProperties = new HashMap<>(); + private final FakeRulesLoader rulesLoader = new FakeRulesLoader(); + private LogOutput logOutput = null; + + public BatchMediumTester build() { + return new BatchMediumTester(this); + } + + public BatchMediumTesterBuilder setLogOutput(LogOutput logOutput) { + this.logOutput = logOutput; + return this; + } + + public BatchMediumTesterBuilder registerPlugin(String pluginKey, File location) { + pluginInstaller.add(pluginKey, location); + return this; + } + + public BatchMediumTesterBuilder registerPlugin(String pluginKey, SonarPlugin instance) { + pluginInstaller.add(pluginKey, instance); + return this; + } + + public BatchMediumTesterBuilder registerCoreMetrics() { + for (Metric<?> m : CoreMetrics.getMetrics()) { + registerMetric(m); + } + return this; + } + + public BatchMediumTesterBuilder registerMetric(Metric<?> metric) { + globalRefProvider.add(metric); + return this; + } + + public BatchMediumTesterBuilder addQProfile(String language, String name) { + projectRefProvider.addQProfile(language, name); + return this; + } + + public BatchMediumTesterBuilder addRule(Rule rule) { + rulesLoader.addRule(rule); + return this; + } + + public BatchMediumTesterBuilder addRule(String key, String repoKey, String internalKey, String name) { + Rule.Builder builder = Rule.newBuilder(); + builder.setKey(key); + builder.setRepository(repoKey); + if (internalKey != null) { + builder.setInternalKey(internalKey); + } + builder.setName(name); + + rulesLoader.addRule(builder.build()); + return this; + } + + public BatchMediumTesterBuilder addRules(RulesDefinition rulesDefinition) { + RulesDefinition.Context context = new RulesDefinition.Context(); + rulesDefinition.define(context); + List<Repository> repositories = context.repositories(); + for (Repository repo : repositories) { + for (RulesDefinition.Rule rule : repo.rules()) { + this.addRule(rule.key(), rule.repository().key(), rule.internalKey(), rule.name()); + } + } + return this; + } + + public BatchMediumTesterBuilder addDefaultQProfile(String language, String name) { + addQProfile(language, name); + globalRefProvider.globalSettings().put("sonar.profile." + language, name); + return this; + } + + public BatchMediumTesterBuilder setPreviousAnalysisDate(Date previousAnalysis) { + projectRefProvider.ref.setLastAnalysisDate(previousAnalysis); + return this; + } + + public BatchMediumTesterBuilder bootstrapProperties(Map<String, String> props) { + bootstrapProperties.putAll(props); + return this; + } + + public BatchMediumTesterBuilder activateRule(ActiveRule activeRule) { + projectRefProvider.addActiveRule(activeRule); + return this; + } + + public BatchMediumTesterBuilder addFileData(String moduleKey, String path, FileData fileData) { + projectRefProvider.addFileData(moduleKey, path, fileData); + return this; + } + + public BatchMediumTesterBuilder setLastBuildDate(Date d) { + projectRefProvider.setLastAnalysisDate(d); + return this; + } + + public BatchMediumTesterBuilder mockServerIssue(ServerIssue issue) { + serverIssues.getServerIssues().add(issue); + return this; + } + + public BatchMediumTesterBuilder mockLineHashes(String fileKey, String[] lineHashes) { + serverLineHashes.byKey.put(fileKey, lineHashes); + return this; + } + + } + + public void start() { + batch.start(); + } + + public void stop() { + batch.stop(); + } + + public void syncProject(String projectKey) { + batch.syncProject(projectKey); + } + + private BatchMediumTester(BatchMediumTesterBuilder builder) { + batch = Batch.builder() + .setEnableLoggingConfiguration(true) + .addComponents( + new EnvironmentInformation("mediumTest", "1.0"), + builder.pluginInstaller, + builder.globalRefProvider, + builder.projectRefProvider, + builder.serverIssues, + builder.serverLineHashes, + builder.rulesLoader, + new DefaultDebtModel()) + .setBootstrapProperties(builder.bootstrapProperties) + .setLogOutput(builder.logOutput) + .build(); + } + + public TaskBuilder newTask() { + return new TaskBuilder(this); + } + + public TaskBuilder newScanTask(File sonarProps) { + Properties prop = new Properties(); + try (Reader reader = new InputStreamReader(new FileInputStream(sonarProps), StandardCharsets.UTF_8)) { + prop.load(reader); + } catch (Exception e) { + throw new IllegalStateException("Unable to read configuration file", e); + } + TaskBuilder builder = new TaskBuilder(this); + builder.property("sonar.projectBaseDir", sonarProps.getParentFile().getAbsolutePath()); + for (Map.Entry<Object, Object> entry : prop.entrySet()) { + builder.property(entry.getKey().toString(), entry.getValue().toString()); + } + return builder; + } + + public static class TaskBuilder { + private final Map<String, String> taskProperties = new HashMap<>(); + private BatchMediumTester tester; + private IssueListener issueListener = null; + + public TaskBuilder(BatchMediumTester tester) { + this.tester = tester; + } + + public TaskResult start() { + TaskResult result = new TaskResult(); + Map<String, String> props = new HashMap<>(); + props.putAll(taskProperties); + if (issueListener != null) { + tester.batch.executeTask(props, result, issueListener); + } else { + tester.batch.executeTask(props, result); + } + return result; + } + + public TaskBuilder properties(Map<String, String> props) { + taskProperties.putAll(props); + return this; + } + + public TaskBuilder property(String key, String value) { + taskProperties.put(key, value); + return this; + } + + public TaskBuilder setIssueListener(IssueListener issueListener) { + this.issueListener = issueListener; + return this; + } + } + + private static class FakeRulesLoader implements RulesLoader { + private List<org.sonarqube.ws.Rules.ListResponse.Rule> rules = new LinkedList<>(); + + public FakeRulesLoader addRule(Rule rule) { + rules.add(rule); + return this; + } + + @Override + public List<Rule> load() { + return rules; + } + + @Override + public boolean loadedFromCache() { + return false; + } + } + + private static class FakeGlobalRepositoriesLoader implements GlobalRepositoriesLoader { + + private int metricId = 1; + + private GlobalRepositories ref = new GlobalRepositories(); + + @Override + public GlobalRepositories load() { + return ref; + } + + public Map<String, String> globalSettings() { + return ref.globalSettings(); + } + + public FakeGlobalRepositoriesLoader add(Metric<?> metric) { + Boolean optimizedBestValue = metric.isOptimizedBestValue(); + ref.metrics().add(new org.sonar.batch.protocol.input.Metric(metricId, + metric.key(), + metric.getType().name(), + metric.getDescription(), + metric.getDirection(), + metric.getName(), + metric.getQualitative(), + metric.getUserManaged(), + metric.getWorstValue(), + metric.getBestValue(), + optimizedBestValue != null ? optimizedBestValue : false)); + metricId++; + return this; + } + + @Override + public boolean loadedFromCache() { + return true; + } + } + + private static class FakeProjectRepositoriesLoader implements ProjectRepositoriesLoader { + + private ProjectRepositories ref = new ProjectRepositories(); + + @Override + public ProjectRepositories load(ProjectDefinition projDefinition, AnalysisProperties taskProperties) { + return ref; + } + + 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))); + return this; + } + + public FakeProjectRepositoriesLoader addActiveRule(ActiveRule activeRule) { + ref.addActiveRule(activeRule); + return this; + } + + public FakeProjectRepositoriesLoader addFileData(String moduleKey, String path, FileData fileData) { + ref.addFileData(moduleKey, path, fileData); + return this; + } + + public FakeProjectRepositoriesLoader setLastAnalysisDate(Date d) { + ref.setLastAnalysisDate(d); + return this; + } + + @Override + public boolean loadedFromCache() { + return true; + } + } + + private static class FakeServerIssuesLoader implements ServerIssuesLoader { + + private List<ServerIssue> serverIssues = new ArrayList<>(); + + public List<ServerIssue> getServerIssues() { + return serverIssues; + } + + @Override + public boolean load(String componentKey, Function<ServerIssue, Void> consumer, boolean incremental) { + for (ServerIssue serverIssue : serverIssues) { + if (!incremental || ComponentKeys.createEffectiveKey(serverIssue.getModuleKey(), serverIssue.hasPath() ? serverIssue.getPath() : null).equals(componentKey)) { + consumer.apply(serverIssue); + } + } + return false; + } + + } + + private static class FakeServerLineHashesLoader implements ServerLineHashesLoader { + private Map<String, String[]> byKey = new HashMap<>(); + + @Override + public String[] getLineHashes(String fileKey) { + if (byKey.containsKey(fileKey)) { + return byKey.get(fileKey); + } else { + throw new IllegalStateException("You forgot to mock line hashes for " + fileKey); + } + } + } + +} 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 new file mode 100644 index 00000000000..581c32789dc --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/cache/CacheSyncTest.java @@ -0,0 +1,76 @@ +/* + * 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.cache; + +import org.sonar.batch.protocol.input.FileData; + +import org.junit.Test; +import org.junit.Rule; +import com.google.common.collect.ImmutableMap; +import org.junit.After; +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 java.util.Date; + +import org.junit.rules.TemporaryFolder; + +public class CacheSyncTest { + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + public BatchMediumTester tester; + + @After + public void stop() { + if (tester != null) { + tester.stop(); + tester = null; + } + } + + @Test + public void testSyncFirstTime() { + FileData file1 = new FileData("hash", true); + String[] hashes = new String[] { + "line1", "line2" + }; + + 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")) + .setPreviousAnalysisDate(new Date()) + .addFileData("test-project", "file1", file1) + .mockLineHashes("test-project:file1", hashes) + .build(); + + tester.start(); + tester.syncProject("test-project"); + + + } + +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/EmptyFileTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issuesmode/EmptyFileTest.java index f6849c64756..03e11861bd0 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/EmptyFileTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issuesmode/EmptyFileTest.java @@ -17,7 +17,7 @@ * 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.preview; +package org.sonar.batch.mediumtest.issuesmode; import org.apache.commons.io.filefilter.FileFilterUtils; diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/IssueModeAndReportsMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issuesmode/IssueModeAndReportsMediumTest.java index 92743b4f125..9b0a4a7a643 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/IssueModeAndReportsMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issuesmode/IssueModeAndReportsMediumTest.java @@ -17,7 +17,7 @@ * 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.preview; +package org.sonar.batch.mediumtest.issuesmode; import com.google.common.collect.ImmutableMap; 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 2d667f8d039..32f5fe36f59 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,18 +19,20 @@ */ package org.sonar.batch.repository; +import org.apache.commons.io.IOUtils; import org.sonar.batch.bootstrap.WSLoaderResult; - import com.google.common.collect.Maps; +import java.io.IOException; import java.util.Date; +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.batch.bootstrap.ProjectReactor; import org.sonar.api.utils.MessageException; import org.sonar.batch.bootstrap.AnalysisProperties; import org.sonar.batch.bootstrap.GlobalMode; @@ -52,7 +54,7 @@ public class DefaultProjectRepositoriesLoaderTest { private DefaultProjectRepositoriesLoader loader; private WSLoader wsLoader; private GlobalMode globalMode; - private ProjectReactor reactor; + private ProjectDefinition project; private AnalysisProperties taskProperties; @Before @@ -68,30 +70,43 @@ public class DefaultProjectRepositoriesLoaderTest { @Test public void passPreviewParameter() { addQualityProfile(); - reactor = new ProjectReactor(ProjectDefinition.create().setKey("foo")); - when(globalMode.isPreview()).thenReturn(false); - loader.load(reactor, taskProperties); + project = ProjectDefinition.create().setKey("foo"); + when(globalMode.isIssues()).thenReturn(false); + loader.load(project, taskProperties); verify(wsLoader).loadString("/batch/project?key=foo&preview=false"); when(globalMode.isIssues()).thenReturn(true); - loader.load(reactor, taskProperties); + loader.load(project, taskProperties); verify(wsLoader).loadString("/batch/project?key=foo&preview=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, false)); + project = ProjectDefinition.create().setKey("foo"); + ProjectRepositories projectRepo = loader.load(project, taskProperties); + + assertThat(projectRepo.activeRules().size()).isEqualTo(221); + assertThat(projectRepo.fileDataByPath("my:project").size()).isEqualTo(11); + + } + + @Test public void passAndEncodeProjectKeyParameter() { addQualityProfile(); - reactor = new ProjectReactor(ProjectDefinition.create().setKey("foo bàr")); - loader.load(reactor, taskProperties); + project = ProjectDefinition.create().setKey("foo bàr"); + loader.load(project, taskProperties); verify(wsLoader).loadString("/batch/project?key=foo+b%C3%A0r&preview=false"); } @Test public void passAndEncodeProfileParameter() { addQualityProfile(); - reactor = new ProjectReactor(ProjectDefinition.create().setKey("foo")); + project = ProjectDefinition.create().setKey("foo"); taskProperties.properties().put(ModuleQProfiles.SONAR_PROFILE_PROP, "my-profile#2"); - loader.load(reactor, taskProperties); + loader.load(project, taskProperties); verify(wsLoader).loadString("/batch/project?key=foo&profile=my-profile%232&preview=false"); } @@ -100,10 +115,10 @@ public class DefaultProjectRepositoriesLoaderTest { 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."); - reactor = new ProjectReactor(ProjectDefinition.create().setKey("foo")); + project = ProjectDefinition.create().setKey("foo"); when(wsLoader.loadString(anyString())).thenReturn(new WSLoaderResult<>(new ProjectRepositories().toJson(), true)); - loader.load(reactor, taskProperties); + loader.load(project, taskProperties); } private void addQualityProfile() { diff --git a/sonar-batch/src/test/java/org/sonar/batch/repository/user/UserRepositoryTest.java b/sonar-batch/src/test/java/org/sonar/batch/repository/user/UserRepositoryLoaderTest.java index 4aa5c91153d..bd0b3e7af88 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/repository/user/UserRepositoryTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/repository/user/UserRepositoryLoaderTest.java @@ -40,14 +40,14 @@ import static org.assertj.core.api.Assertions.tuple; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -public class UserRepositoryTest { +public class UserRepositoryLoaderTest { @Rule public final ExpectedException exception = ExpectedException.none(); @Test public void testLoad() throws IOException { WSLoader wsLoader = mock(WSLoader.class); - UserRepository userRepo = new UserRepository(wsLoader); + UserRepositoryLoader userRepo = new UserRepositoryLoader(wsLoader); ByteArrayOutputStream out = new ByteArrayOutputStream(); BatchInput.User.Builder builder = BatchInput.User.newBuilder(); @@ -58,13 +58,13 @@ public class UserRepositoryTest { when(wsLoader.loadSource("/batch/users?logins=fmallet,sbrandhof")).thenReturn(new WSLoaderResult<>(source, true)); when(source.openStream()).thenReturn(new ByteArrayInputStream(out.toByteArray())); - assertThat(userRepo.loadFromWs(Arrays.asList("fmallet", "sbrandhof"))).extracting("login", "name").containsOnly(tuple("fmallet", "Freddy Mallet"), tuple("sbrandhof", "Simon")); + assertThat(userRepo.load(Arrays.asList("fmallet", "sbrandhof"))).extracting("login", "name").containsOnly(tuple("fmallet", "Freddy Mallet"), tuple("sbrandhof", "Simon")); } @Test public void testInputStreamError() throws IOException { WSLoader wsLoader = mock(WSLoader.class); - UserRepository userRepo = new UserRepository(wsLoader); + UserRepositoryLoader userRepo = new UserRepositoryLoader(wsLoader); ByteSource source = mock(ByteSource.class); when(wsLoader.loadSource("/batch/users?logins=fmallet,sbrandhof")).thenReturn(new WSLoaderResult<>(source, true)); @@ -75,6 +75,6 @@ public class UserRepositoryTest { exception.expect(IllegalStateException.class); exception.expectMessage("Unable to get user details from server"); - assertThat(userRepo.loadFromWs(Arrays.asList("fmallet", "sbrandhof"))).extracting("login", "name").containsOnly(tuple("fmallet", "Freddy Mallet"), tuple("sbrandhof", "Simon")); + assertThat(userRepo.load(Arrays.asList("fmallet", "sbrandhof"))).extracting("login", "name").containsOnly(tuple("fmallet", "Freddy Mallet"), tuple("sbrandhof", "Simon")); } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/WSLoaderProjectProviderTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectWSLoaderProviderTest.java index c0366c40af6..d4fe0b2e109 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/WSLoaderProjectProviderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectWSLoaderProviderTest.java @@ -35,7 +35,7 @@ import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; -public class WSLoaderProjectProviderTest { +public class ProjectWSLoaderProviderTest { @Mock private PersistentCache cache; @@ -61,7 +61,6 @@ public class WSLoaderProjectProviderTest { props = new AnalysisProperties(propMap, null); WSLoader loader = loaderProvider.provide(props, mode, cache, client); - assertThat(loader.getStrategy()).isEqualTo(LoadStrategy.SERVER_FIRST); - assertThat(loader.isCacheEnabled()).isEqualTo(false); + assertThat(loader.getStrategy()).isEqualTo(LoadStrategy.SERVER_ONLY); } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/report/JSONReportTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/report/JSONReportTest.java index 74f2fa77106..a5392d36288 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/report/JSONReportTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/report/JSONReportTest.java @@ -46,7 +46,7 @@ import org.sonar.api.resources.Resource; import org.sonar.api.rule.RuleKey; import org.sonar.batch.issue.IssueCache; import org.sonar.batch.protocol.input.BatchInput; -import org.sonar.batch.repository.user.UserRepository; +import org.sonar.batch.repository.user.UserRepositoryLoader; import org.sonar.batch.scan.filesystem.InputPathCache; import org.sonar.core.issue.DefaultIssue; import org.sonar.test.JsonAssert; @@ -71,7 +71,7 @@ public class JSONReportTest { Rules rules = mock(Rules.class); Settings settings = new Settings(); IssueCache issueCache = mock(IssueCache.class); - private UserRepository userRepository; + private UserRepositoryLoader userRepository; @Before public void before() throws Exception { @@ -79,7 +79,7 @@ public class JSONReportTest { SIMPLE_DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT+02:00")); when(resource.getEffectiveKey()).thenReturn("Action.java"); when(server.getVersion()).thenReturn("3.6"); - userRepository = mock(UserRepository.class); + userRepository = mock(UserRepositoryLoader.class); DefaultInputDir inputDir = new DefaultInputDir("struts", "src/main/java/org/apache/struts"); DefaultInputFile inputFile = new DefaultInputFile("struts", "src/main/java/org/apache/struts/Action.java"); inputFile.setStatus(InputFile.Status.CHANGED); @@ -118,7 +118,7 @@ public class JSONReportTest { when(issueCache.all()).thenReturn(Lists.newArrayList(issue)); BatchInput.User user1 = BatchInput.User.newBuilder().setLogin("julien").setName("Julien").build(); BatchInput.User user2 = BatchInput.User.newBuilder().setLogin("simon").setName("Simon").build(); - when(userRepository.loadFromWs(anyListOf(String.class))).thenReturn(Lists.newArrayList(user1, user2)); + when(userRepository.load(anyListOf(String.class))).thenReturn(Lists.newArrayList(user1, user2)); StringWriter writer = new StringWriter(); jsonReport.writeJson(writer); |