diff --git a/pkg/whitesource/scanUA.go b/pkg/whitesource/scanUA.go index 3ce9c932e..b9d60c75f 100644 --- a/pkg/whitesource/scanUA.go +++ b/pkg/whitesource/scanUA.go @@ -9,6 +9,7 @@ import ( "os" "path/filepath" "regexp" + "strings" "sync" "github.com/SAP/jenkins-library/pkg/log" @@ -176,6 +177,17 @@ func downloadAgent(config *ScanOptions, utils Utils) error { } if !exists { err := utils.DownloadFile(config.AgentDownloadURL, agentFile, nil, nil) + if err != nil { + // we check if the copy error occurs and retry the download + // if the copy error did not happen, we rerun the whole download mechanism once + if strings.Contains(err.Error(), "unable to copy content from url to file") { + // retry the download once again + log.Entry().Warnf("Previous Download failed due to %v", err) + err = nil // reset error to nil + err = utils.DownloadFile(config.AgentDownloadURL, agentFile, nil, nil) + } + } + if err != nil { return errors.Wrapf(err, "failed to download unified agent from URL '%s' to file '%s'", config.AgentDownloadURL, agentFile) } @@ -193,7 +205,18 @@ func downloadJre(config *ScanOptions, utils Utils) (string, error) { javaPath := "java" if err != nil { log.Entry().Infof("No Java installation found, downloading JVM from %v", config.JreDownloadURL) - err := utils.DownloadFile(config.JreDownloadURL, jvmTarGz, nil, nil) + err = utils.DownloadFile(config.JreDownloadURL, jvmTarGz, nil, nil) + if err != nil { + // we check if the copy error occurs and retry the download + // if the copy error did not happen, we rerun the whole download mechanism once + if strings.Contains(err.Error(), "unable to copy content from url to file") { + // retry the download once again + log.Entry().Warnf("Previous Download failed due to %v", err) + err = nil + err = utils.DownloadFile(config.JreDownloadURL, jvmTarGz, nil, nil) + } + } + if err != nil { return "", errors.Wrapf(err, "failed to download jre from URL '%s'", config.JreDownloadURL) } diff --git a/pkg/whitesource/scanUA_test.go b/pkg/whitesource/scanUA_test.go index f848c08ce..2d7b64138 100644 --- a/pkg/whitesource/scanUA_test.go +++ b/pkg/whitesource/scanUA_test.go @@ -2,12 +2,11 @@ package whitesource import ( "fmt" + "github.com/SAP/jenkins-library/pkg/log" + "github.com/stretchr/testify/assert" "path/filepath" "strings" "testing" - - "github.com/SAP/jenkins-library/pkg/log" - "github.com/stretchr/testify/assert" ) func TestExecuteUAScan(t *testing.T) { @@ -291,6 +290,17 @@ func TestDownloadAgent(t *testing.T) { err := downloadAgent(&config, utilsMock) assert.Contains(t, fmt.Sprint(err), "failed to download unified agent from URL") }) + t.Run("error - download with retry", func(t *testing.T) { + config := ScanOptions{ + AgentDownloadURL: "errorCopyFile", // Misusing this ScanOptions to tell DownloadFile Mock to raise an error + AgentFileName: "unified-agent.jar", + } + utilsMock := NewScanUtilsMock() + utilsMock.DownloadError = map[string]error{"https://download.ua.org/agent.jar": fmt.Errorf("unable to copy content from url to file")} + + err := downloadAgent(&config, utilsMock) + assert.Contains(t, fmt.Sprint(err), "unable to copy content from url to file") + }) } func TestDownloadJre(t *testing.T) { @@ -350,6 +360,18 @@ func TestDownloadJre(t *testing.T) { assert.Contains(t, fmt.Sprint(err), "failed to download jre from URL") }) + t.Run("error - download with retry", func(t *testing.T) { + config := ScanOptions{ + JreDownloadURL: "errorCopyFile", + } + utilsMock := NewScanUtilsMock() + utilsMock.ShouldFailOnCommand = map[string]error{"java": fmt.Errorf("failed to run java")} + //utilsMock.DownloadError = map[string]error{"https://download.jre.org/jvm.jar": fmt.Errorf("failed to download file")} + + _, err := downloadJre(&config, utilsMock) + assert.Contains(t, fmt.Sprint(err), "unable to copy content from url to file") + }) + t.Run("error - tar execution", func(t *testing.T) { config := ScanOptions{ JreDownloadURL: "https://download.jre.org/jvm.jar", diff --git a/pkg/whitesource/utilsMock.go b/pkg/whitesource/utilsMock.go index 3e2d9b7aa..58e0210e3 100644 --- a/pkg/whitesource/utilsMock.go +++ b/pkg/whitesource/utilsMock.go @@ -8,6 +8,7 @@ import ( "github.com/SAP/jenkins-library/pkg/mock" "github.com/SAP/jenkins-library/pkg/piperutils" + "github.com/pkg/errors" ) func newTestScan(config *ScanOptions) *Scan { @@ -67,6 +68,9 @@ func (m *ScanUtilsMock) InstallAllNPMDependencies(_ *ScanOptions, packageJSONs [ // DownloadFile mimics http.Downloader and records the downloaded file. func (m *ScanUtilsMock) DownloadFile(url, filename string, _ http.Header, _ []*http.Cookie) error { + if url == "errorCopyFile" { + return errors.New("unable to copy content from url to file") + } if m.DownloadError[url] != nil { return m.DownloadError[url] }