From a1fd606b3482ebd4e75dfe75d1b4efcfcb37cd86 Mon Sep 17 00:00:00 2001 From: Jason Coble Date: Mon, 31 Jul 2017 12:02:38 -0500 Subject: [PATCH] Initial commit of vfs --- .gitignore | 2 + LICENSE | 21 + README.md | 117 + errors/errors.go | 53 + errors/errors_example_test.go | 29 + glide.lock | 138 + glide.yaml | 25 + gs/file.go | 356 +++ gs/fileSystem.go | 52 + gs/location.go | 158 + mocks/File.go | 314 ++ mocks/FileSystem.go | 85 + mocks/Location.go | 248 ++ mocks/S3API.go | 5520 +++++++++++++++++++++++++++++++++ mocks/StringFile.go | 80 + os/file.go | 234 ++ os/fileSystem.go | 38 + os/file_test.go | 338 ++ os/location.go | 147 + os/location_test.go | 177 ++ os/test_files/prefix-file.txt | 1 + os/test_files/subdir/test.txt | 1 + os/test_files/test.txt | 1 + s3/file.go | 365 +++ s3/fileSystem.go | 51 + s3/fileSystem_test.go | 50 + s3/file_test.go | 400 +++ s3/location.go | 180 ++ s3/location_test.go | 273 ++ utils/utils.go | 75 + utils/utils_test.go | 93 + vfs.go | 132 + vfssimple/vfssimple.go | 122 + 33 files changed, 9876 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 errors/errors.go create mode 100644 errors/errors_example_test.go create mode 100644 glide.lock create mode 100644 glide.yaml create mode 100644 gs/file.go create mode 100644 gs/fileSystem.go create mode 100644 gs/location.go create mode 100644 mocks/File.go create mode 100644 mocks/FileSystem.go create mode 100644 mocks/Location.go create mode 100644 mocks/S3API.go create mode 100644 mocks/StringFile.go create mode 100644 os/file.go create mode 100644 os/fileSystem.go create mode 100644 os/file_test.go create mode 100644 os/location.go create mode 100644 os/location_test.go create mode 100644 os/test_files/prefix-file.txt create mode 100644 os/test_files/subdir/test.txt create mode 100644 os/test_files/test.txt create mode 100644 s3/file.go create mode 100644 s3/fileSystem.go create mode 100644 s3/fileSystem_test.go create mode 100644 s3/file_test.go create mode 100644 s3/location.go create mode 100644 s3/location_test.go create mode 100644 utils/utils.go create mode 100644 utils/utils_test.go create mode 100644 vfs.go create mode 100644 vfssimple/vfssimple.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..3ce5adbb --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.idea +vendor diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..f1102159 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2011-2012 C2FO + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 00000000..60a9343b --- /dev/null +++ b/README.md @@ -0,0 +1,117 @@ +# vfs - Virtual File System +> Go library to generalize commands and behavior when interacting with various file systems. + +The vfs library includes interfaces which allow you to interact with files and locations on various file systems in a generic way. Currently supported file systems: +* Local fs (Windows, OS X, Linux) +* Amazon S3 +* GCS + +These interfaces are composed of standard Go library interfaces, allowing for simple file manipulation within, and between +the supported file systems. + +At C2FO we have created a factory system that is integrated with our app configuration that allows for simply initializing the various locations we tend to do file work in. You can build your own similar system directly on top of the various file system implementations and the provided generic interfaces, or you can use the simple interface included in the vfs package. +The usage examples below will detail this simple interface. We will eventually be providing a version of our factory as an example of how this library can be used in a more complex project. + +A couple notes on configuration for this interface (vfs.NewFile and vfs.NewLocation): +* Before calling either function you must initialize any file systems you expect to be using. +* Local: The local file system requires no configuration. Simply call vfs.InitializeLocalFileSystem so the internals are prepared to expect "file:///" URIs. +* S3: The vfs.InitializeS3FileSystem() method requires authentication parameters for the user, see godoc for this function. +* GCS: In addition to calling vfs.InitializeGSFileSystem, you are expected to have authenticated with GCS using the Google Cloud Shell for the user running the app. We will be looking into more flexible forms of authentication (similar to the S3 library) in the future, but this was an ideal use case for us to start with, and therefore, all that is currently provided. + +## Installation + +OS X, Linux, and Windows: + +```sh +glide install github.com/c2fo/vfs +``` + +## Usage example + +```go +import "github.com/c2fo/vfs" + +// The following functions tell vfs we expect to handle a particular file system in subsequent calls to +// vfs.NewFile() and vfs.NewLocation +// Local files, ie: "file:///" +vfs.InitializeLocalFileSystem() + +// Google Cloud Storage, ie: "gs://" +vfs.InitializeGSFileSystem() + +// Amazon S3, ie: "s3://" +vfs.InitializeS3FileSystem(accessKeyId, secreteAccessKey, token) + +// alternative to above for S3, if you've already initialized a client of interface s3iface.S3API +vfs.SetS3Client(client) +``` + +You can then use those file systems to initialize locations which you'll be referencing frequently, or initialize files directly + +```go +osFile, err := vfs.NewFile("file:///path/to/file.txt") +s3File, err := vfs.NewFile("s3://bucket/prefix/file.txt") + +osLocation, err := vfs.NewLocation("file:///tmp") +s3Location, err := vfs.NewLocation("s3://bucket") + +osTmpFile, err := osLocation.NewFile("anotherFile.txt") // file at /tmp/anotherFile.txt +``` + +With a number of files and locations between s3 and the local file system you can perform a number of actions without any consideration for the system's api or implementation details. + +```go +osFileExists, err := osFile.Exists() // true, nil +s3FileExists, err := s3File.Exists() // false, nil +err = osFile.CopyToFile(s3File) // nil +s3FileExists, err = s3File.Exists() // true, nil + +movedOsFile, err := osFile.MoveToLocation(osLocation) +osFileExists, err = osFile.Exists() // false, nil (move actions delete the original file) +movedOsFileExists, err := movedOsFile.Exists() // true, nil + +s3FileUri := s3File.URI() // s3://bucket/prefix/file.txt +s3FileName := s3File.Name() // file.txt +s3FilePath := s3File.Path() // /prefix/file.txt + +// vfs.File and vfs.Location implement fmt.Stringer, returning x.URI() +fmt.Sprintf("Working on file: %s", s3File) // "Working on file: s3://bucket/prefix/file.txt" +``` + +## Development setup + +Fork the project and clone it locally, then in the cloned directory... + +```sh +glide install +go test $(glide novendor) +``` + +## Release History + +* 0.1.0 + * The first release + * Support for local file system, s3, and gcs + * Initial README.md + +## Meta + +Brought to you by the Enterprise Pipeline team at C2FO: + +John Judd - john.judd@c2fo.com + +Jason Coble - [@jasonkcoble](https://twitter.com/jasonkcoble) - jason@c2fo.com + +Chris Roush – chris.roush@c2fo.com + +Distributed under the MIT license. See ``LICENSE`` for more information. + +[https://github.com/c2fo/](https://github.com/c2fo/) + +## Contributing + +1. Fork it () +2. Create your feature branch (`git checkout -b feature/fooBar`) +3. Commit your changes (`git commit -am 'Add some fooBar'`) +4. Push to the branch (`git push origin feature/fooBar`) +5. Create a new Pull Request \ No newline at end of file diff --git a/errors/errors.go b/errors/errors.go new file mode 100644 index 00000000..10c406fc --- /dev/null +++ b/errors/errors.go @@ -0,0 +1,53 @@ +// Package which provides a technique for handling multiple errors in the event of deferred method calls +// such as file.Close() +package errors + +import ( + "errors" + "fmt" +) + +//MultiErr provides a set of functions to handle the scenario where, because of errors in defers, we have a way to handle +//the potenetial of multiple errors. +//for instance, if you do a open a file, defer it's close, then fail to Seek. The seek fauilure has one error but then +//the Close fails as well. This ensure neither are ignored. +type MultiErr struct { + errs []error +} + +// Constructor for generating a zero-value MultiErr reference. +func NewMutliErr() *MultiErr { + return &MultiErr{} +} + +// Returns the error message string. +func (me *MultiErr) Error() string { + var errorString string + for _, err := range me.errs { + errorString = fmt.Sprintf("%s%s\n", errorString, err.Error()) + } + return errorString +} + +// Appends the provided errors to the errs slice for future message reporting. +func (me *MultiErr) Append(errs ...error) error { + me.errs = append(me.errs, errs...) + return errors.New("return value for multiErr must be set in the first deferred function") +} + +// If there are no errors in the MultErr instance, then return nil, otherwise return the full MultiErr instance. +func (me *MultiErr) OrNil() error { + if len(me.errs) > 0 { + return me + } + return nil +} + +type singleErrReturn func() error + + +func (me *MultiErr) DeferFunc(f singleErrReturn) { + if err := f(); err != nil { + _ = me.Append(err) + } +} diff --git a/errors/errors_example_test.go b/errors/errors_example_test.go new file mode 100644 index 00000000..ae7e97a4 --- /dev/null +++ b/errors/errors_example_test.go @@ -0,0 +1,29 @@ +package errors + +import "github.com/c2fo/vfs" + +func ExampleMultiErr_DeferFunc() { + // NOTE: We use a named error in the function since our first defer will set it based on any appended errors + _ = func(f vfs.File) (rerr error) { + //THESE LINES REQUIRED + errs := NewMutliErr() + defer func() { rerr = errs.OrNil() }() + + _, err := f.Read(nil) + if err != nil { + //for REGULAR ERROR RETURNS we just return the Appended errors + return errs.Append(err) + } + + // for defers, use DeferFunc and pass it the func name + defer errs.DeferFunc(f.Close) + + _, err = f.Seek(0, 0) + if err != nil { + //for REGULAR ERROR RETURNS we just return the Appended errors + return errs.Append(err) + } + + return nil + } +} diff --git a/glide.lock b/glide.lock new file mode 100644 index 00000000..293e9d19 --- /dev/null +++ b/glide.lock @@ -0,0 +1,138 @@ +hash: 4db116c9488144cda83f2350582eed85e53e8fa4e408028bd08b882dfdd40c43 +updated: 2017-07-31T11:04:59.384828251-05:00 +imports: +- name: cloud.google.com/go + version: 085c05ca074a8de9107005f9baa6308eae7eaf41 + subpackages: + - compute/metadata + - iam + - internal + - internal/optional + - internal/version + - storage +- name: github.com/aws/aws-sdk-go + version: 5e436e55ac5eddc739f26a2a209b3f4248ee8e0e + subpackages: + - aws + - aws/awserr + - aws/awsutil + - aws/client + - aws/client/metadata + - aws/credentials + - aws/endpoints + - aws/request + - aws/signer/v4 + - internal/shareddefaults + - private/protocol + - private/protocol/query + - private/protocol/query/queryutil + - private/protocol/rest + - private/protocol/restxml + - private/protocol/xml/xmlutil + - service/s3 + - service/s3/s3iface + - service/s3/s3manager +- name: github.com/davecgh/go-spew + version: 6d212800a42e8ab5c146b8ace3490ee17e5225f9 + subpackages: + - spew +- name: github.com/go-ini/ini + version: 887c8d36f8411bededfd2281daa3907f5f36552e +- name: github.com/golang/protobuf + version: 18c9bb3261723cd5401db4d0c9fbc5c3b6c70fe8 + subpackages: + - proto + - protoc-gen-go/descriptor + - ptypes/any +- name: github.com/googleapis/gax-go + version: 9af46dd5a1713e8b5cd71106287eba3cefdde50b +- name: github.com/jmespath/go-jmespath + version: c01cf91b011868172fdcd9f41838e80c9d716264 +- name: github.com/pmezard/go-difflib + version: d8ed2627bdf02c080bf22230dbb337003b7aba2d + subpackages: + - difflib +- name: github.com/stretchr/objx + version: cbeaeb16a013161a98496fad62933b1d21786672 +- name: github.com/stretchr/testify + version: 69483b4bd14f5845b5a1e55bca19e954e827f1d0 + subpackages: + - assert + - mock + - require + - suite +- name: golang.org/x/net + version: ffcf1bedda3b04ebb15a168a59800a73d6dc0f4d + subpackages: + - context + - context/ctxhttp + - http2 + - http2/hpack + - idna + - internal/timeseries + - lex/httplex + - trace +- name: golang.org/x/oauth2 + version: 7fdf09982454086d5570c7db3e11f360194830ca + subpackages: + - google + - internal + - jws + - jwt +- name: golang.org/x/text + version: f4b4367115ec2de254587813edaa901bc1c723a8 + subpackages: + - secure/bidirule + - transform + - unicode/bidi + - unicode/norm +- name: google.golang.org/api + version: 48e49d1645e228d1c50c3d54fb476b2224477303 + subpackages: + - gensupport + - googleapi + - googleapi/internal/uritemplates + - googleapi/transport + - internal + - iterator + - option + - storage/v1 + - transport +- name: google.golang.org/appengine + version: a2f4131514e563cedfdb6e7d267df9ad48591e93 + subpackages: + - internal + - internal/app_identity + - internal/base + - internal/datastore + - internal/log + - internal/modules + - internal/remote_api + - internal/socket + - internal/urlfetch + - socket + - urlfetch +- name: google.golang.org/genproto + version: 411e09b969b1170a9f0c467558eb4c4c110d9c77 + subpackages: + - googleapis/api/annotations + - googleapis/iam/v1 + - googleapis/rpc/status +- name: google.golang.org/grpc + version: 68a5d50f4517bae2b44b18092410fe248d153f1e + subpackages: + - codes + - credentials + - credentials/oauth + - grpclb/grpc_lb_v1 + - grpclog + - internal + - keepalive + - metadata + - naming + - peer + - stats + - status + - tap + - transport +testImports: [] diff --git a/glide.yaml b/glide.yaml new file mode 100644 index 00000000..811e49d1 --- /dev/null +++ b/glide.yaml @@ -0,0 +1,25 @@ +package: github.com/c2fo/vfs +import: +- package: cloud.google.com/go + version: 085c05ca074a8de9107005f9baa6308eae7eaf41 + subpackages: + - storage +- package: github.com/aws/aws-sdk-go + version: ~1.10.18 + subpackages: + - aws/awserr + - aws/request + - service/s3 + - service/s3/s3iface + - service/s3/s3manager +- package: github.com/stretchr/testify + version: ~1.1.4 + subpackages: + - mock +- package: golang.org/x/net + subpackages: + - context +- package: google.golang.org/api + version: 48e49d1645e228d1c50c3d54fb476b2224477303 + subpackages: + - iterator diff --git a/gs/file.go b/gs/file.go new file mode 100644 index 00000000..9607ccb2 --- /dev/null +++ b/gs/file.go @@ -0,0 +1,356 @@ +package gs + +import ( + "bytes" + "errors" + "fmt" + "io" + "io/ioutil" + "os" + "path" + "time" + + "cloud.google.com/go/storage" + + "github.com/c2fo/vfs" + _errors "github.com/c2fo/vfs/errors" + "github.com/c2fo/vfs/utils" +) + +const ( + doesNotExistError = "storage: object doesn't exist" +) + +type File struct { + fileSystem *FileSystem + bucket string + key string + tempFile *os.File + writeBuffer *bytes.Buffer + bucketHandle *storage.BucketHandle + objectHandle *storage.ObjectHandle +} + +// Close cleans up underlying mechanisms for reading from and writing to the file. Closes and removes the +// local temp file, and triggers a write to GCS of anything in the f.writeBuffer if it has been created. +func (f *File) Close() (rerr error) { + //setup multi error return using named error rerr + errs := _errors.NewMutliErr() + defer func() { rerr = errs.OrNil() }() + + if f.tempFile != nil { + defer errs.DeferFunc(f.tempFile.Close) + + err := os.Remove(f.tempFile.Name()) + if err != nil && !os.IsNotExist(err) { + return errs.Append(err) + } + + f.tempFile = nil + } + + if f.writeBuffer != nil { + + w := f.getObjectHandle().NewWriter(f.fileSystem.ctx) + if _, err := io.Copy(w, f.writeBuffer); err != nil { + //CloseWithError always returns nil + _ = w.CloseWithError(err) + return errs.Append(err) + } + defer errs.DeferFunc(w.Close) + } + + f.writeBuffer = nil + return nil +} + +// Read implements the standard for io.Reader. For this to work with an GCS file, a temporary local copy of +// the file is created, and reads work on that. This file is closed and removed upon calling f.Close() +func (f *File) Read(p []byte) (n int, err error) { + if err := f.checkTempFile(); err != nil { + return 0, err + } + return f.tempFile.Read(p) +} + +// Seek implements the standard for io.Seeker. A temporary local copy of the GCS file is created (the same +// one used for Reads) which Seek() acts on. This file is closed and removed upon calling f.Close() +func (f *File) Seek(offset int64, whence int) (int64, error) { + if err := f.checkTempFile(); err != nil { + return 0, err + } + return f.tempFile.Seek(offset, whence) +} + +// Write implements the standard for io.Writer. A buffer is added to with each subsequent +// write. Calling Close() will write the contents back to GCS. +func (f *File) Write(data []byte) (n int, err error) { + if f.writeBuffer == nil { + //note, initializing with 'data' and returning len(data), nil + //causes issues with some Write usages, notably csv.Writer + //so we simply intialize with no bytes and call the buffer Write after + // + //f.writeBuffer = bytes.NewBuffer(data) + //return len(data), nil + // + //so now we do: + + f.writeBuffer = bytes.NewBuffer([]byte{}) + + } + return f.writeBuffer.Write(data) +} + +//String returns the file URI string. +func (f *File) String() string { + return f.URI() +} + +// Exists returns a boolean of whether or not the object exists in GCS. +func (f *File) Exists() (bool, error) { + _, err := f.getObjectAttrs() + if err != nil { + if err.Error() == doesNotExistError { + return false, nil + } + return false, err + } + return true, nil +} + + +// Location returns a Location instance for the file's current location. +// +// TODO should this be including trailing slash? +func (f *File) Location() vfs.Location { + return vfs.Location(&Location{ + fileSystem: f.fileSystem, + prefix: utils.EnsureTrailingSlash(utils.CleanPrefix(path.Dir(f.key))), + bucket: f.bucket, + }) +} + +// CopyToLocation creates a copy of *File, using the file's current name as the new file's +// name at the given location. If the given location is also GCS, the GCS API for copying +// files will be utilized, otherwise, standard io.Copy will be done to the new file. +func (f *File) CopyToLocation(location vfs.Location) (vfs.File, error) { + // This is a copy to gcs, from gcs, we should attempt to utilize the Google Cloud Storage API for this. + if location.FileSystem().Scheme() == Scheme { + dest, err := location.NewFile(f.Name()) + if err != nil { + return nil, err + } + cerr := f.copyWithinGCSToFile(dest.(*File)) + if cerr != nil { + return nil, cerr + } + return dest, nil + } + + newFile, err := location.FileSystem().NewFile(location.Volume(), path.Join(location.Path(), f.Name())) + if err != nil { + return nil, err + } + + if _, err := io.Copy(newFile, f); err != nil { + return nil, err + } + //Close target file to flush and ensure that cursor isn't at the end of the file when the caller reopens for read + if cerr := newFile.Close(); cerr != nil { + return nil, cerr + } + //Close file (f) reader + if cerr := f.Close(); cerr != nil { + return nil, cerr + } + return newFile, nil +} + +// CopyToFile puts the contents of File into the targetFile passed. Uses the GCS CopierFrom +// method if the target file is also on GCS, otherwise uses io.Copy. +func (f *File) CopyToFile(targetFile vfs.File) error { + if tf, ok := targetFile.(*File); ok { + return f.copyWithinGCSToFile(tf) + } + + if _, err := io.Copy(targetFile, f); err != nil { + return err + } + //Close target to flush and ensure that cursor isn't at the end of the file when the caller reopens for read + if cerr := targetFile.Close(); cerr != nil { + return cerr + } + //Close file (f) reader + if cerr := f.Close(); cerr != nil { + return cerr + } + return nil +} + +// MoveToLocation works by first calling File.CopyToLocation(vfs.Location) then, if that +// succeeds, it deletes the original file, returning the new file. If the copy process fails +// the error is returned, and the Delete isn't called. If the call to Delete fails, the error +// and the file generated by the copy are both returned. +func (f *File) MoveToLocation(location vfs.Location) (vfs.File, error) { + newFile, err := f.CopyToLocation(location) + if err != nil { + return nil, err + } + delErr := f.Delete() + return newFile, delErr +} + +// MoveToFile puts the contents of File into the targetFile passed using File.CopyToFile. +// If the copy succeeds, the source file is deleted. Any errors from the copy or delete are +// returned. +func (f *File) MoveToFile(targetFile vfs.File) error { + if err := f.CopyToFile(targetFile); err != nil { + return err + } + + return f.Delete() +} + +// Delete clears any local temp file, or write buffer from read/writes to the file, then makes +// a DeleteObject call to s3 for the file. Returns any error returned by the API. +func (f *File) Delete() error { + f.writeBuffer = nil + if err := f.Close(); err != nil { + return err + } + return f.getObjectHandle().Delete(f.fileSystem.ctx) +} + +// LastModified returns the 'Updated' property from the GCS attributes. +func (f *File) LastModified() (*time.Time, error) { + attr, err := f.getObjectAttrs() + if err != nil { + return nil, err + } + return &attr.Updated, nil +} + +// LastModified returns the 'Size' property from the GCS attributes. +func (f *File) Size() (uint64, error) { + attr, err := f.getObjectAttrs() + if err != nil { + return 0, err + } + return uint64(attr.Size), nil +} + +// Path returns full path with leading slash of the GCS file key. +func (f *File) Path() string { + return "/" + f.key +} + +// Name returns the file name. +func (f *File) Name() string { + return path.Base(f.key) +} + +// URI returns a full GCS URI string of the file. +func (f *File) URI() string { + return utils.GetFileURI(vfs.File(f)) +} + +func (f *File) checkTempFile() error { + if f.tempFile == nil { + localTempFile, err := f.copyToLocalTempReader() + if err != nil { + return err + } + f.tempFile = localTempFile + } + return nil +} + +func (f *File) copyToLocalTempReader() (*os.File, error) { + tmpFile, err := ioutil.TempFile("", fmt.Sprintf("%s.%d", f.Name(), time.Now().UnixNano())) + if err != nil { + return nil, err + } + + outputReader, err := f.getObjectHandle().NewReader(f.fileSystem.ctx) + if err != nil { + return nil, err + } + + if _, err := io.Copy(tmpFile, outputReader); err != nil { + return nil, err + } + + if err := outputReader.Close(); err != nil { + if cerr := tmpFile.Close(); cerr != nil { + return nil, cerr + } + return nil, err + } + + // Return cursor to the beginning of the new temp file + if _, err := tmpFile.Seek(0, 0); err != nil { + return nil, err + } + + //initialize temp ReadCloser + return tmpFile, nil +} + +// getBucketHandle returns cached Bucket struct for file +func (f *File) getBucketHandle() *storage.BucketHandle { + if f.bucketHandle != nil { + return f.bucketHandle + } + f.bucketHandle = f.fileSystem.client.Bucket(f.bucket) + return f.bucketHandle +} + +// getObjectHandle returns cached Object struct for file +func (f *File) getObjectHandle() *storage.ObjectHandle { + if f.objectHandle != nil { + return f.objectHandle + } + f.objectHandle = f.getBucketHandle().Object(f.key) + return f.objectHandle +} + +// getObjectAttrs returns the file's attributes +func (f *File) getObjectAttrs() (*storage.ObjectAttrs, error) { + return f.getObjectHandle().Attrs(f.fileSystem.ctx) +} + +func (f *File) copyWithinGCSToFile(targetFile *File) error { + // Copy content and modify metadata. + copier := targetFile.getObjectHandle().CopierFrom(f.getObjectHandle()) + attrs, gerr := f.getObjectAttrs() + if gerr != nil { + return gerr + } + copier.ContentType = attrs.ContentType + _, cerr := copier.Run(f.fileSystem.ctx) + if cerr != nil { + return cerr + } + + // Just copy content. + _, err := targetFile.getObjectHandle().CopierFrom(f.getObjectHandle()).Run(f.fileSystem.ctx) + + return err +} + +/* private helper functions */ + +func newFile(fs *FileSystem, bucket, key string) (*File, error) { + if fs == nil { + return nil, errors.New("non-nil gs.FileSystem pointer is required") + } + if bucket == "" || key == "" { + return nil, errors.New("non-empty strings for Bucket and Key are required") + } + key = utils.CleanPrefix(key) + return &File{ + fileSystem: fs, + bucket: bucket, + key: key, + }, nil +} diff --git a/gs/fileSystem.go b/gs/fileSystem.go new file mode 100644 index 00000000..bd6cdde6 --- /dev/null +++ b/gs/fileSystem.go @@ -0,0 +1,52 @@ +package gs + +import ( + "cloud.google.com/go/storage" + "golang.org/x/net/context" + + "github.com/c2fo/vfs" + "github.com/c2fo/vfs/utils" +) + +//Scheme defines the filesystem type. +const Scheme = "gs" + +// FileSystem implements vfs.Filesystem for the GCS filesystem. +type FileSystem struct { + client *storage.Client + ctx context.Context +} + +// NewFile function returns the gcs implementation of vfs.File. +func (fs *FileSystem) NewFile(volume string, name string) (vfs.File, error) { + file, err := newFile(fs, volume, name) + return vfs.File(file), err +} + +// NewLocation function returns the s3 implementation of vfs.Location. +func (fs *FileSystem) NewLocation(volume string, path string) (loc vfs.Location, err error) { + loc = &Location{ + fileSystem: fs, + bucket: volume, + prefix: utils.EnsureTrailingSlash(path), + } + return +} + +// Name returns "Google Cloud Storage" +func (fs *FileSystem) Name() string { + return "Google Cloud Storage" +} + +// Scheme return "gs" as the initial part of a file URI ie: gs:// +func (fs *FileSystem) Scheme() string { + return Scheme +} + +// NewFileSystem intializer for FileSystem struct accepts google cloud storage client and returns Filesystem or error. +func NewFileSystem(ctx context.Context, client *storage.Client) *FileSystem { + return &FileSystem{ + client: client, + ctx: ctx, + } +} diff --git a/gs/location.go b/gs/location.go new file mode 100644 index 00000000..69711b4f --- /dev/null +++ b/gs/location.go @@ -0,0 +1,158 @@ +// Google Cloud Storage VFS implementation. +// +// See: https://github.com/GoogleCloudPlatform/google-cloud-go. +package gs + +import ( + "path" + "regexp" + "strings" + + "cloud.google.com/go/storage" + "google.golang.org/api/iterator" + + "github.com/c2fo/vfs" + "github.com/c2fo/vfs/utils" +) + +// Implements vfs.Location +type Location struct { + fileSystem *FileSystem + prefix string + bucket string + bucketHandle *storage.BucketHandle +} + +// String returns the full URI of the file. +func (l *Location) String() string { + return l.URI() +} + +// List returns a list of file name strings for the current location. +func (l *Location) List() ([]string, error) { + return l.ListByPrefix("") +} + +//ListByPrefix returns a slice of file base names and any error, if any +//prefix means filename prefix and therefore should not have slash +//List functions return only files +//List functions return only basenames +func (l *Location) ListByPrefix(filenamePrefix string) ([]string, error) { + q := &storage.Query{ + Delimiter: "/", + Prefix: l.prefix + filenamePrefix, + Versions: false, + } + + it := l.getBucketHandle().Objects(l.fileSystem.ctx, q) + + var fileNames []string + for { + objAttrs, err := it.Next() + if err != nil { + if err == iterator.Done { + break + } + return nil, err + } + //only include objects, not "directories" + if objAttrs.Prefix == "" && objAttrs.Name != l.prefix{ + fileNames = append(fileNames, strings.TrimPrefix(objAttrs.Name, l.prefix)) + } + } + return fileNames, nil +} + +// ListByPrefix returns a list of file names at the location which match the provided regular expression. +func (l *Location) ListByRegex(regex *regexp.Regexp) ([]string, error) { + keys, err := l.List() + if err != nil { + return []string{}, err + } + + filteredKeys := []string{} + for _, key := range keys { + if regex.MatchString(key) { + filteredKeys = append(filteredKeys, key) + } + } + return filteredKeys, nil +} + +// Volume returns the GCS bucket name. +func (l *Location) Volume() string { + return l.bucket +} + +// Path returns the path of the file at the current location, starting with a leading '/' +func (l *Location) Path() string { + return "/" + utils.EnsureTrailingSlash(l.prefix) +} + +// Exists returns whether the location exists or not. In the case of an error, false is returned. +func (l *Location) Exists() (bool, error) { + _, err := l.getBucketAttrs() + if err != nil { + if err.Error() == doesNotExistError { + return false, nil + } + return false, err + } + return true, nil +} + +// NewLocation creates a new location instance relative to the current location's path. +func (l *Location) NewLocation(relativePath string) (vfs.Location, error) { + newLocation := *l + err := newLocation.ChangeDir(relativePath) + if err != nil { + return nil, err + } + return &newLocation, nil +} + +// ChangeDir changes the current location's path to the new, relative path. +func (l *Location) ChangeDir(relativePath string) error { + newPrefix := path.Join(l.prefix, relativePath) + l.prefix = utils.EnsureTrailingSlash(utils.CleanPrefix(newPrefix)) + return nil +} + +// FileSystem returns the GCS file system instance. +func (l *Location) FileSystem() vfs.FileSystem { + return l.fileSystem +} + +// NewFile returns a new file instance at the given path, relative to the current location. +func (l *Location) NewFile(filePath string) (vfs.File, error) { + return newFile(l.fileSystem, l.bucket, path.Join(l.prefix, filePath)) +} + +// DeleteFile deletes the file at the given path, relative to the current location. +func (l *Location) DeleteFile(fileName string) error { + file, err := l.NewFile(fileName) + if err != nil { + return err + } + + return file.Delete() +} + +// URI returns a URI string for the GCS file. +func (l *Location) URI() string { + return utils.GetLocationURI(l) +} + +// getBucketHandle returns cached Bucket struct for file +func (l *Location) getBucketHandle() *storage.BucketHandle { + if l.bucketHandle != nil { + return l.bucketHandle + } + l.bucketHandle = l.fileSystem.client.Bucket(l.bucket) + return l.bucketHandle +} + +// getObjectAttrs returns the file's attributes +func (l *Location) getBucketAttrs() (*storage.BucketAttrs, error) { + return l.getBucketHandle().Attrs(l.fileSystem.ctx) +} diff --git a/mocks/File.go b/mocks/File.go new file mode 100644 index 00000000..09e4cc6f --- /dev/null +++ b/mocks/File.go @@ -0,0 +1,314 @@ +package mocks + +import mock "github.com/stretchr/testify/mock" +import time "time" +import vfs "github.com/c2fo/vfs" + +// File is an autogenerated mock type for the File type +type File struct { + mock.Mock +} + +// Close provides a mock function with given fields: +func (_m *File) Close() error { + ret := _m.Called() + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// CopyToFile provides a mock function with given fields: _a0 +func (_m *File) CopyToFile(_a0 vfs.File) error { + ret := _m.Called(_a0) + + var r0 error + if rf, ok := ret.Get(0).(func(vfs.File) error); ok { + r0 = rf(_a0) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// CopyToLocation provides a mock function with given fields: location +func (_m *File) CopyToLocation(location vfs.Location) (vfs.File, error) { + ret := _m.Called(location) + + var r0 vfs.File + if rf, ok := ret.Get(0).(func(vfs.Location) vfs.File); ok { + r0 = rf(location) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(vfs.File) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(vfs.Location) error); ok { + r1 = rf(location) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Delete provides a mock function with given fields: +func (_m *File) Delete() error { + ret := _m.Called() + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Exists provides a mock function with given fields: +func (_m *File) Exists() (bool, error) { + ret := _m.Called() + + var r0 bool + if rf, ok := ret.Get(0).(func() bool); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(bool) + } + + var r1 error + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Location provides a mock function with given fields: +func (_m *File) Location() vfs.Location { + ret := _m.Called() + + var r0 vfs.Location + if rf, ok := ret.Get(0).(func() vfs.Location); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(vfs.Location) + } + } + + return r0 +} + +// LastModified provides a mock function with given fields: +func (_m *File) LastModified() (*time.Time, error) { + ret := _m.Called() + + var r0 *time.Time + if rf, ok := ret.Get(0).(func() *time.Time); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*time.Time) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MoveToFile provides a mock function with given fields: _a0 +func (_m *File) MoveToFile(_a0 vfs.File) error { + ret := _m.Called(_a0) + + var r0 error + if rf, ok := ret.Get(0).(func(vfs.File) error); ok { + r0 = rf(_a0) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MoveToLocation provides a mock function with given fields: location +func (_m *File) MoveToLocation(location vfs.Location) (vfs.File, error) { + ret := _m.Called(location) + + var r0 vfs.File + if rf, ok := ret.Get(0).(func(vfs.Location) vfs.File); ok { + r0 = rf(location) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(vfs.File) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(vfs.Location) error); ok { + r1 = rf(location) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Name provides a mock function with given fields: +func (_m *File) Name() string { + ret := _m.Called() + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// Path provides a mock function with given fields: +func (_m *File) Path() string { + ret := _m.Called() + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// Read provides a mock function with given fields: p +func (_m *File) Read(p []byte) (int, error) { + ret := _m.Called(p) + + var r0 int + if rf, ok := ret.Get(0).(func([]byte) int); ok { + r0 = rf(p) + } else { + r0 = ret.Get(0).(int) + } + + var r1 error + if rf, ok := ret.Get(1).(func([]byte) error); ok { + r1 = rf(p) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Seek provides a mock function with given fields: offset, whence +func (_m *File) Seek(offset int64, whence int) (int64, error) { + ret := _m.Called(offset, whence) + + var r0 int64 + if rf, ok := ret.Get(0).(func(int64, int) int64); ok { + r0 = rf(offset, whence) + } else { + r0 = ret.Get(0).(int64) + } + + var r1 error + if rf, ok := ret.Get(1).(func(int64, int) error); ok { + r1 = rf(offset, whence) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Size provides a mock function with given fields: +func (_m *File) Size() (uint64, error) { + ret := _m.Called() + + var r0 uint64 + if rf, ok := ret.Get(0).(func() uint64); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(uint64) + } + + var r1 error + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Write provides a mock function with given fields: p +func (_m *File) Write(p []byte) (int, error) { + ret := _m.Called(p) + + var r0 int + if rf, ok := ret.Get(0).(func([]byte) int); ok { + r0 = rf(p) + } else { + r0 = ret.Get(0).(int) + } + + var r1 error + if rf, ok := ret.Get(1).(func([]byte) error); ok { + r1 = rf(p) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// URI provides a mock function with given fields: +func (_m *File) URI() string { + ret := _m.Called() + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// String provides a mock function with given fields: +func (_m *File) String() string { + ret := _m.Called() + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +var _ vfs.File = (*File)(nil) diff --git a/mocks/FileSystem.go b/mocks/FileSystem.go new file mode 100644 index 00000000..1f4f1b09 --- /dev/null +++ b/mocks/FileSystem.go @@ -0,0 +1,85 @@ +package mocks + +import mock "github.com/stretchr/testify/mock" +import vfs "github.com/c2fo/vfs" + +// FileSystem is an autogenerated mock type for the FileSystem type +type FileSystem struct { + mock.Mock +} + +// Name provides a mock function with given fields: +func (_m *FileSystem) Name() string { + ret := _m.Called() + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// NewFile provides a mock function with given fields: volume, name +func (_m *FileSystem) NewFile(volume string, name string) (vfs.File, error) { + ret := _m.Called(volume, name) + + var r0 vfs.File + if rf, ok := ret.Get(0).(func(string, string) vfs.File); ok { + r0 = rf(volume, name) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(vfs.File) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(string, string) error); ok { + r1 = rf(volume, name) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NewLocation provides a mock function with given fields: volume, path +func (_m *FileSystem) NewLocation(volume string, path string) (vfs.Location, error) { + ret := _m.Called(volume, path) + + var r0 vfs.Location + if rf, ok := ret.Get(0).(func(string, string) vfs.Location); ok { + r0 = rf(volume, path) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(vfs.Location) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(string, string) error); ok { + r1 = rf(volume, path) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Scheme provides a mock function with given fields: +func (_m *FileSystem) Scheme() string { + ret := _m.Called() + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +var _ vfs.FileSystem = (*FileSystem)(nil) diff --git a/mocks/Location.go b/mocks/Location.go new file mode 100644 index 00000000..e86314bd --- /dev/null +++ b/mocks/Location.go @@ -0,0 +1,248 @@ +package mocks + +import mock "github.com/stretchr/testify/mock" +import regexp "regexp" +import vfs "github.com/c2fo/vfs" + +// Location is an autogenerated mock type for the Location type +type Location struct { + mock.Mock +} + +// ChangeDir provides a mock function with given fields: relativePath +func (_m *Location) ChangeDir(relativePath string) error { + ret := _m.Called(relativePath) + + var r0 error + if rf, ok := ret.Get(0).(func(string) error); ok { + r0 = rf(relativePath) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DeleteFile provides a mock function with given fields: fileName +func (_m *Location) DeleteFile(fileName string) error { + ret := _m.Called(fileName) + + var r0 error + if rf, ok := ret.Get(0).(func(string) error); ok { + r0 = rf(fileName) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Exists provides a mock function with given fields: +func (_m *Location) Exists() (bool, error) { + ret := _m.Called() + + var r0 bool + if rf, ok := ret.Get(0).(func() bool); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(bool) + } + + var r1 error + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FileSystem provides a mock function with given fields: +func (_m *Location) FileSystem() vfs.FileSystem { + ret := _m.Called() + + var r0 vfs.FileSystem + if rf, ok := ret.Get(0).(func() vfs.FileSystem); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(vfs.FileSystem) + } + } + + return r0 +} + +// List provides a mock function with given fields: +func (_m *Location) List() ([]string, error) { + ret := _m.Called() + + var r0 []string + if rf, ok := ret.Get(0).(func() []string); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]string) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListByPrefix provides a mock function with given fields: prefix +func (_m *Location) ListByPrefix(prefix string) ([]string, error) { + ret := _m.Called(prefix) + + var r0 []string + if rf, ok := ret.Get(0).(func(string) []string); ok { + r0 = rf(prefix) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]string) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(string) error); ok { + r1 = rf(prefix) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListByRegex provides a mock function with given fields: regex +func (_m *Location) ListByRegex(regex *regexp.Regexp) ([]string, error) { + ret := _m.Called(regex) + + var r0 []string + if rf, ok := ret.Get(0).(func(*regexp.Regexp) []string); ok { + r0 = rf(regex) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]string) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*regexp.Regexp) error); ok { + r1 = rf(regex) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NewFile provides a mock function with given fields: fileName +func (_m *Location) NewFile(fileName string) (vfs.File, error) { + ret := _m.Called(fileName) + + var r0 vfs.File + if rf, ok := ret.Get(0).(func(string) vfs.File); ok { + r0 = rf(fileName) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(vfs.File) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(string) error); ok { + r1 = rf(fileName) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NewLocation provides a mock function with given fields: relativePath +func (_m *Location) NewLocation(relativePath string) (vfs.Location, error) { + ret := _m.Called(relativePath) + + var r0 vfs.Location + if rf, ok := ret.Get(0).(func(string) vfs.Location); ok { + r0 = rf(relativePath) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(vfs.Location) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(string) error); ok { + r1 = rf(relativePath) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Path provides a mock function with given fields: +func (_m *Location) Path() string { + ret := _m.Called() + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// String provides a mock function with given fields: +func (_m *Location) String() string { + ret := _m.Called() + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// URI provides a mock function with given fields: +func (_m *Location) URI() string { + ret := _m.Called() + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// Volume provides a mock function with given fields: +func (_m *Location) Volume() string { + ret := _m.Called() + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +var _ vfs.Location = (*Location)(nil) diff --git a/mocks/S3API.go b/mocks/S3API.go new file mode 100644 index 00000000..7bf8aefc --- /dev/null +++ b/mocks/S3API.go @@ -0,0 +1,5520 @@ +package mocks + +import aws "github.com/aws/aws-sdk-go/aws" +import mock "github.com/stretchr/testify/mock" +import request "github.com/aws/aws-sdk-go/aws/request" +import s3 "github.com/aws/aws-sdk-go/service/s3" +import s3iface "github.com/aws/aws-sdk-go/service/s3/s3iface" + +// S3API is an autogenerated mock type for the S3API type +type S3API struct { + mock.Mock +} + +// AbortMultipartUpload provides a mock function with given fields: _a0 +func (_m *S3API) AbortMultipartUpload(_a0 *s3.AbortMultipartUploadInput) (*s3.AbortMultipartUploadOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.AbortMultipartUploadOutput + if rf, ok := ret.Get(0).(func(*s3.AbortMultipartUploadInput) *s3.AbortMultipartUploadOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.AbortMultipartUploadOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.AbortMultipartUploadInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// AbortMultipartUploadRequest provides a mock function with given fields: _a0 +func (_m *S3API) AbortMultipartUploadRequest(_a0 *s3.AbortMultipartUploadInput) (*request.Request, *s3.AbortMultipartUploadOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.AbortMultipartUploadInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.AbortMultipartUploadOutput + if rf, ok := ret.Get(1).(func(*s3.AbortMultipartUploadInput) *s3.AbortMultipartUploadOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.AbortMultipartUploadOutput) + } + } + + return r0, r1 +} + +// AbortMultipartUploadWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) AbortMultipartUploadWithContext(_a0 aws.Context, _a1 *s3.AbortMultipartUploadInput, _a2 ...request.Option) (*s3.AbortMultipartUploadOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.AbortMultipartUploadOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.AbortMultipartUploadInput, ...request.Option) *s3.AbortMultipartUploadOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.AbortMultipartUploadOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.AbortMultipartUploadInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CompleteMultipartUpload provides a mock function with given fields: _a0 +func (_m *S3API) CompleteMultipartUpload(_a0 *s3.CompleteMultipartUploadInput) (*s3.CompleteMultipartUploadOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.CompleteMultipartUploadOutput + if rf, ok := ret.Get(0).(func(*s3.CompleteMultipartUploadInput) *s3.CompleteMultipartUploadOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.CompleteMultipartUploadOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.CompleteMultipartUploadInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CompleteMultipartUploadRequest provides a mock function with given fields: _a0 +func (_m *S3API) CompleteMultipartUploadRequest(_a0 *s3.CompleteMultipartUploadInput) (*request.Request, *s3.CompleteMultipartUploadOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.CompleteMultipartUploadInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.CompleteMultipartUploadOutput + if rf, ok := ret.Get(1).(func(*s3.CompleteMultipartUploadInput) *s3.CompleteMultipartUploadOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.CompleteMultipartUploadOutput) + } + } + + return r0, r1 +} + +// CompleteMultipartUploadWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) CompleteMultipartUploadWithContext(_a0 aws.Context, _a1 *s3.CompleteMultipartUploadInput, _a2 ...request.Option) (*s3.CompleteMultipartUploadOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.CompleteMultipartUploadOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.CompleteMultipartUploadInput, ...request.Option) *s3.CompleteMultipartUploadOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.CompleteMultipartUploadOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.CompleteMultipartUploadInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CopyObject provides a mock function with given fields: _a0 +func (_m *S3API) CopyObject(_a0 *s3.CopyObjectInput) (*s3.CopyObjectOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.CopyObjectOutput + if rf, ok := ret.Get(0).(func(*s3.CopyObjectInput) *s3.CopyObjectOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.CopyObjectOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.CopyObjectInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CopyObjectRequest provides a mock function with given fields: _a0 +func (_m *S3API) CopyObjectRequest(_a0 *s3.CopyObjectInput) (*request.Request, *s3.CopyObjectOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.CopyObjectInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.CopyObjectOutput + if rf, ok := ret.Get(1).(func(*s3.CopyObjectInput) *s3.CopyObjectOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.CopyObjectOutput) + } + } + + return r0, r1 +} + +// CopyObjectWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) CopyObjectWithContext(_a0 aws.Context, _a1 *s3.CopyObjectInput, _a2 ...request.Option) (*s3.CopyObjectOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.CopyObjectOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.CopyObjectInput, ...request.Option) *s3.CopyObjectOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.CopyObjectOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.CopyObjectInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreateBucket provides a mock function with given fields: _a0 +func (_m *S3API) CreateBucket(_a0 *s3.CreateBucketInput) (*s3.CreateBucketOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.CreateBucketOutput + if rf, ok := ret.Get(0).(func(*s3.CreateBucketInput) *s3.CreateBucketOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.CreateBucketOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.CreateBucketInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreateBucketRequest provides a mock function with given fields: _a0 +func (_m *S3API) CreateBucketRequest(_a0 *s3.CreateBucketInput) (*request.Request, *s3.CreateBucketOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.CreateBucketInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.CreateBucketOutput + if rf, ok := ret.Get(1).(func(*s3.CreateBucketInput) *s3.CreateBucketOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.CreateBucketOutput) + } + } + + return r0, r1 +} + +// CreateBucketWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) CreateBucketWithContext(_a0 aws.Context, _a1 *s3.CreateBucketInput, _a2 ...request.Option) (*s3.CreateBucketOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.CreateBucketOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.CreateBucketInput, ...request.Option) *s3.CreateBucketOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.CreateBucketOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.CreateBucketInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreateMultipartUpload provides a mock function with given fields: _a0 +func (_m *S3API) CreateMultipartUpload(_a0 *s3.CreateMultipartUploadInput) (*s3.CreateMultipartUploadOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.CreateMultipartUploadOutput + if rf, ok := ret.Get(0).(func(*s3.CreateMultipartUploadInput) *s3.CreateMultipartUploadOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.CreateMultipartUploadOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.CreateMultipartUploadInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreateMultipartUploadRequest provides a mock function with given fields: _a0 +func (_m *S3API) CreateMultipartUploadRequest(_a0 *s3.CreateMultipartUploadInput) (*request.Request, *s3.CreateMultipartUploadOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.CreateMultipartUploadInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.CreateMultipartUploadOutput + if rf, ok := ret.Get(1).(func(*s3.CreateMultipartUploadInput) *s3.CreateMultipartUploadOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.CreateMultipartUploadOutput) + } + } + + return r0, r1 +} + +// CreateMultipartUploadWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) CreateMultipartUploadWithContext(_a0 aws.Context, _a1 *s3.CreateMultipartUploadInput, _a2 ...request.Option) (*s3.CreateMultipartUploadOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.CreateMultipartUploadOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.CreateMultipartUploadInput, ...request.Option) *s3.CreateMultipartUploadOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.CreateMultipartUploadOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.CreateMultipartUploadInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DeleteBucket provides a mock function with given fields: _a0 +func (_m *S3API) DeleteBucket(_a0 *s3.DeleteBucketInput) (*s3.DeleteBucketOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.DeleteBucketOutput + if rf, ok := ret.Get(0).(func(*s3.DeleteBucketInput) *s3.DeleteBucketOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.DeleteBucketOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.DeleteBucketInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DeleteBucketAnalyticsConfiguration provides a mock function with given fields: _a0 +func (_m *S3API) DeleteBucketAnalyticsConfiguration(_a0 *s3.DeleteBucketAnalyticsConfigurationInput) (*s3.DeleteBucketAnalyticsConfigurationOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.DeleteBucketAnalyticsConfigurationOutput + if rf, ok := ret.Get(0).(func(*s3.DeleteBucketAnalyticsConfigurationInput) *s3.DeleteBucketAnalyticsConfigurationOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.DeleteBucketAnalyticsConfigurationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.DeleteBucketAnalyticsConfigurationInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DeleteBucketAnalyticsConfigurationRequest provides a mock function with given fields: _a0 +func (_m *S3API) DeleteBucketAnalyticsConfigurationRequest(_a0 *s3.DeleteBucketAnalyticsConfigurationInput) (*request.Request, *s3.DeleteBucketAnalyticsConfigurationOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.DeleteBucketAnalyticsConfigurationInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.DeleteBucketAnalyticsConfigurationOutput + if rf, ok := ret.Get(1).(func(*s3.DeleteBucketAnalyticsConfigurationInput) *s3.DeleteBucketAnalyticsConfigurationOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.DeleteBucketAnalyticsConfigurationOutput) + } + } + + return r0, r1 +} + +// DeleteBucketAnalyticsConfigurationWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) DeleteBucketAnalyticsConfigurationWithContext(_a0 aws.Context, _a1 *s3.DeleteBucketAnalyticsConfigurationInput, _a2 ...request.Option) (*s3.DeleteBucketAnalyticsConfigurationOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.DeleteBucketAnalyticsConfigurationOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.DeleteBucketAnalyticsConfigurationInput, ...request.Option) *s3.DeleteBucketAnalyticsConfigurationOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.DeleteBucketAnalyticsConfigurationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.DeleteBucketAnalyticsConfigurationInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DeleteBucketCors provides a mock function with given fields: _a0 +func (_m *S3API) DeleteBucketCors(_a0 *s3.DeleteBucketCorsInput) (*s3.DeleteBucketCorsOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.DeleteBucketCorsOutput + if rf, ok := ret.Get(0).(func(*s3.DeleteBucketCorsInput) *s3.DeleteBucketCorsOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.DeleteBucketCorsOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.DeleteBucketCorsInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DeleteBucketCorsRequest provides a mock function with given fields: _a0 +func (_m *S3API) DeleteBucketCorsRequest(_a0 *s3.DeleteBucketCorsInput) (*request.Request, *s3.DeleteBucketCorsOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.DeleteBucketCorsInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.DeleteBucketCorsOutput + if rf, ok := ret.Get(1).(func(*s3.DeleteBucketCorsInput) *s3.DeleteBucketCorsOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.DeleteBucketCorsOutput) + } + } + + return r0, r1 +} + +// DeleteBucketCorsWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) DeleteBucketCorsWithContext(_a0 aws.Context, _a1 *s3.DeleteBucketCorsInput, _a2 ...request.Option) (*s3.DeleteBucketCorsOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.DeleteBucketCorsOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.DeleteBucketCorsInput, ...request.Option) *s3.DeleteBucketCorsOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.DeleteBucketCorsOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.DeleteBucketCorsInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DeleteBucketInventoryConfiguration provides a mock function with given fields: _a0 +func (_m *S3API) DeleteBucketInventoryConfiguration(_a0 *s3.DeleteBucketInventoryConfigurationInput) (*s3.DeleteBucketInventoryConfigurationOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.DeleteBucketInventoryConfigurationOutput + if rf, ok := ret.Get(0).(func(*s3.DeleteBucketInventoryConfigurationInput) *s3.DeleteBucketInventoryConfigurationOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.DeleteBucketInventoryConfigurationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.DeleteBucketInventoryConfigurationInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DeleteBucketInventoryConfigurationRequest provides a mock function with given fields: _a0 +func (_m *S3API) DeleteBucketInventoryConfigurationRequest(_a0 *s3.DeleteBucketInventoryConfigurationInput) (*request.Request, *s3.DeleteBucketInventoryConfigurationOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.DeleteBucketInventoryConfigurationInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.DeleteBucketInventoryConfigurationOutput + if rf, ok := ret.Get(1).(func(*s3.DeleteBucketInventoryConfigurationInput) *s3.DeleteBucketInventoryConfigurationOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.DeleteBucketInventoryConfigurationOutput) + } + } + + return r0, r1 +} + +// DeleteBucketInventoryConfigurationWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) DeleteBucketInventoryConfigurationWithContext(_a0 aws.Context, _a1 *s3.DeleteBucketInventoryConfigurationInput, _a2 ...request.Option) (*s3.DeleteBucketInventoryConfigurationOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.DeleteBucketInventoryConfigurationOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.DeleteBucketInventoryConfigurationInput, ...request.Option) *s3.DeleteBucketInventoryConfigurationOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.DeleteBucketInventoryConfigurationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.DeleteBucketInventoryConfigurationInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DeleteBucketLifecycle provides a mock function with given fields: _a0 +func (_m *S3API) DeleteBucketLifecycle(_a0 *s3.DeleteBucketLifecycleInput) (*s3.DeleteBucketLifecycleOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.DeleteBucketLifecycleOutput + if rf, ok := ret.Get(0).(func(*s3.DeleteBucketLifecycleInput) *s3.DeleteBucketLifecycleOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.DeleteBucketLifecycleOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.DeleteBucketLifecycleInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DeleteBucketLifecycleRequest provides a mock function with given fields: _a0 +func (_m *S3API) DeleteBucketLifecycleRequest(_a0 *s3.DeleteBucketLifecycleInput) (*request.Request, *s3.DeleteBucketLifecycleOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.DeleteBucketLifecycleInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.DeleteBucketLifecycleOutput + if rf, ok := ret.Get(1).(func(*s3.DeleteBucketLifecycleInput) *s3.DeleteBucketLifecycleOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.DeleteBucketLifecycleOutput) + } + } + + return r0, r1 +} + +// DeleteBucketLifecycleWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) DeleteBucketLifecycleWithContext(_a0 aws.Context, _a1 *s3.DeleteBucketLifecycleInput, _a2 ...request.Option) (*s3.DeleteBucketLifecycleOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.DeleteBucketLifecycleOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.DeleteBucketLifecycleInput, ...request.Option) *s3.DeleteBucketLifecycleOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.DeleteBucketLifecycleOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.DeleteBucketLifecycleInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DeleteBucketMetricsConfiguration provides a mock function with given fields: _a0 +func (_m *S3API) DeleteBucketMetricsConfiguration(_a0 *s3.DeleteBucketMetricsConfigurationInput) (*s3.DeleteBucketMetricsConfigurationOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.DeleteBucketMetricsConfigurationOutput + if rf, ok := ret.Get(0).(func(*s3.DeleteBucketMetricsConfigurationInput) *s3.DeleteBucketMetricsConfigurationOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.DeleteBucketMetricsConfigurationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.DeleteBucketMetricsConfigurationInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DeleteBucketMetricsConfigurationRequest provides a mock function with given fields: _a0 +func (_m *S3API) DeleteBucketMetricsConfigurationRequest(_a0 *s3.DeleteBucketMetricsConfigurationInput) (*request.Request, *s3.DeleteBucketMetricsConfigurationOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.DeleteBucketMetricsConfigurationInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.DeleteBucketMetricsConfigurationOutput + if rf, ok := ret.Get(1).(func(*s3.DeleteBucketMetricsConfigurationInput) *s3.DeleteBucketMetricsConfigurationOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.DeleteBucketMetricsConfigurationOutput) + } + } + + return r0, r1 +} + +// DeleteBucketMetricsConfigurationWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) DeleteBucketMetricsConfigurationWithContext(_a0 aws.Context, _a1 *s3.DeleteBucketMetricsConfigurationInput, _a2 ...request.Option) (*s3.DeleteBucketMetricsConfigurationOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.DeleteBucketMetricsConfigurationOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.DeleteBucketMetricsConfigurationInput, ...request.Option) *s3.DeleteBucketMetricsConfigurationOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.DeleteBucketMetricsConfigurationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.DeleteBucketMetricsConfigurationInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DeleteBucketPolicy provides a mock function with given fields: _a0 +func (_m *S3API) DeleteBucketPolicy(_a0 *s3.DeleteBucketPolicyInput) (*s3.DeleteBucketPolicyOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.DeleteBucketPolicyOutput + if rf, ok := ret.Get(0).(func(*s3.DeleteBucketPolicyInput) *s3.DeleteBucketPolicyOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.DeleteBucketPolicyOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.DeleteBucketPolicyInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DeleteBucketPolicyRequest provides a mock function with given fields: _a0 +func (_m *S3API) DeleteBucketPolicyRequest(_a0 *s3.DeleteBucketPolicyInput) (*request.Request, *s3.DeleteBucketPolicyOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.DeleteBucketPolicyInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.DeleteBucketPolicyOutput + if rf, ok := ret.Get(1).(func(*s3.DeleteBucketPolicyInput) *s3.DeleteBucketPolicyOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.DeleteBucketPolicyOutput) + } + } + + return r0, r1 +} + +// DeleteBucketPolicyWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) DeleteBucketPolicyWithContext(_a0 aws.Context, _a1 *s3.DeleteBucketPolicyInput, _a2 ...request.Option) (*s3.DeleteBucketPolicyOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.DeleteBucketPolicyOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.DeleteBucketPolicyInput, ...request.Option) *s3.DeleteBucketPolicyOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.DeleteBucketPolicyOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.DeleteBucketPolicyInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DeleteBucketReplication provides a mock function with given fields: _a0 +func (_m *S3API) DeleteBucketReplication(_a0 *s3.DeleteBucketReplicationInput) (*s3.DeleteBucketReplicationOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.DeleteBucketReplicationOutput + if rf, ok := ret.Get(0).(func(*s3.DeleteBucketReplicationInput) *s3.DeleteBucketReplicationOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.DeleteBucketReplicationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.DeleteBucketReplicationInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DeleteBucketReplicationRequest provides a mock function with given fields: _a0 +func (_m *S3API) DeleteBucketReplicationRequest(_a0 *s3.DeleteBucketReplicationInput) (*request.Request, *s3.DeleteBucketReplicationOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.DeleteBucketReplicationInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.DeleteBucketReplicationOutput + if rf, ok := ret.Get(1).(func(*s3.DeleteBucketReplicationInput) *s3.DeleteBucketReplicationOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.DeleteBucketReplicationOutput) + } + } + + return r0, r1 +} + +// DeleteBucketReplicationWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) DeleteBucketReplicationWithContext(_a0 aws.Context, _a1 *s3.DeleteBucketReplicationInput, _a2 ...request.Option) (*s3.DeleteBucketReplicationOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.DeleteBucketReplicationOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.DeleteBucketReplicationInput, ...request.Option) *s3.DeleteBucketReplicationOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.DeleteBucketReplicationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.DeleteBucketReplicationInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DeleteBucketRequest provides a mock function with given fields: _a0 +func (_m *S3API) DeleteBucketRequest(_a0 *s3.DeleteBucketInput) (*request.Request, *s3.DeleteBucketOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.DeleteBucketInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.DeleteBucketOutput + if rf, ok := ret.Get(1).(func(*s3.DeleteBucketInput) *s3.DeleteBucketOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.DeleteBucketOutput) + } + } + + return r0, r1 +} + +// DeleteBucketTagging provides a mock function with given fields: _a0 +func (_m *S3API) DeleteBucketTagging(_a0 *s3.DeleteBucketTaggingInput) (*s3.DeleteBucketTaggingOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.DeleteBucketTaggingOutput + if rf, ok := ret.Get(0).(func(*s3.DeleteBucketTaggingInput) *s3.DeleteBucketTaggingOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.DeleteBucketTaggingOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.DeleteBucketTaggingInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DeleteBucketTaggingRequest provides a mock function with given fields: _a0 +func (_m *S3API) DeleteBucketTaggingRequest(_a0 *s3.DeleteBucketTaggingInput) (*request.Request, *s3.DeleteBucketTaggingOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.DeleteBucketTaggingInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.DeleteBucketTaggingOutput + if rf, ok := ret.Get(1).(func(*s3.DeleteBucketTaggingInput) *s3.DeleteBucketTaggingOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.DeleteBucketTaggingOutput) + } + } + + return r0, r1 +} + +// DeleteBucketTaggingWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) DeleteBucketTaggingWithContext(_a0 aws.Context, _a1 *s3.DeleteBucketTaggingInput, _a2 ...request.Option) (*s3.DeleteBucketTaggingOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.DeleteBucketTaggingOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.DeleteBucketTaggingInput, ...request.Option) *s3.DeleteBucketTaggingOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.DeleteBucketTaggingOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.DeleteBucketTaggingInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DeleteBucketWebsite provides a mock function with given fields: _a0 +func (_m *S3API) DeleteBucketWebsite(_a0 *s3.DeleteBucketWebsiteInput) (*s3.DeleteBucketWebsiteOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.DeleteBucketWebsiteOutput + if rf, ok := ret.Get(0).(func(*s3.DeleteBucketWebsiteInput) *s3.DeleteBucketWebsiteOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.DeleteBucketWebsiteOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.DeleteBucketWebsiteInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DeleteBucketWebsiteRequest provides a mock function with given fields: _a0 +func (_m *S3API) DeleteBucketWebsiteRequest(_a0 *s3.DeleteBucketWebsiteInput) (*request.Request, *s3.DeleteBucketWebsiteOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.DeleteBucketWebsiteInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.DeleteBucketWebsiteOutput + if rf, ok := ret.Get(1).(func(*s3.DeleteBucketWebsiteInput) *s3.DeleteBucketWebsiteOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.DeleteBucketWebsiteOutput) + } + } + + return r0, r1 +} + +// DeleteBucketWebsiteWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) DeleteBucketWebsiteWithContext(_a0 aws.Context, _a1 *s3.DeleteBucketWebsiteInput, _a2 ...request.Option) (*s3.DeleteBucketWebsiteOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.DeleteBucketWebsiteOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.DeleteBucketWebsiteInput, ...request.Option) *s3.DeleteBucketWebsiteOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.DeleteBucketWebsiteOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.DeleteBucketWebsiteInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DeleteBucketWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) DeleteBucketWithContext(_a0 aws.Context, _a1 *s3.DeleteBucketInput, _a2 ...request.Option) (*s3.DeleteBucketOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.DeleteBucketOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.DeleteBucketInput, ...request.Option) *s3.DeleteBucketOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.DeleteBucketOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.DeleteBucketInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DeleteObject provides a mock function with given fields: _a0 +func (_m *S3API) DeleteObject(_a0 *s3.DeleteObjectInput) (*s3.DeleteObjectOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.DeleteObjectOutput + if rf, ok := ret.Get(0).(func(*s3.DeleteObjectInput) *s3.DeleteObjectOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.DeleteObjectOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.DeleteObjectInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DeleteObjectRequest provides a mock function with given fields: _a0 +func (_m *S3API) DeleteObjectRequest(_a0 *s3.DeleteObjectInput) (*request.Request, *s3.DeleteObjectOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.DeleteObjectInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.DeleteObjectOutput + if rf, ok := ret.Get(1).(func(*s3.DeleteObjectInput) *s3.DeleteObjectOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.DeleteObjectOutput) + } + } + + return r0, r1 +} + +// DeleteObjectTagging provides a mock function with given fields: _a0 +func (_m *S3API) DeleteObjectTagging(_a0 *s3.DeleteObjectTaggingInput) (*s3.DeleteObjectTaggingOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.DeleteObjectTaggingOutput + if rf, ok := ret.Get(0).(func(*s3.DeleteObjectTaggingInput) *s3.DeleteObjectTaggingOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.DeleteObjectTaggingOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.DeleteObjectTaggingInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DeleteObjectTaggingRequest provides a mock function with given fields: _a0 +func (_m *S3API) DeleteObjectTaggingRequest(_a0 *s3.DeleteObjectTaggingInput) (*request.Request, *s3.DeleteObjectTaggingOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.DeleteObjectTaggingInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.DeleteObjectTaggingOutput + if rf, ok := ret.Get(1).(func(*s3.DeleteObjectTaggingInput) *s3.DeleteObjectTaggingOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.DeleteObjectTaggingOutput) + } + } + + return r0, r1 +} + +// DeleteObjectTaggingWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) DeleteObjectTaggingWithContext(_a0 aws.Context, _a1 *s3.DeleteObjectTaggingInput, _a2 ...request.Option) (*s3.DeleteObjectTaggingOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.DeleteObjectTaggingOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.DeleteObjectTaggingInput, ...request.Option) *s3.DeleteObjectTaggingOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.DeleteObjectTaggingOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.DeleteObjectTaggingInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DeleteObjectWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) DeleteObjectWithContext(_a0 aws.Context, _a1 *s3.DeleteObjectInput, _a2 ...request.Option) (*s3.DeleteObjectOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.DeleteObjectOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.DeleteObjectInput, ...request.Option) *s3.DeleteObjectOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.DeleteObjectOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.DeleteObjectInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DeleteObjects provides a mock function with given fields: _a0 +func (_m *S3API) DeleteObjects(_a0 *s3.DeleteObjectsInput) (*s3.DeleteObjectsOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.DeleteObjectsOutput + if rf, ok := ret.Get(0).(func(*s3.DeleteObjectsInput) *s3.DeleteObjectsOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.DeleteObjectsOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.DeleteObjectsInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DeleteObjectsRequest provides a mock function with given fields: _a0 +func (_m *S3API) DeleteObjectsRequest(_a0 *s3.DeleteObjectsInput) (*request.Request, *s3.DeleteObjectsOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.DeleteObjectsInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.DeleteObjectsOutput + if rf, ok := ret.Get(1).(func(*s3.DeleteObjectsInput) *s3.DeleteObjectsOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.DeleteObjectsOutput) + } + } + + return r0, r1 +} + +// DeleteObjectsWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) DeleteObjectsWithContext(_a0 aws.Context, _a1 *s3.DeleteObjectsInput, _a2 ...request.Option) (*s3.DeleteObjectsOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.DeleteObjectsOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.DeleteObjectsInput, ...request.Option) *s3.DeleteObjectsOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.DeleteObjectsOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.DeleteObjectsInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketAccelerateConfiguration provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketAccelerateConfiguration(_a0 *s3.GetBucketAccelerateConfigurationInput) (*s3.GetBucketAccelerateConfigurationOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.GetBucketAccelerateConfigurationOutput + if rf, ok := ret.Get(0).(func(*s3.GetBucketAccelerateConfigurationInput) *s3.GetBucketAccelerateConfigurationOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetBucketAccelerateConfigurationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.GetBucketAccelerateConfigurationInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketAccelerateConfigurationRequest provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketAccelerateConfigurationRequest(_a0 *s3.GetBucketAccelerateConfigurationInput) (*request.Request, *s3.GetBucketAccelerateConfigurationOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.GetBucketAccelerateConfigurationInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.GetBucketAccelerateConfigurationOutput + if rf, ok := ret.Get(1).(func(*s3.GetBucketAccelerateConfigurationInput) *s3.GetBucketAccelerateConfigurationOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.GetBucketAccelerateConfigurationOutput) + } + } + + return r0, r1 +} + +// GetBucketAccelerateConfigurationWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) GetBucketAccelerateConfigurationWithContext(_a0 aws.Context, _a1 *s3.GetBucketAccelerateConfigurationInput, _a2 ...request.Option) (*s3.GetBucketAccelerateConfigurationOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.GetBucketAccelerateConfigurationOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.GetBucketAccelerateConfigurationInput, ...request.Option) *s3.GetBucketAccelerateConfigurationOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetBucketAccelerateConfigurationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.GetBucketAccelerateConfigurationInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketAcl provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketAcl(_a0 *s3.GetBucketAclInput) (*s3.GetBucketAclOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.GetBucketAclOutput + if rf, ok := ret.Get(0).(func(*s3.GetBucketAclInput) *s3.GetBucketAclOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetBucketAclOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.GetBucketAclInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketAclRequest provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketAclRequest(_a0 *s3.GetBucketAclInput) (*request.Request, *s3.GetBucketAclOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.GetBucketAclInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.GetBucketAclOutput + if rf, ok := ret.Get(1).(func(*s3.GetBucketAclInput) *s3.GetBucketAclOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.GetBucketAclOutput) + } + } + + return r0, r1 +} + +// GetBucketAclWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) GetBucketAclWithContext(_a0 aws.Context, _a1 *s3.GetBucketAclInput, _a2 ...request.Option) (*s3.GetBucketAclOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.GetBucketAclOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.GetBucketAclInput, ...request.Option) *s3.GetBucketAclOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetBucketAclOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.GetBucketAclInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketAnalyticsConfiguration provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketAnalyticsConfiguration(_a0 *s3.GetBucketAnalyticsConfigurationInput) (*s3.GetBucketAnalyticsConfigurationOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.GetBucketAnalyticsConfigurationOutput + if rf, ok := ret.Get(0).(func(*s3.GetBucketAnalyticsConfigurationInput) *s3.GetBucketAnalyticsConfigurationOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetBucketAnalyticsConfigurationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.GetBucketAnalyticsConfigurationInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketAnalyticsConfigurationRequest provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketAnalyticsConfigurationRequest(_a0 *s3.GetBucketAnalyticsConfigurationInput) (*request.Request, *s3.GetBucketAnalyticsConfigurationOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.GetBucketAnalyticsConfigurationInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.GetBucketAnalyticsConfigurationOutput + if rf, ok := ret.Get(1).(func(*s3.GetBucketAnalyticsConfigurationInput) *s3.GetBucketAnalyticsConfigurationOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.GetBucketAnalyticsConfigurationOutput) + } + } + + return r0, r1 +} + +// GetBucketAnalyticsConfigurationWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) GetBucketAnalyticsConfigurationWithContext(_a0 aws.Context, _a1 *s3.GetBucketAnalyticsConfigurationInput, _a2 ...request.Option) (*s3.GetBucketAnalyticsConfigurationOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.GetBucketAnalyticsConfigurationOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.GetBucketAnalyticsConfigurationInput, ...request.Option) *s3.GetBucketAnalyticsConfigurationOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetBucketAnalyticsConfigurationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.GetBucketAnalyticsConfigurationInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketCors provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketCors(_a0 *s3.GetBucketCorsInput) (*s3.GetBucketCorsOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.GetBucketCorsOutput + if rf, ok := ret.Get(0).(func(*s3.GetBucketCorsInput) *s3.GetBucketCorsOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetBucketCorsOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.GetBucketCorsInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketCorsRequest provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketCorsRequest(_a0 *s3.GetBucketCorsInput) (*request.Request, *s3.GetBucketCorsOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.GetBucketCorsInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.GetBucketCorsOutput + if rf, ok := ret.Get(1).(func(*s3.GetBucketCorsInput) *s3.GetBucketCorsOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.GetBucketCorsOutput) + } + } + + return r0, r1 +} + +// GetBucketCorsWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) GetBucketCorsWithContext(_a0 aws.Context, _a1 *s3.GetBucketCorsInput, _a2 ...request.Option) (*s3.GetBucketCorsOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.GetBucketCorsOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.GetBucketCorsInput, ...request.Option) *s3.GetBucketCorsOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetBucketCorsOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.GetBucketCorsInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketInventoryConfiguration provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketInventoryConfiguration(_a0 *s3.GetBucketInventoryConfigurationInput) (*s3.GetBucketInventoryConfigurationOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.GetBucketInventoryConfigurationOutput + if rf, ok := ret.Get(0).(func(*s3.GetBucketInventoryConfigurationInput) *s3.GetBucketInventoryConfigurationOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetBucketInventoryConfigurationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.GetBucketInventoryConfigurationInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketInventoryConfigurationRequest provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketInventoryConfigurationRequest(_a0 *s3.GetBucketInventoryConfigurationInput) (*request.Request, *s3.GetBucketInventoryConfigurationOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.GetBucketInventoryConfigurationInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.GetBucketInventoryConfigurationOutput + if rf, ok := ret.Get(1).(func(*s3.GetBucketInventoryConfigurationInput) *s3.GetBucketInventoryConfigurationOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.GetBucketInventoryConfigurationOutput) + } + } + + return r0, r1 +} + +// GetBucketInventoryConfigurationWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) GetBucketInventoryConfigurationWithContext(_a0 aws.Context, _a1 *s3.GetBucketInventoryConfigurationInput, _a2 ...request.Option) (*s3.GetBucketInventoryConfigurationOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.GetBucketInventoryConfigurationOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.GetBucketInventoryConfigurationInput, ...request.Option) *s3.GetBucketInventoryConfigurationOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetBucketInventoryConfigurationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.GetBucketInventoryConfigurationInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketLifecycle provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketLifecycle(_a0 *s3.GetBucketLifecycleInput) (*s3.GetBucketLifecycleOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.GetBucketLifecycleOutput + if rf, ok := ret.Get(0).(func(*s3.GetBucketLifecycleInput) *s3.GetBucketLifecycleOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetBucketLifecycleOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.GetBucketLifecycleInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketLifecycleConfiguration provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketLifecycleConfiguration(_a0 *s3.GetBucketLifecycleConfigurationInput) (*s3.GetBucketLifecycleConfigurationOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.GetBucketLifecycleConfigurationOutput + if rf, ok := ret.Get(0).(func(*s3.GetBucketLifecycleConfigurationInput) *s3.GetBucketLifecycleConfigurationOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetBucketLifecycleConfigurationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.GetBucketLifecycleConfigurationInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketLifecycleConfigurationRequest provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketLifecycleConfigurationRequest(_a0 *s3.GetBucketLifecycleConfigurationInput) (*request.Request, *s3.GetBucketLifecycleConfigurationOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.GetBucketLifecycleConfigurationInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.GetBucketLifecycleConfigurationOutput + if rf, ok := ret.Get(1).(func(*s3.GetBucketLifecycleConfigurationInput) *s3.GetBucketLifecycleConfigurationOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.GetBucketLifecycleConfigurationOutput) + } + } + + return r0, r1 +} + +// GetBucketLifecycleConfigurationWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) GetBucketLifecycleConfigurationWithContext(_a0 aws.Context, _a1 *s3.GetBucketLifecycleConfigurationInput, _a2 ...request.Option) (*s3.GetBucketLifecycleConfigurationOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.GetBucketLifecycleConfigurationOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.GetBucketLifecycleConfigurationInput, ...request.Option) *s3.GetBucketLifecycleConfigurationOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetBucketLifecycleConfigurationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.GetBucketLifecycleConfigurationInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketLifecycleRequest provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketLifecycleRequest(_a0 *s3.GetBucketLifecycleInput) (*request.Request, *s3.GetBucketLifecycleOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.GetBucketLifecycleInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.GetBucketLifecycleOutput + if rf, ok := ret.Get(1).(func(*s3.GetBucketLifecycleInput) *s3.GetBucketLifecycleOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.GetBucketLifecycleOutput) + } + } + + return r0, r1 +} + +// GetBucketLifecycleWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) GetBucketLifecycleWithContext(_a0 aws.Context, _a1 *s3.GetBucketLifecycleInput, _a2 ...request.Option) (*s3.GetBucketLifecycleOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.GetBucketLifecycleOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.GetBucketLifecycleInput, ...request.Option) *s3.GetBucketLifecycleOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetBucketLifecycleOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.GetBucketLifecycleInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketLocation provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketLocation(_a0 *s3.GetBucketLocationInput) (*s3.GetBucketLocationOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.GetBucketLocationOutput + if rf, ok := ret.Get(0).(func(*s3.GetBucketLocationInput) *s3.GetBucketLocationOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetBucketLocationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.GetBucketLocationInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketLocationRequest provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketLocationRequest(_a0 *s3.GetBucketLocationInput) (*request.Request, *s3.GetBucketLocationOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.GetBucketLocationInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.GetBucketLocationOutput + if rf, ok := ret.Get(1).(func(*s3.GetBucketLocationInput) *s3.GetBucketLocationOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.GetBucketLocationOutput) + } + } + + return r0, r1 +} + +// GetBucketLocationWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) GetBucketLocationWithContext(_a0 aws.Context, _a1 *s3.GetBucketLocationInput, _a2 ...request.Option) (*s3.GetBucketLocationOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.GetBucketLocationOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.GetBucketLocationInput, ...request.Option) *s3.GetBucketLocationOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetBucketLocationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.GetBucketLocationInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketLogging provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketLogging(_a0 *s3.GetBucketLoggingInput) (*s3.GetBucketLoggingOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.GetBucketLoggingOutput + if rf, ok := ret.Get(0).(func(*s3.GetBucketLoggingInput) *s3.GetBucketLoggingOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetBucketLoggingOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.GetBucketLoggingInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketLoggingRequest provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketLoggingRequest(_a0 *s3.GetBucketLoggingInput) (*request.Request, *s3.GetBucketLoggingOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.GetBucketLoggingInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.GetBucketLoggingOutput + if rf, ok := ret.Get(1).(func(*s3.GetBucketLoggingInput) *s3.GetBucketLoggingOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.GetBucketLoggingOutput) + } + } + + return r0, r1 +} + +// GetBucketLoggingWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) GetBucketLoggingWithContext(_a0 aws.Context, _a1 *s3.GetBucketLoggingInput, _a2 ...request.Option) (*s3.GetBucketLoggingOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.GetBucketLoggingOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.GetBucketLoggingInput, ...request.Option) *s3.GetBucketLoggingOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetBucketLoggingOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.GetBucketLoggingInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketMetricsConfiguration provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketMetricsConfiguration(_a0 *s3.GetBucketMetricsConfigurationInput) (*s3.GetBucketMetricsConfigurationOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.GetBucketMetricsConfigurationOutput + if rf, ok := ret.Get(0).(func(*s3.GetBucketMetricsConfigurationInput) *s3.GetBucketMetricsConfigurationOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetBucketMetricsConfigurationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.GetBucketMetricsConfigurationInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketMetricsConfigurationRequest provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketMetricsConfigurationRequest(_a0 *s3.GetBucketMetricsConfigurationInput) (*request.Request, *s3.GetBucketMetricsConfigurationOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.GetBucketMetricsConfigurationInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.GetBucketMetricsConfigurationOutput + if rf, ok := ret.Get(1).(func(*s3.GetBucketMetricsConfigurationInput) *s3.GetBucketMetricsConfigurationOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.GetBucketMetricsConfigurationOutput) + } + } + + return r0, r1 +} + +// GetBucketMetricsConfigurationWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) GetBucketMetricsConfigurationWithContext(_a0 aws.Context, _a1 *s3.GetBucketMetricsConfigurationInput, _a2 ...request.Option) (*s3.GetBucketMetricsConfigurationOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.GetBucketMetricsConfigurationOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.GetBucketMetricsConfigurationInput, ...request.Option) *s3.GetBucketMetricsConfigurationOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetBucketMetricsConfigurationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.GetBucketMetricsConfigurationInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketNotification provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketNotification(_a0 *s3.GetBucketNotificationConfigurationRequest) (*s3.NotificationConfigurationDeprecated, error) { + ret := _m.Called(_a0) + + var r0 *s3.NotificationConfigurationDeprecated + if rf, ok := ret.Get(0).(func(*s3.GetBucketNotificationConfigurationRequest) *s3.NotificationConfigurationDeprecated); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.NotificationConfigurationDeprecated) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.GetBucketNotificationConfigurationRequest) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketNotificationConfiguration provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketNotificationConfiguration(_a0 *s3.GetBucketNotificationConfigurationRequest) (*s3.NotificationConfiguration, error) { + ret := _m.Called(_a0) + + var r0 *s3.NotificationConfiguration + if rf, ok := ret.Get(0).(func(*s3.GetBucketNotificationConfigurationRequest) *s3.NotificationConfiguration); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.NotificationConfiguration) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.GetBucketNotificationConfigurationRequest) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketNotificationConfigurationRequest provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketNotificationConfigurationRequest(_a0 *s3.GetBucketNotificationConfigurationRequest) (*request.Request, *s3.NotificationConfiguration) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.GetBucketNotificationConfigurationRequest) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.NotificationConfiguration + if rf, ok := ret.Get(1).(func(*s3.GetBucketNotificationConfigurationRequest) *s3.NotificationConfiguration); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.NotificationConfiguration) + } + } + + return r0, r1 +} + +// GetBucketNotificationConfigurationWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) GetBucketNotificationConfigurationWithContext(_a0 aws.Context, _a1 *s3.GetBucketNotificationConfigurationRequest, _a2 ...request.Option) (*s3.NotificationConfiguration, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.NotificationConfiguration + if rf, ok := ret.Get(0).(func(aws.Context, *s3.GetBucketNotificationConfigurationRequest, ...request.Option) *s3.NotificationConfiguration); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.NotificationConfiguration) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.GetBucketNotificationConfigurationRequest, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketNotificationRequest provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketNotificationRequest(_a0 *s3.GetBucketNotificationConfigurationRequest) (*request.Request, *s3.NotificationConfigurationDeprecated) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.GetBucketNotificationConfigurationRequest) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.NotificationConfigurationDeprecated + if rf, ok := ret.Get(1).(func(*s3.GetBucketNotificationConfigurationRequest) *s3.NotificationConfigurationDeprecated); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.NotificationConfigurationDeprecated) + } + } + + return r0, r1 +} + +// GetBucketNotificationWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) GetBucketNotificationWithContext(_a0 aws.Context, _a1 *s3.GetBucketNotificationConfigurationRequest, _a2 ...request.Option) (*s3.NotificationConfigurationDeprecated, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.NotificationConfigurationDeprecated + if rf, ok := ret.Get(0).(func(aws.Context, *s3.GetBucketNotificationConfigurationRequest, ...request.Option) *s3.NotificationConfigurationDeprecated); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.NotificationConfigurationDeprecated) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.GetBucketNotificationConfigurationRequest, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketPolicy provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketPolicy(_a0 *s3.GetBucketPolicyInput) (*s3.GetBucketPolicyOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.GetBucketPolicyOutput + if rf, ok := ret.Get(0).(func(*s3.GetBucketPolicyInput) *s3.GetBucketPolicyOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetBucketPolicyOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.GetBucketPolicyInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketPolicyRequest provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketPolicyRequest(_a0 *s3.GetBucketPolicyInput) (*request.Request, *s3.GetBucketPolicyOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.GetBucketPolicyInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.GetBucketPolicyOutput + if rf, ok := ret.Get(1).(func(*s3.GetBucketPolicyInput) *s3.GetBucketPolicyOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.GetBucketPolicyOutput) + } + } + + return r0, r1 +} + +// GetBucketPolicyWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) GetBucketPolicyWithContext(_a0 aws.Context, _a1 *s3.GetBucketPolicyInput, _a2 ...request.Option) (*s3.GetBucketPolicyOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.GetBucketPolicyOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.GetBucketPolicyInput, ...request.Option) *s3.GetBucketPolicyOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetBucketPolicyOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.GetBucketPolicyInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketReplication provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketReplication(_a0 *s3.GetBucketReplicationInput) (*s3.GetBucketReplicationOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.GetBucketReplicationOutput + if rf, ok := ret.Get(0).(func(*s3.GetBucketReplicationInput) *s3.GetBucketReplicationOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetBucketReplicationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.GetBucketReplicationInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketReplicationRequest provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketReplicationRequest(_a0 *s3.GetBucketReplicationInput) (*request.Request, *s3.GetBucketReplicationOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.GetBucketReplicationInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.GetBucketReplicationOutput + if rf, ok := ret.Get(1).(func(*s3.GetBucketReplicationInput) *s3.GetBucketReplicationOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.GetBucketReplicationOutput) + } + } + + return r0, r1 +} + +// GetBucketReplicationWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) GetBucketReplicationWithContext(_a0 aws.Context, _a1 *s3.GetBucketReplicationInput, _a2 ...request.Option) (*s3.GetBucketReplicationOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.GetBucketReplicationOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.GetBucketReplicationInput, ...request.Option) *s3.GetBucketReplicationOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetBucketReplicationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.GetBucketReplicationInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketRequestPayment provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketRequestPayment(_a0 *s3.GetBucketRequestPaymentInput) (*s3.GetBucketRequestPaymentOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.GetBucketRequestPaymentOutput + if rf, ok := ret.Get(0).(func(*s3.GetBucketRequestPaymentInput) *s3.GetBucketRequestPaymentOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetBucketRequestPaymentOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.GetBucketRequestPaymentInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketRequestPaymentRequest provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketRequestPaymentRequest(_a0 *s3.GetBucketRequestPaymentInput) (*request.Request, *s3.GetBucketRequestPaymentOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.GetBucketRequestPaymentInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.GetBucketRequestPaymentOutput + if rf, ok := ret.Get(1).(func(*s3.GetBucketRequestPaymentInput) *s3.GetBucketRequestPaymentOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.GetBucketRequestPaymentOutput) + } + } + + return r0, r1 +} + +// GetBucketRequestPaymentWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) GetBucketRequestPaymentWithContext(_a0 aws.Context, _a1 *s3.GetBucketRequestPaymentInput, _a2 ...request.Option) (*s3.GetBucketRequestPaymentOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.GetBucketRequestPaymentOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.GetBucketRequestPaymentInput, ...request.Option) *s3.GetBucketRequestPaymentOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetBucketRequestPaymentOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.GetBucketRequestPaymentInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketTagging provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketTagging(_a0 *s3.GetBucketTaggingInput) (*s3.GetBucketTaggingOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.GetBucketTaggingOutput + if rf, ok := ret.Get(0).(func(*s3.GetBucketTaggingInput) *s3.GetBucketTaggingOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetBucketTaggingOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.GetBucketTaggingInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketTaggingRequest provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketTaggingRequest(_a0 *s3.GetBucketTaggingInput) (*request.Request, *s3.GetBucketTaggingOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.GetBucketTaggingInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.GetBucketTaggingOutput + if rf, ok := ret.Get(1).(func(*s3.GetBucketTaggingInput) *s3.GetBucketTaggingOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.GetBucketTaggingOutput) + } + } + + return r0, r1 +} + +// GetBucketTaggingWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) GetBucketTaggingWithContext(_a0 aws.Context, _a1 *s3.GetBucketTaggingInput, _a2 ...request.Option) (*s3.GetBucketTaggingOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.GetBucketTaggingOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.GetBucketTaggingInput, ...request.Option) *s3.GetBucketTaggingOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetBucketTaggingOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.GetBucketTaggingInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketVersioning provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketVersioning(_a0 *s3.GetBucketVersioningInput) (*s3.GetBucketVersioningOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.GetBucketVersioningOutput + if rf, ok := ret.Get(0).(func(*s3.GetBucketVersioningInput) *s3.GetBucketVersioningOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetBucketVersioningOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.GetBucketVersioningInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketVersioningRequest provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketVersioningRequest(_a0 *s3.GetBucketVersioningInput) (*request.Request, *s3.GetBucketVersioningOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.GetBucketVersioningInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.GetBucketVersioningOutput + if rf, ok := ret.Get(1).(func(*s3.GetBucketVersioningInput) *s3.GetBucketVersioningOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.GetBucketVersioningOutput) + } + } + + return r0, r1 +} + +// GetBucketVersioningWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) GetBucketVersioningWithContext(_a0 aws.Context, _a1 *s3.GetBucketVersioningInput, _a2 ...request.Option) (*s3.GetBucketVersioningOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.GetBucketVersioningOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.GetBucketVersioningInput, ...request.Option) *s3.GetBucketVersioningOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetBucketVersioningOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.GetBucketVersioningInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketWebsite provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketWebsite(_a0 *s3.GetBucketWebsiteInput) (*s3.GetBucketWebsiteOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.GetBucketWebsiteOutput + if rf, ok := ret.Get(0).(func(*s3.GetBucketWebsiteInput) *s3.GetBucketWebsiteOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetBucketWebsiteOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.GetBucketWebsiteInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBucketWebsiteRequest provides a mock function with given fields: _a0 +func (_m *S3API) GetBucketWebsiteRequest(_a0 *s3.GetBucketWebsiteInput) (*request.Request, *s3.GetBucketWebsiteOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.GetBucketWebsiteInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.GetBucketWebsiteOutput + if rf, ok := ret.Get(1).(func(*s3.GetBucketWebsiteInput) *s3.GetBucketWebsiteOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.GetBucketWebsiteOutput) + } + } + + return r0, r1 +} + +// GetBucketWebsiteWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) GetBucketWebsiteWithContext(_a0 aws.Context, _a1 *s3.GetBucketWebsiteInput, _a2 ...request.Option) (*s3.GetBucketWebsiteOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.GetBucketWebsiteOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.GetBucketWebsiteInput, ...request.Option) *s3.GetBucketWebsiteOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetBucketWebsiteOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.GetBucketWebsiteInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetObject provides a mock function with given fields: _a0 +func (_m *S3API) GetObject(_a0 *s3.GetObjectInput) (*s3.GetObjectOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.GetObjectOutput + if rf, ok := ret.Get(0).(func(*s3.GetObjectInput) *s3.GetObjectOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetObjectOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.GetObjectInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetObjectAcl provides a mock function with given fields: _a0 +func (_m *S3API) GetObjectAcl(_a0 *s3.GetObjectAclInput) (*s3.GetObjectAclOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.GetObjectAclOutput + if rf, ok := ret.Get(0).(func(*s3.GetObjectAclInput) *s3.GetObjectAclOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetObjectAclOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.GetObjectAclInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetObjectAclRequest provides a mock function with given fields: _a0 +func (_m *S3API) GetObjectAclRequest(_a0 *s3.GetObjectAclInput) (*request.Request, *s3.GetObjectAclOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.GetObjectAclInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.GetObjectAclOutput + if rf, ok := ret.Get(1).(func(*s3.GetObjectAclInput) *s3.GetObjectAclOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.GetObjectAclOutput) + } + } + + return r0, r1 +} + +// GetObjectAclWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) GetObjectAclWithContext(_a0 aws.Context, _a1 *s3.GetObjectAclInput, _a2 ...request.Option) (*s3.GetObjectAclOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.GetObjectAclOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.GetObjectAclInput, ...request.Option) *s3.GetObjectAclOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetObjectAclOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.GetObjectAclInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetObjectRequest provides a mock function with given fields: _a0 +func (_m *S3API) GetObjectRequest(_a0 *s3.GetObjectInput) (*request.Request, *s3.GetObjectOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.GetObjectInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.GetObjectOutput + if rf, ok := ret.Get(1).(func(*s3.GetObjectInput) *s3.GetObjectOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.GetObjectOutput) + } + } + + return r0, r1 +} + +// GetObjectTagging provides a mock function with given fields: _a0 +func (_m *S3API) GetObjectTagging(_a0 *s3.GetObjectTaggingInput) (*s3.GetObjectTaggingOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.GetObjectTaggingOutput + if rf, ok := ret.Get(0).(func(*s3.GetObjectTaggingInput) *s3.GetObjectTaggingOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetObjectTaggingOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.GetObjectTaggingInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetObjectTaggingRequest provides a mock function with given fields: _a0 +func (_m *S3API) GetObjectTaggingRequest(_a0 *s3.GetObjectTaggingInput) (*request.Request, *s3.GetObjectTaggingOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.GetObjectTaggingInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.GetObjectTaggingOutput + if rf, ok := ret.Get(1).(func(*s3.GetObjectTaggingInput) *s3.GetObjectTaggingOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.GetObjectTaggingOutput) + } + } + + return r0, r1 +} + +// GetObjectTaggingWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) GetObjectTaggingWithContext(_a0 aws.Context, _a1 *s3.GetObjectTaggingInput, _a2 ...request.Option) (*s3.GetObjectTaggingOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.GetObjectTaggingOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.GetObjectTaggingInput, ...request.Option) *s3.GetObjectTaggingOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetObjectTaggingOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.GetObjectTaggingInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetObjectTorrent provides a mock function with given fields: _a0 +func (_m *S3API) GetObjectTorrent(_a0 *s3.GetObjectTorrentInput) (*s3.GetObjectTorrentOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.GetObjectTorrentOutput + if rf, ok := ret.Get(0).(func(*s3.GetObjectTorrentInput) *s3.GetObjectTorrentOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetObjectTorrentOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.GetObjectTorrentInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetObjectTorrentRequest provides a mock function with given fields: _a0 +func (_m *S3API) GetObjectTorrentRequest(_a0 *s3.GetObjectTorrentInput) (*request.Request, *s3.GetObjectTorrentOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.GetObjectTorrentInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.GetObjectTorrentOutput + if rf, ok := ret.Get(1).(func(*s3.GetObjectTorrentInput) *s3.GetObjectTorrentOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.GetObjectTorrentOutput) + } + } + + return r0, r1 +} + +// GetObjectTorrentWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) GetObjectTorrentWithContext(_a0 aws.Context, _a1 *s3.GetObjectTorrentInput, _a2 ...request.Option) (*s3.GetObjectTorrentOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.GetObjectTorrentOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.GetObjectTorrentInput, ...request.Option) *s3.GetObjectTorrentOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetObjectTorrentOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.GetObjectTorrentInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetObjectWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) GetObjectWithContext(_a0 aws.Context, _a1 *s3.GetObjectInput, _a2 ...request.Option) (*s3.GetObjectOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.GetObjectOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.GetObjectInput, ...request.Option) *s3.GetObjectOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.GetObjectOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.GetObjectInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// HeadBucket provides a mock function with given fields: _a0 +func (_m *S3API) HeadBucket(_a0 *s3.HeadBucketInput) (*s3.HeadBucketOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.HeadBucketOutput + if rf, ok := ret.Get(0).(func(*s3.HeadBucketInput) *s3.HeadBucketOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.HeadBucketOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.HeadBucketInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// HeadBucketRequest provides a mock function with given fields: _a0 +func (_m *S3API) HeadBucketRequest(_a0 *s3.HeadBucketInput) (*request.Request, *s3.HeadBucketOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.HeadBucketInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.HeadBucketOutput + if rf, ok := ret.Get(1).(func(*s3.HeadBucketInput) *s3.HeadBucketOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.HeadBucketOutput) + } + } + + return r0, r1 +} + +// HeadBucketWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) HeadBucketWithContext(_a0 aws.Context, _a1 *s3.HeadBucketInput, _a2 ...request.Option) (*s3.HeadBucketOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.HeadBucketOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.HeadBucketInput, ...request.Option) *s3.HeadBucketOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.HeadBucketOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.HeadBucketInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// HeadObject provides a mock function with given fields: _a0 +func (_m *S3API) HeadObject(_a0 *s3.HeadObjectInput) (*s3.HeadObjectOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.HeadObjectOutput + if rf, ok := ret.Get(0).(func(*s3.HeadObjectInput) *s3.HeadObjectOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.HeadObjectOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.HeadObjectInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// HeadObjectRequest provides a mock function with given fields: _a0 +func (_m *S3API) HeadObjectRequest(_a0 *s3.HeadObjectInput) (*request.Request, *s3.HeadObjectOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.HeadObjectInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.HeadObjectOutput + if rf, ok := ret.Get(1).(func(*s3.HeadObjectInput) *s3.HeadObjectOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.HeadObjectOutput) + } + } + + return r0, r1 +} + +// HeadObjectWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) HeadObjectWithContext(_a0 aws.Context, _a1 *s3.HeadObjectInput, _a2 ...request.Option) (*s3.HeadObjectOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.HeadObjectOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.HeadObjectInput, ...request.Option) *s3.HeadObjectOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.HeadObjectOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.HeadObjectInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListBucketAnalyticsConfigurations provides a mock function with given fields: _a0 +func (_m *S3API) ListBucketAnalyticsConfigurations(_a0 *s3.ListBucketAnalyticsConfigurationsInput) (*s3.ListBucketAnalyticsConfigurationsOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.ListBucketAnalyticsConfigurationsOutput + if rf, ok := ret.Get(0).(func(*s3.ListBucketAnalyticsConfigurationsInput) *s3.ListBucketAnalyticsConfigurationsOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.ListBucketAnalyticsConfigurationsOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.ListBucketAnalyticsConfigurationsInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListBucketAnalyticsConfigurationsRequest provides a mock function with given fields: _a0 +func (_m *S3API) ListBucketAnalyticsConfigurationsRequest(_a0 *s3.ListBucketAnalyticsConfigurationsInput) (*request.Request, *s3.ListBucketAnalyticsConfigurationsOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.ListBucketAnalyticsConfigurationsInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.ListBucketAnalyticsConfigurationsOutput + if rf, ok := ret.Get(1).(func(*s3.ListBucketAnalyticsConfigurationsInput) *s3.ListBucketAnalyticsConfigurationsOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.ListBucketAnalyticsConfigurationsOutput) + } + } + + return r0, r1 +} + +// ListBucketAnalyticsConfigurationsWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) ListBucketAnalyticsConfigurationsWithContext(_a0 aws.Context, _a1 *s3.ListBucketAnalyticsConfigurationsInput, _a2 ...request.Option) (*s3.ListBucketAnalyticsConfigurationsOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.ListBucketAnalyticsConfigurationsOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.ListBucketAnalyticsConfigurationsInput, ...request.Option) *s3.ListBucketAnalyticsConfigurationsOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.ListBucketAnalyticsConfigurationsOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.ListBucketAnalyticsConfigurationsInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListBucketInventoryConfigurations provides a mock function with given fields: _a0 +func (_m *S3API) ListBucketInventoryConfigurations(_a0 *s3.ListBucketInventoryConfigurationsInput) (*s3.ListBucketInventoryConfigurationsOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.ListBucketInventoryConfigurationsOutput + if rf, ok := ret.Get(0).(func(*s3.ListBucketInventoryConfigurationsInput) *s3.ListBucketInventoryConfigurationsOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.ListBucketInventoryConfigurationsOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.ListBucketInventoryConfigurationsInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListBucketInventoryConfigurationsRequest provides a mock function with given fields: _a0 +func (_m *S3API) ListBucketInventoryConfigurationsRequest(_a0 *s3.ListBucketInventoryConfigurationsInput) (*request.Request, *s3.ListBucketInventoryConfigurationsOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.ListBucketInventoryConfigurationsInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.ListBucketInventoryConfigurationsOutput + if rf, ok := ret.Get(1).(func(*s3.ListBucketInventoryConfigurationsInput) *s3.ListBucketInventoryConfigurationsOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.ListBucketInventoryConfigurationsOutput) + } + } + + return r0, r1 +} + +// ListBucketInventoryConfigurationsWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) ListBucketInventoryConfigurationsWithContext(_a0 aws.Context, _a1 *s3.ListBucketInventoryConfigurationsInput, _a2 ...request.Option) (*s3.ListBucketInventoryConfigurationsOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.ListBucketInventoryConfigurationsOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.ListBucketInventoryConfigurationsInput, ...request.Option) *s3.ListBucketInventoryConfigurationsOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.ListBucketInventoryConfigurationsOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.ListBucketInventoryConfigurationsInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListBucketMetricsConfigurations provides a mock function with given fields: _a0 +func (_m *S3API) ListBucketMetricsConfigurations(_a0 *s3.ListBucketMetricsConfigurationsInput) (*s3.ListBucketMetricsConfigurationsOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.ListBucketMetricsConfigurationsOutput + if rf, ok := ret.Get(0).(func(*s3.ListBucketMetricsConfigurationsInput) *s3.ListBucketMetricsConfigurationsOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.ListBucketMetricsConfigurationsOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.ListBucketMetricsConfigurationsInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListBucketMetricsConfigurationsRequest provides a mock function with given fields: _a0 +func (_m *S3API) ListBucketMetricsConfigurationsRequest(_a0 *s3.ListBucketMetricsConfigurationsInput) (*request.Request, *s3.ListBucketMetricsConfigurationsOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.ListBucketMetricsConfigurationsInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.ListBucketMetricsConfigurationsOutput + if rf, ok := ret.Get(1).(func(*s3.ListBucketMetricsConfigurationsInput) *s3.ListBucketMetricsConfigurationsOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.ListBucketMetricsConfigurationsOutput) + } + } + + return r0, r1 +} + +// ListBucketMetricsConfigurationsWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) ListBucketMetricsConfigurationsWithContext(_a0 aws.Context, _a1 *s3.ListBucketMetricsConfigurationsInput, _a2 ...request.Option) (*s3.ListBucketMetricsConfigurationsOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.ListBucketMetricsConfigurationsOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.ListBucketMetricsConfigurationsInput, ...request.Option) *s3.ListBucketMetricsConfigurationsOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.ListBucketMetricsConfigurationsOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.ListBucketMetricsConfigurationsInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListBuckets provides a mock function with given fields: _a0 +func (_m *S3API) ListBuckets(_a0 *s3.ListBucketsInput) (*s3.ListBucketsOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.ListBucketsOutput + if rf, ok := ret.Get(0).(func(*s3.ListBucketsInput) *s3.ListBucketsOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.ListBucketsOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.ListBucketsInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListBucketsRequest provides a mock function with given fields: _a0 +func (_m *S3API) ListBucketsRequest(_a0 *s3.ListBucketsInput) (*request.Request, *s3.ListBucketsOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.ListBucketsInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.ListBucketsOutput + if rf, ok := ret.Get(1).(func(*s3.ListBucketsInput) *s3.ListBucketsOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.ListBucketsOutput) + } + } + + return r0, r1 +} + +// ListBucketsWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) ListBucketsWithContext(_a0 aws.Context, _a1 *s3.ListBucketsInput, _a2 ...request.Option) (*s3.ListBucketsOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.ListBucketsOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.ListBucketsInput, ...request.Option) *s3.ListBucketsOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.ListBucketsOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.ListBucketsInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListMultipartUploads provides a mock function with given fields: _a0 +func (_m *S3API) ListMultipartUploads(_a0 *s3.ListMultipartUploadsInput) (*s3.ListMultipartUploadsOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.ListMultipartUploadsOutput + if rf, ok := ret.Get(0).(func(*s3.ListMultipartUploadsInput) *s3.ListMultipartUploadsOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.ListMultipartUploadsOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.ListMultipartUploadsInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListMultipartUploadsPages provides a mock function with given fields: _a0, _a1 +func (_m *S3API) ListMultipartUploadsPages(_a0 *s3.ListMultipartUploadsInput, _a1 func(*s3.ListMultipartUploadsOutput, bool) bool) error { + ret := _m.Called(_a0, _a1) + + var r0 error + if rf, ok := ret.Get(0).(func(*s3.ListMultipartUploadsInput, func(*s3.ListMultipartUploadsOutput, bool) bool) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ListMultipartUploadsPagesWithContext provides a mock function with given fields: _a0, _a1, _a2, _a3 +func (_m *S3API) ListMultipartUploadsPagesWithContext(_a0 aws.Context, _a1 *s3.ListMultipartUploadsInput, _a2 func(*s3.ListMultipartUploadsOutput, bool) bool, _a3 ...request.Option) error { + ret := _m.Called(_a0, _a1, _a2, _a3) + + var r0 error + if rf, ok := ret.Get(0).(func(aws.Context, *s3.ListMultipartUploadsInput, func(*s3.ListMultipartUploadsOutput, bool) bool, ...request.Option) error); ok { + r0 = rf(_a0, _a1, _a2, _a3...) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ListMultipartUploadsRequest provides a mock function with given fields: _a0 +func (_m *S3API) ListMultipartUploadsRequest(_a0 *s3.ListMultipartUploadsInput) (*request.Request, *s3.ListMultipartUploadsOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.ListMultipartUploadsInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.ListMultipartUploadsOutput + if rf, ok := ret.Get(1).(func(*s3.ListMultipartUploadsInput) *s3.ListMultipartUploadsOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.ListMultipartUploadsOutput) + } + } + + return r0, r1 +} + +// ListMultipartUploadsWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) ListMultipartUploadsWithContext(_a0 aws.Context, _a1 *s3.ListMultipartUploadsInput, _a2 ...request.Option) (*s3.ListMultipartUploadsOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.ListMultipartUploadsOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.ListMultipartUploadsInput, ...request.Option) *s3.ListMultipartUploadsOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.ListMultipartUploadsOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.ListMultipartUploadsInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListObjectVersions provides a mock function with given fields: _a0 +func (_m *S3API) ListObjectVersions(_a0 *s3.ListObjectVersionsInput) (*s3.ListObjectVersionsOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.ListObjectVersionsOutput + if rf, ok := ret.Get(0).(func(*s3.ListObjectVersionsInput) *s3.ListObjectVersionsOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.ListObjectVersionsOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.ListObjectVersionsInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListObjectVersionsPages provides a mock function with given fields: _a0, _a1 +func (_m *S3API) ListObjectVersionsPages(_a0 *s3.ListObjectVersionsInput, _a1 func(*s3.ListObjectVersionsOutput, bool) bool) error { + ret := _m.Called(_a0, _a1) + + var r0 error + if rf, ok := ret.Get(0).(func(*s3.ListObjectVersionsInput, func(*s3.ListObjectVersionsOutput, bool) bool) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ListObjectVersionsPagesWithContext provides a mock function with given fields: _a0, _a1, _a2, _a3 +func (_m *S3API) ListObjectVersionsPagesWithContext(_a0 aws.Context, _a1 *s3.ListObjectVersionsInput, _a2 func(*s3.ListObjectVersionsOutput, bool) bool, _a3 ...request.Option) error { + ret := _m.Called(_a0, _a1, _a2, _a3) + + var r0 error + if rf, ok := ret.Get(0).(func(aws.Context, *s3.ListObjectVersionsInput, func(*s3.ListObjectVersionsOutput, bool) bool, ...request.Option) error); ok { + r0 = rf(_a0, _a1, _a2, _a3...) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ListObjectVersionsRequest provides a mock function with given fields: _a0 +func (_m *S3API) ListObjectVersionsRequest(_a0 *s3.ListObjectVersionsInput) (*request.Request, *s3.ListObjectVersionsOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.ListObjectVersionsInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.ListObjectVersionsOutput + if rf, ok := ret.Get(1).(func(*s3.ListObjectVersionsInput) *s3.ListObjectVersionsOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.ListObjectVersionsOutput) + } + } + + return r0, r1 +} + +// ListObjectVersionsWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) ListObjectVersionsWithContext(_a0 aws.Context, _a1 *s3.ListObjectVersionsInput, _a2 ...request.Option) (*s3.ListObjectVersionsOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.ListObjectVersionsOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.ListObjectVersionsInput, ...request.Option) *s3.ListObjectVersionsOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.ListObjectVersionsOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.ListObjectVersionsInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListObjects provides a mock function with given fields: _a0 +func (_m *S3API) ListObjects(_a0 *s3.ListObjectsInput) (*s3.ListObjectsOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.ListObjectsOutput + if rf, ok := ret.Get(0).(func(*s3.ListObjectsInput) *s3.ListObjectsOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.ListObjectsOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.ListObjectsInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListObjectsPages provides a mock function with given fields: _a0, _a1 +func (_m *S3API) ListObjectsPages(_a0 *s3.ListObjectsInput, _a1 func(*s3.ListObjectsOutput, bool) bool) error { + ret := _m.Called(_a0, _a1) + + var r0 error + if rf, ok := ret.Get(0).(func(*s3.ListObjectsInput, func(*s3.ListObjectsOutput, bool) bool) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ListObjectsPagesWithContext provides a mock function with given fields: _a0, _a1, _a2, _a3 +func (_m *S3API) ListObjectsPagesWithContext(_a0 aws.Context, _a1 *s3.ListObjectsInput, _a2 func(*s3.ListObjectsOutput, bool) bool, _a3 ...request.Option) error { + ret := _m.Called(_a0, _a1, _a2, _a3) + + var r0 error + if rf, ok := ret.Get(0).(func(aws.Context, *s3.ListObjectsInput, func(*s3.ListObjectsOutput, bool) bool, ...request.Option) error); ok { + r0 = rf(_a0, _a1, _a2, _a3...) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ListObjectsRequest provides a mock function with given fields: _a0 +func (_m *S3API) ListObjectsRequest(_a0 *s3.ListObjectsInput) (*request.Request, *s3.ListObjectsOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.ListObjectsInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.ListObjectsOutput + if rf, ok := ret.Get(1).(func(*s3.ListObjectsInput) *s3.ListObjectsOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.ListObjectsOutput) + } + } + + return r0, r1 +} + +// ListObjectsV2 provides a mock function with given fields: _a0 +func (_m *S3API) ListObjectsV2(_a0 *s3.ListObjectsV2Input) (*s3.ListObjectsV2Output, error) { + ret := _m.Called(_a0) + + var r0 *s3.ListObjectsV2Output + if rf, ok := ret.Get(0).(func(*s3.ListObjectsV2Input) *s3.ListObjectsV2Output); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.ListObjectsV2Output) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.ListObjectsV2Input) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListObjectsV2Pages provides a mock function with given fields: _a0, _a1 +func (_m *S3API) ListObjectsV2Pages(_a0 *s3.ListObjectsV2Input, _a1 func(*s3.ListObjectsV2Output, bool) bool) error { + ret := _m.Called(_a0, _a1) + + var r0 error + if rf, ok := ret.Get(0).(func(*s3.ListObjectsV2Input, func(*s3.ListObjectsV2Output, bool) bool) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ListObjectsV2PagesWithContext provides a mock function with given fields: _a0, _a1, _a2, _a3 +func (_m *S3API) ListObjectsV2PagesWithContext(_a0 aws.Context, _a1 *s3.ListObjectsV2Input, _a2 func(*s3.ListObjectsV2Output, bool) bool, _a3 ...request.Option) error { + ret := _m.Called(_a0, _a1, _a2, _a3) + + var r0 error + if rf, ok := ret.Get(0).(func(aws.Context, *s3.ListObjectsV2Input, func(*s3.ListObjectsV2Output, bool) bool, ...request.Option) error); ok { + r0 = rf(_a0, _a1, _a2, _a3...) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ListObjectsV2Request provides a mock function with given fields: _a0 +func (_m *S3API) ListObjectsV2Request(_a0 *s3.ListObjectsV2Input) (*request.Request, *s3.ListObjectsV2Output) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.ListObjectsV2Input) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.ListObjectsV2Output + if rf, ok := ret.Get(1).(func(*s3.ListObjectsV2Input) *s3.ListObjectsV2Output); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.ListObjectsV2Output) + } + } + + return r0, r1 +} + +// ListObjectsV2WithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) ListObjectsV2WithContext(_a0 aws.Context, _a1 *s3.ListObjectsV2Input, _a2 ...request.Option) (*s3.ListObjectsV2Output, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.ListObjectsV2Output + if rf, ok := ret.Get(0).(func(aws.Context, *s3.ListObjectsV2Input, ...request.Option) *s3.ListObjectsV2Output); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.ListObjectsV2Output) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.ListObjectsV2Input, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListObjectsWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) ListObjectsWithContext(_a0 aws.Context, _a1 *s3.ListObjectsInput, _a2 ...request.Option) (*s3.ListObjectsOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.ListObjectsOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.ListObjectsInput, ...request.Option) *s3.ListObjectsOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.ListObjectsOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.ListObjectsInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListParts provides a mock function with given fields: _a0 +func (_m *S3API) ListParts(_a0 *s3.ListPartsInput) (*s3.ListPartsOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.ListPartsOutput + if rf, ok := ret.Get(0).(func(*s3.ListPartsInput) *s3.ListPartsOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.ListPartsOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.ListPartsInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListPartsPages provides a mock function with given fields: _a0, _a1 +func (_m *S3API) ListPartsPages(_a0 *s3.ListPartsInput, _a1 func(*s3.ListPartsOutput, bool) bool) error { + ret := _m.Called(_a0, _a1) + + var r0 error + if rf, ok := ret.Get(0).(func(*s3.ListPartsInput, func(*s3.ListPartsOutput, bool) bool) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ListPartsPagesWithContext provides a mock function with given fields: _a0, _a1, _a2, _a3 +func (_m *S3API) ListPartsPagesWithContext(_a0 aws.Context, _a1 *s3.ListPartsInput, _a2 func(*s3.ListPartsOutput, bool) bool, _a3 ...request.Option) error { + ret := _m.Called(_a0, _a1, _a2, _a3) + + var r0 error + if rf, ok := ret.Get(0).(func(aws.Context, *s3.ListPartsInput, func(*s3.ListPartsOutput, bool) bool, ...request.Option) error); ok { + r0 = rf(_a0, _a1, _a2, _a3...) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ListPartsRequest provides a mock function with given fields: _a0 +func (_m *S3API) ListPartsRequest(_a0 *s3.ListPartsInput) (*request.Request, *s3.ListPartsOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.ListPartsInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.ListPartsOutput + if rf, ok := ret.Get(1).(func(*s3.ListPartsInput) *s3.ListPartsOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.ListPartsOutput) + } + } + + return r0, r1 +} + +// ListPartsWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) ListPartsWithContext(_a0 aws.Context, _a1 *s3.ListPartsInput, _a2 ...request.Option) (*s3.ListPartsOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.ListPartsOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.ListPartsInput, ...request.Option) *s3.ListPartsOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.ListPartsOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.ListPartsInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutBucketAccelerateConfiguration provides a mock function with given fields: _a0 +func (_m *S3API) PutBucketAccelerateConfiguration(_a0 *s3.PutBucketAccelerateConfigurationInput) (*s3.PutBucketAccelerateConfigurationOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.PutBucketAccelerateConfigurationOutput + if rf, ok := ret.Get(0).(func(*s3.PutBucketAccelerateConfigurationInput) *s3.PutBucketAccelerateConfigurationOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutBucketAccelerateConfigurationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.PutBucketAccelerateConfigurationInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutBucketAccelerateConfigurationRequest provides a mock function with given fields: _a0 +func (_m *S3API) PutBucketAccelerateConfigurationRequest(_a0 *s3.PutBucketAccelerateConfigurationInput) (*request.Request, *s3.PutBucketAccelerateConfigurationOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.PutBucketAccelerateConfigurationInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.PutBucketAccelerateConfigurationOutput + if rf, ok := ret.Get(1).(func(*s3.PutBucketAccelerateConfigurationInput) *s3.PutBucketAccelerateConfigurationOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.PutBucketAccelerateConfigurationOutput) + } + } + + return r0, r1 +} + +// PutBucketAccelerateConfigurationWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) PutBucketAccelerateConfigurationWithContext(_a0 aws.Context, _a1 *s3.PutBucketAccelerateConfigurationInput, _a2 ...request.Option) (*s3.PutBucketAccelerateConfigurationOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.PutBucketAccelerateConfigurationOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.PutBucketAccelerateConfigurationInput, ...request.Option) *s3.PutBucketAccelerateConfigurationOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutBucketAccelerateConfigurationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.PutBucketAccelerateConfigurationInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutBucketAcl provides a mock function with given fields: _a0 +func (_m *S3API) PutBucketAcl(_a0 *s3.PutBucketAclInput) (*s3.PutBucketAclOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.PutBucketAclOutput + if rf, ok := ret.Get(0).(func(*s3.PutBucketAclInput) *s3.PutBucketAclOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutBucketAclOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.PutBucketAclInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutBucketAclRequest provides a mock function with given fields: _a0 +func (_m *S3API) PutBucketAclRequest(_a0 *s3.PutBucketAclInput) (*request.Request, *s3.PutBucketAclOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.PutBucketAclInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.PutBucketAclOutput + if rf, ok := ret.Get(1).(func(*s3.PutBucketAclInput) *s3.PutBucketAclOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.PutBucketAclOutput) + } + } + + return r0, r1 +} + +// PutBucketAclWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) PutBucketAclWithContext(_a0 aws.Context, _a1 *s3.PutBucketAclInput, _a2 ...request.Option) (*s3.PutBucketAclOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.PutBucketAclOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.PutBucketAclInput, ...request.Option) *s3.PutBucketAclOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutBucketAclOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.PutBucketAclInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutBucketAnalyticsConfiguration provides a mock function with given fields: _a0 +func (_m *S3API) PutBucketAnalyticsConfiguration(_a0 *s3.PutBucketAnalyticsConfigurationInput) (*s3.PutBucketAnalyticsConfigurationOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.PutBucketAnalyticsConfigurationOutput + if rf, ok := ret.Get(0).(func(*s3.PutBucketAnalyticsConfigurationInput) *s3.PutBucketAnalyticsConfigurationOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutBucketAnalyticsConfigurationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.PutBucketAnalyticsConfigurationInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutBucketAnalyticsConfigurationRequest provides a mock function with given fields: _a0 +func (_m *S3API) PutBucketAnalyticsConfigurationRequest(_a0 *s3.PutBucketAnalyticsConfigurationInput) (*request.Request, *s3.PutBucketAnalyticsConfigurationOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.PutBucketAnalyticsConfigurationInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.PutBucketAnalyticsConfigurationOutput + if rf, ok := ret.Get(1).(func(*s3.PutBucketAnalyticsConfigurationInput) *s3.PutBucketAnalyticsConfigurationOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.PutBucketAnalyticsConfigurationOutput) + } + } + + return r0, r1 +} + +// PutBucketAnalyticsConfigurationWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) PutBucketAnalyticsConfigurationWithContext(_a0 aws.Context, _a1 *s3.PutBucketAnalyticsConfigurationInput, _a2 ...request.Option) (*s3.PutBucketAnalyticsConfigurationOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.PutBucketAnalyticsConfigurationOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.PutBucketAnalyticsConfigurationInput, ...request.Option) *s3.PutBucketAnalyticsConfigurationOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutBucketAnalyticsConfigurationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.PutBucketAnalyticsConfigurationInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutBucketCors provides a mock function with given fields: _a0 +func (_m *S3API) PutBucketCors(_a0 *s3.PutBucketCorsInput) (*s3.PutBucketCorsOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.PutBucketCorsOutput + if rf, ok := ret.Get(0).(func(*s3.PutBucketCorsInput) *s3.PutBucketCorsOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutBucketCorsOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.PutBucketCorsInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutBucketCorsRequest provides a mock function with given fields: _a0 +func (_m *S3API) PutBucketCorsRequest(_a0 *s3.PutBucketCorsInput) (*request.Request, *s3.PutBucketCorsOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.PutBucketCorsInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.PutBucketCorsOutput + if rf, ok := ret.Get(1).(func(*s3.PutBucketCorsInput) *s3.PutBucketCorsOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.PutBucketCorsOutput) + } + } + + return r0, r1 +} + +// PutBucketCorsWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) PutBucketCorsWithContext(_a0 aws.Context, _a1 *s3.PutBucketCorsInput, _a2 ...request.Option) (*s3.PutBucketCorsOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.PutBucketCorsOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.PutBucketCorsInput, ...request.Option) *s3.PutBucketCorsOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutBucketCorsOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.PutBucketCorsInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutBucketInventoryConfiguration provides a mock function with given fields: _a0 +func (_m *S3API) PutBucketInventoryConfiguration(_a0 *s3.PutBucketInventoryConfigurationInput) (*s3.PutBucketInventoryConfigurationOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.PutBucketInventoryConfigurationOutput + if rf, ok := ret.Get(0).(func(*s3.PutBucketInventoryConfigurationInput) *s3.PutBucketInventoryConfigurationOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutBucketInventoryConfigurationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.PutBucketInventoryConfigurationInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutBucketInventoryConfigurationRequest provides a mock function with given fields: _a0 +func (_m *S3API) PutBucketInventoryConfigurationRequest(_a0 *s3.PutBucketInventoryConfigurationInput) (*request.Request, *s3.PutBucketInventoryConfigurationOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.PutBucketInventoryConfigurationInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.PutBucketInventoryConfigurationOutput + if rf, ok := ret.Get(1).(func(*s3.PutBucketInventoryConfigurationInput) *s3.PutBucketInventoryConfigurationOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.PutBucketInventoryConfigurationOutput) + } + } + + return r0, r1 +} + +// PutBucketInventoryConfigurationWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) PutBucketInventoryConfigurationWithContext(_a0 aws.Context, _a1 *s3.PutBucketInventoryConfigurationInput, _a2 ...request.Option) (*s3.PutBucketInventoryConfigurationOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.PutBucketInventoryConfigurationOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.PutBucketInventoryConfigurationInput, ...request.Option) *s3.PutBucketInventoryConfigurationOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutBucketInventoryConfigurationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.PutBucketInventoryConfigurationInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutBucketLifecycle provides a mock function with given fields: _a0 +func (_m *S3API) PutBucketLifecycle(_a0 *s3.PutBucketLifecycleInput) (*s3.PutBucketLifecycleOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.PutBucketLifecycleOutput + if rf, ok := ret.Get(0).(func(*s3.PutBucketLifecycleInput) *s3.PutBucketLifecycleOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutBucketLifecycleOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.PutBucketLifecycleInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutBucketLifecycleConfiguration provides a mock function with given fields: _a0 +func (_m *S3API) PutBucketLifecycleConfiguration(_a0 *s3.PutBucketLifecycleConfigurationInput) (*s3.PutBucketLifecycleConfigurationOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.PutBucketLifecycleConfigurationOutput + if rf, ok := ret.Get(0).(func(*s3.PutBucketLifecycleConfigurationInput) *s3.PutBucketLifecycleConfigurationOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutBucketLifecycleConfigurationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.PutBucketLifecycleConfigurationInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutBucketLifecycleConfigurationRequest provides a mock function with given fields: _a0 +func (_m *S3API) PutBucketLifecycleConfigurationRequest(_a0 *s3.PutBucketLifecycleConfigurationInput) (*request.Request, *s3.PutBucketLifecycleConfigurationOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.PutBucketLifecycleConfigurationInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.PutBucketLifecycleConfigurationOutput + if rf, ok := ret.Get(1).(func(*s3.PutBucketLifecycleConfigurationInput) *s3.PutBucketLifecycleConfigurationOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.PutBucketLifecycleConfigurationOutput) + } + } + + return r0, r1 +} + +// PutBucketLifecycleConfigurationWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) PutBucketLifecycleConfigurationWithContext(_a0 aws.Context, _a1 *s3.PutBucketLifecycleConfigurationInput, _a2 ...request.Option) (*s3.PutBucketLifecycleConfigurationOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.PutBucketLifecycleConfigurationOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.PutBucketLifecycleConfigurationInput, ...request.Option) *s3.PutBucketLifecycleConfigurationOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutBucketLifecycleConfigurationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.PutBucketLifecycleConfigurationInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutBucketLifecycleRequest provides a mock function with given fields: _a0 +func (_m *S3API) PutBucketLifecycleRequest(_a0 *s3.PutBucketLifecycleInput) (*request.Request, *s3.PutBucketLifecycleOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.PutBucketLifecycleInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.PutBucketLifecycleOutput + if rf, ok := ret.Get(1).(func(*s3.PutBucketLifecycleInput) *s3.PutBucketLifecycleOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.PutBucketLifecycleOutput) + } + } + + return r0, r1 +} + +// PutBucketLifecycleWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) PutBucketLifecycleWithContext(_a0 aws.Context, _a1 *s3.PutBucketLifecycleInput, _a2 ...request.Option) (*s3.PutBucketLifecycleOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.PutBucketLifecycleOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.PutBucketLifecycleInput, ...request.Option) *s3.PutBucketLifecycleOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutBucketLifecycleOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.PutBucketLifecycleInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutBucketLogging provides a mock function with given fields: _a0 +func (_m *S3API) PutBucketLogging(_a0 *s3.PutBucketLoggingInput) (*s3.PutBucketLoggingOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.PutBucketLoggingOutput + if rf, ok := ret.Get(0).(func(*s3.PutBucketLoggingInput) *s3.PutBucketLoggingOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutBucketLoggingOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.PutBucketLoggingInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutBucketLoggingRequest provides a mock function with given fields: _a0 +func (_m *S3API) PutBucketLoggingRequest(_a0 *s3.PutBucketLoggingInput) (*request.Request, *s3.PutBucketLoggingOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.PutBucketLoggingInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.PutBucketLoggingOutput + if rf, ok := ret.Get(1).(func(*s3.PutBucketLoggingInput) *s3.PutBucketLoggingOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.PutBucketLoggingOutput) + } + } + + return r0, r1 +} + +// PutBucketLoggingWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) PutBucketLoggingWithContext(_a0 aws.Context, _a1 *s3.PutBucketLoggingInput, _a2 ...request.Option) (*s3.PutBucketLoggingOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.PutBucketLoggingOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.PutBucketLoggingInput, ...request.Option) *s3.PutBucketLoggingOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutBucketLoggingOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.PutBucketLoggingInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutBucketMetricsConfiguration provides a mock function with given fields: _a0 +func (_m *S3API) PutBucketMetricsConfiguration(_a0 *s3.PutBucketMetricsConfigurationInput) (*s3.PutBucketMetricsConfigurationOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.PutBucketMetricsConfigurationOutput + if rf, ok := ret.Get(0).(func(*s3.PutBucketMetricsConfigurationInput) *s3.PutBucketMetricsConfigurationOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutBucketMetricsConfigurationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.PutBucketMetricsConfigurationInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutBucketMetricsConfigurationRequest provides a mock function with given fields: _a0 +func (_m *S3API) PutBucketMetricsConfigurationRequest(_a0 *s3.PutBucketMetricsConfigurationInput) (*request.Request, *s3.PutBucketMetricsConfigurationOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.PutBucketMetricsConfigurationInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.PutBucketMetricsConfigurationOutput + if rf, ok := ret.Get(1).(func(*s3.PutBucketMetricsConfigurationInput) *s3.PutBucketMetricsConfigurationOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.PutBucketMetricsConfigurationOutput) + } + } + + return r0, r1 +} + +// PutBucketMetricsConfigurationWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) PutBucketMetricsConfigurationWithContext(_a0 aws.Context, _a1 *s3.PutBucketMetricsConfigurationInput, _a2 ...request.Option) (*s3.PutBucketMetricsConfigurationOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.PutBucketMetricsConfigurationOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.PutBucketMetricsConfigurationInput, ...request.Option) *s3.PutBucketMetricsConfigurationOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutBucketMetricsConfigurationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.PutBucketMetricsConfigurationInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutBucketNotification provides a mock function with given fields: _a0 +func (_m *S3API) PutBucketNotification(_a0 *s3.PutBucketNotificationInput) (*s3.PutBucketNotificationOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.PutBucketNotificationOutput + if rf, ok := ret.Get(0).(func(*s3.PutBucketNotificationInput) *s3.PutBucketNotificationOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutBucketNotificationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.PutBucketNotificationInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutBucketNotificationConfiguration provides a mock function with given fields: _a0 +func (_m *S3API) PutBucketNotificationConfiguration(_a0 *s3.PutBucketNotificationConfigurationInput) (*s3.PutBucketNotificationConfigurationOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.PutBucketNotificationConfigurationOutput + if rf, ok := ret.Get(0).(func(*s3.PutBucketNotificationConfigurationInput) *s3.PutBucketNotificationConfigurationOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutBucketNotificationConfigurationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.PutBucketNotificationConfigurationInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutBucketNotificationConfigurationRequest provides a mock function with given fields: _a0 +func (_m *S3API) PutBucketNotificationConfigurationRequest(_a0 *s3.PutBucketNotificationConfigurationInput) (*request.Request, *s3.PutBucketNotificationConfigurationOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.PutBucketNotificationConfigurationInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.PutBucketNotificationConfigurationOutput + if rf, ok := ret.Get(1).(func(*s3.PutBucketNotificationConfigurationInput) *s3.PutBucketNotificationConfigurationOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.PutBucketNotificationConfigurationOutput) + } + } + + return r0, r1 +} + +// PutBucketNotificationConfigurationWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) PutBucketNotificationConfigurationWithContext(_a0 aws.Context, _a1 *s3.PutBucketNotificationConfigurationInput, _a2 ...request.Option) (*s3.PutBucketNotificationConfigurationOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.PutBucketNotificationConfigurationOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.PutBucketNotificationConfigurationInput, ...request.Option) *s3.PutBucketNotificationConfigurationOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutBucketNotificationConfigurationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.PutBucketNotificationConfigurationInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutBucketNotificationRequest provides a mock function with given fields: _a0 +func (_m *S3API) PutBucketNotificationRequest(_a0 *s3.PutBucketNotificationInput) (*request.Request, *s3.PutBucketNotificationOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.PutBucketNotificationInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.PutBucketNotificationOutput + if rf, ok := ret.Get(1).(func(*s3.PutBucketNotificationInput) *s3.PutBucketNotificationOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.PutBucketNotificationOutput) + } + } + + return r0, r1 +} + +// PutBucketNotificationWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) PutBucketNotificationWithContext(_a0 aws.Context, _a1 *s3.PutBucketNotificationInput, _a2 ...request.Option) (*s3.PutBucketNotificationOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.PutBucketNotificationOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.PutBucketNotificationInput, ...request.Option) *s3.PutBucketNotificationOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutBucketNotificationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.PutBucketNotificationInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutBucketPolicy provides a mock function with given fields: _a0 +func (_m *S3API) PutBucketPolicy(_a0 *s3.PutBucketPolicyInput) (*s3.PutBucketPolicyOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.PutBucketPolicyOutput + if rf, ok := ret.Get(0).(func(*s3.PutBucketPolicyInput) *s3.PutBucketPolicyOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutBucketPolicyOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.PutBucketPolicyInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutBucketPolicyRequest provides a mock function with given fields: _a0 +func (_m *S3API) PutBucketPolicyRequest(_a0 *s3.PutBucketPolicyInput) (*request.Request, *s3.PutBucketPolicyOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.PutBucketPolicyInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.PutBucketPolicyOutput + if rf, ok := ret.Get(1).(func(*s3.PutBucketPolicyInput) *s3.PutBucketPolicyOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.PutBucketPolicyOutput) + } + } + + return r0, r1 +} + +// PutBucketPolicyWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) PutBucketPolicyWithContext(_a0 aws.Context, _a1 *s3.PutBucketPolicyInput, _a2 ...request.Option) (*s3.PutBucketPolicyOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.PutBucketPolicyOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.PutBucketPolicyInput, ...request.Option) *s3.PutBucketPolicyOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutBucketPolicyOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.PutBucketPolicyInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutBucketReplication provides a mock function with given fields: _a0 +func (_m *S3API) PutBucketReplication(_a0 *s3.PutBucketReplicationInput) (*s3.PutBucketReplicationOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.PutBucketReplicationOutput + if rf, ok := ret.Get(0).(func(*s3.PutBucketReplicationInput) *s3.PutBucketReplicationOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutBucketReplicationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.PutBucketReplicationInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutBucketReplicationRequest provides a mock function with given fields: _a0 +func (_m *S3API) PutBucketReplicationRequest(_a0 *s3.PutBucketReplicationInput) (*request.Request, *s3.PutBucketReplicationOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.PutBucketReplicationInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.PutBucketReplicationOutput + if rf, ok := ret.Get(1).(func(*s3.PutBucketReplicationInput) *s3.PutBucketReplicationOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.PutBucketReplicationOutput) + } + } + + return r0, r1 +} + +// PutBucketReplicationWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) PutBucketReplicationWithContext(_a0 aws.Context, _a1 *s3.PutBucketReplicationInput, _a2 ...request.Option) (*s3.PutBucketReplicationOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.PutBucketReplicationOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.PutBucketReplicationInput, ...request.Option) *s3.PutBucketReplicationOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutBucketReplicationOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.PutBucketReplicationInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutBucketRequestPayment provides a mock function with given fields: _a0 +func (_m *S3API) PutBucketRequestPayment(_a0 *s3.PutBucketRequestPaymentInput) (*s3.PutBucketRequestPaymentOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.PutBucketRequestPaymentOutput + if rf, ok := ret.Get(0).(func(*s3.PutBucketRequestPaymentInput) *s3.PutBucketRequestPaymentOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutBucketRequestPaymentOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.PutBucketRequestPaymentInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutBucketRequestPaymentRequest provides a mock function with given fields: _a0 +func (_m *S3API) PutBucketRequestPaymentRequest(_a0 *s3.PutBucketRequestPaymentInput) (*request.Request, *s3.PutBucketRequestPaymentOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.PutBucketRequestPaymentInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.PutBucketRequestPaymentOutput + if rf, ok := ret.Get(1).(func(*s3.PutBucketRequestPaymentInput) *s3.PutBucketRequestPaymentOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.PutBucketRequestPaymentOutput) + } + } + + return r0, r1 +} + +// PutBucketRequestPaymentWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) PutBucketRequestPaymentWithContext(_a0 aws.Context, _a1 *s3.PutBucketRequestPaymentInput, _a2 ...request.Option) (*s3.PutBucketRequestPaymentOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.PutBucketRequestPaymentOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.PutBucketRequestPaymentInput, ...request.Option) *s3.PutBucketRequestPaymentOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutBucketRequestPaymentOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.PutBucketRequestPaymentInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutBucketTagging provides a mock function with given fields: _a0 +func (_m *S3API) PutBucketTagging(_a0 *s3.PutBucketTaggingInput) (*s3.PutBucketTaggingOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.PutBucketTaggingOutput + if rf, ok := ret.Get(0).(func(*s3.PutBucketTaggingInput) *s3.PutBucketTaggingOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutBucketTaggingOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.PutBucketTaggingInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutBucketTaggingRequest provides a mock function with given fields: _a0 +func (_m *S3API) PutBucketTaggingRequest(_a0 *s3.PutBucketTaggingInput) (*request.Request, *s3.PutBucketTaggingOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.PutBucketTaggingInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.PutBucketTaggingOutput + if rf, ok := ret.Get(1).(func(*s3.PutBucketTaggingInput) *s3.PutBucketTaggingOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.PutBucketTaggingOutput) + } + } + + return r0, r1 +} + +// PutBucketTaggingWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) PutBucketTaggingWithContext(_a0 aws.Context, _a1 *s3.PutBucketTaggingInput, _a2 ...request.Option) (*s3.PutBucketTaggingOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.PutBucketTaggingOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.PutBucketTaggingInput, ...request.Option) *s3.PutBucketTaggingOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutBucketTaggingOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.PutBucketTaggingInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutBucketVersioning provides a mock function with given fields: _a0 +func (_m *S3API) PutBucketVersioning(_a0 *s3.PutBucketVersioningInput) (*s3.PutBucketVersioningOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.PutBucketVersioningOutput + if rf, ok := ret.Get(0).(func(*s3.PutBucketVersioningInput) *s3.PutBucketVersioningOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutBucketVersioningOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.PutBucketVersioningInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutBucketVersioningRequest provides a mock function with given fields: _a0 +func (_m *S3API) PutBucketVersioningRequest(_a0 *s3.PutBucketVersioningInput) (*request.Request, *s3.PutBucketVersioningOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.PutBucketVersioningInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.PutBucketVersioningOutput + if rf, ok := ret.Get(1).(func(*s3.PutBucketVersioningInput) *s3.PutBucketVersioningOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.PutBucketVersioningOutput) + } + } + + return r0, r1 +} + +// PutBucketVersioningWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) PutBucketVersioningWithContext(_a0 aws.Context, _a1 *s3.PutBucketVersioningInput, _a2 ...request.Option) (*s3.PutBucketVersioningOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.PutBucketVersioningOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.PutBucketVersioningInput, ...request.Option) *s3.PutBucketVersioningOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutBucketVersioningOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.PutBucketVersioningInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutBucketWebsite provides a mock function with given fields: _a0 +func (_m *S3API) PutBucketWebsite(_a0 *s3.PutBucketWebsiteInput) (*s3.PutBucketWebsiteOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.PutBucketWebsiteOutput + if rf, ok := ret.Get(0).(func(*s3.PutBucketWebsiteInput) *s3.PutBucketWebsiteOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutBucketWebsiteOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.PutBucketWebsiteInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutBucketWebsiteRequest provides a mock function with given fields: _a0 +func (_m *S3API) PutBucketWebsiteRequest(_a0 *s3.PutBucketWebsiteInput) (*request.Request, *s3.PutBucketWebsiteOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.PutBucketWebsiteInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.PutBucketWebsiteOutput + if rf, ok := ret.Get(1).(func(*s3.PutBucketWebsiteInput) *s3.PutBucketWebsiteOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.PutBucketWebsiteOutput) + } + } + + return r0, r1 +} + +// PutBucketWebsiteWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) PutBucketWebsiteWithContext(_a0 aws.Context, _a1 *s3.PutBucketWebsiteInput, _a2 ...request.Option) (*s3.PutBucketWebsiteOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.PutBucketWebsiteOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.PutBucketWebsiteInput, ...request.Option) *s3.PutBucketWebsiteOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutBucketWebsiteOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.PutBucketWebsiteInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutObject provides a mock function with given fields: _a0 +func (_m *S3API) PutObject(_a0 *s3.PutObjectInput) (*s3.PutObjectOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.PutObjectOutput + if rf, ok := ret.Get(0).(func(*s3.PutObjectInput) *s3.PutObjectOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutObjectOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.PutObjectInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutObjectAcl provides a mock function with given fields: _a0 +func (_m *S3API) PutObjectAcl(_a0 *s3.PutObjectAclInput) (*s3.PutObjectAclOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.PutObjectAclOutput + if rf, ok := ret.Get(0).(func(*s3.PutObjectAclInput) *s3.PutObjectAclOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutObjectAclOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.PutObjectAclInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutObjectAclRequest provides a mock function with given fields: _a0 +func (_m *S3API) PutObjectAclRequest(_a0 *s3.PutObjectAclInput) (*request.Request, *s3.PutObjectAclOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.PutObjectAclInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.PutObjectAclOutput + if rf, ok := ret.Get(1).(func(*s3.PutObjectAclInput) *s3.PutObjectAclOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.PutObjectAclOutput) + } + } + + return r0, r1 +} + +// PutObjectAclWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) PutObjectAclWithContext(_a0 aws.Context, _a1 *s3.PutObjectAclInput, _a2 ...request.Option) (*s3.PutObjectAclOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.PutObjectAclOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.PutObjectAclInput, ...request.Option) *s3.PutObjectAclOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutObjectAclOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.PutObjectAclInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutObjectRequest provides a mock function with given fields: _a0 +func (_m *S3API) PutObjectRequest(_a0 *s3.PutObjectInput) (*request.Request, *s3.PutObjectOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.PutObjectInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.PutObjectOutput + if rf, ok := ret.Get(1).(func(*s3.PutObjectInput) *s3.PutObjectOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.PutObjectOutput) + } + } + + return r0, r1 +} + +// PutObjectTagging provides a mock function with given fields: _a0 +func (_m *S3API) PutObjectTagging(_a0 *s3.PutObjectTaggingInput) (*s3.PutObjectTaggingOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.PutObjectTaggingOutput + if rf, ok := ret.Get(0).(func(*s3.PutObjectTaggingInput) *s3.PutObjectTaggingOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutObjectTaggingOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.PutObjectTaggingInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutObjectTaggingRequest provides a mock function with given fields: _a0 +func (_m *S3API) PutObjectTaggingRequest(_a0 *s3.PutObjectTaggingInput) (*request.Request, *s3.PutObjectTaggingOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.PutObjectTaggingInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.PutObjectTaggingOutput + if rf, ok := ret.Get(1).(func(*s3.PutObjectTaggingInput) *s3.PutObjectTaggingOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.PutObjectTaggingOutput) + } + } + + return r0, r1 +} + +// PutObjectTaggingWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) PutObjectTaggingWithContext(_a0 aws.Context, _a1 *s3.PutObjectTaggingInput, _a2 ...request.Option) (*s3.PutObjectTaggingOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.PutObjectTaggingOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.PutObjectTaggingInput, ...request.Option) *s3.PutObjectTaggingOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutObjectTaggingOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.PutObjectTaggingInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PutObjectWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) PutObjectWithContext(_a0 aws.Context, _a1 *s3.PutObjectInput, _a2 ...request.Option) (*s3.PutObjectOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.PutObjectOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.PutObjectInput, ...request.Option) *s3.PutObjectOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.PutObjectOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.PutObjectInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// RestoreObject provides a mock function with given fields: _a0 +func (_m *S3API) RestoreObject(_a0 *s3.RestoreObjectInput) (*s3.RestoreObjectOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.RestoreObjectOutput + if rf, ok := ret.Get(0).(func(*s3.RestoreObjectInput) *s3.RestoreObjectOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.RestoreObjectOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.RestoreObjectInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// RestoreObjectRequest provides a mock function with given fields: _a0 +func (_m *S3API) RestoreObjectRequest(_a0 *s3.RestoreObjectInput) (*request.Request, *s3.RestoreObjectOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.RestoreObjectInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.RestoreObjectOutput + if rf, ok := ret.Get(1).(func(*s3.RestoreObjectInput) *s3.RestoreObjectOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.RestoreObjectOutput) + } + } + + return r0, r1 +} + +// RestoreObjectWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) RestoreObjectWithContext(_a0 aws.Context, _a1 *s3.RestoreObjectInput, _a2 ...request.Option) (*s3.RestoreObjectOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.RestoreObjectOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.RestoreObjectInput, ...request.Option) *s3.RestoreObjectOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.RestoreObjectOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.RestoreObjectInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UploadPart provides a mock function with given fields: _a0 +func (_m *S3API) UploadPart(_a0 *s3.UploadPartInput) (*s3.UploadPartOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.UploadPartOutput + if rf, ok := ret.Get(0).(func(*s3.UploadPartInput) *s3.UploadPartOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.UploadPartOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.UploadPartInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UploadPartCopy provides a mock function with given fields: _a0 +func (_m *S3API) UploadPartCopy(_a0 *s3.UploadPartCopyInput) (*s3.UploadPartCopyOutput, error) { + ret := _m.Called(_a0) + + var r0 *s3.UploadPartCopyOutput + if rf, ok := ret.Get(0).(func(*s3.UploadPartCopyInput) *s3.UploadPartCopyOutput); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.UploadPartCopyOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*s3.UploadPartCopyInput) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UploadPartCopyRequest provides a mock function with given fields: _a0 +func (_m *S3API) UploadPartCopyRequest(_a0 *s3.UploadPartCopyInput) (*request.Request, *s3.UploadPartCopyOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.UploadPartCopyInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.UploadPartCopyOutput + if rf, ok := ret.Get(1).(func(*s3.UploadPartCopyInput) *s3.UploadPartCopyOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.UploadPartCopyOutput) + } + } + + return r0, r1 +} + +// UploadPartCopyWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) UploadPartCopyWithContext(_a0 aws.Context, _a1 *s3.UploadPartCopyInput, _a2 ...request.Option) (*s3.UploadPartCopyOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.UploadPartCopyOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.UploadPartCopyInput, ...request.Option) *s3.UploadPartCopyOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.UploadPartCopyOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.UploadPartCopyInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UploadPartRequest provides a mock function with given fields: _a0 +func (_m *S3API) UploadPartRequest(_a0 *s3.UploadPartInput) (*request.Request, *s3.UploadPartOutput) { + ret := _m.Called(_a0) + + var r0 *request.Request + if rf, ok := ret.Get(0).(func(*s3.UploadPartInput) *request.Request); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*request.Request) + } + } + + var r1 *s3.UploadPartOutput + if rf, ok := ret.Get(1).(func(*s3.UploadPartInput) *s3.UploadPartOutput); ok { + r1 = rf(_a0) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*s3.UploadPartOutput) + } + } + + return r0, r1 +} + +// UploadPartWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) UploadPartWithContext(_a0 aws.Context, _a1 *s3.UploadPartInput, _a2 ...request.Option) (*s3.UploadPartOutput, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 *s3.UploadPartOutput + if rf, ok := ret.Get(0).(func(aws.Context, *s3.UploadPartInput, ...request.Option) *s3.UploadPartOutput); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*s3.UploadPartOutput) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(aws.Context, *s3.UploadPartInput, ...request.Option) error); ok { + r1 = rf(_a0, _a1, _a2...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// WaitUntilBucketExists provides a mock function with given fields: _a0 +func (_m *S3API) WaitUntilBucketExists(_a0 *s3.HeadBucketInput) error { + ret := _m.Called(_a0) + + var r0 error + if rf, ok := ret.Get(0).(func(*s3.HeadBucketInput) error); ok { + r0 = rf(_a0) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// WaitUntilBucketExistsWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) WaitUntilBucketExistsWithContext(_a0 aws.Context, _a1 *s3.HeadBucketInput, _a2 ...request.WaiterOption) error { + ret := _m.Called(_a0, _a1, _a2) + + var r0 error + if rf, ok := ret.Get(0).(func(aws.Context, *s3.HeadBucketInput, ...request.WaiterOption) error); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// WaitUntilBucketNotExists provides a mock function with given fields: _a0 +func (_m *S3API) WaitUntilBucketNotExists(_a0 *s3.HeadBucketInput) error { + ret := _m.Called(_a0) + + var r0 error + if rf, ok := ret.Get(0).(func(*s3.HeadBucketInput) error); ok { + r0 = rf(_a0) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// WaitUntilBucketNotExistsWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) WaitUntilBucketNotExistsWithContext(_a0 aws.Context, _a1 *s3.HeadBucketInput, _a2 ...request.WaiterOption) error { + ret := _m.Called(_a0, _a1, _a2) + + var r0 error + if rf, ok := ret.Get(0).(func(aws.Context, *s3.HeadBucketInput, ...request.WaiterOption) error); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// WaitUntilObjectExists provides a mock function with given fields: _a0 +func (_m *S3API) WaitUntilObjectExists(_a0 *s3.HeadObjectInput) error { + ret := _m.Called(_a0) + + var r0 error + if rf, ok := ret.Get(0).(func(*s3.HeadObjectInput) error); ok { + r0 = rf(_a0) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// WaitUntilObjectExistsWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) WaitUntilObjectExistsWithContext(_a0 aws.Context, _a1 *s3.HeadObjectInput, _a2 ...request.WaiterOption) error { + ret := _m.Called(_a0, _a1, _a2) + + var r0 error + if rf, ok := ret.Get(0).(func(aws.Context, *s3.HeadObjectInput, ...request.WaiterOption) error); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// WaitUntilObjectNotExists provides a mock function with given fields: _a0 +func (_m *S3API) WaitUntilObjectNotExists(_a0 *s3.HeadObjectInput) error { + ret := _m.Called(_a0) + + var r0 error + if rf, ok := ret.Get(0).(func(*s3.HeadObjectInput) error); ok { + r0 = rf(_a0) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// WaitUntilObjectNotExistsWithContext provides a mock function with given fields: _a0, _a1, _a2 +func (_m *S3API) WaitUntilObjectNotExistsWithContext(_a0 aws.Context, _a1 *s3.HeadObjectInput, _a2 ...request.WaiterOption) error { + ret := _m.Called(_a0, _a1, _a2) + + var r0 error + if rf, ok := ret.Get(0).(func(aws.Context, *s3.HeadObjectInput, ...request.WaiterOption) error); ok { + r0 = rf(_a0, _a1, _a2...) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +var _ s3iface.S3API = (*S3API)(nil) diff --git a/mocks/StringFile.go b/mocks/StringFile.go new file mode 100644 index 00000000..943b18d6 --- /dev/null +++ b/mocks/StringFile.go @@ -0,0 +1,80 @@ +package mocks + +import ( + "bytes" + "io" + "strings" + + "github.com/stretchr/testify/mock" + + "io/ioutil" + "path/filepath" +) + +// Create a new ReadWriteFile instance that can be read from the provided string as it's contents. +func NewStringFile(data, fileName string) *ReadWriteFile { + buffer := &bytes.Buffer{} + file := &ReadWriteFile{ + File: File{}, + Reader: strings.NewReader(data), + Writer: buffer, + Buffer: buffer, + ReaderContent: data, + } + + // Set default expectations for file operations + file.On("Read", mock.Anything).Return(len(data), nil) + file.On("Write", mock.Anything).Return(len(data), nil) + file.On("Close").Return(nil) + file.On("Name").Return(fileName) + + return file +} + +// Create a new ReadWriteFile instance that can read a file from the provided path. +func NewMockFromFilepath(filePath string) *ReadWriteFile { + data, err := ioutil.ReadFile(filePath) + if err != nil { + data = make([]byte, 0) + } + buffer := &bytes.Buffer{} + file := &ReadWriteFile{ + File: File{}, + Reader: strings.NewReader(string(data)), + Writer: buffer, + Buffer: buffer, + ReaderContent: string(data), + } + + // Set default expectations for file operations + file.On("Read", mock.Anything).Return(len(data), nil) + file.On("Write", mock.Anything).Return(len(data), nil) + file.On("Close").Return(nil) + file.On("Name").Return(filepath.Base(filePath)) + + return file +} + +// Custom mock which allows the consumer to assign a custom reader and writer for +// easily mocking file contents. +type ReadWriteFile struct { + File + Reader io.Reader + Writer io.Writer + Buffer *bytes.Buffer + ReaderContent string +} + +func (f *ReadWriteFile) Read(p []byte) (n int, err error) { + // Deal with mocks for potential assertions + f.File.Read(p) + return f.Reader.Read(p) +} + +func (f *ReadWriteFile) Write(p []byte) (n int, err error) { + f.File.Write(p) + return f.Writer.Write(p) +} +func (f *ReadWriteFile) Content() string { + return f.Buffer.String() +} diff --git a/os/file.go b/os/file.go new file mode 100644 index 00000000..943ec2ba --- /dev/null +++ b/os/file.go @@ -0,0 +1,234 @@ +package os + +import ( + "errors" + "fmt" + "io" + "os" + "path" + "path/filepath" + "time" + + "github.com/c2fo/vfs" + "github.com/c2fo/vfs/utils" +) + +//File implements vfs.File interface for S3 fs. +type File struct { + file *os.File + name string + location vfs.Location +} + +// newFile initializer returns a pointer to File. +func newFile(name string) (*File, error) { + fileName := filepath.Base(name) + fullPath, err := filepath.Abs(name) + if err != nil { + return nil, err + } + + fullPath = filepath.Dir(fullPath) + + fullPath = utils.AddTrailingSlash(fullPath) + + location := Location{fileSystem: vfs.FileSystem(new(FileSystem)), name: fullPath} + return &File{name: fileName, location: &location}, nil +} + +// Delete unlinks the file returning any error or nil. +func (f *File) Delete() error { + err := os.Remove(f.Path()) + if err == nil { + f.file = nil + } + return err +} + +// LastModified returns the timestamp of the file's mtime or error, if any. +func (f *File) LastModified() (*time.Time, error) { + stats, err := os.Stat(f.Path()) + if err != nil { + return nil, err + } + + statsTime := stats.ModTime() + return &statsTime, err +} + +// Name returns the full name of the File relative to Location.Name(). +func (f *File) Name() string { + return f.name +} + +// Path returns the the path of the File relative to Location.Name(). +func (f *File) Path() string { + return filepath.Join(f.location.Path(), f.name) +} + +// Size returns the size (in bytes) of the File or any error. +func (f *File) Size() (uint64, error) { + stats, err := os.Stat(f.Path()) + if err != nil { + return 0, err + } + + return uint64(stats.Size()), err +} + +// Close implements the io.Closer interface, closing the underlying *os.File. its an error, if any. +func (f *File) Close() error { + if f.file == nil { + // Do nothing on files that were never referenced + return nil + } + + err := f.file.Close() + if err == nil { + f.file = nil + } + return err +} + +// Read implements the io.Reader interface. It returns the bytes read and an error, if any. +func (f *File) Read(p []byte) (int, error) { + if exists, err := f.Exists(); err != nil { + return 0, err + } else if !exists { + return 0, errors.New(fmt.Sprintf("Failed to read. File does not exist at %s", f)) + } + + file, err := f.openFile() + if err != nil { + return 0, err + } + + return file.Read(p) +} + +//Seek implements the io.Seeker interface. It accepts an offset and "whench" where 0 means relative to the origin of +// the file, 1 means relative to the current offset, and 2 means relative to the end. It returns the new offset and +// an error, if any. +func (f *File) Seek(offset int64, whence int) (int64, error) { + file, err := f.openFile() + if err != nil { + return 0, err + } + + return file.Seek(offset, whence) +} + +// Exists true if the file exists on the filesystem, otherwise false, and an error, if any. +func (f *File) Exists() (bool, error) { + _, err := os.Stat(f.Path()) + if err != nil { + //file does not exist + if os.IsNotExist(err) { + return false, nil + } + //some other error + return false, err + } + //file exists + return true, nil +} + +//Write implements the io.Writer interface. It accepts a slice of bytes and returns the number of btyes written and an error, if any. +func (f *File) Write(p []byte) (n int, err error) { + file, err := f.openFile() + if err != nil { + return 0, err + } + return file.Write(p) +} + +// Location returns the underlying os.Location. +func (f *File) Location() vfs.Location { + return f.location +} + +// MoveToFile move a file. It accepts a target vfs.File and returns an error, if any. +//TODO we might consider using os.Rename() for efficiency when target.Location().FileSystem().Scheme equals f.Location().FileSystem().Scheme() +func (f *File) MoveToFile(target vfs.File) error { + _, err := f.copyWithName(target.Name(), target.Location()) + if err != nil { + return err + } + + err = f.Delete() + return err +} + +// MoveToLocation moves a file to a new Location. It accepts a target vfs.Location and returns a vfs.File and an error, if any. +//TODO we might consider using os.Rename() for effenciency when location.FileSystem().Scheme() equals f.Location().FileSystem().Scheme() +func (f *File) MoveToLocation(location vfs.Location) (vfs.File, error) { + _, err := f.copyWithName(f.name, location) + if err != nil { + return f, err + } + + delErr := f.Delete() + if delErr != nil { + return f, delErr + } + f.location = location + return f, nil +} + +// CopyToFile copies the file to a new File. It accepts a vfs.File and returns an error, if any. +func (f *File) CopyToFile(target vfs.File) error { + _, err := f.copyWithName(target.Name(), target.Location()) + return err +} + +// CopyToLocation copies existing File to new Location with the same name. It accepts a vfs.Location and returns a vfs.File and error, if any. +func (f *File) CopyToLocation(location vfs.Location) (vfs.File, error) { + return f.copyWithName(f.name, location) +} + +// URI returns the File's URI as a string. +func (f *File) URI() string { + return utils.GetFileURI(f) +} + +// String implement fmt.Stringer, returning the file's URI as the default string. +func (f *File) String() string { + return f.URI() +} + +func (f *File) copyWithName(name string, location vfs.Location) (vfs.File, error) { + newFile, err := location.FileSystem().NewFile(location.Volume(), path.Join(location.Path(), name)) + if err != nil { + return nil, err + } + + if _, err := io.Copy(newFile, f); err != nil { + return nil, err + } + fCloseErr := f.Close() + if fCloseErr != nil { + return nil, fCloseErr + } + + newFileCloseErr := newFile.Close() + if newFileCloseErr != nil { + return nil, newFileCloseErr + } + return newFile, nil +} + +func (f *File) openFile() (*os.File, error) { + if f.file != nil { + return f.file, nil + } + + // Ensure the path exists before opening the file, NoOp if dir already exists. + var fileMode os.FileMode = 0666 + if err := os.MkdirAll(f.location.Path(), os.ModeDir|0777); err != nil { + return nil, err + } + + file, err := os.OpenFile(f.Path(), os.O_RDWR|os.O_CREATE, fileMode) + f.file = file + return file, err +} diff --git a/os/fileSystem.go b/os/fileSystem.go new file mode 100644 index 00000000..eaa1e52f --- /dev/null +++ b/os/fileSystem.go @@ -0,0 +1,38 @@ +package os + +import ( + "github.com/c2fo/vfs" + "github.com/c2fo/vfs/utils" +) + +//Scheme defines the filesystem type. +const ( + Scheme = "file" +) + +// FileSystem implements vfs.Filesystem for the OS filesystem. +type FileSystem struct{} + +// NewFile function returns the os implementation of vfs.File. +func (fs FileSystem) NewFile(volume string, name string) (vfs.File, error) { + file, err := newFile(name) + return vfs.File(file), err +} + +// NewLocation function returns the os implementation of vfs.Location. +func (fs FileSystem) NewLocation(volume string, name string) (vfs.Location, error) { + return &Location{ + fileSystem: vfs.FileSystem(fs), + name: utils.AddTrailingSlash(name), + }, nil +} + +// Name returns "os" +func (fs FileSystem) Name() string { + return "os" +} + +// Scheme return "file" as the initial part of a file URI ie: file:// +func (fs FileSystem) Scheme() string { + return Scheme +} diff --git a/os/file_test.go b/os/file_test.go new file mode 100644 index 00000000..49b778f2 --- /dev/null +++ b/os/file_test.go @@ -0,0 +1,338 @@ +package os + +import ( + "io/ioutil" + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/suite" + + "fmt" + "github.com/c2fo/vfs" + "github.com/c2fo/vfs/mocks" +) + +/********************************** + ************TESTS***************** + **********************************/ + +type osFileTest struct { + suite.Suite + testFile vfs.File + fileSystem FileSystem +} + +func (s *osFileTest) SetupTest() { + fs := FileSystem{} + file, err := fs.NewFile("", "test_files/test.txt") + + if err != nil { + s.Fail("No file was opened") + } + + s.testFile = file + s.fileSystem = fs +} + +func (s *osFileTest) TeardownTest() { + err := s.testFile.Close() + assert.NoError(s.T(), err, "close error not expected") +} + +func (s *osFileTest) TestExists() { + doesExist, err := s.testFile.Exists() + if err != nil { + s.Fail("Failed to check for file existance") + } + s.True(doesExist) + + otherFile, err := s.fileSystem.NewFile("", "test_files/foo.txt") + + if err != nil { + s.Fail("Failed to check for file existance") + } + + otherFileExists, _ := otherFile.Exists() + s.False(otherFileExists) +} + +func (s *osFileTest) TestOpenFile() { + expectedText := "hello world" + data := make([]byte, len(expectedText)) + _, err := s.testFile.Read(data) + assert.NoError(s.T(), err, "read error not expected") + + s.Equal(expectedText, string(data)) +} + +func (s *osFileTest) TestSeek() { + expectedText := "world" + data := make([]byte, len(expectedText)) + _, serr := s.testFile.Seek(6, 0) + assert.NoError(s.T(), serr, "seek error not expected") + _, rerr := s.testFile.Read(data) + assert.NoError(s.T(), rerr, "read error not expected") + s.Equal(expectedText, string(data)) +} + +func (s *osFileTest) TestCopyToLocation() { + expectedText := "hello world" + otherFs := new(mocks.FileSystem) + otherFile := new(mocks.File) + + // Expected behavior + otherFile.On("Write", mock.Anything).Return(len(expectedText), nil) + otherFile.On("Close").Return(nil) + otherFs.On("NewFile", mock.Anything, mock.Anything).Return(otherFile, nil) + + location := Location{"/some/path", otherFs} + + _, err := s.testFile.CopyToLocation(&location) + + if err != nil { + s.Fail(err.Error()) + } + + otherFs.AssertCalled(s.T(), "NewFile", "", "/some/path/test.txt") + otherFile.AssertExpectations(s.T()) + otherFile.AssertCalled(s.T(), "Write", []uint8(expectedText)) +} + +func (s *osFileTest) TestCopyToFile() { + expectedText := "hello world" + otherFs := new(mocks.FileSystem) + otherFile := new(mocks.File) + + location := Location{"/some/path", otherFs} + + // Expected behavior + otherFile.On("Write", mock.Anything).Return(len(expectedText), nil) + otherFile.On("Close").Return(nil) + otherFile.On("Name").Return("other.txt") + otherFile.On("Location").Return(vfs.Location(&location)) + + otherFs.On("NewFile", mock.Anything, mock.Anything).Return(otherFile, nil) + + err := s.testFile.CopyToFile(otherFile) + + if err != nil { + s.Fail(err.Error()) + } + + otherFs.AssertCalled(s.T(), "NewFile", "", "/some/path/other.txt") + otherFile.AssertExpectations(s.T()) + otherFile.AssertCalled(s.T(), "Write", []uint8(expectedText)) +} + +func (s *osFileTest) TestCopyToLocationIgnoreExtraSeparator() { + expectedText := "hello world" + otherFs := new(mocks.FileSystem) + otherFile := new(mocks.File) + + // Expected behavior + otherFile.On("Write", mock.Anything).Return(len(expectedText), nil) + otherFile.On("Close").Return(nil) + otherFs.On("NewFile", mock.Anything, mock.Anything).Return(otherFile, nil) + + // Add trailing slash + location := Location{"/some/path/", otherFs} + + _, err := s.testFile.CopyToLocation(&location) + + if err != nil { + s.Fail(err.Error()) + } + + otherFs.AssertCalled(s.T(), "NewFile", "", "/some/path/test.txt") +} + +func (s *osFileTest) TestMoveToLocation() { + expectedText := "moved file" + dir, terr := ioutil.TempDir("test_files", "example") + if terr != nil { + s.Fail(terr.Error()) + } + + origFileName := "test_files/move.txt" + file, nerr := s.fileSystem.NewFile("", origFileName) + if nerr != nil { + s.Fail(nerr.Error()) + } + + defer func() { + err := os.RemoveAll(dir) + assert.NoError(s.T(), err, "remove all error not expected") + }() + + defer func() { + err := file.Delete() + assert.NoError(s.T(), err, "delete error not expected") + }() + + _, werr := file.Write([]byte(expectedText)) + assert.NoError(s.T(), werr, "write error not expected") + + cerr := file.Close() + assert.NoError(s.T(), cerr, "close error not expected") + + found, eerr := file.Exists() + assert.NoError(s.T(), eerr, "exists error not expected") + s.True(found) + + //setup location + location := Location{dir, s.fileSystem} + + //move the file to new location + movedFile, err := file.MoveToLocation(&location) + if err != nil { + s.Fail(err.Error()) + } + + s.Equal(movedFile.Location().Path(), location.Path()) + + //ensure the original file no longer exists + origFile, _ := s.fileSystem.NewFile(file.Location().Volume(), origFileName) + origFound, eerr := origFile.Exists() + assert.NoError(s.T(), eerr, "exists error not expected") + s.False(origFound) +} + +func (s *osFileTest) TestMoveToFile() { + dir, terr := ioutil.TempDir("test_files", "example") + if terr != nil { + s.Fail(terr.Error()) + } + + file1, _ := s.fileSystem.NewFile("", filepath.Join(dir, "original.txt")) + file2, _ := s.fileSystem.NewFile("", filepath.Join(dir, "move.txt")) + + defer func() { + err := os.RemoveAll(dir) + assert.NoError(s.T(), err, "remove all error not expected") + }() + + text := "original file" + _, werr := file1.Write([]byte(text)) + assert.NoError(s.T(), werr, "write error not expected") + cerr := file1.Close() + assert.NoError(s.T(), cerr, "close error not expected") + + found1, eErr1 := file1.Exists() + s.True(found1) + assert.NoError(s.T(), eErr1, "exists error not expected") + + found2, eErr2 := file2.Exists() + s.False(found2) + assert.NoError(s.T(), eErr2, "exists error not expected") + + merr := file1.MoveToFile(file2) + if merr != nil { + s.Fail(merr.Error()) + } + + f1Exists, _ := file1.Exists() + f2Exists, _ := file2.Exists() + s.False(f1Exists) + s.True(f2Exists) + + data := make([]byte, len(text)) + _, rerr := file2.Read(data) + assert.NoError(s.T(), rerr, "read error not expected") + cErr := file2.Close() + assert.NoError(s.T(), cErr, "close error not expected") + + s.Equal(text, string(data)) +} + +func (s *osFileTest) TestWrite() { + expectedText := "new file" + data := make([]byte, len(expectedText)) + file, _ := s.fileSystem.NewFile("", "test_files/new.txt") + + _, werr := file.Write([]byte(expectedText)) + assert.NoError(s.T(), werr, "write error not expected") + + _, serr := file.Seek(0, 0) + assert.NoError(s.T(), serr, "seek error not expected") + _, rerr := file.Read(data) + assert.NoError(s.T(), rerr, "read error not expected") + cerr := file.Close() + assert.NoError(s.T(), cerr, "close error not expected") + + s.Equal(expectedText, string(data)) + + found, eErr := file.Exists() + assert.NoError(s.T(), eErr, "exists error not expected") + s.True(found) + + err := file.Delete() + if err != nil { + s.Fail("File was not deleted properly") + } + + found2, eErr2 := file.Exists() + assert.NoError(s.T(), eErr2, "exists error not expected") + s.False(found2) +} + +func (s *osFileTest) TestLastModified() { + file, _ := s.fileSystem.NewFile("", "test_files/test.txt") + + lastModified, err := file.LastModified() + if err != nil { + s.Fail(err.Error()) + } + osStats, err := os.Stat("test_files/test.txt") + + if err != nil { + s.Fail(err.Error()) + } + s.NotNil(lastModified) + s.Equal(osStats.ModTime(), *lastModified) +} + +func (s *osFileTest) TestName() { + file, _ := s.fileSystem.NewFile("", "test_files/test.txt") + s.Equal("test.txt", file.Name()) +} + +func (s *osFileTest) TestSize() { + file, _ := s.fileSystem.NewFile("", "test_files/test.txt") + + size, err := file.Size() + if err != nil { + s.Fail(err.Error()) + } + + osStats, err := os.Stat("test_files/test.txt") + + if err != nil { + s.Fail(err.Error()) + } + s.NotNil(size) + s.Equal(osStats.Size(), int64(size)) +} + +func (s *osFileTest) TestPath() { + file, _ := s.fileSystem.NewFile("", "test_files/test.txt") + s.Equal(filepath.Join(file.Location().Path(), file.Name()), file.Path()) +} + +func (s *osFileTest) TestURI() { + file, _ := s.fileSystem.NewFile("", "/some/file/test.txt") + expected := "file:///some/file/test.txt" + s.Equal(expected, file.URI(), "%s does not match %s", file.URI(), expected) +} + +func (s *osFileTest) TestStringer() { + file, _ := s.fileSystem.NewFile("", "/some/file/test.txt") + s.Equal("file:///some/file/test.txt", fmt.Sprintf("%s", file)) +} + +func TestOSFile(t *testing.T) { + suite.Run(t, new(osFileTest)) + _ = os.Remove("test_files/new.txt") +} diff --git a/os/location.go b/os/location.go new file mode 100644 index 00000000..b3568e1a --- /dev/null +++ b/os/location.go @@ -0,0 +1,147 @@ +package os + +import ( + "io/ioutil" + "os" + "path/filepath" + "regexp" + "strings" + + "github.com/c2fo/vfs" + "github.com/c2fo/vfs/utils" +) + +//Location implements the vfs.Location interface specific to OS fs. +type Location struct { + name string + fileSystem vfs.FileSystem +} + +// NewFile uses the properties of the calling location to generate a vfs.File (backed by an os.File). A string +// argument is expected to be a relative path to the location's current path. +func (l *Location) NewFile(fileName string) (vfs.File, error) { + return l.fileSystem.NewFile(l.Volume(), filepath.Join(l.Path(), fileName)) +} + +// DeleteFile deletes the file of the given name at the location. This is meant to be a short cut for instantiating a +// new file and calling delete on that with all the necessary error handling overhead. +func (l *Location) DeleteFile(fileName string) error { + file, err := l.NewFile(fileName) + if err != nil { + return err + } + + return file.Delete() +} + +type fileTest func(fileName string) bool + +// List returns a slice of all files in the top directory of of the location. +func (l *Location) List() ([]string, error) { + return l.fileList(func(name string) bool { return true }) +} + +// ListByPrefix returns a slice of all files starting with "prefix" in the top directory of of the location. +func (l *Location) ListByPrefix(prefix string) ([]string, error) { + if err := utils.ValidateFilePrefix(prefix); err != nil { + return nil, err + } + return l.fileList(func(name string) bool { + return strings.HasPrefix(name, prefix) + }) +} + +// ListByRegex returns a slice of all files matching the regex in the top directory of of the location. +func (l *Location) ListByRegex(regex *regexp.Regexp) ([]string, error) { + return l.fileList(func(name string) bool { + return regex.MatchString(name) + }) +} + +func (l *Location) fileList(testEval fileTest) ([]string, error) { + files := make([]string, 0) + exists, err := l.Exists() + if err != nil { + return files, err + } + + // Function should return an empty slice if the directory doesn't exist. This is to match behavior of remote + // systems. If the user cares about the distinction between directories that are empty, vs non-existent then + // Location.Exists() should be used first. + if exists { + entries, err := ioutil.ReadDir(l.Path()) + if err != nil { + return files, err + } + + for _, info := range entries { + if !info.IsDir() && testEval(info.Name()) { + files = append(files, info.Name()) + } + } + } + + return files, nil +} + +// Volume returns if any of of the location. Given "C:\foo\bar" it returns "C:" on Windows. On other platforms it returns "". +func (l *Location) Volume() string { + return filepath.VolumeName(l.name) +} + +// Path returns the location path. +func (l *Location) Path() string { + return l.name +} + +// Exists returns true if the location exists, and the calling user has the appropriate +// permissions. Will receive false without an error if the location simply doesn't exist. Otherwise could receive +// false and any errors passed back from the OS. +func (l *Location) Exists() (bool, error) { + _, err := os.Stat(l.Path()) + if err != nil { + if os.IsNotExist(err) { + return false, nil + } + return false, err + } + return true, nil +} + +// URI returns the Location's URI as a string. +func (l *Location) URI() string { + return utils.GetLocationURI(l) +} + +// String implement fmt.Stringer, returning the location's URI as the default string. +func (l *Location) String() string { + return l.URI() +} + +// NewLocation makes a copy of the underlying Location, then modifies its path by calling ChangeDir with the +// relativePath argument, returning the resulting location. The only possible errors come from the call to +// ChangeDir. +func (l *Location) NewLocation(relativePath string) (vfs.Location, error) { + fullPath, err := filepath.Abs(filepath.Join(l.name, relativePath)) + if err != nil { + return nil, err + } + + fullPath = utils.AddTrailingSlash(fullPath) + return &Location{ + name: fullPath, + fileSystem: l.fileSystem, + }, nil +} + +// ChangeDir takes a relative path, and modifies the underlying Location's path. The caller is modified by this +// so the only return is any error. For this implementation there are no errors. +func (l *Location) ChangeDir(relativePath string) error { + l.name = filepath.Join(l.name, relativePath) + return nil +} + +// FileSystem returns a vfs.FileSystem interface of the location's underlying fileSystem. +func (l *Location) FileSystem() vfs.FileSystem { + return l.fileSystem +} diff --git a/os/location_test.go b/os/location_test.go new file mode 100644 index 00000000..fc0eaa02 --- /dev/null +++ b/os/location_test.go @@ -0,0 +1,177 @@ +package os + +import ( + "fmt" + "path/filepath" + "regexp" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" + + "github.com/c2fo/vfs" + "github.com/c2fo/vfs/utils" + "io/ioutil" + "os" +) + +/********************************** + ************TESTS***************** + **********************************/ + +type osLocationTest struct { + suite.Suite + testFile vfs.File + fileSystem FileSystem +} + +func (s *osLocationTest) SetupTest() { + fs := FileSystem{} + file, err := fs.NewFile("", "test_files/test.txt") + + if err != nil { + s.Fail("No file was opened") + } + + s.testFile = file + s.fileSystem = fs +} + +func (s *osLocationTest) TestList() { + + expected := []string{"prefix-file.txt", "test.txt"} + actual, _ := s.testFile.Location().List() + s.Equal(expected, actual) +} + +func (s *osLocationTest) TestList_NonExistentDirectory() { + location, err := s.testFile.Location().NewLocation("not/a/directory/") + s.Nil(err, "error isn't expected") + + exists, err := location.Exists() + s.Nil(err, "error isn't expected") + s.False(exists, "location should return false for Exists") + + contents, err := location.List() + s.Nil(err, "error isn't expected") + s.Equal(0, len(contents), "List should return empty slice for non-existent directory") + + prefixContents, err := location.ListByPrefix("anything") + s.Nil(err, "error isn't expected") + s.Equal(0, len(prefixContents), "ListByPrefix should return empty slice for non-existent directory") + + regex, _ := regexp.Compile("[-]+") + regexContents, err := location.ListByRegex(regex) + s.Nil(err, "error isn't expected") + s.Equal(0, len(regexContents), "ListByRegex should return empty slice for non-existent directory") +} + +func (s *osLocationTest) TestListByPrefix() { + expected := []string{"prefix-file.txt"} + actual, _ := s.testFile.Location().ListByPrefix("prefix") + s.Equal(expected, actual) + + _, err := s.testFile.Location().ListByPrefix("bad/prefix") + s.EqualError(err, utils.BadFilePrefix, "got expected error") +} + +func (s *osLocationTest) TestListByRegex() { + expected := []string{"prefix-file.txt"} + regex, _ := regexp.Compile("[-]+") + actual, _ := s.testFile.Location().ListByRegex(regex) + s.Equal(expected, actual) +} + +func (s *osLocationTest) TestExists() { + otherFile, _ := s.fileSystem.NewFile("", "foo/foo.txt") + s.True(s.testFile.Location().Exists()) + s.False(otherFile.Location().Exists()) +} + +func (s *osLocationTest) TestNewLocation() { + otherFile, _ := s.fileSystem.NewFile("", "/foo/foo.txt") + fileLocation := otherFile.Location() + subDir, _ := fileLocation.NewLocation("other/") + s.Equal("/foo/other/", subDir.Path()) + + relDir, _ := subDir.NewLocation("../../bar/") + s.Equal("/bar/", relDir.Path(), "relative dot path works") +} + +func (s *osLocationTest) TestNewFile() { + loc, err := s.fileSystem.NewLocation("", "/foo/bar/baz/") + s.NoError(err) + + newfile, _ := loc.NewFile("../../bam/this.txt") + s.Equal("/foo/bam/this.txt", newfile.Path(), "relative dot path works") +} + +func (s *osLocationTest) TestChangeDir() { + otherFile, _ := s.fileSystem.NewFile("", "foo/foo.txt") + fileLocation := otherFile.Location() + cwd := fileLocation.Path() + err := fileLocation.ChangeDir("other/") + assert.NoError(s.T(), err, "change dir error not expected") + s.Equal(fileLocation.Path(), filepath.Join(cwd, "other/")) +} + +func (s *osLocationTest) TestVolume() { + volume := s.testFile.Location().Volume() + + // For Unix, this returns an empty string. For windows, it would be something like 'C:' + s.Equal(filepath.VolumeName("test_files/test.txt"), volume) +} + +func (s *osLocationTest) TestPath() { + file, _ := s.fileSystem.NewFile("", "/some/file/test.txt") + location := file.Location() + s.Equal("/some/file/", location.Path()) + + rootLocation := Location{fileSystem: s.fileSystem, name: "/"} + s.Equal("/", rootLocation.Path()) +} + +func (s *osLocationTest) TestURI() { + file, _ := s.fileSystem.NewFile("", "/some/file/test.txt") + location := file.Location() + expected := "file:///some/file/" + s.Equal(expected, location.URI(), "%s does not match %s", location.URI(), expected) +} + +func (s *osLocationTest) TestStringer() { + file, _ := s.fileSystem.NewFile("", "/some/file/test.txt") + location := file.Location() + s.Equal("file:///some/file/", fmt.Sprintf("%s", location)) +} + +func (s *osLocationTest) TestDeleteFile() { + dir, err := ioutil.TempDir("test_files", "example") + s.NoError(err, "Setup not expected to fail.") + defer func() { + err := os.RemoveAll(dir) + s.NoError(err, "Cleanup shouldn't fail.") + }() + + expectedText := "file to delete" + fileName := "test.txt" + location := Location{dir, s.fileSystem} + file, err := location.NewFile(fileName) + s.NoError(err, "Creating file to test delete shouldn't fail") + + _, err = file.Write([]byte(expectedText)) + s.NoError(err, "Shouldn't fail to write text to file.") + + exists, err := file.Exists() + s.NoError(err, "Exists shouldn't throw error.") + s.True(exists, "Exists should return true for test file.") + + s.NoError(location.DeleteFile(fileName), "Deleting the file shouldn't throw an error.") + exists, err = file.Exists() + s.NoError(err, "Shouldn't throw error testing for exists after delete.") + s.False(exists, "Exists should return false after deleting the file.") + +} + +func TestOSLocation(t *testing.T) { + suite.Run(t, new(osLocationTest)) +} diff --git a/os/test_files/prefix-file.txt b/os/test_files/prefix-file.txt new file mode 100644 index 00000000..5ba6ab4e --- /dev/null +++ b/os/test_files/prefix-file.txt @@ -0,0 +1 @@ +hello, Dave \ No newline at end of file diff --git a/os/test_files/subdir/test.txt b/os/test_files/subdir/test.txt new file mode 100644 index 00000000..debc1baf --- /dev/null +++ b/os/test_files/subdir/test.txt @@ -0,0 +1 @@ +hello world too \ No newline at end of file diff --git a/os/test_files/test.txt b/os/test_files/test.txt new file mode 100644 index 00000000..95d09f2b --- /dev/null +++ b/os/test_files/test.txt @@ -0,0 +1 @@ +hello world \ No newline at end of file diff --git a/s3/file.go b/s3/file.go new file mode 100644 index 00000000..5cf27122 --- /dev/null +++ b/s3/file.go @@ -0,0 +1,365 @@ +package s3 + +import ( + "bytes" + "errors" + "fmt" + "io" + "io/ioutil" + "os" + "path" + "time" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/service/s3" + "github.com/aws/aws-sdk-go/service/s3/s3manager" + + "github.com/c2fo/vfs" + _errors "github.com/c2fo/vfs/errors" + "github.com/c2fo/vfs/utils" +) + +//File implements vfs.File interface for S3 fs. +type File struct { + fileSystem *FileSystem + bucket string + key string + tempFile *os.File + writeBuffer *bytes.Buffer +} + +// newFile initializer returns a pointer to File. +func newFile(fs *FileSystem, bucket, key string) (*File, error) { + if fs == nil { + return nil, errors.New("non-nil s3.fileSystem pointer is required") + } + if bucket == "" || key == "" { + return nil, errors.New("non-empty strings for bucket and key are required") + } + key = utils.CleanPrefix(key) + return &File{ + fileSystem: fs, + bucket: bucket, + key: key, + }, nil +} + +// Info Functions + +// LastModified returns the LastModified property of a HEAD request to the s3 object. +func (f *File) LastModified() (*time.Time, error) { + head, err := f.getHeadObject() + if err != nil { + return nil, err + } + return head.LastModified, nil +} + +// Name returns the name portion of the file's key property. IE: "file.txt" of "s3://some/path/to/file.txt +func (f *File) Name() string { + return path.Base(f.key) +} + +// Path return the directory portion of the file's key. IE: "path/to" of "s3://some/path/to/file.txt +func (f *File) Path() string { + return "/" + f.key +} + +// Exists returns a boolean of whether or not the object exists on s3, based on a call for +// the object's HEAD through the s3 API. +func (f *File) Exists() (bool, error) { + _, err := f.getHeadObject() + code := "" + if err != nil { + code = err.(awserr.Error).Code() + } + if err != nil && (code == s3.ErrCodeNoSuchKey || code == "NotFound") { + return false, nil + } else if err != nil { + return false, err + } + + return true, nil +} + +// Size returns the ContentLength value from an s3 HEAD request on the file's object. +func (f *File) Size() (uint64, error) { + head, err := f.getHeadObject() + if err != nil { + return 0, err + } + return uint64(*head.ContentLength), nil +} + +// Location returns a vfs.Location at the location of the object. IE: if file is at +// s3://bucket/here/is/the/file.txt the location points to s3://bucket/here/is/the/ +func (f *File) Location() vfs.Location { + return vfs.Location(&Location{ + fileSystem: f.fileSystem, + prefix: path.Dir(f.key), + bucket: f.bucket, + }) +} + +// Move/Copy Operations + +// CopyToFile puts the contents of File into the targetFile passed. Uses the S3 CopyObject +// method if the target file is also on S3, otherwise uses io.Copy. +func (f *File) CopyToFile(targetFile vfs.File) error { + if tf, ok := targetFile.(*File); ok { + return f.copyWithinS3ToFile(tf) + } + + if _, err := io.Copy(targetFile, f); err != nil { + return err + } + //Close target to flush and ensure that cursor isn't at the end of the file when the caller reopens for read + if cerr := targetFile.Close(); cerr != nil { + return cerr + } + //Close file (f) reader + if cerr := f.Close(); cerr != nil { + return cerr + } + return nil +} + +// MoveToFile puts the contents of File into the targetFile passed using File.CopyToFile. +// If the copy succeeds, the source file is deleted. Any errors from the copy or delete are +// returned. +func (f *File) MoveToFile(targetFile vfs.File) error { + if err := f.CopyToFile(targetFile); err != nil { + return err + } + + return f.Delete() +} + +// MoveToLocation works by first calling File.CopyToLocation(vfs.Location) then, if that +// succeeds, it deletes the original file, returning the new file. If the copy process fails +// the error is returned, and the Delete isn't called. If the call to Delete fails, the error +// and the file generated by the copy are both returned. +func (f *File) MoveToLocation(location vfs.Location) (vfs.File, error) { + newFile, err := f.CopyToLocation(location) + if err != nil { + return nil, err + } + delErr := f.Delete() + return newFile, delErr +} + +// CopyToLocation creates a copy of *File, using the file's current name as the new file's +// name at the given location. If the given location is also s3, the AWS API for copying +// files will be utilized, otherwise, standard io.Copy will be done to the new file. +func (f *File) CopyToLocation(location vfs.Location) (vfs.File, error) { + // This is a copy to s3, from s3, we should attempt to utilize the AWS S3 API for this. + if location.FileSystem().Scheme() == Scheme { + return f.copyWithinS3ToLocation(location) + } + + newFile, err := location.FileSystem().NewFile(location.Volume(), path.Join(location.Path(), f.Name())) + if err != nil { + return nil, err + } + + if _, err := io.Copy(newFile, f); err != nil { + return nil, err + } + //Close target file to flush and ensure that cursor isn't at the end of the file when the caller reopens for read + if cerr := newFile.Close(); cerr != nil { + return nil, cerr + } + //Close file (f) reader + if cerr := f.Close(); cerr != nil { + return nil, cerr + } + return newFile, nil +} + +// CRUD Operations + +// Delete clears any local temp file, or write buffer from read/writes to the file, then makes +// a DeleteObject call to s3 for the file. Returns any error returned by the API. +func (f *File) Delete() error { + f.writeBuffer = nil + if err := f.Close(); err != nil { + return err + } + + _, err := f.fileSystem.Client.DeleteObject(&s3.DeleteObjectInput{ + Key: &f.key, + Bucket: &f.bucket, + }) + return err +} + +// Close cleans up underlying mechanisms for reading from and writing to the file. Closes and removes the +// local temp file, and triggers a write to s3 of anything in the f.writeBuffer if it has been created. +func (f *File) Close() (rerr error) { + //setup multi error return using named error + errs := _errors.NewMutliErr() + defer func() { rerr = errs.OrNil() }() + + if f.tempFile != nil { + defer errs.DeferFunc(f.tempFile.Close) + + err := os.Remove(f.tempFile.Name()) + if err != nil && !os.IsNotExist(err) { + return errs.Append(err) + } + + f.tempFile = nil + } + + if f.writeBuffer != nil { + uploader := s3manager.NewUploaderWithClient(f.fileSystem.Client) + uploadInput := f.uploadInput() + uploadInput.Body = f.writeBuffer + _, err := uploader.Upload(uploadInput) + if err != nil { + return errs.Append(err) + } + } + + f.writeBuffer = nil + return nil +} + +// Read implements the standard for io.Reader. For this to work with an s3 file, a temporary local copy of +// the file is created, and reads work on that. This file is closed and removed upon calling f.Close() +func (f *File) Read(p []byte) (n int, err error) { + if err := f.checkTempFile(); err != nil { + return 0, err + } + return f.tempFile.Read(p) +} + +// Seek implements the standard for io.Seeker. A temporary local copy of the s3 file is created (the same +// one used for Reads) which Seek() acts on. This file is closed and removed upon calling f.Close() +func (f *File) Seek(offset int64, whence int) (int64, error) { + if err := f.checkTempFile(); err != nil { + return 0, err + } + return f.tempFile.Seek(offset, whence) +} + +// Write implements the standard for io.Writer. A buffer is added to with each subsequent +// write. When f.Close() is called, the contents of the buffer are used to initiate the +// PutObject to s3. The underlying implementation uses s3manager which will determine whether +// it is appropriate to call PutObject, or initiate a multi-part upload. +func (f *File) Write(data []byte) (res int, err error) { + if f.writeBuffer == nil { + //note, initializing with 'data' and returning len(data), nil + //causes issues with some Write usages, notably csv.Writer + //so we simply intialize with no bytes and call the buffer Write after + // + //f.writeBuffer = bytes.NewBuffer(data) + //return len(data), nil + // + //so now we do: + + f.writeBuffer = bytes.NewBuffer([]byte{}) + } + return f.writeBuffer.Write(data) +} + +// URI returns the File's URI as a string. +func (f *File) URI() string { + return utils.GetFileURI(f) +} + +// String implement fmt.Stringer, returning the file's URI as the default string. +func (f *File) String() string { + return f.URI() +} + +/* + Private helper functions +*/ +func (f *File) getHeadObject() (*s3.HeadObjectOutput, error) { + headObjectInput := new(s3.HeadObjectInput).SetKey(f.key).SetBucket(f.bucket) + return f.fileSystem.Client.HeadObject(headObjectInput) +} + +func (f *File) copyWithinS3ToFile(targetFile *File) error { + copyInput := new(s3.CopyObjectInput).SetKey(targetFile.key).SetBucket(targetFile.bucket).SetCopySource(path.Join(f.bucket, f.key)) + _, err := f.fileSystem.Client.CopyObject(copyInput) + + return err +} + +func (f *File) copyWithinS3ToLocation(location vfs.Location) (vfs.File, error) { + copyInput := new(s3.CopyObjectInput).SetKey(path.Join(location.Path(), f.Name())).SetBucket(location.Volume()).SetCopySource(path.Join(f.bucket, f.key)) + _, err := f.fileSystem.Client.CopyObject(copyInput) + if err != nil { + return nil, err + } + + return location.FileSystem().NewFile(location.Volume(), path.Join(location.Path(), f.Name())) +} + +func (f *File) checkTempFile() error { + if f.tempFile == nil { + localTempFile, err := f.copyToLocalTempReader() + if err != nil { + return err + } + f.tempFile = localTempFile + } + + return nil +} + +func (f *File) copyToLocalTempReader() (*os.File, error) { + tmpFile, err := ioutil.TempFile("", fmt.Sprintf("%s.%d", f.Name(), time.Now().UnixNano())) + if err != nil { + return nil, err + } + + outputReader, err := f.getObject() + if err != nil { + return nil, err + } + + if _, err := io.Copy(tmpFile, outputReader); err != nil { + return nil, err + } + + // Return cursor to the beginning of the new temp file + if _, err := tmpFile.Seek(0, 0); err != nil { + return nil, err + } + + //initialize temp ReadCloser + return tmpFile, nil +} + +func (f *File) putObjectInput() *s3.PutObjectInput { + return new(s3.PutObjectInput).SetBucket(f.bucket).SetKey(f.key) +} + +func (f *File) putObject(reader io.ReadSeeker) error { + _, err := f.fileSystem.Client.PutObject(f.putObjectInput().SetBody(reader)) + + return err +} + +func (f *File) uploadInput() *s3manager.UploadInput { + return &s3manager.UploadInput{ + Bucket: &f.bucket, + Key: &f.key, + } +} + +func (f *File) getObjectInput() *s3.GetObjectInput { + return new(s3.GetObjectInput).SetBucket(f.bucket).SetKey(f.key) +} + +func (f *File) getObject() (io.ReadCloser, error) { + getOutput, err := f.fileSystem.Client.GetObject(f.getObjectInput()) + if err != nil { + return nil, err + } + + return getOutput.Body, nil +} diff --git a/s3/fileSystem.go b/s3/fileSystem.go new file mode 100644 index 00000000..29dad1af --- /dev/null +++ b/s3/fileSystem.go @@ -0,0 +1,51 @@ +package s3 + +import ( + "github.com/aws/aws-sdk-go/service/s3/s3iface" + + "github.com/c2fo/vfs" + "github.com/c2fo/vfs/utils" +) + +//Scheme defines the filesystem type. +const Scheme = "s3" + +// fileSystem implements vfs.Filesystem for the S3 filesystem. +type FileSystem struct { + Client s3iface.S3API +} + +// NewFile function returns the s3 implementation of vfs.File. +func (fs FileSystem) NewFile(volume string, name string) (vfs.File, error) { + file, err := newFile(&fs, volume, name) + if err != nil { + return nil, err + } + return vfs.File(file), nil +} + +// NewLocation function returns the s3 implementation of vfs.Location. +func (fs FileSystem) NewLocation(volume string, name string) (vfs.Location, error) { + name = utils.CleanPrefix(name) + return &Location{ + fileSystem: &fs, + prefix: name, + bucket: volume, + }, nil +} + +// Name returns "AWS S3" +func (fs FileSystem) Name() string { + return "AWS S3" +} + +// Scheme return "s3" as the initial part of a file URI ie: s3:// +func (fs FileSystem) Scheme() string { + return Scheme +} + +// NewFileSystem intializer for fileSystem struct accepts aws-sdk s3iface.S3API client and returns Filesystem or error. +func NewFileSystem(client s3iface.S3API) (*FileSystem, error) { + fs := &FileSystem{client} + return fs, nil +} diff --git a/s3/fileSystem_test.go b/s3/fileSystem_test.go new file mode 100644 index 00000000..b1048d17 --- /dev/null +++ b/s3/fileSystem_test.go @@ -0,0 +1,50 @@ +package s3 + +import ( + "testing" + + "github.com/stretchr/testify/suite" + + "github.com/c2fo/vfs/mocks" +) + +type fileSystemTestSuite struct { + suite.Suite +} + +var ( + s3fs *FileSystem +) + +func (ts *fileSystemTestSuite) SetupTest() { + var err error + s3apiMock = &mocks.S3API{} + s3fs, err = NewFileSystem(s3apiMock) + if err != nil { + ts.Fail("Shouldn't return an error creating NewFileSystem.") + } +} + +func (ts *fileSystemTestSuite) TestNewFileSystem() { + newFS, err := NewFileSystem(s3apiMock) + ts.Nil(err, "s3.NewFileSystem() shouldn't return an error") + ts.NotNil(newFS, "Should return a new fileSystem for s3") +} + +func (ts *fileSystemTestSuite) TestNewFile() { + filePath := "/path/to/file.txt" + file, err := s3fs.NewFile("bucketName", filePath) + ts.Nil(err, "No errors returned by NewFile(%s)", filePath) + ts.NotNil(file, "fs.NewFile(%s) should assign all but first name component to key", filePath) +} + +func (ts *fileSystemTestSuite) TestNewFile_Error() { + filePath := "" + file, err := s3fs.NewFile("", filePath) + ts.Error(err, "NewFile(%s)", filePath) + ts.Nil(file, "NewFile(%s) shouldn't return a file", filePath) +} + +func TestFileSystem(t *testing.T) { + suite.Run(t, new(fileSystemTestSuite)) +} diff --git a/s3/file_test.go b/s3/file_test.go new file mode 100644 index 00000000..de7c3ba5 --- /dev/null +++ b/s3/file_test.go @@ -0,0 +1,400 @@ +package s3 + +import ( + "bytes" + "errors" + "io" + "testing" + "time" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/service/s3" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/suite" + + "fmt" + "github.com/c2fo/vfs" + "github.com/c2fo/vfs/mocks" +) + +type fileTestSuite struct { + suite.Suite +} + +var ( + s3apiMock *mocks.S3API + fs FileSystem + testFile vfs.File +) + +func (ts *fileTestSuite) SetupTest() { + var err error + s3apiMock = &mocks.S3API{} + fs = FileSystem{Client: s3apiMock} + testFile, err = fs.NewFile("bucket", "some/path/to/file.txt") + if err != nil { + ts.Fail("Shouldn't return error creating test s3.File instance.") + } +} + +type nopCloser struct { + io.Reader +} + +func (nopCloser) Close() error { return nil } + +func (ts *fileTestSuite) TestRead() { + contents := "hello world!" + s3apiMock.On("GetObject", mock.AnythingOfType("*s3.GetObjectInput")).Return(&s3.GetObjectOutput{ + Body: nopCloser{bytes.NewBufferString(contents)}, + }, nil) + + file, err := fs.NewFile("bucket", "/some/path/file.txt") + if err != nil { + ts.Fail("Shouldn't fail creating new file") + } + + var localFile *bytes.Buffer = bytes.NewBuffer([]byte{}) + + _, copyErr := io.Copy(localFile, file) + assert.NoError(ts.T(), copyErr, "no error expected") + closeErr := file.Close() + assert.NoError(ts.T(), closeErr, "no error expected") + + s3apiMock.AssertExpectations(ts.T()) + ts.Equal(localFile.String(), contents, "Copying an s3 file to a buffer should fill buffer with file's contents") +} + +// TODO: Write on Close() (actual s3 calls wait until file is closed to be made.) + +func (ts *fileTestSuite) TestWrite() { + file, err := fs.NewFile("bucket", "hello.txt") + if err != nil { + ts.Fail("Shouldn't fail creating new file") + } + + contents := []byte("Hello world!") + count, err := file.Write(contents) + + ts.Equal(len(contents), count, "Returned count of bytes written should match number of bytes passed to Write.") + ts.Nil(err, "Error should be nil when calling Write") +} + +func (ts *fileTestSuite) TestSeek() { + contents := "hello world!" + file, err := fs.NewFile("bucket", "hello.txt") + if err != nil { + ts.Fail("Shouldn't fail creating new file") + } + + s3apiMock.On("GetObject", mock.AnythingOfType("*s3.GetObjectInput")).Return(&s3.GetObjectOutput{ + Body: nopCloser{bytes.NewBufferString(contents)}, + }, nil) + + _, seekErr := file.Seek(6, 0) + assert.NoError(ts.T(), seekErr, "no error expected") + + var localFile *bytes.Buffer = bytes.NewBuffer([]byte{}) + + s3apiMock.AssertExpectations(ts.T()) + + _, copyErr := io.Copy(localFile, file) + assert.NoError(ts.T(), copyErr, "no error expected") + + defer func() { + closeErr := file.Close() + assert.NoError(ts.T(), closeErr, "no error expected") + }() + + ts.Equal("world!", localFile.String(), "Seeking should download the file and move the cursor as expected") + + localFile = bytes.NewBuffer([]byte{}) + _, seekErr2 := file.Seek(0, 0) + assert.NoError(ts.T(), seekErr2, "no error expected") + + _, copyErr2 := io.Copy(localFile, file) + assert.NoError(ts.T(), copyErr2, "no error expected") + ts.Equal(contents, localFile.String(), "Subsequent calls to seek work on temp file as expected") +} + +func (ts *fileTestSuite) TestGetLocation() { + file, err := fs.NewFile("bucket", "path/hello.txt") + if err != nil { + ts.Fail("Shouldn't fail creating new file.") + } + + location := file.Location() + ts.Equal("s3", location.FileSystem().Scheme(), "Should initialize location with FS underlying file.") + ts.Equal("/path/", location.Path(), "Should initialize path with the location of the file.") + ts.Equal("bucket", location.Volume(), "Should initialize bucket with the bucket containing the file.") +} + +func (ts *fileTestSuite) TestExists() { + file, err := fs.NewFile("bucket", "/path/hello.txt") + if err != nil { + ts.Fail("Shouldn't fail creating new file.") + } + + s3apiMock.On("HeadObject", mock.AnythingOfType("*s3.HeadObjectInput")).Return(&s3.HeadObjectOutput{}, nil) + + exists, err := file.Exists() + ts.True(exists, "Should return true for exists based on this setup") + ts.Nil(err, "Shouldn't return an error when exists is true") +} + +func (ts *fileTestSuite) TestNotExists() { + file, err := fs.NewFile("bucket", "/path/hello.txt") + if err != nil { + ts.Fail("Shouldn't fail creating new file.") + } + + s3apiMock.On("HeadObject", mock.AnythingOfType("*s3.HeadObjectInput")).Return(&s3.HeadObjectOutput{}, awserr.New(s3.ErrCodeNoSuchKey, "key doesn't exist", nil)) + + exists, err := file.Exists() + ts.False(exists, "Should return false for exists based on setup") + ts.Nil(err, "Error from key not existing should be hidden since it just confirms it doesn't") +} + +func (ts *fileTestSuite) TestCopyToFile() { + targetFile := &File{ + fileSystem: &FileSystem{ + Client: s3apiMock, + }, + bucket: "TestBucket", + key: "testKey.txt", + } + + s3apiMock.On("CopyObject", mock.AnythingOfType("*s3.CopyObjectInput")).Return(&s3.CopyObjectOutput{}, nil) + + err := testFile.CopyToFile(targetFile) + ts.Nil(err, "Error shouldn't be returned from successful call to CopyToFile") + s3apiMock.AssertExpectations(ts.T()) +} + +func (ts *fileTestSuite) TestMoveToFile() { + targetFile := &File{ + fileSystem: &FileSystem{ + Client: s3apiMock, + }, + bucket: "TestBucket", + key: "testKey.txt", + } + + s3apiMock.On("CopyObject", mock.AnythingOfType("*s3.CopyObjectInput")).Return(&s3.CopyObjectOutput{}, nil) + s3apiMock.On("DeleteObject", mock.AnythingOfType("*s3.DeleteObjectInput")).Return(&s3.DeleteObjectOutput{}, nil) + + err := testFile.MoveToFile(targetFile) + ts.Nil(err, "Error shouldn't be returned from successful call to CopyToFile") + s3apiMock.AssertExpectations(ts.T()) +} + +func (ts *fileTestSuite) TestMoveToFile_CopyError() { + targetFile := &File{ + fileSystem: &FileSystem{ + Client: s3apiMock, + }, + bucket: "TestBucket", + key: "testKey.txt", + } + + s3apiMock.On("CopyObject", mock.AnythingOfType("*s3.CopyObjectInput")).Return(nil, errors.New("some copy error")) + + err := testFile.MoveToFile(targetFile) + ts.NotNil(err, "Error shouldn't be returned from successful call to CopyToFile") + s3apiMock.AssertNotCalled(ts.T(), "DeleteObject", mock.Anything) + s3apiMock.AssertExpectations(ts.T()) +} + +func (ts *fileTestSuite) TestCopyToLocation() { + expectedText := "hello world!" + otherFs := new(mocks.FileSystem) + otherFs.On("Scheme", mock.Anything).Return("") + otherFile := new(mocks.File) + location := new(mocks.Location) + location.On("FileSystem", mock.Anything).Return(otherFs) + location.On("Volume").Return("bucket") + + s3apiMock.On("GetObject", mock.AnythingOfType("*s3.GetObjectInput")).Return(&s3.GetObjectOutput{ + Body: nopCloser{bytes.NewBufferString(expectedText)}, + }, nil) + file, err := fs.NewFile("bucket", "/hello.txt") + if err != nil { + ts.Fail("Shouldn't return error creating test s3.File instance.") + } + + defer func() { + closeErr := file.Close() + assert.NoError(ts.T(), closeErr, "no error expected") + }() + + otherFs.On("Scheme").Return("") + otherFs.On("NewFile", mock.Anything, mock.Anything).Return(otherFile, nil) + otherFile.On("Write", mock.Anything).Return(len(expectedText), nil) + otherFile.On("Close", mock.Anything).Return(nil) + location.On("Path", mock.Anything).Return("/someother/path") + _, err = file.CopyToLocation(location) + if err != nil { + ts.Fail("Shouldn't return error for this call to CopyToLocation") + } + + location.AssertExpectations(ts.T()) + otherFs.AssertExpectations(ts.T()) + otherFs.AssertCalled(ts.T(), "NewFile", "bucket", "/someother/path/hello.txt") + otherFile.AssertExpectations(ts.T()) + otherFile.AssertCalled(ts.T(), "Write", []byte(expectedText)) +} + +func (ts *fileTestSuite) TestCopyToLocationWithinS3() { + otherFs := new(mocks.FileSystem) + otherFs.On("Scheme", mock.Anything).Return(Scheme) + otherFile := new(mocks.File) + location := new(mocks.Location) + location.On("FileSystem", mock.Anything).Return(otherFs) + location.On("Path", mock.Anything).Return("new/file/path").Twice() + location.On("Volume", mock.Anything).Return("newBucket").Twice() + + s3apiMock.On("CopyObject", mock.AnythingOfType("*s3.CopyObjectInput")).Return(&s3.CopyObjectOutput{}, nil) + + file, err := fs.NewFile("bucket", "/hello.txt") + if err != nil { + ts.Fail("Shouldn't return error creating test s3.File instance.") + } + + defer func() { + closeErr := file.Close() + assert.NoError(ts.T(), closeErr, "no error expected") + }() + + otherFs.On("Scheme").Return(Scheme) + otherFs.On("NewFile", "newBucket", "new/file/path/hello.txt").Return(otherFile, nil) + + _, err = file.CopyToLocation(location) + assert.NoError(ts.T(), err, "no error expected") + + s3apiMock.AssertExpectations(ts.T()) + otherFs.AssertExpectations(ts.T()) + location.AssertExpectations(ts.T()) +} + +func (ts *fileTestSuite) TestMoveToLocation() { + // Copy portion tested through CopyToLocation, just need to test whether or not Delete happens + // in addition to CopyToLocation + otherFs := new(mocks.FileSystem) + otherFs.On("Scheme", mock.Anything).Return(Scheme) + otherFile := new(mocks.File) + location := new(mocks.Location) + location.On("FileSystem", mock.Anything).Return(otherFs) + location.On("Path", mock.Anything).Return("new/file/path").Twice() + location.On("Volume", mock.Anything).Return("newBucket").Twice() + + s3apiMock.On("CopyObject", mock.AnythingOfType("*s3.CopyObjectInput")).Return(&s3.CopyObjectOutput{}, nil) + s3apiMock.On("DeleteObject", mock.AnythingOfType("*s3.DeleteObjectInput")).Return(&s3.DeleteObjectOutput{}, nil) + + file, err := fs.NewFile("bucket", "/hello.txt") + if err != nil { + ts.Fail("Shouldn't return error creating test s3.File instance.") + } + + defer func() { + closeErr := file.Close() + assert.NoError(ts.T(), closeErr, "no error expected") + }() + + otherFs.On("Scheme").Return(Scheme) + otherFs.On("NewFile", "newBucket", "new/file/path/hello.txt").Return(otherFile, nil) + + _, err = file.MoveToLocation(location) + assert.NoError(ts.T(), err, "no error expected") + + s3apiMock.AssertExpectations(ts.T()) + otherFs.AssertExpectations(ts.T()) + location.AssertExpectations(ts.T()) +} + +func (ts *fileTestSuite) TestMoveToLocationFail() { + // If CopyToLocation fails we need to ensure DeleteObject isn't called. + otherFs := new(mocks.FileSystem) + otherFs.On("Scheme", mock.Anything).Return(Scheme).Once() + location := new(mocks.Location) + location.On("FileSystem", mock.Anything).Return(otherFs).Once() + location.On("Path", mock.Anything).Return("new/file/path").Once() + location.On("Volume", mock.Anything).Return("newBucket").Once() + + s3apiMock.On("CopyObject", mock.AnythingOfType("*s3.CopyObjectInput")).Return(nil, errors.New("didn't copy, oh noes")) + + file, err := fs.NewFile("bucket", "/hello.txt") + if err != nil { + ts.Fail("Shouldn't return error creating test s3.File instance.") + } + + defer func() { + closeErr := file.Close() + assert.NoError(ts.T(), closeErr, "no close error expected") + }() + + _, merr := file.MoveToLocation(location) + assert.Error(ts.T(), merr, "MoveToLocation error not expected") + + s3apiMock.AssertExpectations(ts.T()) + s3apiMock.AssertNotCalled(ts.T(), "DeleteObject", mock.AnythingOfType("*s3.DeleteObjectInput")) + otherFs.AssertExpectations(ts.T()) + location.AssertExpectations(ts.T()) +} + +func (ts *fileTestSuite) TestDelete() { + s3apiMock.On("DeleteObject", mock.AnythingOfType("*s3.DeleteObjectInput")).Return(&s3.DeleteObjectOutput{}, nil) + + err := testFile.Delete() + ts.Nil(err, "Successful delete should not return an error.") + s3apiMock.AssertExpectations(ts.T()) +} + +func (ts *fileTestSuite) TestLastModified() { + now := time.Now() + s3apiMock.On("HeadObject", mock.AnythingOfType("*s3.HeadObjectInput")).Return(&s3.HeadObjectOutput{ + LastModified: &now, + }, nil) + + modTime, err := testFile.LastModified() + ts.Nil(err, "Error should be nil when correctly returning time of object.") + ts.Equal(&now, modTime, "Returned time matches expected LastModified time.") +} + +func (ts *fileTestSuite) TestName() { + ts.Equal("file.txt", testFile.Name(), "Name should return just the name of the file.") +} + +func (ts *fileTestSuite) TestSize() { + contentLength := int64(100) + s3apiMock.On("HeadObject", mock.AnythingOfType("*s3.HeadObjectInput")).Return(&s3.HeadObjectOutput{ + ContentLength: &contentLength, + }, nil) + + size, err := testFile.Size() + ts.Nil(err, "Error should be nil when requesting size for file that exists.") + ts.Equal(uint64(100), size, "Size should return the ContentLength value from s3 HEAD request.") + s3apiMock.AssertExpectations(ts.T()) +} + +func (ts *fileTestSuite) TestPath() { + ts.Equal("/some/path/to/file.txt", testFile.Path(), "Should return file.key (with leading slash)") +} + +func (ts *fileTestSuite) TestURI() { + s3apiMock = &mocks.S3API{} + fs = FileSystem{Client: s3apiMock} + file, _ := fs.NewFile("mybucket", "/some/file/test.txt") + expected := "s3://mybucket/some/file/test.txt" + ts.Equal(expected, file.URI(), "%s does not match %s", file.URI(), expected) +} + +func (ts *fileTestSuite) TestStringer() { + fs = FileSystem{Client: &mocks.S3API{}} + file, _ := fs.NewFile("mybucket", "/some/file/test.txt") + ts.Equal("s3://mybucket/some/file/test.txt", fmt.Sprintf("%s", file)) +} + +func TestFile(t *testing.T) { + suite.Run(t, new(fileTestSuite)) +} diff --git a/s3/location.go b/s3/location.go new file mode 100644 index 00000000..a4d5b2c3 --- /dev/null +++ b/s3/location.go @@ -0,0 +1,180 @@ +package s3 + +import ( + "path" + "regexp" + "strings" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/service/s3" + + "github.com/c2fo/vfs" + "github.com/c2fo/vfs/utils" +) + +//Location implements the vfs.Location interface specific to S3 fs. +type Location struct { + fileSystem *FileSystem + prefix string + bucket string +} + +// List calls the s3 API to list all objects in the location's bucket, with a prefix automatically +// set to the location's path. This will make a call to the s3 API for every 1000 keys to return. +// If you have many thousands of keys at the given location, this could become quite expensive. +func (l *Location) List() ([]string, error) { + listObjectsInput := l.getListObjectsInput().SetPrefix(utils.EnsureTrailingSlash(l.prefix)) + return l.fullLocationList(listObjectsInput) +} + +// ListByPrefix calls the s3 API with the location's prefix modified relatively by the prefix arg passed to the +// function. The resource considerations of List() apply to this function as well. +func (l *Location) ListByPrefix(prefix string) ([]string, error) { + if err := utils.ValidateFilePrefix(prefix); err != nil { + return nil, err + } + searchPrefix := path.Join(l.prefix, prefix) + listObjectsInput := l.getListObjectsInput().SetPrefix(searchPrefix) + return l.fullLocationList(listObjectsInput) +} + +// ListByRegex retrieves the keys of all the files at the location's current path, then filters out all those +// that don't match the given regex. The resource considerations of List() apply here as well. +func (l *Location) ListByRegex(regex *regexp.Regexp) ([]string, error) { + keys, err := l.List() + if err != nil { + return []string{}, err + } + + filteredKeys := []string{} + for _, key := range keys { + if regex.MatchString(key) { + filteredKeys = append(filteredKeys, key) + } + } + return filteredKeys, nil +} + +// Volume returns the bucket the location is contained in. +func (l *Location) Volume() string { + return l.bucket +} + +// Path returns the prefix the location references in most s3 calls. +func (l *Location) Path() string { + return "/" + utils.EnsureTrailingSlash(l.prefix) +} + +// Exists returns true if the bucket exists, and the user in the underlying s3.fileSystem.Client has the appropriate +// permissions. Will receive false without an error if the bucket simply doesn't exist. Otherwise could receive +// false and any errors passed back from the API. +func (l *Location) Exists() (bool, error) { + headBucketInput := new(s3.HeadBucketInput).SetBucket(l.bucket) + _, err := l.fileSystem.Client.HeadBucket(headBucketInput) + if err == nil { + return true, nil + } + + if err.(awserr.Error).Code() == s3.ErrCodeNoSuchBucket { + return false, nil + } + + return false, err +} + +// NewLocation makes a copy of the underlying Location, then modifies its path by calling ChangeDir with the +// relativePath argument, returning the resulting location. The only possible errors come from the call to +// ChangeDir, which, for the s3 implementation doesn't ever result in an error. +func (l *Location) NewLocation(relativePath string) (vfs.Location, error) { + newLocation := &Location{} + *newLocation = *l + err := newLocation.ChangeDir(relativePath) + if err != nil { + return nil, err + } + return newLocation, nil +} + +// ChangeDir takes a relative path, and modifies the underlying Location's path. The caller is modified by this +// so the only return is any error. For this implementation there are no errors. +func (l *Location) ChangeDir(relativePath string) error { + newPrefix := path.Join(l.prefix, relativePath) + l.prefix = utils.CleanPrefix(newPrefix) + return nil +} + +// NewFile uses the properties of the calling location to generate a vfs.File (backed by an s3.File). The filePath +// argument is expected to be a relative path to the location's current path. +func (l *Location) NewFile(filePath string) (vfs.File, error) { + newFile := &File{ + fileSystem: l.fileSystem, + bucket: l.bucket, + key: utils.CleanPrefix(path.Join(l.prefix, filePath)), + } + return newFile, nil +} + +// DeleteFile removes the file at fileName path. +func (l *Location) DeleteFile(fileName string) error { + file, err := l.NewFile(fileName) + if err != nil { + return err + } + + return file.Delete() +} + +// FileSystem returns a vfs.fileSystem interface of the location's underlying fileSystem. +func (l *Location) FileSystem() vfs.FileSystem { + return l.fileSystem +} + +// URI returns the Location's URI as a string. +func (l *Location) URI() string { + return utils.GetLocationURI(l) +} + +// String implement fmt.Stringer, returning the location's URI as the default string. +func (l *Location) String() string { + return l.URI() +} + +/* + Private helpers +*/ + +func (l *Location) fullLocationList(input *s3.ListObjectsInput) ([]string, error) { + keys := []string{} + for { + listObjectsOutput, err := l.fileSystem.Client.ListObjects(input) + if err != nil { + return []string{}, err + } + newKeys := getNamesFromObjectSlice(listObjectsOutput.Contents, utils.EnsureTrailingSlash(l.prefix)) + keys = append(keys, newKeys...) + + // if s3 response "IsTruncated" we need to call List again with + // an updated Marker (s3 version of paging) + if *listObjectsOutput.IsTruncated { + input.Marker = listObjectsOutput.Marker + } else { + break + } + } + + return keys, nil +} + +func (l *Location) getListObjectsInput() *s3.ListObjectsInput { + return new(s3.ListObjectsInput).SetBucket(l.bucket).SetDelimiter("/") +} + +func getNamesFromObjectSlice(objects []*s3.Object, locationPrefix string) []string { + keys := []string{} + for _, object := range objects { + if *object.Key != locationPrefix { + keys = append(keys, strings.TrimPrefix(*object.Key, locationPrefix)) + } + } + return keys +} diff --git a/s3/location_test.go b/s3/location_test.go new file mode 100644 index 00000000..08d1f579 --- /dev/null +++ b/s3/location_test.go @@ -0,0 +1,273 @@ +package s3 + +import ( + "path" + "regexp" + "testing" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/service/s3" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/suite" + + "github.com/c2fo/vfs/mocks" + "github.com/c2fo/vfs/utils" +) + +type locationTestSuite struct { + suite.Suite + fs *FileSystem + s3apiMock *mocks.S3API +} + +func (lt *locationTestSuite) SetupTest() { + lt.s3apiMock = &mocks.S3API{} + lt.fs = &FileSystem{lt.s3apiMock} +} + +func (lt *locationTestSuite) TestList() { + expectedFileList := []string{"file.txt", "file2.txt"} + keyListFromAPI := []string{"dir1/file.txt", "dir1/file2.txt"} + bucket := "bucket" + locPath := "dir1/" + delimiter := "/" + isTruncated := false + lt.s3apiMock.On("ListObjects", &s3.ListObjectsInput{ + Bucket: &bucket, + Prefix: &locPath, + Delimiter: &delimiter, + }).Return(&s3.ListObjectsOutput{ + Contents: convertKeysToS3Objects(keyListFromAPI), + IsTruncated: &isTruncated, + Prefix: &locPath, + }, nil).Once() + + loc := &Location{lt.fs, locPath, bucket} + fileList, err := loc.List() + lt.Nil(err, "Shouldn't return an error when successfully returning list.") + lt.Len(fileList, len(expectedFileList), "Should return the expected number of files.") + for _, fileKey := range fileList { + lt.Contains(expectedFileList, fileKey, "All returned keys should be in expected file list.") + } + lt.s3apiMock.AssertExpectations(lt.T()) +} + +func (lt *locationTestSuite) TestList_pagedCall() { + firstKeyList := []string{"dir1/file.txt", "dir1/file2.txt"} + firstCallOutputMarker := firstKeyList[len(firstKeyList)-1] + secondKeyList := []string{"dir1/file3.txt", "dir1/file4.txt"} + expectedFileList := []string{"file.txt", "file2.txt", "file3.txt", "file4.txt"} + bucket := "bucket" + locPath := "dir1/" + delimiter := "/" + isTruncatedTrue := true + isTruncatedFalse := false + lt.s3apiMock.On("ListObjects", &s3.ListObjectsInput{ + Bucket: &bucket, + Prefix: &locPath, + Delimiter: &delimiter, + }).Return(&s3.ListObjectsOutput{ + Contents: convertKeysToS3Objects(firstKeyList), + IsTruncated: &isTruncatedTrue, + Marker: &firstCallOutputMarker, + Prefix: &locPath, + }, nil) + + lt.s3apiMock.On("ListObjects", &s3.ListObjectsInput{ + Bucket: &bucket, + Prefix: &locPath, + Delimiter: &delimiter, + Marker: &firstCallOutputMarker, + }).Return(&s3.ListObjectsOutput{ + Contents: convertKeysToS3Objects(secondKeyList), + IsTruncated: &isTruncatedFalse, + Prefix: &locPath, + }, nil) + + loc := &Location{lt.fs, locPath, bucket} + fileList, err := loc.List() + lt.Nil(err, "Shouldn't return an error when successfully returning list.") + lt.Len(fileList, len(expectedFileList), "Should return the expected number of files.") + for _, expectedKey := range expectedFileList { + lt.Contains(fileList, expectedKey, "All returned keys should be in expected file list.") + } + lt.s3apiMock.AssertNumberOfCalls(lt.T(), "ListObjects", 2) +} + +func (lt *locationTestSuite) TestListByPrefix() { + //TODO this should probably be an 'fsdevsonly' test using real calls to s3 + lt.T().Skip("this test only tests that the files exected are returned by the mock object") + expectedFileList := []string{"file1.txt", "file2.txt"} + keyListFromAPI := []string{"dir1/file1.txt", "dir1/file2.txt"} + bucket := "bucket" + locPath := "dir1/" + prefix := "fil" + apiCallPrefix := utils.EnsureTrailingSlash(path.Join(locPath, prefix)) + delimiter := "/" + isTruncated := false + lt.s3apiMock.On("ListObjects", &s3.ListObjectsInput{ + Bucket: &bucket, + Prefix: &apiCallPrefix, + Delimiter: &delimiter, + }).Return(&s3.ListObjectsOutput{ + Contents: convertKeysToS3Objects(keyListFromAPI), + IsTruncated: &isTruncated, + Prefix: &apiCallPrefix, + }, nil).Once() + loc := &Location{lt.fs, locPath, bucket} + fileList, err := loc.ListByPrefix(prefix) + lt.Nil(err, "Shouldn't return an error when successfully returning list.") + lt.Len(fileList, len(expectedFileList), "Should return expected number of file keys.") + for _, fileKey := range fileList { + lt.Contains(expectedFileList, fileKey, "All returned keys should be in the expected list.") + } + lt.s3apiMock.AssertExpectations(lt.T()) +} + +func (lt *locationTestSuite) TestListByRegex() { + expectedFileList := []string{"file1.txt", "file2.txt"} + keysReturnedFromAPI := append(expectedFileList, "file3.png", "file4.jpg") + bucket := "bucket" + locPath := "" + delimiter := "/" + isTruncated := false + lt.s3apiMock.On("ListObjects", &s3.ListObjectsInput{ + Bucket: &bucket, + Prefix: &locPath, + Delimiter: &delimiter, + }).Return(&s3.ListObjectsOutput{ + Contents: convertKeysToS3Objects(keysReturnedFromAPI), + IsTruncated: &isTruncated, + Prefix: &locPath, + }, nil).Once() + loc := &Location{lt.fs, locPath, bucket} + fileTypeRegex, err := regexp.Compile("txt$") + if err != nil { + lt.Fail("Failed to compile regex for test.") + } + fileList, err := loc.ListByRegex(fileTypeRegex) + lt.Nil(err, "Shouldn't return an error on successful call to ListByRegex") + lt.Len(fileList, len(expectedFileList), "Should return expected number of file keys.") + for _, fileKey := range fileList { + lt.Contains(expectedFileList, fileKey, "All returned keys should be in the expected list.") + } + lt.s3apiMock.AssertExpectations(lt.T()) +} + +func (lt *locationTestSuite) TestVolume() { + bucket := "bucket" + loc := &Location{lt.fs, "", bucket} + lt.Equal(bucket, loc.Volume(), "Volume() should return the bucket name on location.") +} + +func (lt *locationTestSuite) TestPath() { + loc, err := lt.fs.NewLocation("bucket", "path/") + lt.NoError(err) + lt.Equal("/path/", loc.Path(), "Path() should return the path on location.") + + loc2, err2 := lt.fs.NewLocation("bucket", "/path/") + lt.NoError(err2) + lt.Equal("/path/", loc2.Path(), "Path() should return the path on location.") + + loc3, err3 := lt.fs.NewLocation("bucket", "path") + lt.NoError(err3) + lt.Equal("/path/", loc3.Path(), "Path() should return the path on location.") +} + +func (lt *locationTestSuite) TestNewFile() { + loc, err := lt.fs.NewLocation("bucket", "some/path/to/") + lt.NoError(err) + lt.Equal("/some/path/to/", loc.Path(), "Path() should return the path on location.") + + newfile, _ := loc.NewFile("a/file.txt") + lt.Equal("/some/path/to/a/file.txt", newfile.Path(), "NewFile relative path works") + + newrelfile, _ := loc.NewFile("../../where/file.txt") + lt.Equal("/some/where/file.txt", newrelfile.Path(), "Newfile relative dot path works") +} + +func (lt *locationTestSuite) TestExists_true() { + bucket := "foo" + lt.s3apiMock.On("HeadBucket", &s3.HeadBucketInput{ + Bucket: &bucket, + }).Return(&s3.HeadBucketOutput{}, nil).Once() + loc := &Location{lt.fs, "", bucket} + exists, err := loc.Exists() + lt.Nil(err, "No error expected from Exists") + lt.True(exists, "Call to Exists expected to return true.") + lt.s3apiMock.AssertExpectations(lt.T()) +} + +func (lt *locationTestSuite) TestExists_false() { + bucket := "foo" + lt.s3apiMock.On("HeadBucket", &s3.HeadBucketInput{ + Bucket: &bucket, + }).Return(nil, awserr.New(s3.ErrCodeNoSuchBucket, "NoSuchBucket", nil)).Once() + loc := &Location{lt.fs, "", bucket} + exists, err := loc.Exists() + lt.Nil(err, "No error expected from Exists") + lt.False(exists, "Call to Exists expected to return true.") + lt.s3apiMock.AssertExpectations(lt.T()) +} + +func (lt *locationTestSuite) TestChangeDir() { + loc := &Location{lt.fs, "", "bucket"} + + err1 := loc.ChangeDir("..") + assert.NoError(lt.T(), err1, "no error expected") + lt.Equal("/", loc.Path()) + + err2 := loc.ChangeDir("/hello") + assert.NoError(lt.T(), err2, "no error expected") + lt.Equal("/hello/", loc.Path()) + + err3 := loc.ChangeDir("../.././..") + assert.NoError(lt.T(), err3, "no error expected") + lt.Equal("/", loc.Path()) + + err4 := loc.ChangeDir("here/is/a/path/") + assert.NoError(lt.T(), err4, "no error expected") + lt.Equal("/here/is/a/path/", loc.Path()) + + err5 := loc.ChangeDir("../") + assert.NoError(lt.T(), err5, "no error expected") + lt.Equal("/here/is/a/", loc.Path()) +} + +func (lt *locationTestSuite) TestNewLocation() { + loc := &Location{lt.fs, "old", "bucket"} + newLoc, err := loc.NewLocation("new/path") + lt.Nil(err, "No error from successful call to NewLocation") + lt.Equal("/old/new/path/", newLoc.Path(), "New location should have correct path set") + lt.Equal("/old/", loc.Path(), "Ensure original path is unchanged.") + + newRelLoc, err := newLoc.NewLocation("../../some/path") + lt.NoError(err) + lt.Equal("/old/some/path/", newRelLoc.Path(), "NewLocation works with rel dot paths") +} + +func (lt *locationTestSuite) TestDeleteFile() { + lt.s3apiMock.On("DeleteObject", mock.AnythingOfType("*s3.DeleteObjectInput")).Return(&s3.DeleteObjectOutput{}, nil) + loc := &Location{lt.fs, "old", "bucket"} + + err := loc.DeleteFile("filename.txt") + lt.Nil(err, "Successful delete should not return an error.") + lt.s3apiMock.AssertExpectations(lt.T()) +} + +func TestLocation(t *testing.T) { + suite.Run(t, new(locationTestSuite)) +} + +/* + Helpers +*/ +func convertKeysToS3Objects(keys []string) []*s3.Object { + var objects []*s3.Object + for _, key := range keys { + object := &s3.Object{} + objects = append(objects, object.SetKey(key)) + } + return objects +} diff --git a/utils/utils.go b/utils/utils.go new file mode 100644 index 00000000..a4322cd3 --- /dev/null +++ b/utils/utils.go @@ -0,0 +1,75 @@ +package utils + +import ( + "fmt" + "path" + "regexp" + "runtime" + + "errors" + "github.com/c2fo/vfs" + "strings" +) + +const ( + Windows = "windows" + BadFilePrefix = "expecting only a filename prefix, which may not include slashes or backslashes" +) + +// regex to ensure prefix doesn't have leading '/', '.', '..', etc... +var prefixCleanRegex = regexp.MustCompile("^[/.]*") + +// regex to test whether the last character is a '/' +var hasTrailingSlash = regexp.MustCompile("/$") + +// AddTrailingSlash is a helper function accepts a path string and returns the path string with a trailing slash if +// there wasn't one. +func AddTrailingSlash(path string) string { + + runePath := []rune(path) + lastRune := runePath[len(runePath)-1] + + slash := "/" + if runtime.GOOS == Windows { + slash = "\\" + } + + //add trailing slash, if none + if string(lastRune) != "/" && string(lastRune) != "\\" { + path = path + slash + } + return path +} + +// GetFile returns a vfs.File URI +func GetFileURI(f vfs.File) string { + return fmt.Sprintf("%s://%s%s", f.Location().FileSystem().Scheme(), f.Location().Volume(), f.Path()) +} + +// GetFile returns a vfs.Location URI +func GetLocationURI(l vfs.Location) string { + return fmt.Sprintf("%s://%s%s", l.FileSystem().Scheme(), l.Volume(), l.Path()) +} + +// EnsureTrailingSlash is like AddTrailingSlash but will only ever use / since it's use for web uri's, never an Windows OS path. +func EnsureTrailingSlash(dir string) string { + if dir == "" || hasTrailingSlash.MatchString(dir) { + return dir + } + return dir + "/" +} + +// CleanPrefix resolves relative dot pathing, removing any leading . or / and removes any trailing / +func CleanPrefix(prefix string) string { + prefix = path.Clean(prefix) + return prefixCleanRegex.ReplaceAllString(prefix, "") +} + +// Performs a validation check on a prefix. The prefix should not include "/" or "\\" characters. An +// error is returned if either of those conditions are true. +func ValidateFilePrefix(filenamePrefix string) error { + if strings.Contains(filenamePrefix, "/") || strings.Contains(filenamePrefix, "\\") { + return errors.New(BadFilePrefix) + } + return nil +} diff --git a/utils/utils_test.go b/utils/utils_test.go new file mode 100644 index 00000000..2992c49b --- /dev/null +++ b/utils/utils_test.go @@ -0,0 +1,93 @@ +package utils + +import ( + "testing" + + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/suite" + + "github.com/c2fo/vfs/mocks" +) + +/********************************** + ************TESTS***************** + **********************************/ + +type utilsTest struct { + suite.Suite +} + +type slashTest struct { + path string + expected string + message string +} + +func (s *utilsTest) TestAddTrailingSlash() { + tests := []slashTest{ + { + path: "/some/path", + expected: "/some/path/", + message: "no slash - adding one", + }, + { + path: "/some/path/", + expected: "/some/path/", + message: "slash founn - don't add one", + }, + { + path: "/some/path\\", + expected: "/some/path\\", + message: "backslash found - don't add one", + }, + { + path: "/some/path/file.txt", + expected: "/some/path/file.txt/", + message: "no slash but looks like a file - add one anyaway", + }, + } + + for _, slashtest := range tests { + s.Equal(slashtest.expected, AddTrailingSlash(slashtest.path), slashtest.message) + } +} + +func (s *utilsTest) TestGetURI() { + + //set up mocks + mockFs1 := new(mocks.FileSystem) + mockFs1.On("Scheme", mock.Anything).Return("file") + + mockLoc1 := new(mocks.Location) + mockLoc1.On("Path").Return("/some/path/to/") + mockLoc1.On("Volume", mock.Anything).Return("") + mockLoc1.On("FileSystem", mock.Anything).Return(mockFs1) + + mockFile1 := new(mocks.File) + mockFile1.On("Path").Return("/some/path/to/file.txt") + mockFile1.On("Location").Return(mockLoc1) + + mockFs2 := new(mocks.FileSystem) + mockFs2.On("Scheme", mock.Anything).Return("s3") + + mockLoc2 := new(mocks.Location) + mockLoc2.On("Path").Return("/this/path/to/") + mockLoc2.On("Volume", mock.Anything).Return("mybucket") + mockLoc2.On("FileSystem", mock.Anything).Return(mockFs2) + + mockFile2 := new(mocks.File) + mockFile2.On("Path").Return("/this/path/to/file.txt") + mockFile2.On("Location").Return(mockLoc2) + + //GetFileURI + s.Equal("file:///some/path/to/file.txt", GetFileURI(mockFile1), "os file uri matches ") + s.Equal("s3://mybucket/this/path/to/file.txt", GetFileURI(mockFile2), "s3 file uri matches ") + + //GetLocationURI + s.Equal("file:///some/path/to/", GetLocationURI(mockLoc1), "os location uri matches ") + s.Equal("s3://mybucket/this/path/to/", GetLocationURI(mockLoc2), "s3 location uri matches ") +} + +func TestUtils(t *testing.T) { + suite.Run(t, new(utilsTest)) +} diff --git a/vfs.go b/vfs.go new file mode 100644 index 00000000..fdda6113 --- /dev/null +++ b/vfs.go @@ -0,0 +1,132 @@ +// Package vfs provides a platform-independent interface to generalized set of filesystem +// functionality across a number of filesystem types such as os, S3, and GCS. +package vfs + +import ( + "fmt" + "io" + "regexp" + "time" +) + +// FileSystem represents a filesystem with any authentication accounted for. +type FileSystem interface { + // NewFile initializes a File on the specified volume at path 'name'. On error, nil is returned + // for the file. + NewFile(volume string, name string) (File, error) + + // NewLocation initializes a Location on the specified volume with the given path. On error, nil is returned + // for the location. + NewLocation(volume string, path string) (Location, error) + + // Name returns the name of the FileSystem ie: s3, disk, gcs, etc... + Name() string + + // Scheme, related to Name, is the uri scheme used by the FileSystem: s3, file, gcs, etc... + Scheme() string +} + +// Location represents a filesystem path which serves as a start point for directory-like functionality. A location may +// or may not actually exist on the filesystem. +type Location interface { + fmt.Stringer + + // List returns a slice of strings representing the base names of the files found at the Location. All implementations + // are expected to return ([]string{}, nil) in the case of a non-existent directory/prefix/location. If the user + // cares about the distinction between an empty location and a non-existent one, Location.Exists() should be checked + // first. + List() ([]string, error) + + // ListByPrefix returns a slice of strings representing the base names of the files found in Location whose + // filenames match the given prefix. An empty slice will be returned even for locations that don't exist. + ListByPrefix(prefix string) ([]string, error) + + // ListByRegex returns a slice of strings representing the base names of the files found in Location that + // matched the given regular expression. An empty slice will be returned even for locations that don't exist. + ListByRegex(regex *regexp.Regexp) ([]string, error) + + // Returns the volume as string. Some filesystems may not have a volume and will return "". In URI parlance, + // volume equates to authority. For example s3://mybucket/path/to/file.txt, volume would return "mybucket". + Volume() string + + //Path returns absolute path to the Location with leading and trailing slashes, ie /some/path/to/ + Path() string + + // Exists returns boolean if the file exists on the file system. Also returns an error if any. + Exists() (bool, error) + + // NewLocation is an initializer for a new Location relative to the existing one. For instance, for location: + // file://some/path/to/, calling NewLocation("../../") would return a new vfs.Location representing file://some/. + // The new location instance should be on the same file system volume as the location it originated from. + NewLocation(relativePath string) (Location, error) + + // ChangeDir updates the existing Location's path to the provided relative path. For instance, for location: + // file://some/path/to/, calling ChangeDir("../../") update the location instance to file://some/. + ChangeDir(relativePath string) error + + //FileSystem returns the underlying vfs.FileSystem struct for Location. + FileSystem() FileSystem + + // NewFile will instantiate a vfs.File instance at the current location's path. In the case of an error, + // nil will be returned. + NewFile(fileName string) (File, error) + + // DeleteFile deletes the file of the given name at the location. This is meant to be a short cut for + // instantiating a new file and calling delete on that, with all the necessary error handling overhead. + DeleteFile(fileName string) error + + // URI returns the fully qualified URI for the Location. IE, file://bucket/some/path/ + URI() string +} + +// File represents a file on a filesystem. A File may or may not actually exist on the filesystem. +type File interface { + io.Closer + io.Reader + io.Seeker + io.Writer + fmt.Stringer + + // Exists returns boolean if the file exists on the file system. Also returns an error if any. + Exists() (bool, error) + + // Location returns the vfs.Location for the File. + Location() Location + + // CopyToLocation will copy the current file to the provided location. If the file already exists at the location, + // the contents will be overwritten with the current file's contents. In the case of an error, nil is returned + // for the file. + CopyToLocation(location Location) (File, error) + + // CopyToFile will copy the current file to the provided file instance. If the file already exists, + // the contents will be overwritten with the current file's contents. In the case of an error, nil is returned + // for the file. + CopyToFile(File) error + + // MoveToLocation will move the current file to the provided location. If the file already exists at the location, + // the contents will be overwritten with the current file's contents. In the case of an error, nil is returned + // for the file. + MoveToLocation(location Location) (File, error) + + // MoveToFile will move the current file to the provided file instance. If a file with the current file's name already exists, + // the contents will be overwritten with the current file's contents. The current instance of the file will be removed. + MoveToFile(File) error + + // Delete unlinks the File on the filesystem. + Delete() error + + // LastModified returns the timestamp the file was last modified (as *time.Time). + LastModified() (*time.Time, error) + + // Size returns the size of the file in bytes. + Size() (uint64, error) + + // Path returns absolute path (with leading slash) including filename, ie /some/path/to/file.txt + Path() string + + // Name returns the base name of the file path. For file:///some/path/to/file.txt, it would return file.txt + Name() string + + // URI returns the fully qualified URI for the File. IE, s3://bucket/some/path/to/file.txt + URI() string +} diff --git a/vfssimple/vfssimple.go b/vfssimple/vfssimple.go new file mode 100644 index 00000000..d5414cee --- /dev/null +++ b/vfssimple/vfssimple.go @@ -0,0 +1,122 @@ +package vfssimple + +import ( + "context" + "errors" + "fmt" + "net/url" + + "cloud.google.com/go/storage" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/s3" + "github.com/aws/aws-sdk-go/service/s3/s3iface" + "github.com/c2fo/vfs" + "github.com/c2fo/vfs/gs" + "github.com/c2fo/vfs/os" + _s3 "github.com/c2fo/vfs/s3" +) + +var ( + fileSystems map[string]vfs.FileSystem +) + +func InitializeLocalFileSystem() { + fileSystems[os.Scheme] = vfs.FileSystem(os.FileSystem{}) +} + +func InitializeGSFileSystem() error { + ctx := context.Background() + client, err := storage.NewClient(ctx) + if err != nil { + return err + } + fileSystems[gs.Scheme] = vfs.FileSystem(gs.NewFileSystem(ctx, client)) + return nil +} + +// InitializeS3FileSystem will handle the bare minimum requirements for setting up an s3.FileSystem +// by setting up an s3 client with the accessKeyId and secreteAccessKey (both required), and an optional +// session token. It is required before making calls to vfs.NewLocation or vfs.NewFile with s3 URIs +// to have set this up ahead of time. If you require more in depth configuration of the s3 Client you +// may set one up yourself and pass the resulting s3iface.S3API to vfs.SetS3Client which will also +// fulfil this requirement. +func InitializeS3FileSystem(accessKeyId, secretAccessKey, token string) error { + if accessKeyId == "" { + return errors.New("accessKeyId argument of InitializeS3FileSystem cannot be an empty string.") + } + if secretAccessKey == "" { + return errors.New("secretAccessKey argument of InitializeS3FileSystem cannot be an empty string.") + } + auth := credentials.NewStaticCredentials(accessKeyId, secretAccessKey, token) + awsConfig := aws.NewConfig().WithCredentials(auth) + awsSession, err := session.NewSession(awsConfig) + if err != nil { + return err + } + + SetS3Client(s3.New(awsSession)) + return nil +} + +// SetS3Client configures an s3.FileSystem with the client passed to it. This will be used by vfs when +// calling vfs.NewLocation or vfs.NewFile with an s3 URI. If you don't want to bother configuring the +// client manually vfs.InitializeS3FileSystem() will handle the client set up with the minimum +// required arguments (an access key id and secret access key.) +func SetS3Client(client s3iface.S3API) { + fileSystems[_s3.Scheme] = vfs.FileSystem(_s3.FileSystem{client}) +} + +// NewLocation is a convenience function that allows for instantiating a location based on a uri string. +// "file://", "s3://", and "gs://" are supported, assuming they have been configured ahead of time. +func NewLocation(uri string) (vfs.Location, error) { + u, err := parseSupportedURI(uri) + if err != nil { + return nil, err + } + + return fileSystems[u.Scheme].NewLocation(u.Host, u.Path) +} + +// NewFile is a convenience function that allows for instantiating a file based on a uri string. Any +// supported file system is supported, though some may require prior configuration. See the docs for +// specific requirements of each. +func NewFile(uri string) (vfs.File, error) { + u, err := parseSupportedURI(uri) + if err != nil { + return nil, err + } + + return fileSystems[u.Scheme].NewFile(u.Host, u.Path) +} + +func parseSupportedURI(uri string) (*url.URL, error) { + u, err := url.Parse(uri) + if err != nil { + return nil, err + } + switch u.Scheme { + case gs.Scheme: + if _, ok := fileSystems[gs.Scheme]; ok { + return u, nil + } else { + return nil, fmt.Errorf("gs is a supported scheme but must be initialized. Call vfs.InitializeGSFileSystem() first.") + } + return u, nil + case os.Scheme: + if _, ok := fileSystems[os.Scheme]; ok { + return u, nil + } else { + return nil, fmt.Errorf("file is a supported scheme but must be initialized. Call vfs.InitializeLocalFileSystem() first.") + } + case _s3.Scheme: + if _, ok := fileSystems[_s3.Scheme]; ok { + return u, nil + } else { + return nil, fmt.Errorf("s3 is a supported scheme but must be intialized. Call vfs.InitializeS3FileSystem(accessKeyId, secretAccessKey, token string), or vfs.SetS3Client(client s3iface.S3API) first.") + } + default: + return nil, fmt.Errorf("scheme [%s] is not supported.", u.Scheme) + } +}