feat(loopback): add ability to mock putObject response

This commit is contained in:
Damian Debkowski authored and Timothy Messier committed 2023-05-31 12:18:18 +00:00
1 parent e1540be9f3
commit 331254402a
3 files changed
+60 -9

No files matched your search

+7 -3
View File
@@ -52,9 +52,10 @@ func NewLoopbackPlugin(opt ...TestOption) (*LoopbackPlugin, error) {
hostMap: make(map[string][]*loopbackPluginHostInfo),
},
LoopbackStorage: &LoopbackStorage{
chunksSize: opts.withChunkSize,
buckets: map[BucketName]Bucket{"default": {}},
errs: make([]PluginMockError, 0),
chunksSize: opts.withChunkSize,
buckets: map[BucketName]Bucket{"default": {}},
errs: make([]PluginMockError, 0),
putObjectResponse: make([]PluginMockPutObjectResponse, 0),
},
}
@@ -80,6 +81,9 @@ func NewLoopbackPlugin(opt ...TestOption) (*LoopbackPlugin, error) {
if len(opts.withMockError) > 0 {
ret.errs = opts.withMockError
}
if len(opts.withMockPutObjectResponse) > 0 {
ret.putObjectResponse = opts.withMockPutObjectResponse
}
return ret, nil
}
+42 -3
View File
@@ -5,6 +5,7 @@ package loopback
import (
"github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/storagebuckets"
plgpb "github.com/hashicorp/boundary/sdk/pbs/plugin"
"google.golang.org/grpc/codes"
)
@@ -82,12 +83,43 @@ func (e PluginMockError) match(bucket *storagebuckets.StorageBucket, key string,
return true
}
// PluginMockPutObjectResponse is used to mock a response when calling putObject.
type PluginMockPutObjectResponse struct {
BucketName string
BucketPrefix string
ObjectKey string
Response *plgpb.PutObjectResponse
}
// match compares the given values from the parameters to the values provided in the mocked response.
// The bucket and key parameter values should be provided from the plugin request.
//
// When match returns false, the mocked response should not be used for the plugin response.
// When match returns true, the mocked response should be used for the plugin response.
func (r PluginMockPutObjectResponse) match(bucket *storagebuckets.StorageBucket, key string) bool {
// if the mocked response object key does not match the request's object key, return false.
if r.ObjectKey != key {
return false
}
// if the mocked response bucket name does not match the request's bucket name, return false.
if r.BucketName != bucket.BucketName {
return false
}
// if the request has a bucket prefix and it does not match the mocked response bucket prefix, return false.
if bucket.BucketPrefix != "" && r.BucketPrefix != bucket.BucketPrefix {
return false
}
// all checks comparison checks passed, return true.
return true
}
type TestOption func(*TestOptions) error
type TestOptions struct {
withMockBuckets map[BucketName]Bucket
withMockError []PluginMockError
withChunkSize int
withMockBuckets map[BucketName]Bucket
withMockError []PluginMockError
withMockPutObjectResponse []PluginMockPutObjectResponse
withChunkSize int
}
// getTestOpts - iterate the inbound Options and return a struct
@@ -123,6 +155,13 @@ func WithMockError(err PluginMockError) TestOption {
}
}
func WithMockPutObjectResponse(response PluginMockPutObjectResponse) TestOption {
return func(o *TestOptions) error {
o.withMockPutObjectResponse = append(o.withMockPutObjectResponse, response)
return nil
}
}
// WithChunkSize provides an option to set the chunkSize used for grpc streams.
func WithChunkSize(size int) TestOption {
return func(o *TestOptions) error {
+11 -3
View File
@@ -109,9 +109,10 @@ type storagePluginStorageInfo struct {
type LoopbackStorage struct {
m sync.Mutex
chunksSize int
buckets map[BucketName]Bucket
errs []PluginMockError
chunksSize int
buckets map[BucketName]Bucket
errs []PluginMockError
putObjectResponse []PluginMockPutObjectResponse
}
func (l *LoopbackStorage) onCreateStorageBucket(ctx context.Context, req *plgpb.OnCreateStorageBucketRequest) (*plgpb.OnCreateStorageBucketResponse, error) {
@@ -334,11 +335,18 @@ func (l *LoopbackStorage) putObject(ctx context.Context, req *plgpb.PutObjectReq
if !ok {
return nil, status.Errorf(codes.InvalidArgument, "%s: bucket not found", op)
}
// return an expected mock error if one was provided
for _, err := range l.errs {
if err.match(req.GetBucket(), req.GetKey(), PutObject) {
return nil, status.Errorf(err.ErrCode, "%s: %s", op, err.ErrMsg)
}
}
// return an expected mock response if one was provided
for _, mock := range l.putObjectResponse {
if mock.match(req.GetBucket(), req.GetKey()) {
return mock.Response, nil
}
}
lastModified := time.Now()
objectData, err := os.ReadFile(req.Path)