]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-19994 Scanner property for plugins download timeout
authorEric Giffon <eric.giffon@sonarsource.com>
Tue, 25 Jul 2023 16:07:17 +0000 (18:07 +0200)
committersonartech <sonartech@sonarsource.com>
Wed, 26 Jul 2023 20:03:25 +0000 (20:03 +0000)
sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/PluginFiles.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/PluginFilesTest.java

index adc0c01247fbdeab8d7ac31bbed16e55ddabe332..eb1551d8b3bd227bc8b1e5bbff4c2170260fc2b2 100644 (file)
@@ -19,6 +19,7 @@
  */
 package org.sonar.scanner.bootstrap;
 
+import com.google.common.annotations.VisibleForTesting;
 import java.io.BufferedInputStream;
 import java.io.File;
 import java.io.IOException;
@@ -30,9 +31,9 @@ import java.util.Optional;
 import java.util.stream.Stream;
 import org.apache.commons.codec.digest.DigestUtils;
 import org.apache.commons.io.FileUtils;
-import org.sonar.api.config.Configuration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.sonar.api.config.Configuration;
 import org.sonar.scanner.bootstrap.ScannerPluginInstaller.InstalledPlugin;
 import org.sonarqube.ws.client.GetRequest;
 import org.sonarqube.ws.client.HttpException;
@@ -44,13 +45,18 @@ public class PluginFiles {
 
   private static final Logger LOGGER = LoggerFactory.getLogger(PluginFiles.class);
   private static final String MD5_HEADER = "Sonar-MD5";
+  @VisibleForTesting
+  static final String PLUGINS_DOWNLOAD_TIMEOUT_PROPERTY = "sonar.plugins.download.timeout";
+  private static final int PLUGINS_DOWNLOAD_TIMEOUT_DEFAULT = 300;
 
   private final DefaultScannerWsClient wsClient;
+  private final Configuration configuration;
   private final File cacheDir;
   private final File tempDir;
 
   public PluginFiles(DefaultScannerWsClient wsClient, Configuration configuration) {
     this.wsClient = wsClient;
+    this.configuration = configuration;
     File home = locateHomeDir(configuration);
     this.cacheDir = mkdir(new File(home, "cache"), "user cache");
     this.tempDir = mkdir(new File(home, "_tmp"), "temp dir");
@@ -85,7 +91,7 @@ public class PluginFiles {
   private Optional<File> download(InstalledPlugin plugin) {
     GetRequest request = new GetRequest("api/plugins/download")
       .setParam("plugin", plugin.key)
-      .setTimeOutInMs(5 * 60_000);
+      .setTimeOutInMs(configuration.getInt(PLUGINS_DOWNLOAD_TIMEOUT_PROPERTY).orElse(PLUGINS_DOWNLOAD_TIMEOUT_DEFAULT) * 1000);
 
     File downloadedFile = newTempFile();
     LOGGER.debug("Download plugin '{}' to '{}'", plugin.key, downloadedFile);
index e072875e19df36776af239435262956746ce2388..6ac3838aafa7a958c3664618ba92af4297aaa786 100644 (file)
@@ -22,8 +22,10 @@ package org.sonar.scanner.bootstrap;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.net.SocketTimeoutException;
 import java.util.Collections;
 import java.util.Optional;
+import java.util.concurrent.TimeUnit;
 import javax.annotation.Nullable;
 import okhttp3.HttpUrl;
 import okhttp3.mockwebserver.MockResponse;
@@ -47,6 +49,7 @@ import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.assertj.core.api.ThrowableAssert.ThrowingCallable;
 import static org.mockito.Mockito.mock;
+import static org.sonar.scanner.bootstrap.PluginFiles.PLUGINS_DOWNLOAD_TIMEOUT_PROPERTY;
 
 public class PluginFilesTest {
 
@@ -70,6 +73,7 @@ public class PluginFilesTest {
     userHome = temp.newFolder();
     MapSettings settings = new MapSettings();
     settings.setProperty("sonar.userHome", userHome.getAbsolutePath());
+    settings.setProperty(PLUGINS_DOWNLOAD_TIMEOUT_PROPERTY, 1);
 
     underTest = new PluginFiles(wsClient, settings.asConfig());
   }
@@ -141,6 +145,19 @@ public class PluginFilesTest {
     expectISE("foo", "returned code 500", () -> underTest.get(plugin));
   }
 
+  @Test
+  public void getPlugin_whenTimeOutReached_thenDownloadFails() {
+    MockResponse response = new MockResponse().setBody("test").setBodyDelay(2, TimeUnit.SECONDS);
+    response.setHeader("Sonar-MD5", "md5");
+    server.enqueue(response);
+    InstalledPlugin plugin = newInstalledPlugin("foo", "abc");
+
+    assertThatThrownBy(() -> underTest.get(plugin))
+      .isInstanceOf(IllegalStateException.class)
+      .hasMessageStartingWith("Fail to download plugin [" + plugin.key + "]")
+      .cause().isInstanceOf(SocketTimeoutException.class);
+  }
+
   @Test
   public void download_a_new_version_of_plugin_during_blue_green_switch() throws IOException {
     FileAndMd5 tempJar = new FileAndMd5();