Browse Source

SONAR-16395 Activate Analyzers Cache by default

tags/9.5.0.56709
Duarte Meneses 1 year ago
parent
commit
7475e9d7a6

+ 1
- 1
sonar-scanner-engine/src/main/java/org/sonar/scanner/cache/AnalysisCacheEnabled.java View File

} }


public boolean isEnabled() { public boolean isEnabled() {
return configuration.getBoolean(PROP_KEY).orElse(false);
return configuration.getBoolean(PROP_KEY).orElse(true);
} }
} }

+ 2
- 63
sonar-scanner-engine/src/main/java/org/sonar/scanner/cache/AnalysisCacheLoader.java View File

*/ */
package org.sonar.scanner.cache; package org.sonar.scanner.cache;


import java.io.IOException;
import java.io.InputStream;
import java.util.Optional; import java.util.Optional;
import java.util.zip.InflaterInputStream;
import org.sonar.api.scanner.fs.InputProject;
import org.sonar.api.utils.MessageException;
import org.sonar.core.util.Protobuf;
import org.sonar.scanner.bootstrap.DefaultScannerWsClient;
import org.sonar.scanner.protocol.internal.ScannerInternal; import org.sonar.scanner.protocol.internal.ScannerInternal;
import org.sonar.scanner.protocol.internal.ScannerInternal.AnalysisCacheMsg;
import org.sonar.scanner.scan.branch.BranchConfiguration;
import org.sonar.scanner.scan.branch.BranchType;
import org.sonarqube.ws.client.GetRequest;
import org.sonarqube.ws.client.HttpException;
import org.sonarqube.ws.client.WsResponse;


/**
* Loads plugin cache into the local storage
*/
public class AnalysisCacheLoader {
static final String CONTENT_ENCODING = "Content-Encoding";
static final String ACCEPT_ENCODING = "Accept-Encoding";
private static final String URL = "api/analysis_cache/get";

private final DefaultScannerWsClient wsClient;
private final InputProject project;
private final BranchConfiguration branchConfiguration;

public AnalysisCacheLoader(DefaultScannerWsClient wsClient, InputProject project, BranchConfiguration branchConfiguration) {
this.project = project;
this.branchConfiguration = branchConfiguration;
this.wsClient = wsClient;
}

public Optional<AnalysisCacheMsg> load() {
String url = URL + "?project=" + project.key();
if (branchConfiguration.referenceBranchName() != null) {
url = url + "&branch=" + branchConfiguration.referenceBranchName();
}

GetRequest request = new GetRequest(url).setHeader(ACCEPT_ENCODING, "gzip");

try (WsResponse response = wsClient.call(request); InputStream is = response.contentStream()) {
Optional<String> contentEncoding = response.header(CONTENT_ENCODING);
if (contentEncoding.isPresent() && contentEncoding.get().equals("gzip")) {
return Optional.of(decompress(is));
} else {
return Optional.of(Protobuf.read(is, AnalysisCacheMsg.parser()));
}
} catch (HttpException e) {
if (e.code() == 404) {
return Optional.empty();
}
throw MessageException.of("Failed to download analysis cache: " + DefaultScannerWsClient.createErrorMessage(e));
} catch (Exception e) {
throw new IllegalStateException("Failed to download analysis cache", e);
}
}

private static AnalysisCacheMsg decompress(InputStream is) {
try (InflaterInputStream iis = new InflaterInputStream(is)) {
return Protobuf.read(iis, ScannerInternal.AnalysisCacheMsg.parser());
} catch (IOException e) {
throw new IllegalStateException("Failed to decompress analysis cache", e);
}
}
public interface AnalysisCacheLoader {
Optional<ScannerInternal.AnalysisCacheMsg> load();
} }

+ 87
- 0
sonar-scanner-engine/src/main/java/org/sonar/scanner/cache/DefaultAnalysisCacheLoader.java View File

