2022-03-22 11:03:15 -04:00
|
|
|
package storage
|
|
|
|
|
|
|
|
import (
|
2022-03-25 06:55:49 -04:00
|
|
|
"bytes"
|
2022-03-22 11:03:15 -04:00
|
|
|
"context"
|
2022-03-25 06:55:49 -04:00
|
|
|
"errors"
|
2022-03-22 11:03:15 -04:00
|
|
|
"io"
|
|
|
|
"testing"
|
|
|
|
|
2022-03-25 06:55:49 -04:00
|
|
|
"cloud.google.com/go/storage"
|
2022-03-22 11:03:15 -04:00
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"google.golang.org/api/option"
|
|
|
|
)
|
|
|
|
|
2022-03-25 06:55:49 -04:00
|
|
|
type stubGCPStorageAPI struct {
|
|
|
|
newClientErr error
|
|
|
|
attrsErr error
|
|
|
|
createBucketErr error
|
|
|
|
createBucketCalled bool
|
|
|
|
newReaderErr error
|
|
|
|
newReaderOutput []byte
|
|
|
|
writer *stubWriteCloser
|
|
|
|
}
|
2022-03-22 11:03:15 -04:00
|
|
|
|
2022-03-25 06:55:49 -04:00
|
|
|
func (s *stubGCPStorageAPI) stubClientFactory(ctx context.Context, opts ...option.ClientOption) (gcpStorageAPI, error) {
|
|
|
|
return s, s.newClientErr
|
|
|
|
}
|
2022-03-22 11:03:15 -04:00
|
|
|
|
2022-03-25 06:55:49 -04:00
|
|
|
func (s *stubGCPStorageAPI) Attrs(ctx context.Context, bucketName string) (*storage.BucketAttrs, error) {
|
|
|
|
return &storage.BucketAttrs{}, s.attrsErr
|
|
|
|
}
|
2022-03-22 11:03:15 -04:00
|
|
|
|
2022-03-25 06:55:49 -04:00
|
|
|
func (s *stubGCPStorageAPI) Close() error {
|
|
|
|
return nil
|
|
|
|
}
|
2022-03-22 11:03:15 -04:00
|
|
|
|
2022-03-25 06:55:49 -04:00
|
|
|
func (s *stubGCPStorageAPI) CreateBucket(ctx context.Context, bucketName, projectID string, attrs *storage.BucketAttrs) error {
|
|
|
|
s.createBucketCalled = true
|
|
|
|
return s.createBucketErr
|
|
|
|
}
|
2022-03-22 11:03:15 -04:00
|
|
|
|
2022-03-25 06:55:49 -04:00
|
|
|
func (s *stubGCPStorageAPI) NewWriter(ctx context.Context, bucketName, objectName string) io.WriteCloser {
|
|
|
|
return s.writer
|
|
|
|
}
|
2022-03-22 11:03:15 -04:00
|
|
|
|
2022-03-25 06:55:49 -04:00
|
|
|
func (s *stubGCPStorageAPI) NewReader(ctx context.Context, bucketName, objectName string) (io.ReadCloser, error) {
|
|
|
|
return io.NopCloser(bytes.NewReader(s.newReaderOutput)), s.newReaderErr
|
|
|
|
}
|
2022-03-22 11:03:15 -04:00
|
|
|
|
2022-03-25 06:55:49 -04:00
|
|
|
type stubWriteCloser struct {
|
|
|
|
result *[]byte
|
|
|
|
writeErr error
|
|
|
|
writeN int
|
|
|
|
}
|
2022-03-22 11:03:15 -04:00
|
|
|
|
2022-03-25 06:55:49 -04:00
|
|
|
func (s stubWriteCloser) Write(p []byte) (int, error) {
|
|
|
|
*s.result = p
|
|
|
|
return s.writeN, s.writeErr
|
|
|
|
}
|
2022-03-22 11:03:15 -04:00
|
|
|
|
2022-03-25 06:55:49 -04:00
|
|
|
func (s stubWriteCloser) Close() error {
|
|
|
|
return nil
|
2022-03-22 11:03:15 -04:00
|
|
|
}
|
|
|
|
|
2022-03-25 06:55:49 -04:00
|
|
|
func TestGCPGet(t *testing.T) {
|
|
|
|
someErr := errors.New("error")
|
|
|
|
|
|
|
|
testCases := map[string]struct {
|
2022-04-26 10:54:05 -04:00
|
|
|
client *stubGCPStorageAPI
|
|
|
|
unsetError bool
|
|
|
|
wantErr bool
|
2022-03-25 06:55:49 -04:00
|
|
|
}{
|
|
|
|
"success": {
|
|
|
|
client: &stubGCPStorageAPI{newReaderOutput: []byte("test-data")},
|
|
|
|
},
|
|
|
|
"creating client fails": {
|
2022-04-26 10:54:05 -04:00
|
|
|
client: &stubGCPStorageAPI{newClientErr: someErr},
|
|
|
|
wantErr: true,
|
2022-03-25 06:55:49 -04:00
|
|
|
},
|
|
|
|
"NewReader fails": {
|
2022-04-26 10:54:05 -04:00
|
|
|
client: &stubGCPStorageAPI{newReaderErr: someErr},
|
|
|
|
wantErr: true,
|
2022-03-25 06:55:49 -04:00
|
|
|
},
|
|
|
|
"ErrObjectNotExist error": {
|
2022-04-26 10:54:05 -04:00
|
|
|
client: &stubGCPStorageAPI{newReaderErr: storage.ErrObjectNotExist},
|
|
|
|
unsetError: true,
|
|
|
|
wantErr: true,
|
2022-03-25 06:55:49 -04:00
|
|
|
},
|
2022-03-22 11:03:15 -04:00
|
|
|
}
|
2022-03-25 06:55:49 -04:00
|
|
|
|
|
|
|
for name, tc := range testCases {
|
|
|
|
t.Run(name, func(t *testing.T) {
|
|
|
|
assert := assert.New(t)
|
|
|
|
|
|
|
|
client := &GoogleCloudStorage{
|
|
|
|
newClient: tc.client.stubClientFactory,
|
|
|
|
projectID: "test",
|
|
|
|
bucketName: "test",
|
|
|
|
}
|
|
|
|
|
|
|
|
out, err := client.Get(context.Background(), "test-key")
|
2022-04-26 10:54:05 -04:00
|
|
|
if tc.wantErr {
|
2022-03-25 06:55:49 -04:00
|
|
|
assert.Error(err)
|
|
|
|
|
|
|
|
if tc.unsetError {
|
|
|
|
assert.ErrorIs(err, ErrDEKUnset)
|
|
|
|
} else {
|
|
|
|
assert.False(errors.Is(err, ErrDEKUnset))
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
assert.NoError(err)
|
|
|
|
assert.Equal(tc.client.newReaderOutput, out)
|
|
|
|
}
|
|
|
|
})
|
2022-03-22 11:03:15 -04:00
|
|
|
}
|
2022-03-25 06:55:49 -04:00
|
|
|
}
|
2022-03-22 11:03:15 -04:00
|
|
|
|
2022-03-25 06:55:49 -04:00
|
|
|
func TestGCPPut(t *testing.T) {
|
|
|
|
someErr := errors.New("error")
|
|
|
|
testCases := map[string]struct {
|
2022-04-26 10:54:05 -04:00
|
|
|
client *stubGCPStorageAPI
|
|
|
|
unsetError bool
|
|
|
|
wantErr bool
|
2022-03-25 06:55:49 -04:00
|
|
|
}{
|
|
|
|
"success": {
|
|
|
|
client: &stubGCPStorageAPI{
|
|
|
|
writer: &stubWriteCloser{
|
|
|
|
result: new([]byte),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"creating client fails": {
|
2022-04-26 10:54:05 -04:00
|
|
|
client: &stubGCPStorageAPI{newClientErr: someErr},
|
|
|
|
wantErr: true,
|
2022-03-25 06:55:49 -04:00
|
|
|
},
|
|
|
|
"NewWriter fails": {
|
|
|
|
client: &stubGCPStorageAPI{
|
|
|
|
writer: &stubWriteCloser{
|
|
|
|
result: new([]byte),
|
|
|
|
writeErr: someErr,
|
|
|
|
},
|
|
|
|
},
|
2022-04-26 10:54:05 -04:00
|
|
|
wantErr: true,
|
2022-03-25 06:55:49 -04:00
|
|
|
},
|
2022-03-22 11:03:15 -04:00
|
|
|
}
|
2022-03-25 06:55:49 -04:00
|
|
|
|
|
|
|
for name, tc := range testCases {
|
|
|
|
t.Run(name, func(t *testing.T) {
|
|
|
|
assert := assert.New(t)
|
|
|
|
|
|
|
|
client := &GoogleCloudStorage{
|
|
|
|
newClient: tc.client.stubClientFactory,
|
|
|
|
projectID: "test",
|
|
|
|
bucketName: "test",
|
|
|
|
}
|
|
|
|
testData := []byte{0x1, 0x2, 0x3}
|
|
|
|
|
|
|
|
err := client.Put(context.Background(), "test-key", testData)
|
2022-04-26 10:54:05 -04:00
|
|
|
if tc.wantErr {
|
2022-03-25 06:55:49 -04:00
|
|
|
assert.Error(err)
|
|
|
|
} else {
|
|
|
|
assert.NoError(err)
|
|
|
|
assert.Equal(testData, *tc.client.writer.result)
|
|
|
|
}
|
|
|
|
})
|
2022-03-22 11:03:15 -04:00
|
|
|
}
|
2022-03-25 06:55:49 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestGCPCreateContainerOrContinue(t *testing.T) {
|
|
|
|
someErr := errors.New("error")
|
|
|
|
testCases := map[string]struct {
|
|
|
|
client *stubGCPStorageAPI
|
|
|
|
createNewBucket bool
|
2022-04-26 10:54:05 -04:00
|
|
|
wantErr bool
|
2022-03-25 06:55:49 -04:00
|
|
|
}{
|
|
|
|
"success": {
|
|
|
|
client: &stubGCPStorageAPI{},
|
|
|
|
},
|
|
|
|
"container does not exist": {
|
|
|
|
client: &stubGCPStorageAPI{attrsErr: storage.ErrBucketNotExist},
|
|
|
|
createNewBucket: true,
|
|
|
|
},
|
|
|
|
"creating client fails": {
|
2022-04-26 10:54:05 -04:00
|
|
|
client: &stubGCPStorageAPI{newClientErr: someErr},
|
|
|
|
wantErr: true,
|
2022-03-25 06:55:49 -04:00
|
|
|
},
|
|
|
|
"Attrs fails": {
|
2022-04-26 10:54:05 -04:00
|
|
|
client: &stubGCPStorageAPI{attrsErr: someErr},
|
|
|
|
wantErr: true,
|
2022-03-25 06:55:49 -04:00
|
|
|
},
|
|
|
|
"CreateBucket fails": {
|
|
|
|
client: &stubGCPStorageAPI{
|
|
|
|
attrsErr: storage.ErrBucketNotExist,
|
|
|
|
createBucketErr: someErr,
|
|
|
|
},
|
2022-04-26 10:54:05 -04:00
|
|
|
wantErr: true,
|
2022-03-25 06:55:49 -04:00
|
|
|
},
|
2022-03-22 11:03:15 -04:00
|
|
|
}
|
|
|
|
|
2022-03-25 06:55:49 -04:00
|
|
|
for name, tc := range testCases {
|
|
|
|
t.Run(name, func(t *testing.T) {
|
|
|
|
assert := assert.New(t)
|
|
|
|
|
|
|
|
client := &GoogleCloudStorage{
|
|
|
|
newClient: tc.client.stubClientFactory,
|
|
|
|
projectID: "test",
|
|
|
|
bucketName: "test",
|
|
|
|
}
|
|
|
|
|
|
|
|
err := client.createContainerOrContinue(context.Background(), nil)
|
2022-04-26 10:54:05 -04:00
|
|
|
if tc.wantErr {
|
2022-03-25 06:55:49 -04:00
|
|
|
assert.Error(err)
|
|
|
|
} else {
|
|
|
|
assert.NoError(err)
|
|
|
|
if tc.createNewBucket {
|
|
|
|
assert.True(tc.client.createBucketCalled)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
2022-03-22 11:03:15 -04:00
|
|
|
}
|
|
|
|
}
|