pkg/test/gcs/mock/mock_test.go

1100 lines
29 KiB
Go

/*
Copyright 2020 The Knative Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package mock
import (
"bytes"
"context"
"errors"
"fmt"
"io/ioutil"
"os"
"path"
"reflect"
"sort"
"testing"
)
func TestSetError(t *testing.T) {
ctx := context.Background()
bkt := "dummy"
project := "dummy"
dirPath := "/"
testCases := []struct {
testname string
m map[Method]*ReturnError //error map to load into mockClient
}{
{
testname: "set errors for methods",
m: map[Method]*ReturnError{
MethodNewStorageBucket: {
NumCall: 2,
Err: fmt.Errorf("MethodNewStorageBucket Error"),
},
MethodDeleteStorageBucket: {
NumCall: 1,
Err: fmt.Errorf("MethodDeleteStorageBucketError"),
},
MethodListChildrenFiles: {
NumCall: 0,
Err: fmt.Errorf("MethodListChildrenFilesError"),
},
MethodListDirectChildren: {
NumCall: 1,
Err: fmt.Errorf("MethodListDirectChildrenError"),
},
MethodAttrObject: {
NumCall: 2,
Err: fmt.Errorf("MethodAttrObjectError"),
},
MethodCopyObject: {
NumCall: 3,
Err: fmt.Errorf("MethodCopyObjectError"),
},
MethodReadObject: {
NumCall: 2,
Err: fmt.Errorf("MethodReadObjectError"),
},
MethodWriteObject: {
NumCall: 1,
Err: fmt.Errorf("MethodWriteObjectError"),
},
MethodDeleteObject: {
NumCall: 0,
Err: fmt.Errorf("MethodDeleteObjectError"),
},
MethodDownload: {
NumCall: 1,
Err: fmt.Errorf("MethodDownload"),
},
MethodUpload: {
NumCall: 2,
Err: fmt.Errorf("MethodUpload"),
},
},
},
}
for _, tt := range testCases {
t.Run(tt.testname, func(t *testing.T) {
mockClient := newClientMocker()
mockClient.SetError(tt.m)
for k, v := range tt.m {
switch numCall := v.NumCall; k {
case MethodNewStorageBucket:
for i := uint8(0); i < numCall; i++ {
mockClient.NewStorageBucket(ctx, bkt, project)
}
if err := mockClient.NewStorageBucket(ctx, bkt, project); err == nil {
t.Error("expected error", v.Err)
} else if err.Error() != v.Err.Error() {
t.Errorf("expected error %v, got error %v", v.Err, err)
}
case MethodDeleteStorageBucket:
for i := uint8(0); i < numCall; i++ {
mockClient.DeleteStorageBucket(ctx, bkt, true)
}
if err := mockClient.DeleteStorageBucket(ctx, bkt, true); err == nil {
t.Error("expected error", v.Err)
} else if err.Error() != v.Err.Error() {
t.Errorf("expected error %v, got error %v", v.Err, err)
}
case MethodListChildrenFiles:
for i := uint8(0); i < numCall; i++ {
mockClient.ListChildrenFiles(ctx, bkt, dirPath)
}
if _, err := mockClient.ListChildrenFiles(ctx, bkt, dirPath); err == nil {
t.Error("expected error", v.Err)
} else if err.Error() != v.Err.Error() {
t.Errorf("expected error %v, got error %v", v.Err, err)
}
case MethodListDirectChildren:
for i := uint8(0); i < numCall; i++ {
mockClient.ListDirectChildren(ctx, bkt, dirPath)
}
if _, err := mockClient.ListDirectChildren(ctx, bkt, dirPath); err == nil {
t.Error("expected error", v.Err)
} else if err.Error() != v.Err.Error() {
t.Errorf("expected error %v, got error %v", v.Err, err)
}
case MethodAttrObject:
for i := uint8(0); i < numCall; i++ {
mockClient.AttrObject(ctx, bkt, dirPath)
}
if _, err := mockClient.AttrObject(ctx, bkt, dirPath); err == nil {
t.Error("expected error", v.Err)
} else if err.Error() != v.Err.Error() {
t.Errorf("expected error %v, got error %v", v.Err, err)
}
case MethodCopyObject:
for i := uint8(0); i < numCall; i++ {
mockClient.CopyObject(ctx, bkt, dirPath, bkt, dirPath)
}
if err := mockClient.CopyObject(ctx, bkt, dirPath, bkt, dirPath); err == nil {
t.Error("expected error", v.Err)
} else if err.Error() != v.Err.Error() {
t.Errorf("expected error %v, got error %v", v.Err, err)
}
case MethodReadObject:
for i := uint8(0); i < numCall; i++ {
mockClient.ReadObject(ctx, bkt, dirPath)
}
if _, err := mockClient.ReadObject(ctx, bkt, dirPath); err == nil {
t.Error("expected error", v.Err)
} else if err.Error() != v.Err.Error() {
t.Errorf("expected error %v, got error %v", v.Err, err)
}
case MethodWriteObject:
for i := uint8(0); i < numCall; i++ {
mockClient.WriteObject(ctx, bkt, dirPath, []byte{})
}
if _, err := mockClient.WriteObject(ctx, bkt, dirPath, []byte{}); err == nil {
t.Error("expected error", v.Err)
} else if err.Error() != v.Err.Error() {
t.Errorf("expected error %v, got error %v", v.Err, err)
}
case MethodDeleteObject:
for i := uint8(0); i < numCall; i++ {
mockClient.DeleteObject(ctx, bkt, dirPath)
}
if err := mockClient.DeleteObject(ctx, bkt, dirPath); err == nil {
t.Error("expected error", v.Err)
} else if err.Error() != v.Err.Error() {
t.Errorf("expected error %v, got error %v", v.Err, err)
}
case MethodDownload:
for i := uint8(0); i < numCall; i++ {
mockClient.Download(ctx, bkt, dirPath, dirPath)
}
if err := mockClient.Download(ctx, bkt, dirPath, dirPath); err == nil {
t.Error("expected error", v.Err)
} else if err.Error() != v.Err.Error() {
t.Errorf("expected error %v, got error %v", v.Err, err)
}
case MethodUpload:
for i := uint8(0); i < numCall; i++ {
mockClient.Upload(ctx, bkt, dirPath, dirPath)
}
if err := mockClient.Upload(ctx, bkt, dirPath, dirPath); err == nil {
t.Error("expected error", v.Err)
} else if err.Error() != v.Err.Error() {
t.Errorf("expected error %v, got error %v", v.Err, err)
}
default:
t.Errorf("unknown method")
}
}
})
}
}
func TestClearError(t *testing.T) {
ctx := context.Background()
bkt := "dummy"
project := "dummy"
dirPath := "/"
testCases := []struct {
testname string
m map[Method]*ReturnError //error map to load into mockClient
}{
{
testname: "set errors for methods",
m: map[Method]*ReturnError{
MethodNewStorageBucket: {
NumCall: 0,
Err: fmt.Errorf("MethodNewStorageBucket Error"),
},
MethodDeleteStorageBucket: {
NumCall: 0,
Err: fmt.Errorf("MethodDeleteStorageBucketError"),
},
MethodListChildrenFiles: {
NumCall: 0,
Err: fmt.Errorf("MethodListChildrenFilesError"),
},
MethodListDirectChildren: {
NumCall: 0,
Err: fmt.Errorf("MethodListDirectChildrenError"),
},
MethodAttrObject: {
NumCall: 0,
Err: fmt.Errorf("MethodAttrObjectError"),
},
MethodCopyObject: {
NumCall: 0,
Err: fmt.Errorf("MethodCopyObjectError"),
},
MethodReadObject: {
NumCall: 0,
Err: fmt.Errorf("MethodReadObjectError"),
},
MethodWriteObject: {
NumCall: 0,
Err: fmt.Errorf("MethodWriteObjectError"),
},
MethodDeleteObject: {
NumCall: 0,
Err: fmt.Errorf("MethodDeleteObjectError"),
},
MethodDownload: {
NumCall: 0,
Err: fmt.Errorf("MethodDownload"),
},
MethodUpload: {
NumCall: 0,
Err: fmt.Errorf("MethodUpload"),
},
},
},
}
for _, tt := range testCases {
t.Run(tt.testname, func(t *testing.T) {
mockClient := newClientMocker()
mockClient.SetError(tt.m)
mockClient.ClearError()
for k, v := range tt.m {
switch k {
case MethodNewStorageBucket:
if err := mockClient.NewStorageBucket(ctx, bkt, project); err != nil && err.Error() == v.Err.Error() {
t.Errorf("error %v should have been cleared", v.Err)
}
case MethodDeleteStorageBucket:
if err := mockClient.DeleteStorageBucket(ctx, bkt, true); err != nil && err.Error() == v.Err.Error() {
t.Errorf("error %v should have been cleared", v.Err)
}
case MethodListChildrenFiles:
if _, err := mockClient.ListChildrenFiles(ctx, bkt, dirPath); err != nil && err.Error() == v.Err.Error() {
t.Errorf("error %v should have been cleared", v.Err)
}
case MethodListDirectChildren:
if _, err := mockClient.ListDirectChildren(ctx, bkt, dirPath); err != nil && err.Error() == v.Err.Error() {
t.Errorf("error %v should have been cleared", v.Err)
}
case MethodAttrObject:
if _, err := mockClient.AttrObject(ctx, bkt, dirPath); err != nil && err.Error() == v.Err.Error() {
t.Errorf("error %v should have been cleared", v.Err)
}
case MethodCopyObject:
if err := mockClient.CopyObject(ctx, bkt, dirPath, bkt, dirPath); err != nil && err.Error() == v.Err.Error() {
t.Errorf("error %v should have been cleared", v.Err)
}
case MethodReadObject:
if _, err := mockClient.ReadObject(ctx, bkt, dirPath); err != nil && err.Error() == v.Err.Error() {
t.Errorf("error %v should have been cleared", v.Err)
}
case MethodWriteObject:
if _, err := mockClient.WriteObject(ctx, bkt, dirPath, []byte{}); err != nil && err.Error() == v.Err.Error() {
t.Errorf("error %v should have been cleared", v.Err)
}
case MethodDeleteObject:
if err := mockClient.DeleteObject(ctx, bkt, dirPath); err != nil && err.Error() == v.Err.Error() {
t.Errorf("error %v should have been cleared", v.Err)
}
case MethodDownload:
if err := mockClient.Download(ctx, bkt, dirPath, dirPath); err != nil && err.Error() == v.Err.Error() {
t.Errorf("error %v should have been cleared", v.Err)
}
case MethodUpload:
if err := mockClient.Upload(ctx, bkt, dirPath, dirPath); err != nil && err.Error() == v.Err.Error() {
t.Errorf("error %v should have been cleared", v.Err)
}
default:
t.Errorf("unknown method")
}
}
})
}
}
func TestNewStorageBucket(t *testing.T) {
ctx := context.Background()
mockClient := newClientMocker()
bktName1 := "test-bucket1"
project1 := "test-project1"
bktName2 := "test-bucket2"
project2 := "test-project2"
testCases := []struct {
testname string
bkt string
projectName string
err error
}{
{
testname: "createNewBucket",
bkt: bktName1,
projectName: project1,
err: nil,
},
{
testname: "existingNewBucket",
bkt: bktName1,
projectName: project1,
err: NewBucketExistError(bktName1),
},
{
testname: "existingNewBucketDifferentProject",
bkt: bktName1,
projectName: project2,
err: NewBucketExistError(bktName1),
},
{
testname: "secondNewBucket",
bkt: bktName2,
projectName: project1,
err: nil,
},
}
for _, tt := range testCases {
t.Run(tt.testname, func(t *testing.T) {
err := mockClient.NewStorageBucket(ctx, tt.bkt, tt.projectName)
if (tt.err == nil || err == nil) && !errors.Is(err, tt.err) {
t.Fatalf("expected error %v, got error %v", tt.err, err)
} else if (tt.err != nil && err != nil) && tt.err.Error() != err.Error() {
t.Fatalf("expected error %v, got error %v", tt.err, err)
}
if tt.err != nil {
return
}
if p, ok := mockClient.revIndex[bucket(tt.bkt)]; !ok {
t.Fatal("expected revIndex to contain key", bucket(tt.bkt))
} else if p != project(tt.projectName) {
t.Fatalf("expected revIndex value %v, got %v", project(tt.projectName), p)
}
if p, ok := mockClient.gcp[project(tt.projectName)]; !ok {
t.Fatal("expected gcp to contain key", project(tt.projectName))
} else if _, ok := p.bkt[bucket(tt.bkt)]; !ok {
t.Fatal("expected gcp.bucket to contain key", bucket(tt.bkt))
}
})
}
}
func TestDeleteStorageBucket(t *testing.T) {
ctx := context.Background()
mockClient := newClientMocker()
bktName1 := "test-bucket1"
project1 := "test-project1"
mockClient.NewStorageBucket(ctx, bktName1, project1)
mockClient.WriteObject(ctx, bktName1, "object1", []byte("Hello"))
testCases := []struct {
testname string
bkt string
force bool
err error
}{
{
testname: "deleteBucket",
bkt: bktName1,
force: false,
err: NewNotEmptyBucketError(bktName1),
},
{
testname: "deleteBucket",
bkt: bktName1,
force: true,
err: nil,
},
{
testname: "deleteNonExistentBucket",
bkt: bktName1,
err: NewNoBucketError(bktName1),
},
}
for _, tt := range testCases {
t.Run(tt.testname, func(t *testing.T) {
err := mockClient.DeleteStorageBucket(ctx, tt.bkt, tt.force)
if (tt.err == nil || err == nil) && !errors.Is(err, tt.err) {
t.Fatalf("expected error %v, got error %v", tt.err, err)
} else if (tt.err != nil && err != nil) && tt.err.Error() != err.Error() {
t.Fatalf("expected error %v, got error %v", tt.err, err)
}
if tt.err != nil {
return
}
if _, ok := mockClient.revIndex[bucket(tt.bkt)]; ok {
t.Fatalf("bucket %v should have been deleted", bucket(tt.bkt))
}
if _, ok := mockClient.gcp[project(project1)].bkt[bucket(tt.bkt)]; ok {
t.Fatalf("bucket %v should have been deleted", bucket(tt.bkt))
}
})
}
}
func TestExists(t *testing.T) {
ctx := context.Background()
mockClient := newClientMocker()
bktName1 := "test-bucket1"
project1 := "test-project1"
object1 := "object1"
dir1 := "dir"
content := []byte("Hello World")
mockClient.NewStorageBucket(ctx, bktName1, project1)
mockClient.WriteObject(ctx, bktName1, path.Join(dir1, object1), content)
testCases := []struct {
testname string
bkt string
objpath string
exist bool
}{
{
testname: "existObject",
bkt: bktName1,
objpath: path.Join(dir1, object1),
exist: true,
},
{
testname: "existBucket",
bkt: bktName1,
objpath: "",
exist: true,
},
{
testname: "existDir",
bkt: bktName1,
objpath: "dir",
exist: true,
},
{
testname: "nonexistentObject",
bkt: bktName1,
objpath: "badobjectpath",
exist: false,
},
{
testname: "nonexistentBkt",
bkt: "non-existent-bucket",
exist: false,
},
}
for _, tt := range testCases {
t.Run(tt.testname, func(t *testing.T) {
if exist := mockClient.Exists(ctx, tt.bkt, tt.objpath); exist != tt.exist {
t.Fatalf("expected exist %v to return %v, got %v", tt.objpath, tt.exist, exist)
}
})
}
}
func TestListChildrenFiles(t *testing.T) {
ctx := context.Background()
mockClient := newClientMocker()
bktName1 := "test-bucket1"
project1 := "test-project1"
dir1 := "dir"
dir2 := "dir/subdir"
object1 := path.Join(dir1, "object1")
object2 := path.Join(dir1, "object2")
object3 := path.Join(dir2, "object3")
content := []byte("Hello World")
mockClient.NewStorageBucket(ctx, bktName1, project1)
mockClient.WriteObject(ctx, bktName1, object1, content)
mockClient.WriteObject(ctx, bktName1, object2, content)
mockClient.WriteObject(ctx, bktName1, object3, content)
testCases := []struct {
testname string
bkt string
dir string
expected []string
err error
}{
{
testname: "listAllChildrenObjects",
bkt: bktName1,
dir: "dir",
expected: []string{object1, object2, object3},
err: nil,
},
{
testname: "listAllChildrenObjects",
bkt: bktName1,
dir: "",
expected: []string{object1, object2, object3},
err: nil,
},
{
testname: "badBucket",
bkt: "non-existent-bucket",
err: NewNoBucketError("non-existent-bucket"),
},
}
for _, tt := range testCases {
t.Run(tt.testname, func(t *testing.T) {
children, err := mockClient.ListChildrenFiles(ctx, tt.bkt, tt.dir)
if (tt.err == nil || err == nil) && !errors.Is(err, tt.err) {
t.Fatalf("expected error %v, got error %v", tt.err, err)
} else if (tt.err != nil && err != nil) && tt.err.Error() != err.Error() {
t.Fatalf("expected error %v, got error %v", tt.err, err)
}
sort.Strings(children)
sort.Strings(tt.expected)
if !reflect.DeepEqual(children, tt.expected) {
t.Fatalf("expected %v, got %v", tt.expected, children)
}
})
}
}
func TestListDirectChildren(t *testing.T) {
ctx := context.Background()
mockClient := newClientMocker()
bktName1 := "test-bucket1"
project1 := "test-project1"
dir1 := "dir"
dir2 := "dir/subdir"
object1 := path.Join(dir1, "object1")
object2 := path.Join(dir1, "object2")
object3 := path.Join(dir2, "object3")
object4 := "object4"
content := []byte("Hello World")
mockClient.NewStorageBucket(ctx, bktName1, project1)
mockClient.WriteObject(ctx, bktName1, object1, content)
mockClient.WriteObject(ctx, bktName1, object2, content)
mockClient.WriteObject(ctx, bktName1, object3, content)
mockClient.WriteObject(ctx, bktName1, object4, content)
testCases := []struct {
testname string
bkt string
dir string
expected []string
err error
}{
{
testname: "listAllChildrenObjects",
bkt: bktName1,
dir: "dir",
expected: []string{object1, object2},
err: nil,
},
{
testname: "listAllChildrenObjects",
bkt: bktName1,
dir: "",
expected: []string{object4},
err: nil,
},
{
testname: "badBucket",
bkt: "non-existent-bucket",
err: NewNoBucketError("non-existent-bucket"),
},
}
for _, tt := range testCases {
t.Run(tt.testname, func(t *testing.T) {
children, err := mockClient.ListDirectChildren(ctx, tt.bkt, tt.dir)
if (tt.err == nil || err == nil) && !errors.Is(err, tt.err) {
t.Fatalf("expected error %v, got error %v", tt.err, err)
} else if (tt.err != nil && err != nil) && tt.err.Error() != err.Error() {
t.Fatalf("expected error %v, got error %v", tt.err, err)
}
sort.Strings(children)
sort.Strings(tt.expected)
if !reflect.DeepEqual(children, tt.expected) {
t.Fatalf("expected %v, got %v", tt.expected, children)
}
})
}
}
func TestAttrObject(t *testing.T) {
ctx := context.Background()
mockClient := newClientMocker()
bktName1 := "test-bucket1"
project1 := "test-project1"
object1 := "dir/object1"
content := []byte("Hello World")
mockClient.NewStorageBucket(ctx, bktName1, project1)
mockClient.WriteObject(ctx, bktName1, object1, content)
testCases := []struct {
testname string
bkt string
objpath string
size int64
err error
}{
{
testname: "existObjectAttr",
bkt: bktName1,
objpath: object1,
size: int64(len(content)),
},
{
testname: "badObject",
bkt: bktName1,
objpath: "badobjectpath",
err: NewNoObjectError(bktName1, "badobjectpath", ""),
},
{
testname: "badBucket",
bkt: "non-existent-bucket",
err: NewNoBucketError("non-existent-bucket"),
},
}
for _, tt := range testCases {
t.Run(tt.testname, func(t *testing.T) {
objAttr, err := mockClient.AttrObject(ctx, tt.bkt, tt.objpath)
if (tt.err == nil || err == nil) && !errors.Is(err, tt.err) {
t.Fatalf("expected error %v, got error %v", tt.err, err)
} else if (tt.err != nil && err != nil) && tt.err.Error() != err.Error() {
t.Fatalf("expected error %v, got error %v", tt.err, err)
}
if tt.err != nil {
return
}
if objAttr.Bucket != tt.bkt {
t.Fatalf("expected content %v, got content %v", tt.bkt, objAttr.Bucket)
} else if objAttr.Name != tt.objpath {
t.Fatalf("expected content %v, got content %v", tt.objpath, objAttr.Name)
} else if objAttr.Size != tt.size {
t.Fatalf("expected content %v, got content %v", tt.size, objAttr.Size)
}
})
}
}
func TestCopyObject(t *testing.T) {
ctx := context.Background()
mockClient := newClientMocker()
bktName1 := "test-bucket1"
bktName2 := "test-bucket2"
project1 := "test-project1"
object1 := "dir/object1"
content := []byte("Hello World")
mockClient.NewStorageBucket(ctx, bktName1, project1)
mockClient.NewStorageBucket(ctx, bktName2, project1)
mockClient.WriteObject(ctx, bktName1, object1, content)
testCases := []struct {
testname string
srcBkt string
srcObjPath string
dstBkt string
dstObjPath string
err error
}{
{
testname: "copySameBucket",
srcBkt: bktName1,
srcObjPath: object1,
dstBkt: bktName1,
dstObjPath: "dir/object2",
err: nil,
},
{
testname: "copyAnotherBucket",
srcBkt: bktName1,
srcObjPath: object1,
dstBkt: bktName2,
dstObjPath: "dir/object2",
err: nil,
},
{
testname: "badSrcObject",
srcBkt: bktName1,
srcObjPath: "badobjectpath",
dstBkt: bktName2,
dstObjPath: "dir/object2",
err: NewNoObjectError(bktName1, "badobjectpath", ""),
},
{
testname: "badDstObject",
srcBkt: bktName1,
srcObjPath: object1,
dstBkt: bktName1,
dstObjPath: "badobjectpath/",
err: NewNoObjectError(bktName1, "", "badobjectpath/"),
},
{
testname: "badSrcBucket",
srcBkt: "non-existent-bucket",
dstBkt: bktName1,
err: NewNoBucketError("non-existent-bucket"),
},
{
testname: "badDstBucket",
srcBkt: bktName1,
dstBkt: "non-existent-bucket",
err: NewNoBucketError("non-existent-bucket"),
},
}
for _, tt := range testCases {
t.Run(tt.testname, func(t *testing.T) {
err := mockClient.CopyObject(ctx, tt.srcBkt, tt.srcObjPath, tt.dstBkt, tt.dstObjPath)
if (tt.err == nil || err == nil) && !errors.Is(err, tt.err) {
t.Fatalf("expected error %v, got error %v", tt.err, err)
} else if (tt.err != nil && err != nil) && tt.err.Error() != err.Error() {
t.Fatalf("expected error %v, got error %v", tt.err, err)
}
if tt.err != nil {
return
}
objContent, err := mockClient.ReadObject(ctx, tt.dstBkt, tt.dstObjPath)
if err != nil {
t.Fatalf("cannot read %v from bucket %v, got error %v", tt.dstObjPath, tt.dstBkt, err)
}
if !bytes.Equal(objContent, content) {
t.Fatalf("expected copied content %v, got content %v", content, objContent)
}
})
}
}
func TestReadObject(t *testing.T) {
ctx := context.Background()
mockClient := newClientMocker()
bktName1 := "test-bucket1"
project1 := "test-project1"
object1 := "object1"
content := []byte("Hello World")
badBkt := "non-existent-bucket"
mockClient.NewStorageBucket(ctx, bktName1, project1)
mockClient.WriteObject(ctx, bktName1, object1, content)
testCases := []struct {
testname string
bkt string
objpath string
err error
}{
{
testname: "readObject",
bkt: bktName1,
objpath: path.Join(object1),
err: nil,
},
{
testname: "ReadObjectBadPath",
bkt: bktName1,
objpath: object1 + "/",
err: NewNoObjectError(bktName1, "", object1+"/"),
},
{
testname: "ReadObjectBadBucket",
bkt: badBkt,
err: NewNoBucketError(badBkt),
},
}
for _, tt := range testCases {
t.Run(tt.testname, func(t *testing.T) {
objContent, err := mockClient.ReadObject(ctx, tt.bkt, tt.objpath)
if (tt.err == nil || err == nil) && !errors.Is(err, tt.err) {
t.Fatalf("expected error %v, got error %v", tt.err, err)
} else if (tt.err != nil && err != nil) && tt.err.Error() != err.Error() {
t.Fatalf("expected error %v, got error %v", tt.err, err)
}
if tt.err != nil {
return
}
if !bytes.Equal(content, objContent) {
t.Fatalf("expected content %v, got content %v", content, objContent)
}
})
}
}
func TestWriteObject(t *testing.T) {
ctx := context.Background()
mockClient := newClientMocker()
bktName1 := "test-bucket1"
project1 := "test-project1"
badBkt := "non-existent-bucket"
mockClient.NewStorageBucket(ctx, bktName1, project1)
testCases := []struct {
testname string
bkt string
objpath string
content []byte
err error
}{
{
testname: "writeObject",
bkt: bktName1,
objpath: "testing/object",
content: []byte("Hello World"),
err: nil,
},
{
testname: "writeObjectBadPath",
bkt: bktName1,
objpath: "testing/",
err: NewNoObjectError(bktName1, "", "testing/"),
},
{
testname: "writeObjectBadBucket",
bkt: badBkt,
err: NewNoBucketError(badBkt),
},
}
for _, tt := range testCases {
t.Run(tt.testname, func(t *testing.T) {
n, err := mockClient.WriteObject(ctx, tt.bkt, tt.objpath, tt.content)
if (tt.err == nil || err == nil) && !errors.Is(err, tt.err) {
t.Fatalf("expected error %v, got error %v", tt.err, err)
} else if (tt.err != nil && err != nil) && tt.err.Error() != err.Error() {
t.Fatalf("expected error %v, got error %v", tt.err, err)
}
if tt.err != nil {
return
}
if n != len(tt.content) {
t.Fatalf("content has length %v, wrote only %v bytes", len(tt.content), n)
}
if content, err := mockClient.ReadObject(ctx, tt.bkt, tt.objpath); err != nil {
t.Fatal("read object returned error", err)
} else if !bytes.Equal(content, tt.content) {
t.Fatalf("expected content %v, got content %v", tt.content, content)
}
})
}
}
func TestDeleteObject(t *testing.T) {
ctx := context.Background()
mockClient := newClientMocker()
bktName1 := "test-bucket1"
project1 := "test-project1"
object1 := "dir/object1"
mockClient.NewStorageBucket(ctx, bktName1, project1)
mockClient.WriteObject(ctx, bktName1, object1, []byte("Hello World"))
testCases := []struct {
testname string
bkt string
objpath string
err error
}{
{
testname: "DeleteObject",
bkt: bktName1,
objpath: object1,
err: nil,
},
{
testname: "DeleteNonExistentObject",
bkt: bktName1,
objpath: "non-existent-object",
err: nil,
},
}
for _, tt := range testCases {
t.Run(tt.testname, func(t *testing.T) {
err := mockClient.DeleteObject(ctx, tt.bkt, tt.objpath)
if (tt.err == nil || err == nil) && !errors.Is(err, tt.err) {
t.Fatalf("expected error %v, got error %v", tt.err, err)
} else if (tt.err != nil && err != nil) && tt.err.Error() != err.Error() {
t.Fatalf("expected error %v, got error %v", tt.err, err)
}
if tt.err != nil {
return
}
if mockClient.Exists(ctx, tt.bkt, tt.objpath) {
t.Fatalf("%v in %v should not exist (deleted)", tt.objpath, tt.bkt)
}
})
}
}
func TestDownload(t *testing.T) {
ctx := context.Background()
mockClient := newClientMocker()
bktName1 := "test-bucket1"
project1 := "test-project1"
object1 := "dir/object1"
file := "test/download"
defer os.Remove(file)
content := []byte("Hello World")
mockClient.NewStorageBucket(ctx, bktName1, project1)
mockClient.WriteObject(ctx, bktName1, object1, content)
testCases := []struct {
testname string
bkt string
objPath string
err error
}{
{
testname: "downloadObject",
bkt: bktName1,
objPath: object1,
err: nil,
},
{
testname: "badObject",
bkt: bktName1,
objPath: "badobjectpath",
err: NewNoObjectError(bktName1, "badobjectpath", ""),
},
{
testname: "badBucket",
bkt: "non-existent-bucket",
err: NewNoBucketError("non-existent-bucket"),
},
}
for _, tt := range testCases {
t.Run(tt.testname, func(t *testing.T) {
err := mockClient.Download(ctx, tt.bkt, tt.objPath, file)
if (tt.err == nil || err == nil) && !errors.Is(err, tt.err) {
t.Fatalf("expected error %v, got error %v", tt.err, err)
} else if (tt.err != nil && err != nil) && tt.err.Error() != err.Error() {
t.Fatalf("expected error %v, got error %v", tt.err, err)
}
if tt.err != nil {
return
}
fileContent, err := ioutil.ReadFile(file)
if err != nil {
t.Fatalf("cannot read content %v, error %v", file, err)
}
if !bytes.Equal(fileContent, content) {
t.Fatalf("expected copied content %v, got content %v", content, fileContent)
}
})
}
}
func TestUpload(t *testing.T) {
ctx := context.Background()
mockClient := newClientMocker()
bktName1 := "test-bucket1"
project1 := "test-project1"
object1 := "dir/object1"
file := "test/upload"
content, err := ioutil.ReadFile(file)
if err != nil {
t.Fatalf("cannot read content %v, error %v", file, err)
}
mockClient.NewStorageBucket(ctx, bktName1, project1)
testCases := []struct {
testname string
bkt string
objPath string
err error
}{
{
testname: "uploadObject",
bkt: bktName1,
objPath: object1,
err: nil,
},
{
testname: "badObject",
bkt: bktName1,
objPath: "badobjectpath/",
err: NewNoObjectError(bktName1, "", "badobjectpath/"),
},
{
testname: "badBucket",
bkt: "non-existent-bucket",
err: NewNoBucketError("non-existent-bucket"),
},
}
for _, tt := range testCases {
t.Run(tt.testname, func(t *testing.T) {
err := mockClient.Upload(ctx, tt.bkt, tt.objPath, file)
if (tt.err == nil || err == nil) && !errors.Is(err, tt.err) {
t.Fatalf("expected error %v, got error %v", tt.err, err)
} else if (tt.err != nil && err != nil) && tt.err.Error() != err.Error() {
t.Fatalf("expected error %v, got error %v", tt.err, err)
}
if tt.err != nil {
return
}
objContent, err := mockClient.ReadObject(ctx, tt.bkt, tt.objPath)
if err != nil {
t.Fatalf("cannot read content %v in bucket %v, error %v", tt.objPath, tt.bkt, err)
}
if !bytes.Equal(objContent, content) {
t.Fatalf("expected copied content %v, got content %v", content, objContent)
}
})
}
}