/*
* SonarQube
* Copyright (C) 2009-2022 SonarSource SA
* mailto:info 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.cache;

import java.io.IOException;
import java.io.InputStream;
import java.util.Optional;
import java.util.zip.InflaterInputStream;
import org.sonar.api.scanner.fs.InputProject;
import org.sonar.api.utils.MessageException;
import org.sonar.core.util.Protobuf;
import org.sonar.scanner.bootstrap.DefaultScannerWsClient;
import org.sonar.scanner.protocol.internal.ScannerInternal;
import org.sonar.scanner.protocol.internal.ScannerInternal.AnalysisCacheMsg;
import org.sonar.scanner.scan.branch.BranchConfiguration;
import org.sonarqube.ws.client.GetRequest;
import org.sonarqube.ws.client.HttpException;
import org.sonarqube.ws.client.WsResponse;

/**
* Loads plugin cache into the local storage
*/
public class DefaultAnalysisCacheLoader implements AnalysisCacheLoader {
static final String CONTENT_ENCODING = "Content-Encoding";
static final String ACCEPT_ENCODING = "Accept-Encoding";
private static final String URL = "api/analysis_cache/get";

private final DefaultScannerWsClient wsClient;
private final InputProject project;
private final BranchConfiguration branchConfiguration;

public DefaultAnalysisCacheLoader(DefaultScannerWsClient wsClient, InputProject project, BranchConfiguration branchConfiguration) {
this.project = project;
this.branchConfiguration = branchConfiguration;
this.wsClient = wsClient;
}

@Override public Optional<AnalysisCacheMsg> load() {
String url = URL + "?project=" + project.key();
if (branchConfiguration.referenceBranchName() != null) {
url = url + "&branch=" + branchConfiguration.referenceBranchName();
}

GetRequest request = new GetRequest(url).setHeader(ACCEPT_ENCODING, "gzip");

try (WsResponse response = wsClient.call(request); InputStream is = response.contentStream()) {
Optional<String> contentEncoding = response.header(CONTENT_ENCODING);
if (contentEncoding.isPresent() && contentEncoding.get().equals("gzip")) {
return Optional.of(decompress(is));
} else {
return Optional.of(Protobuf.read(is, AnalysisCacheMsg.parser()));
}
} catch (HttpException e) {
if (e.code() == 404) {
return Optional.empty();
}
throw MessageException.of("Failed to download analysis cache: " + DefaultScannerWsClient.createErrorMessage(e));
} catch (Exception e) {
throw new IllegalStateException("Failed to download analysis cache", e);
}
}

private static AnalysisCacheMsg decompress(InputStream is) {
try (InflaterInputStream iis = new InflaterInputStream(is)) {
return Protobuf.read(iis, ScannerInternal.AnalysisCacheMsg.parser());
} catch (IOException e) {
throw new IllegalStateException("Failed to decompress analysis cache", e);
}
}
}

+ 2
- 2
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/SpringProjectScanContainer.java View File

import org.sonar.scanner.bootstrap.GlobalAnalysisMode; import org.sonar.scanner.bootstrap.GlobalAnalysisMode;
import org.sonar.scanner.bootstrap.PostJobExtensionDictionary; import org.sonar.scanner.bootstrap.PostJobExtensionDictionary;
import org.sonar.scanner.cache.AnalysisCacheEnabled; import org.sonar.scanner.cache.AnalysisCacheEnabled;
import org.sonar.scanner.cache.AnalysisCacheLoader;
import org.sonar.scanner.cache.DefaultAnalysisCacheLoader;
import org.sonar.scanner.cache.AnalysisCacheMemoryStorage; import org.sonar.scanner.cache.AnalysisCacheMemoryStorage;
import org.sonar.scanner.cache.AnalysisCacheProvider; import org.sonar.scanner.cache.AnalysisCacheProvider;
import org.sonar.scanner.ci.CiConfigurationProvider; import org.sonar.scanner.ci.CiConfigurationProvider;
// Plugin cache // Plugin cache
AnalysisCacheProvider.class, AnalysisCacheProvider.class,
AnalysisCacheMemoryStorage.class, AnalysisCacheMemoryStorage.class,
AnalysisCacheLoader.class,
DefaultAnalysisCacheLoader.class,


// Report // Report
ReferenceBranchSupplier.class, ReferenceBranchSupplier.class,

+ 5
- 5
sonar-scanner-engine/src/test/java/org/sonar/scanner/cache/AnalysisCacheEnabledTest.java View File

private final AnalysisCacheEnabled analysisCacheEnabled = new AnalysisCacheEnabled(configuration); private final AnalysisCacheEnabled analysisCacheEnabled = new AnalysisCacheEnabled(configuration);


@Test @Test
public void disabled_unless_property_set() {
assertThat(analysisCacheEnabled.isEnabled()).isFalse();
public void enabled_by_default() {
assertThat(analysisCacheEnabled.isEnabled()).isTrue();
} }


@Test @Test
public void enabled_if_property_set() {
when(configuration.getBoolean(PROP_KEY)).thenReturn(Optional.of(true));
assertThat(analysisCacheEnabled.isEnabled()).isTrue();
public void disabled_if_property_set() {
when(configuration.getBoolean(PROP_KEY)).thenReturn(Optional.of(false));
assertThat(analysisCacheEnabled.isEnabled()).isFalse();
} }
} }

sonar-scanner-engine/src/test/java/org/sonar/scanner/cache/AnalysisCacheLoaderTest.java → sonar-scanner-engine/src/test/java/org/sonar/scanner/cache/DefaultAnalysisCacheLoaderTest.java View File

import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import static org.sonar.scanner.cache.AnalysisCacheLoader.CONTENT_ENCODING;
import static org.sonar.scanner.cache.DefaultAnalysisCacheLoader.CONTENT_ENCODING;


