@@ -39,9 +39,9 @@ import org.sonar.core.platform.PluginRepository; | |||
import org.sonar.core.util.DefaultHttpDownloader; | |||
import org.sonar.core.util.UuidFactoryImpl; | |||
import org.sonar.scanner.platform.DefaultServer; | |||
import org.sonar.scanner.repository.DefaultGlobalRepositoriesLoader; | |||
import org.sonar.scanner.repository.GlobalRepositoriesLoader; | |||
import org.sonar.scanner.repository.GlobalRepositoriesProvider; | |||
import org.sonar.scanner.repository.DefaultMetricsRepositoryLoader; | |||
import org.sonar.scanner.repository.MetricsRepositoryLoader; | |||
import org.sonar.scanner.repository.MetricsRepositoryProvider; | |||
import org.sonar.scanner.repository.settings.DefaultSettingsLoader; | |||
import org.sonar.scanner.repository.settings.SettingsLoader; | |||
import org.sonar.scanner.storage.StoragesManager; | |||
@@ -93,11 +93,11 @@ public class GlobalContainer extends ComponentContainer { | |||
UriReader.class, | |||
new FileCacheProvider(), | |||
System2.INSTANCE, | |||
new GlobalRepositoriesProvider(), | |||
new MetricsRepositoryProvider(), | |||
UuidFactoryImpl.INSTANCE); | |||
addIfMissing(ScannerPluginInstaller.class, PluginInstaller.class); | |||
addIfMissing(DefaultSettingsLoader.class, SettingsLoader.class); | |||
addIfMissing(DefaultGlobalRepositoriesLoader.class, GlobalRepositoriesLoader.class); | |||
addIfMissing(DefaultMetricsRepositoryLoader.class, MetricsRepositoryLoader.class); | |||
} | |||
@Override |
@@ -46,8 +46,9 @@ public class GlobalSettings extends Settings { | |||
"sonar.jdbc.username", JDBC_SPECIFIC_MESSAGE, | |||
"sonar.jdbc.password", JDBC_SPECIFIC_MESSAGE); | |||
private final Map<String, String> serverSideSettings; | |||
private final GlobalProperties bootstrapProps; | |||
private final SettingsLoader settingsLoader; | |||
private final GlobalMode mode; | |||
private final Map<String, String> properties = new HashMap<>(); | |||
@@ -57,13 +58,13 @@ public class GlobalSettings extends Settings { | |||
super(propertyDefinitions, new Encryption(bootstrapProps.property(CoreProperties.ENCRYPTION_SECRET_KEY_PATH))); | |||
this.mode = mode; | |||
this.bootstrapProps = bootstrapProps; | |||
this.settingsLoader = settingsLoader; | |||
this.serverSideSettings = ImmutableMap.copyOf(settingsLoader.load(null)); | |||
init(); | |||
new DroppedPropertyChecker(this.getProperties(), DROPPED_PROPERTIES).checkDroppedProperties(); | |||
} | |||
private void init() { | |||
addProperties(settingsLoader.load(null)); | |||
addProperties(serverSideSettings); | |||
addProperties(bootstrapProps.properties()); | |||
if (hasKey(CoreProperties.PERMANENT_SERVER_ID)) { | |||
@@ -71,6 +72,10 @@ public class GlobalSettings extends Settings { | |||
} | |||
} | |||
public Map<String, String> getServerSideSettings() { | |||
return serverSideSettings; | |||
} | |||
@Override | |||
protected Optional<String> get(String key) { | |||
if (mode.isIssues() && key.endsWith(".secured") && !key.contains(".license")) { |
@@ -37,8 +37,8 @@ import org.sonar.api.utils.System2; | |||
import org.sonar.api.utils.log.Logger; | |||
import org.sonar.api.utils.log.Loggers; | |||
import org.sonar.core.platform.PluginInfo; | |||
import org.sonar.scanner.bootstrap.GlobalSettings; | |||
import org.sonar.scanner.bootstrap.ScannerPluginRepository; | |||
import org.sonar.scanner.protocol.input.GlobalRepositories; | |||
import org.sonar.scanner.protocol.output.ScannerReportWriter; | |||
import org.sonar.scanner.repository.ProjectRepositories; | |||
@@ -55,17 +55,17 @@ public class AnalysisContextReportPublisher { | |||
private final AnalysisMode mode; | |||
private final System2 system; | |||
private final ProjectRepositories projectRepos; | |||
private final GlobalRepositories globalRepositories; | |||
private final GlobalSettings globalSettings; | |||
private ScannerReportWriter writer; | |||
public AnalysisContextReportPublisher(AnalysisMode mode, ScannerPluginRepository pluginRepo, System2 system, | |||
ProjectRepositories projectRepos, GlobalRepositories globalRepositories) { | |||
ProjectRepositories projectRepos, GlobalSettings globalSettings) { | |||
this.mode = mode; | |||
this.pluginRepo = pluginRepo; | |||
this.system = system; | |||
this.projectRepos = projectRepos; | |||
this.globalRepositories = globalRepositories; | |||
this.globalSettings = globalSettings; | |||
} | |||
public void init(ScannerReportWriter writer) { | |||
@@ -114,7 +114,7 @@ public class AnalysisContextReportPublisher { | |||
private void writeGlobalSettings(BufferedWriter fileWriter) throws IOException { | |||
fileWriter.append("Global properties:\n"); | |||
Map<String, String> props = globalRepositories.globalSettings(); | |||
Map<String, String> props = globalSettings.getServerSideSettings(); | |||
for (String prop : new TreeSet<>(props.keySet())) { | |||
dumpPropIfNotSensitive(fileWriter, prop, props.get(prop)); | |||
} |
@@ -0,0 +1,139 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2016 SonarSource SA | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* This program 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. | |||
* | |||
* This program 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.scanner.repository; | |||
import java.io.IOException; | |||
import java.io.Reader; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import org.sonar.api.measures.Metric; | |||
import org.sonar.api.measures.Metric.ValueType; | |||
import org.sonar.scanner.bootstrap.ScannerWsClient; | |||
import org.sonar.scanner.protocol.GsonHelper; | |||
import org.sonarqube.ws.client.GetRequest; | |||
public class DefaultMetricsRepositoryLoader implements MetricsRepositoryLoader { | |||
private static final String METRICS_SEARCH_URL = "/api/metrics/search?f=name,description,direction,qualitative,custom&ps=500&p="; | |||
private ScannerWsClient wsClient; | |||
public DefaultMetricsRepositoryLoader(ScannerWsClient wsClient) { | |||
this.wsClient = wsClient; | |||
} | |||
@Override | |||
public MetricsRepository load() { | |||
List<Metric> metrics = new ArrayList<>(); | |||
try { | |||
loadFromPaginatedWs(metrics); | |||
} catch (Exception e) { | |||
throw new IllegalStateException("Unable to load metrics", e); | |||
} | |||
return new MetricsRepository(metrics); | |||
} | |||
private void loadFromPaginatedWs(List<Metric> metrics) throws IOException { | |||
int page = 1; | |||
WsMetricsResponse response; | |||
do { | |||
GetRequest getRequest = new GetRequest(METRICS_SEARCH_URL + page); | |||
try (Reader reader = wsClient.call(getRequest).contentReader()) { | |||
response = GsonHelper.create().fromJson(reader, WsMetricsResponse.class); | |||
for (WsMetric metric : response.metrics) { | |||
metrics.add(new Metric.Builder(metric.getKey(), metric.getName(), ValueType.valueOf(metric.getType())) | |||
.create() | |||
.setDirection(metric.getDirection()) | |||
.setQualitative(metric.isQualitative()) | |||
.setUserManaged(metric.isCustom()) | |||
.setDescription(metric.getDescription()) | |||
.setId(metric.getId())); | |||
} | |||
} | |||
page++; | |||
} while (response.getP() < (response.getTotal() / response.getPs() + 1)); | |||
} | |||
private static class WsMetric { | |||
private int id; | |||
private String key; | |||
private String type; | |||
private String name; | |||
private String description; | |||
private int direction; | |||
private boolean qualitative; | |||
private boolean custom; | |||
public int getId() { | |||
return id; | |||
} | |||
public String getKey() { | |||
return key; | |||
} | |||
public String getType() { | |||
return type; | |||
} | |||
public String getName() { | |||
return name; | |||
} | |||
public String getDescription() { | |||
return description; | |||
} | |||
public int getDirection() { | |||
return direction; | |||
} | |||
public boolean isQualitative() { | |||
return qualitative; | |||
} | |||
public boolean isCustom() { | |||
return custom; | |||
} | |||
} | |||
private static class WsMetricsResponse { | |||
private List<WsMetric> metrics = new ArrayList<>(); | |||
private int total; | |||
private int p; | |||
private int ps; | |||
public int getTotal() { | |||
return total; | |||
} | |||
public int getP() { | |||
return p; | |||
} | |||
public int getPs() { | |||
return ps; | |||
} | |||
} | |||
} |
@@ -19,32 +19,20 @@ | |||
*/ | |||
package org.sonar.scanner.repository; | |||
import org.sonar.scanner.bootstrap.ScannerWsClient; | |||
import org.sonar.scanner.protocol.input.GlobalRepositories; | |||
import org.sonarqube.ws.client.GetRequest; | |||
import java.io.IOException; | |||
import java.io.Reader; | |||
import java.util.ArrayList; | |||
import java.util.Collection; | |||
import java.util.List; | |||
import org.sonar.api.measures.Metric; | |||
import org.apache.commons.io.IOUtils; | |||
public class MetricsRepository { | |||
public class DefaultGlobalRepositoriesLoader implements GlobalRepositoriesLoader { | |||
private Collection<Metric> metrics = new ArrayList<>(); | |||
private static final String BATCH_GLOBAL_URL = "/batch/global"; | |||
private ScannerWsClient wsClient; | |||
public DefaultGlobalRepositoriesLoader(ScannerWsClient wsClient) { | |||
this.wsClient = wsClient; | |||
public MetricsRepository(List<Metric> metrics) { | |||
this.metrics = metrics; | |||
} | |||
@Override | |||
public GlobalRepositories load() { | |||
GetRequest getRequest = new GetRequest(BATCH_GLOBAL_URL); | |||
String str; | |||
try (Reader reader = wsClient.call(getRequest).contentReader()) { | |||
str = IOUtils.toString(reader); | |||
} catch (IOException e) { | |||
throw new IllegalStateException(e); | |||
} | |||
return GlobalRepositories.fromJson(str); | |||
public Collection<Metric> metrics() { | |||
return metrics; | |||
} | |||
} |
@@ -19,8 +19,6 @@ | |||
*/ | |||
package org.sonar.scanner.repository; | |||
import org.sonar.scanner.protocol.input.GlobalRepositories; | |||
public interface GlobalRepositoriesLoader { | |||
GlobalRepositories load(); | |||
public interface MetricsRepositoryLoader { | |||
MetricsRepository load(); | |||
} |
@@ -23,20 +23,19 @@ import org.picocontainer.injectors.ProviderAdapter; | |||
import org.sonar.api.utils.log.Logger; | |||
import org.sonar.api.utils.log.Loggers; | |||
import org.sonar.api.utils.log.Profiler; | |||
import org.sonar.scanner.protocol.input.GlobalRepositories; | |||
public class GlobalRepositoriesProvider extends ProviderAdapter { | |||
public class MetricsRepositoryProvider extends ProviderAdapter { | |||
private static final Logger LOG = Loggers.get(GlobalRepositoriesProvider.class); | |||
private static final String LOG_MSG = "Load global repositories"; | |||
private GlobalRepositories globalReferentials; | |||
private static final Logger LOG = Loggers.get(MetricsRepositoryProvider.class); | |||
private static final String LOG_MSG = "Load metrics repository"; | |||
private MetricsRepository metricsRepository; | |||
public GlobalRepositories provide(GlobalRepositoriesLoader loader) { | |||
if (globalReferentials == null) { | |||
public MetricsRepository provide(MetricsRepositoryLoader loader) { | |||
if (metricsRepository == null) { | |||
Profiler profiler = Profiler.create(LOG).startInfo(LOG_MSG); | |||
globalReferentials = loader.load(); | |||
metricsRepository = loader.load(); | |||
profiler.stopInfo(); | |||
} | |||
return globalReferentials; | |||
return metricsRepository; | |||
} | |||
} |
@@ -27,16 +27,15 @@ import java.util.List; | |||
import java.util.Map; | |||
import org.sonar.api.batch.measure.Metric; | |||
import org.sonar.api.batch.measure.MetricFinder; | |||
import org.sonar.api.measures.Metric.ValueType; | |||
import org.sonar.scanner.protocol.input.GlobalRepositories; | |||
import org.sonar.scanner.repository.MetricsRepository; | |||
public class DefaultMetricFinder implements MetricFinder { | |||
private Map<String, Metric<Serializable>> metricsByKey = new LinkedHashMap<>(); | |||
public DefaultMetricFinder(GlobalRepositories globalReferentials) { | |||
for (org.sonar.scanner.protocol.input.Metric metric : globalReferentials.metrics()) { | |||
metricsByKey.put(metric.key(), new org.sonar.api.measures.Metric.Builder(metric.key(), metric.key(), ValueType.valueOf(metric.valueType())).create()); | |||
public DefaultMetricFinder(MetricsRepository metricsRepository) { | |||
for (org.sonar.api.measures.Metric metric : metricsRepository.metrics()) { | |||
metricsByKey.put(metric.key(), new org.sonar.api.measures.Metric.Builder(metric.key(), metric.key(), metric.getType()).create()); | |||
} | |||
} | |||
@@ -25,29 +25,18 @@ import java.util.Collection; | |||
import java.util.List; | |||
import java.util.Map; | |||
import org.sonar.api.measures.Metric; | |||
import org.sonar.api.measures.Metric.ValueType; | |||
import org.sonar.api.measures.MetricFinder; | |||
import org.sonar.scanner.protocol.input.GlobalRepositories; | |||
import org.sonar.scanner.repository.MetricsRepository; | |||
public final class DeprecatedMetricFinder implements MetricFinder { | |||
private Map<String, Metric> metricsByKey = Maps.newLinkedHashMap(); | |||
private Map<Integer, Metric> metricsById = Maps.newLinkedHashMap(); | |||
public DeprecatedMetricFinder(GlobalRepositories globalReferentials) { | |||
for (org.sonar.scanner.protocol.input.Metric metric : globalReferentials.metrics()) { | |||
Metric hibernateMetric = new Metric.Builder(metric.key(), metric.name(), ValueType.valueOf(metric.valueType())) | |||
.create() | |||
.setDirection(metric.direction()) | |||
.setQualitative(metric.isQualitative()) | |||
.setUserManaged(metric.isUserManaged()) | |||
.setDescription(metric.description()) | |||
.setOptimizedBestValue(metric.isOptimizedBestValue()) | |||
.setBestValue(metric.bestValue()) | |||
.setWorstValue(metric.worstValue()) | |||
.setId(metric.id()); | |||
metricsByKey.put(metric.key(), hibernateMetric); | |||
metricsById.put(metric.id(), new Metric.Builder(metric.key(), metric.key(), ValueType.valueOf(metric.valueType())).create().setId(metric.id())); | |||
public DeprecatedMetricFinder(MetricsRepository metricsRepository) { | |||
for (Metric metric : metricsRepository.metrics()) { | |||
metricsByKey.put(metric.key(), metric); | |||
metricsById.put(metric.getId(), metric); | |||
} | |||
} | |||
@@ -54,11 +54,11 @@ import org.sonar.batch.bootstrapper.IssueListener; | |||
import org.sonar.batch.bootstrapper.LogOutput; | |||
import org.sonar.scanner.bootstrap.GlobalMode; | |||
import org.sonar.scanner.issue.tracking.ServerLineHashesLoader; | |||
import org.sonar.scanner.protocol.input.GlobalRepositories; | |||
import org.sonar.scanner.protocol.input.ScannerInput.ServerIssue; | |||
import org.sonar.scanner.report.ReportPublisher; | |||
import org.sonar.scanner.repository.FileData; | |||
import org.sonar.scanner.repository.GlobalRepositoriesLoader; | |||
import org.sonar.scanner.repository.MetricsRepository; | |||
import org.sonar.scanner.repository.MetricsRepositoryLoader; | |||
import org.sonar.scanner.repository.ProjectRepositories; | |||
import org.sonar.scanner.repository.ProjectRepositoriesLoader; | |||
import org.sonar.scanner.repository.QualityProfileLoader; | |||
@@ -116,7 +116,7 @@ public class ScannerMediumTester { | |||
} | |||
public static class BatchMediumTesterBuilder { | |||
private final FakeGlobalRepositoriesLoader globalRefProvider = new FakeGlobalRepositoriesLoader(); | |||
private final FakeMetricsRepositoryLoader globalRefProvider = new FakeMetricsRepositoryLoader(); | |||
private final FakeProjectRepositoriesLoader projectRefProvider = new FakeProjectRepositoriesLoader(); | |||
private final FakePluginInstaller pluginInstaller = new FakePluginInstaller(); | |||
private final FakeServerIssuesLoader serverIssues = new FakeServerIssuesLoader(); | |||
@@ -201,7 +201,6 @@ public class ScannerMediumTester { | |||
public BatchMediumTesterBuilder addDefaultQProfile(String language, String name) { | |||
addQProfile(language, name); | |||
globalRefProvider.globalSettings().put("sonar.profile." + language, name); | |||
return this; | |||
} | |||
@@ -380,34 +379,20 @@ public class ScannerMediumTester { | |||
} | |||
} | |||
private static class FakeGlobalRepositoriesLoader implements GlobalRepositoriesLoader { | |||
private static class FakeMetricsRepositoryLoader implements MetricsRepositoryLoader { | |||
private int metricId = 1; | |||
private GlobalRepositories ref = new GlobalRepositories(); | |||
private List<Metric> metrics = new ArrayList<>(); | |||
@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.scanner.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)); | |||
public MetricsRepository load() { | |||
return new MetricsRepository(metrics); | |||
} | |||
public FakeMetricsRepositoryLoader add(Metric<?> metric) { | |||
metric.setId(metricId++); | |||
metrics.add(metric); | |||
metricId++; | |||
return this; | |||
} |
@@ -35,10 +35,9 @@ import org.sonar.api.utils.System2; | |||
import org.sonar.api.utils.log.LogTester; | |||
import org.sonar.api.utils.log.LoggerLevel; | |||
import org.sonar.core.platform.PluginInfo; | |||
import org.sonar.scanner.bootstrap.GlobalSettings; | |||
import org.sonar.scanner.bootstrap.ScannerPluginRepository; | |||
import org.sonar.scanner.protocol.input.GlobalRepositories; | |||
import org.sonar.scanner.protocol.output.ScannerReportWriter; | |||
import org.sonar.scanner.report.AnalysisContextReportPublisher; | |||
import org.sonar.scanner.repository.ProjectRepositories; | |||
import org.sonar.updatecenter.common.Version; | |||
@@ -65,7 +64,7 @@ public class AnalysisContextReportPublisherTest { | |||
private AnalysisMode analysisMode = mock(AnalysisMode.class); | |||
private System2 system2; | |||
private ProjectRepositories projectRepos; | |||
private GlobalRepositories globalRepositories; | |||
private GlobalSettings globalSettings; | |||
@Before | |||
public void prepare() throws Exception { | |||
@@ -73,8 +72,8 @@ public class AnalysisContextReportPublisherTest { | |||
system2 = mock(System2.class); | |||
when(system2.properties()).thenReturn(new Properties()); | |||
projectRepos = mock(ProjectRepositories.class); | |||
globalRepositories = mock(GlobalRepositories.class); | |||
publisher = new AnalysisContextReportPublisher(analysisMode, pluginRepo, system2, projectRepos, globalRepositories); | |||
globalSettings = mock(GlobalSettings.class); | |||
publisher = new AnalysisContextReportPublisher(analysisMode, pluginRepo, system2, projectRepos, globalSettings); | |||
} | |||
@Test | |||
@@ -105,7 +104,7 @@ public class AnalysisContextReportPublisherTest { | |||
public void dumpServerSideGlobalProps() throws Exception { | |||
logTester.setLevel(LoggerLevel.DEBUG); | |||
ScannerReportWriter writer = new ScannerReportWriter(temp.newFolder()); | |||
when(globalRepositories.globalSettings()).thenReturn(ImmutableMap.of(COM_FOO, "bar", SONAR_SKIP, "true")); | |||
when(globalSettings.getServerSideSettings()).thenReturn(ImmutableMap.of(COM_FOO, "bar", SONAR_SKIP, "true")); | |||
publisher.init(writer); | |||
@@ -206,7 +205,7 @@ public class AnalysisContextReportPublisherTest { | |||
@Test | |||
public void shouldNotDumpSensitiveGlobalProperties() throws Exception { | |||
ScannerReportWriter writer = new ScannerReportWriter(temp.newFolder()); | |||
when(globalRepositories.globalSettings()).thenReturn(ImmutableMap.of("sonar.login", "my_token", "sonar.password", "azerty", "sonar.cpp.license.secured", "AZERTY")); | |||
when(globalSettings.getServerSideSettings()).thenReturn(ImmutableMap.of("sonar.login", "my_token", "sonar.password", "azerty", "sonar.cpp.license.secured", "AZERTY")); | |||
publisher.init(writer); | |||
@@ -22,58 +22,63 @@ package org.sonar.scanner.repository; | |||
import java.io.IOException; | |||
import java.io.Reader; | |||
import java.io.StringReader; | |||
import org.apache.commons.io.IOUtils; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.sonar.scanner.WsTestUtil; | |||
import org.sonar.scanner.bootstrap.ScannerWsClient; | |||
import org.sonar.scanner.protocol.input.GlobalRepositories; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Matchers.any; | |||
import static org.mockito.Matchers.anyInt; | |||
import static org.mockito.Mockito.doThrow; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.verifyNoMoreInteractions; | |||
import static org.mockito.Mockito.when; | |||
public class DefaultGlobalRepositoriesLoaderTest { | |||
private static final String BATCH_GLOBAL_URL = "/batch/global"; | |||
public class DefaultMetricsRepositoryLoaderTest { | |||
private static final String WS_URL = "/api/metrics/search?f=name,description,direction,qualitative,custom&ps=500&p="; | |||
private ScannerWsClient wsClient; | |||
private DefaultGlobalRepositoriesLoader globalRepositoryLoader; | |||
private DefaultMetricsRepositoryLoader metricsRepositoryLoader; | |||
@Rule | |||
public ExpectedException exception = ExpectedException.none(); | |||
@Before | |||
public void setUp() { | |||
public void setUp() throws IOException { | |||
wsClient = mock(ScannerWsClient.class); | |||
WsTestUtil.mockReader(wsClient, BATCH_GLOBAL_URL, new StringReader(new GlobalRepositories().toJson())); | |||
globalRepositoryLoader = new DefaultGlobalRepositoriesLoader(wsClient); | |||
WsTestUtil.mockReader(wsClient, WS_URL + "1", new StringReader(IOUtils.toString(this.getClass().getResourceAsStream("DefaultMetricsRepositoryLoaderTest/page1.json")))); | |||
WsTestUtil.mockReader(wsClient, WS_URL + "2", new StringReader(IOUtils.toString(this.getClass().getResourceAsStream("DefaultMetricsRepositoryLoaderTest/page2.json")))); | |||
metricsRepositoryLoader = new DefaultMetricsRepositoryLoader(wsClient); | |||
} | |||
@Test | |||
public void test() { | |||
globalRepositoryLoader.load(); | |||
WsTestUtil.verifyCall(wsClient, BATCH_GLOBAL_URL); | |||
MetricsRepository metricsRepository = metricsRepositoryLoader.load(); | |||
assertThat(metricsRepository.metrics()).hasSize(3); | |||
WsTestUtil.verifyCall(wsClient, WS_URL + "1"); | |||
WsTestUtil.verifyCall(wsClient, WS_URL + "2"); | |||
verifyNoMoreInteractions(wsClient); | |||
} | |||
@Test | |||
public void testIOError() throws IOException { | |||
Reader reader = mock(Reader.class); | |||
when(reader.read(any(char[].class))).thenThrow(new IOException()); | |||
when(reader.read(any(char[].class), anyInt(), anyInt())).thenThrow(new IOException()); | |||
WsTestUtil.mockReader(wsClient, reader); | |||
exception.expect(IllegalStateException.class); | |||
globalRepositoryLoader.load(); | |||
metricsRepositoryLoader.load(); | |||
} | |||
@Test | |||
public void testCloseError() throws IOException { | |||
Reader reader = mock(Reader.class); | |||
when(reader.read(any(char[].class))).thenReturn(-1); | |||
when(reader.read(any(char[].class), anyInt(), anyInt())).thenReturn(-1); | |||
doThrow(new IOException()).when(reader).close(); | |||
WsTestUtil.mockReader(wsClient, reader); | |||
exception.expect(IllegalStateException.class); | |||
globalRepositoryLoader.load(); | |||
metricsRepositoryLoader.load(); | |||
} | |||
} |
@@ -0,0 +1,27 @@ | |||
{ | |||
"metrics": [ | |||
{ | |||
"id": "10", | |||
"key": "accessors", | |||
"type": "INT", | |||
"name": "Accessors", | |||
"description": "Accessors", | |||
"direction": -1, | |||
"qualitative": false, | |||
"custom": false | |||
}, | |||
{ | |||
"id": "227", | |||
"key": "new_technical_debt", | |||
"type": "WORK_DUR", | |||
"name": "Added Technical Debt", | |||
"description": "Added technical debt", | |||
"direction": -1, | |||
"qualitative": true, | |||
"custom": false | |||
} | |||
], | |||
"total": 3, | |||
"p": 1, | |||
"ps": 2 | |||
} |
@@ -0,0 +1,17 @@ | |||
{ | |||
"metrics": [ | |||
{ | |||
"id": "282", | |||
"key": "afferent_coupling_average", | |||
"type": "FLOAT", | |||
"name": "Afferent Coupling (Average)", | |||
"description": "Shows the Afferent Coupling for a package. This is a count of the number of other packages that depend on the classes within this package. It is an indicator of the package's responsibility.", | |||
"direction": -1, | |||
"qualitative": true, | |||
"custom": false | |||
} | |||
], | |||
"total": 3, | |||
"p": 2, | |||
"ps": 2 | |||
} |