Skip to content

Commit

Permalink
Merge pull request #828 from steinliber/feat-ut-mock-doanwload-test
Browse files Browse the repository at this point in the history
feat: mock download test logic in pluginmanager
  • Loading branch information
xavier-hou authored Jul 12, 2022
2 parents cf36ce7 + bea482d commit fc68afb
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 33 deletions.
42 changes: 27 additions & 15 deletions internal/pkg/pluginmanager/downloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,36 @@ const (
defaultReleaseUrl = "https://download.devstream.io"
)

type plugDownloader func(reqClient *resty.Client, url, plugName string) error

type DownloadClient struct {
*resty.Client
pluginGetter plugDownloader
}

func downloadPlugin(reqClient *resty.Client, url, plugName string) error {
response, err := reqClient.R().
SetOutput(plugName).
SetHeader("Accept", "application/octet-stream").
Get(url)
if err != nil {
return err
}
if response.StatusCode() != http.StatusOK {
if err = os.Remove(filepath.Join(url, plugName)); err != nil {
return err
}
err = fmt.Errorf("downloading plugin %s from %s status code %d", plugName, url, response.StatusCode())
log.Error(err)
return err
}
return nil
}

func NewDownloadClient() *DownloadClient {
dClient := DownloadClient{}
dClient := DownloadClient{
pluginGetter: downloadPlugin,
}
dClient.Client = resty.New()
dClient.SetRetryCount(defaultRetryCount)
return &dClient
Expand All @@ -33,25 +57,13 @@ func NewDownloadClient() *DownloadClient {
func (dc *DownloadClient) download(pluginDir, pluginFilename, version string) error {
dc.SetOutputDirectory(pluginDir)

// download plug file
downloadURL := fmt.Sprintf("%s/v%s/%s", defaultReleaseUrl, version, pluginFilename)
tmpName := pluginFilename + ".tmp"

response, err := dc.R().
SetOutput(tmpName).
SetHeader("Accept", "application/octet-stream").
Get(downloadURL)
err := dc.pluginGetter(dc.Client, downloadURL, tmpName)
if err != nil {
return err
}
if response.StatusCode() != http.StatusOK {
if err = os.Remove(filepath.Join(pluginDir, tmpName)); err != nil {
return err
}
err = fmt.Errorf("downloading plugin %s from %s status code %d", pluginFilename, downloadURL, response.StatusCode())
log.Error(err)
return err
}

// rename, tmp file to real file
err = os.Rename(
filepath.Join(pluginDir, tmpName),
Expand Down
88 changes: 70 additions & 18 deletions internal/pkg/pluginmanager/downloader_test.go
Original file line number Diff line number Diff line change
@@ -1,29 +1,81 @@
package pluginmanager

import (
"fmt"
"os"
"path/filepath"
"testing"

"github.com/stretchr/testify/assert"
"github.com/go-resty/resty/v2"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

func TestDownload(t *testing.T) {
os.Remove(filepath.Join(".", "argocdapp_0.0.1-rc1.so"))

c := NewDownloadClient()
err := c.download(".", "argocdapp_0.0.1-rc1.so", "0.0.1-ut-do-not-delete")
if err != nil {
t.Fatal("downloaded error")
var _ = Describe("DownloadClient", Ordered, func() {
// mock download success func
mockPlugSuccessGetter := func(reqClient *resty.Client, url, plugName string) error {
return nil
}
// mock download failed func
mockPlugNotFoundGetter := func(reqClient *resty.Client, url, plugName string) error {
return fmt.Errorf("downloading plugin %s from %s status code %d", plugName, url, 404)
}
var (
tempDir string
)

const (
validPlugName = "argocdapp_0.0.1-rc1.so"
notExistPlugName = "argocdapp_not_exist.so"
version = "0.0.1-ut-do-not-delete"
)

BeforeAll(func() {
tempDir = GinkgoT().TempDir()

})

Describe("download method failed", func() {
var testTable = []struct {
downloadFunc func(reqClient *resty.Client, url, plugName string) error
plugName string
expectedErrorMsg string
describeMsg string
}{
{
downloadFunc: mockPlugSuccessGetter, plugName: notExistPlugName, expectedErrorMsg: "no such file or directory",
describeMsg: "should return file not exist if plugin not normal download",
},
{
downloadFunc: mockPlugNotFoundGetter, plugName: validPlugName, expectedErrorMsg: "404",
describeMsg: "should return 404 if plugin not exist",
},
}

os.Remove(filepath.Join(".", "argocdapp_0.0.1-rc1.so"))
}
for _, testcase := range testTable {
It(testcase.describeMsg, func() {
c := NewDownloadClient()
c.pluginGetter = testcase.downloadFunc
err := c.download(tempDir, testcase.plugName, version)
Expect(err).Error().Should(HaveOccurred())
Expect(err.Error()).Should(ContainSubstring(testcase.expectedErrorMsg))
})
}
})

func TestDownloadNotFound(t *testing.T) {
c := NewDownloadClient()
err := c.download(".", "doesntexist", "0.0.1-ut-do-not-delete")
// Since the right granted to public users on aws does not include listing bucket
// AWS returns 403 instead of 404 when acquiring an object where bucket does not exist: there is no list right.
assert.Contains(t, err.Error(), "403")
}
Describe("download method success", func() {
It("should reanme file if download success", func() {
tmpFilePath := filepath.Join(tempDir, fmt.Sprintf("%s.tmp", validPlugName))
f, err := os.Create(tmpFilePath)
defer os.Remove(tmpFilePath)
defer f.Close()
Expect(err).NotTo(HaveOccurred())
c := NewDownloadClient()
c.pluginGetter = mockPlugSuccessGetter
err = c.download(tempDir, validPlugName, version)
Expect(err).ShouldNot(HaveOccurred())
renamedFilePath := filepath.Join(tempDir, validPlugName)
_, err = os.Stat(renamedFilePath)
Expect(err).ShouldNot(HaveOccurred())
})
})
})

0 comments on commit fc68afb

Please sign in to comment.