2022-02-23 10:30:19 +02:00
|
|
|
//go:build integration
|
2021-12-15 16:07:47 +02:00
|
|
|
// +build integration
|
2022-02-23 10:30:19 +02:00
|
|
|
|
2021-12-15 16:07:47 +02:00
|
|
|
// can be execute with go test -tags=integration ./integration/...
|
|
|
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"crypto/tls"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"io/ioutil"
|
|
|
|
"net/http"
|
|
|
|
"path/filepath"
|
|
|
|
"strings"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/SAP/jenkins-library/pkg/gcs"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/testcontainers/testcontainers-go"
|
|
|
|
"github.com/testcontainers/testcontainers-go/wait"
|
|
|
|
"google.golang.org/api/option"
|
|
|
|
)
|
|
|
|
|
|
|
|
func Test_gcsClient(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
ctx := context.Background()
|
|
|
|
testdataPath, err := filepath.Abs("testdata/TestGCSIntegration")
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
req := testcontainers.GenericContainerRequest{
|
|
|
|
ContainerRequest: testcontainers.ContainerRequest{
|
|
|
|
AlwaysPullImage: true,
|
|
|
|
Image: "fsouza/fake-gcs-server:1.30.2",
|
|
|
|
ExposedPorts: []string{"4443/tcp"},
|
|
|
|
WaitingFor: wait.ForListeningPort("4443/tcp"),
|
|
|
|
Cmd: []string{"-scheme", "https", "-public-host", "localhost"},
|
|
|
|
BindMounts: map[string]string{
|
|
|
|
testdataPath: "/data",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Started: true,
|
|
|
|
}
|
|
|
|
|
|
|
|
gcsContainer, err := testcontainers.GenericContainer(ctx, req)
|
|
|
|
require.NoError(t, err)
|
|
|
|
defer gcsContainer.Terminate(ctx)
|
|
|
|
|
|
|
|
ip, err := gcsContainer.Host(ctx)
|
|
|
|
require.NoError(t, err)
|
|
|
|
port, err := gcsContainer.MappedPort(ctx, "4443")
|
|
|
|
endpoint := fmt.Sprintf("https://%s:%s/storage/v1/", ip, port.Port())
|
|
|
|
httpclient := http.Client{
|
|
|
|
Transport: &http.Transport{
|
|
|
|
TLSClientConfig: &tls.Config{
|
|
|
|
InsecureSkipVerify: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
t.Run("Test list files - success", func(t *testing.T) {
|
|
|
|
bucketID := "sample-bucket"
|
|
|
|
gcsClient, err := gcs.NewClient(gcs.WithClientOptions(option.WithEndpoint(endpoint), option.WithoutAuthentication(), option.WithHTTPClient(&httpclient)))
|
|
|
|
assert.NoError(t, err)
|
|
|
|
fileNames, err := gcsClient.ListFiles(bucketID)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, []string{"dir/test_file2.yaml", "test_file.txt"}, fileNames)
|
|
|
|
err = gcsClient.Close()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("Test list files in missing bucket", func(t *testing.T) {
|
|
|
|
bucketID := "missing-bucket"
|
|
|
|
gcsClient, err := gcs.NewClient(gcs.WithClientOptions(option.WithEndpoint(endpoint), option.WithoutAuthentication(), option.WithHTTPClient(&httpclient)))
|
|
|
|
defer gcsClient.Close()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
_, err = gcsClient.ListFiles(bucketID)
|
|
|
|
assert.Error(t, err, "bucket doesn't exist")
|
|
|
|
err = gcsClient.Close()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("Test upload & download files - success", func(t *testing.T) {
|
|
|
|
bucketID := "upload-bucket"
|
|
|
|
file1Reader, file1Writer := io.Pipe()
|
|
|
|
file2Reader, file2Writer := io.Pipe()
|
|
|
|
gcsClient, err := gcs.NewClient(gcs.WithOpenFileFunction(openFileMock), gcs.WithCreateFileFunction(getCreateFileMock(file1Writer, file2Writer)),
|
|
|
|
gcs.WithClientOptions(option.WithEndpoint(endpoint), option.WithoutAuthentication(), option.WithHTTPClient(&httpclient)))
|
|
|
|
assert.NoError(t, err)
|
|
|
|
err = gcsClient.UploadFile(bucketID, "file1", "test/file1")
|
|
|
|
assert.NoError(t, err)
|
|
|
|
err = gcsClient.UploadFile(bucketID, "folder/file2", "test/folder/file2")
|
|
|
|
assert.NoError(t, err)
|
|
|
|
fileNames, err := gcsClient.ListFiles(bucketID)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, []string{"placeholder", "test/file1", "test/folder/file2"}, fileNames)
|
|
|
|
go gcsClient.DownloadFile(bucketID, "test/file1", "file1")
|
|
|
|
fileContent, err := ioutil.ReadAll(file1Reader)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, file1Content, string(fileContent))
|
|
|
|
go gcsClient.DownloadFile(bucketID, "test/folder/file2", "file2")
|
|
|
|
fileContent, err = ioutil.ReadAll(file2Reader)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, file2Content, string(fileContent))
|
|
|
|
|
|
|
|
err = gcsClient.Close()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("Test upload missing file", func(t *testing.T) {
|
|
|
|
bucketID := "upload-bucket"
|
|
|
|
gcsClient, err := gcs.NewClient(gcs.WithOpenFileFunction(openFileMock),
|
|
|
|
gcs.WithClientOptions(option.WithEndpoint(endpoint), option.WithoutAuthentication(), option.WithHTTPClient(&httpclient)))
|
|
|
|
assert.NoError(t, err)
|
|
|
|
err = gcsClient.UploadFile(bucketID, "file3", "test/file3")
|
|
|
|
assert.Contains(t, err.Error(), "could not open source file")
|
|
|
|
err = gcsClient.Close()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("Test download missing file", func(t *testing.T) {
|
|
|
|
bucketID := "upload-bucket"
|
|
|
|
gcsClient, err := gcs.NewClient(gcs.WithOpenFileFunction(openFileMock),
|
|
|
|
gcs.WithClientOptions(option.WithEndpoint(endpoint), option.WithoutAuthentication(), option.WithHTTPClient(&httpclient)))
|
|
|
|
assert.NoError(t, err)
|
|
|
|
err = gcsClient.DownloadFile(bucketID, "test/file3", "file3")
|
|
|
|
assert.Contains(t, err.Error(), "could not open source file")
|
|
|
|
err = gcsClient.Close()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("Test download file - failed file creation", func(t *testing.T) {
|
|
|
|
bucketID := "upload-bucket"
|
|
|
|
_, file1Writer := io.Pipe()
|
|
|
|
_, file2Writer := io.Pipe()
|
|
|
|
gcsClient, err := gcs.NewClient(gcs.WithOpenFileFunction(openFileMock), gcs.WithCreateFileFunction(getCreateFileMock(file1Writer, file2Writer)),
|
|
|
|
gcs.WithClientOptions(option.WithEndpoint(endpoint), option.WithoutAuthentication(), option.WithHTTPClient(&httpclient)))
|
|
|
|
assert.NoError(t, err)
|
|
|
|
err = gcsClient.DownloadFile(bucketID, "placeholder", "file3")
|
|
|
|
assert.Contains(t, err.Error(), "could not create target file")
|
|
|
|
err = gcsClient.Close()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
const (
|
|
|
|
file1Content = `test file`
|
|
|
|
file2Content = `
|
|
|
|
foo : bar
|
|
|
|
pleh : help
|
|
|
|
stuff : {'foo': 'bar', 'bar': 'foo'}
|
|
|
|
`
|
|
|
|
)
|
|
|
|
|
|
|
|
func openFileMock(name string) (io.ReadCloser, error) {
|
|
|
|
var fileContent string
|
|
|
|
switch name {
|
|
|
|
case "file1":
|
|
|
|
fileContent = file1Content
|
|
|
|
case "folder/file2":
|
|
|
|
fileContent = file2Content
|
|
|
|
default:
|
|
|
|
return nil, errors.New("open file faled")
|
|
|
|
}
|
|
|
|
return ioutil.NopCloser(strings.NewReader(fileContent)), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func getCreateFileMock(file1Writer io.WriteCloser, file2Writer io.WriteCloser) func(name string) (io.WriteCloser, error) {
|
|
|
|
return func(name string) (io.WriteCloser, error) {
|
|
|
|
switch name {
|
|
|
|
case "file1":
|
|
|
|
return file1Writer, nil
|
|
|
|
case "file2":
|
|
|
|
return file2Writer, nil
|
|
|
|
default:
|
|
|
|
return nil, errors.New("could not create target file")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|