public class AnalysisCacheLoaderTest {
public class DefaultAnalysisCacheLoaderTest {
private final static AnalysisCacheMsg MSG = AnalysisCacheMsg.newBuilder() private final static AnalysisCacheMsg MSG = AnalysisCacheMsg.newBuilder()
.putMap("key", ByteString.copyFrom("value", StandardCharsets.UTF_8)) .putMap("key", ByteString.copyFrom("value", StandardCharsets.UTF_8))
.build(); .build();
private final DefaultScannerWsClient wsClient = mock(DefaultScannerWsClient.class); private final DefaultScannerWsClient wsClient = mock(DefaultScannerWsClient.class);
private final InputProject project = mock(InputProject.class); private final InputProject project = mock(InputProject.class);
private final BranchConfiguration branchConfiguration = mock(BranchConfiguration.class); private final BranchConfiguration branchConfiguration = mock(BranchConfiguration.class);
private final AnalysisCacheLoader loader = new AnalysisCacheLoader(wsClient, project, branchConfiguration);
private final DefaultAnalysisCacheLoader loader = new DefaultAnalysisCacheLoader(wsClient, project, branchConfiguration);


@Before @Before
public void before() { public void before() {

+ 17
- 0
sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/ScannerMediumTester.java View File

import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.Properties; import java.util.Properties;
import javax.annotation.CheckForNull; import javax.annotation.CheckForNull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import org.sonar.api.SonarQubeSide; import org.sonar.api.SonarQubeSide;
import org.sonar.api.SonarRuntime; import org.sonar.api.SonarRuntime;
import org.sonar.api.batch.rule.LoadedActiveRule; import org.sonar.api.batch.rule.LoadedActiveRule;
import org.sonar.api.batch.sensor.cache.ReadCache;
import org.sonar.api.impl.server.RulesDefinitionContext; import org.sonar.api.impl.server.RulesDefinitionContext;
import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Metric; import org.sonar.api.measures.Metric;
import org.sonar.batch.bootstrapper.EnvironmentInformation; import org.sonar.batch.bootstrapper.EnvironmentInformation;
import org.sonar.batch.bootstrapper.LogOutput; import org.sonar.batch.bootstrapper.LogOutput;
import org.sonar.scanner.bootstrap.GlobalAnalysisMode; import org.sonar.scanner.bootstrap.GlobalAnalysisMode;
import org.sonar.scanner.cache.AnalysisCacheLoader;
import org.sonar.scanner.cache.AnalysisCacheMemoryStorage;
import org.sonar.scanner.cache.ReadCacheImpl;
import org.sonar.scanner.protocol.internal.ScannerInternal;
import org.sonar.scanner.report.CeTaskReportDataHolder; import org.sonar.scanner.report.CeTaskReportDataHolder;
import org.sonar.scanner.repository.FileData; import org.sonar.scanner.repository.FileData;
import org.sonar.scanner.repository.MetricsRepository; import org.sonar.scanner.repository.MetricsRepository;
import org.sonarqube.ws.NewCodePeriods; import org.sonarqube.ws.NewCodePeriods;
import org.sonarqube.ws.Qualityprofiles.SearchWsResponse.QualityProfile; import org.sonarqube.ws.Qualityprofiles.SearchWsResponse.QualityProfile;
import org.sonarqube.ws.Rules.ListResponse.Rule; import org.sonarqube.ws.Rules.ListResponse.Rule;
import org.springframework.context.annotation.Bean;


import static java.util.Collections.emptySet; import static java.util.Collections.emptySet;


private final FakeGlobalSettingsLoader globalSettingsLoader = new FakeGlobalSettingsLoader(); private final FakeGlobalSettingsLoader globalSettingsLoader = new FakeGlobalSettingsLoader();
private final FakeProjectSettingsLoader projectSettingsLoader = new FakeProjectSettingsLoader(); private final FakeProjectSettingsLoader projectSettingsLoader = new FakeProjectSettingsLoader();
private final FakeNewCodePeriodLoader newCodePeriodLoader = new FakeNewCodePeriodLoader(); private final FakeNewCodePeriodLoader newCodePeriodLoader = new FakeNewCodePeriodLoader();
private final FakeAnalysisCacheLoader analysisCacheLoader = new FakeAnalysisCacheLoader();
private final FakeRulesLoader rulesLoader = new FakeRulesLoader(); private final FakeRulesLoader rulesLoader = new FakeRulesLoader();
private final FakeQualityProfileLoader qualityProfiles = new FakeQualityProfileLoader(); private final FakeQualityProfileLoader qualityProfiles = new FakeQualityProfileLoader();
private final FakeActiveRulesLoader activeRules = new FakeActiveRulesLoader(); private final FakeActiveRulesLoader activeRules = new FakeActiveRulesLoader();
tester.globalSettingsLoader, tester.globalSettingsLoader,
tester.projectSettingsLoader, tester.projectSettingsLoader,
tester.newCodePeriodLoader, tester.newCodePeriodLoader,
tester.analysisCacheLoader,
tester.sonarRuntime, tester.sonarRuntime,
tester.reportMetadataHolder, tester.reportMetadataHolder,
result) result)
} }
} }


@Priority(1)
private static class FakeAnalysisCacheLoader implements AnalysisCacheLoader {
@Override
public Optional<ScannerInternal.AnalysisCacheMsg> load() {
return Optional.empty();
}
}

@Priority(1) @Priority(1)
private static class FakeGlobalSettingsLoader implements GlobalSettingsLoader { private static class FakeGlobalSettingsLoader implements GlobalSettingsLoader {



Loading…
Cancel
Save