From 20659d0829460ccb85ede6f37a605201758f1ed3 Mon Sep 17 00:00:00 2001 From: JinnyYi Date: Fri, 29 Oct 2021 18:04:57 +0800 Subject: [PATCH 1/2] feat(tests): Run test cases based on features --- tests/appender.go | 241 ++++----- tests/copier.go | 295 +++++----- tests/direr.go | 165 +++--- tests/linker.go | 245 ++++----- tests/mover.go | 325 +++++------ tests/multipart_http_signer.go | 278 +++++----- tests/multiparter.go | 455 ++++++++-------- tests/storage_http_signer.go | 242 +++++---- tests/storager.go | 947 +++++++++++++++++---------------- 9 files changed, 1647 insertions(+), 1546 deletions(-) diff --git a/tests/appender.go b/tests/appender.go index 2445bedd7..cd877d349 100644 --- a/tests/appender.go +++ b/tests/appender.go @@ -18,159 +18,162 @@ import ( func TestAppender(t *testing.T, store types.Storager) { Convey("Given a basic Storager", t, func() { - Convey("When CreateAppend", func() { - path := uuid.NewString() - o, err := store.CreateAppend(path) + f := store.Features() + if f.CreateAppend && f.WriteAppend && f.CommitAppend && f.Write && f.Read && f.Delete && f.Stat { + Convey("When CreateAppend", func() { + path := uuid.NewString() + o, err := store.CreateAppend(path) + + defer func() { + err := store.Delete(path) + if err != nil { + t.Error(err) + } + }() + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("The Object Mode should be appendable", func() { + // Append object's mode must be appendable. + So(o.Mode.IsAppend(), ShouldBeTrue) + }) + }) - defer func() { - err := store.Delete(path) - if err != nil { - t.Error(err) - } - }() + Convey("When CreateAppend with an existing object", func() { + path := uuid.NewString() + o, err := store.CreateAppend(path) - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) + defer func() { + err := store.Delete(path) + if err != nil { + t.Error(err) + } + }() - Convey("The Object Mode should be appendable", func() { - // Append object's mode must be appendable. - So(o.Mode.IsAppend(), ShouldBeTrue) - }) - }) + Convey("The first returned error should be nil", func() { + So(err, ShouldBeNil) + }) - Convey("When CreateAppend with an existing object", func() { - path := uuid.NewString() - o, err := store.CreateAppend(path) + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + r := io.LimitReader(randbytes.NewRand(), size) - defer func() { - err := store.Delete(path) + _, err = store.WriteAppend(o, r, size) if err != nil { - t.Error(err) + t.Fatal(err) } - }() - - Convey("The first returned error should be nil", func() { - So(err, ShouldBeNil) - }) - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - r := io.LimitReader(randbytes.NewRand(), size) + err = store.CommitAppend(o) + if err != nil { + t.Fatal(err) + } - _, err = store.WriteAppend(o, r, size) - if err != nil { - t.Fatal(err) - } + o, err = store.CreateAppend(path) - err = store.CommitAppend(o) - if err != nil { - t.Fatal(err) - } + Convey("The second returned error also should be nil", func() { + So(err, ShouldBeNil) + }) - o, err = store.CreateAppend(path) + Convey("The Object Mode should be appendable", func() { + // Append object's mode must be appendable. + So(o.Mode.IsAppend(), ShouldBeTrue) + }) - Convey("The second returned error also should be nil", func() { - So(err, ShouldBeNil) + Convey("The object append offset should be 0", func() { + So(o.MustGetAppendOffset(), ShouldBeZeroValue) + }) }) - Convey("The Object Mode should be appendable", func() { - // Append object's mode must be appendable. - So(o.Mode.IsAppend(), ShouldBeTrue) - }) + Convey("When Delete", func() { + path := uuid.NewString() + _, err := store.CreateAppend(path) + if err != nil { + t.Error(err) + } - Convey("The object append offset should be 0", func() { - So(o.MustGetAppendOffset(), ShouldBeZeroValue) - }) - }) - - Convey("When Delete", func() { - path := uuid.NewString() - _, err := store.CreateAppend(path) - if err != nil { - t.Error(err) - } - - err = store.Delete(path) - Convey("The first returned error should be nil", func() { - So(err, ShouldBeNil) - }) + err = store.Delete(path) + Convey("The first returned error should be nil", func() { + So(err, ShouldBeNil) + }) - err = store.Delete(path) - Convey("The second returned error also should be nil", func() { - So(err, ShouldBeNil) + err = store.Delete(path) + Convey("The second returned error also should be nil", func() { + So(err, ShouldBeNil) + }) }) - }) - - Convey("When WriteAppend", func() { - path := uuid.NewString() - o, err := store.CreateAppend(path) - if err != nil { - t.Error(err) - } - defer func() { - err := store.Delete(path) + Convey("When WriteAppend", func() { + path := uuid.NewString() + o, err := store.CreateAppend(path) if err != nil { t.Error(err) } - }() - - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - content, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) - r := bytes.NewReader(content) - - n, err := store.WriteAppend(o, r, size) - Convey("WriteAppend error should be nil", func() { - So(err, ShouldBeNil) + defer func() { + err := store.Delete(path) + if err != nil { + t.Error(err) + } + }() + + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + content, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) + r := bytes.NewReader(content) + + n, err := store.WriteAppend(o, r, size) + + Convey("WriteAppend error should be nil", func() { + So(err, ShouldBeNil) + }) + Convey("WriteAppend size should be equal to n", func() { + So(n, ShouldEqual, size) + }) }) - Convey("WriteAppend size should be equal to n", func() { - So(n, ShouldEqual, size) - }) - }) - - Convey("When CommitAppend", func() { - path := uuid.NewString() - o, err := store.CreateAppend(path) - if err != nil { - t.Error(err) - } - defer func() { - err := store.Delete(path) + Convey("When CommitAppend", func() { + path := uuid.NewString() + o, err := store.CreateAppend(path) if err != nil { t.Error(err) } - }() - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - content, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) + defer func() { + err := store.Delete(path) + if err != nil { + t.Error(err) + } + }() - _, err = store.WriteAppend(o, bytes.NewReader(content), size) - if err != nil { - t.Error(err) - } + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + content, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) - _, err = store.WriteAppend(o, bytes.NewReader(content), size) - if err != nil { - t.Error(err) - } + _, err = store.WriteAppend(o, bytes.NewReader(content), size) + if err != nil { + t.Error(err) + } - err = store.CommitAppend(o) + _, err = store.WriteAppend(o, bytes.NewReader(content), size) + if err != nil { + t.Error(err) + } - Convey("CommitAppend error should be nil", func() { - So(err, ShouldBeNil) - }) + err = store.CommitAppend(o) - var buf bytes.Buffer - _, err = store.Read(path, &buf, pairs.WithSize(size*2)) + Convey("CommitAppend error should be nil", func() { + So(err, ShouldBeNil) + }) - Convey("Read error should be nil", func() { - So(err, ShouldBeNil) - }) - Convey("The content should be match", func() { - So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(bytes.Repeat(content, 2))) + var buf bytes.Buffer + _, err = store.Read(path, &buf, pairs.WithSize(size*2)) + + Convey("Read error should be nil", func() { + So(err, ShouldBeNil) + }) + Convey("The content should be match", func() { + So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(bytes.Repeat(content, 2))) + }) }) - }) + } }) } diff --git a/tests/copier.go b/tests/copier.go index d591efd13..c2be1132c 100644 --- a/tests/copier.go +++ b/tests/copier.go @@ -20,215 +20,224 @@ import ( func TestCopier(t *testing.T, store types.Storager) { Convey("Given a basic Storager", t, func() { - Convey("When Copy a file", func() { - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - content, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) - src := uuid.New().String() - - _, err := store.Write(src, bytes.NewReader(content), size) - if err != nil { - t.Fatal(err) - } - - defer func() { - err = store.Delete(src) + f := store.Features() + if f.Copy && f.Write && f.Read && f.Delete { + Convey("When Copy a file", func() { + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + content, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) + src := uuid.New().String() + + _, err := store.Write(src, bytes.NewReader(content), size) if err != nil { - t.Error(err) + t.Fatal(err) } - }() - dst := uuid.New().String() - err = store.Copy(src, dst) + defer func() { + err = store.Delete(src) + if err != nil { + t.Error(err) + } + }() - defer func() { - err = store.Delete(dst) - if err != nil { - t.Error(err) - } - }() - - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) + dst := uuid.New().String() + err = store.Copy(src, dst) - Convey("Read should get dst object data without error", func() { - var buf bytes.Buffer - n, err := store.Read(dst, &buf) + defer func() { + err = store.Delete(dst) + if err != nil { + t.Error(err) + } + }() Convey("The error should be nil", func() { So(err, ShouldBeNil) }) - Convey("The content should be match", func() { - So(buf, ShouldNotBeNil) - So(n, ShouldEqual, size) - So(md5.Sum(buf.Bytes()), ShouldResemble, md5.Sum(content)) + Convey("Read should get dst object data without error", func() { + var buf bytes.Buffer + n, err := store.Read(dst, &buf) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("The content should be match", func() { + So(buf, ShouldNotBeNil) + So(n, ShouldEqual, size) + So(md5.Sum(buf.Bytes()), ShouldResemble, md5.Sum(content)) + }) }) }) - }) - - Convey("When Copy to an existing file", func() { - srcSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - content, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), srcSize)) - src := uuid.New().String() - _, err := store.Write(src, bytes.NewReader(content), srcSize) - if err != nil { - t.Fatal(err) - } + Convey("When Copy to an existing file", func() { + srcSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + content, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), srcSize)) + src := uuid.New().String() - defer func() { - err = store.Delete(src) + _, err := store.Write(src, bytes.NewReader(content), srcSize) if err != nil { - t.Error(err) + t.Fatal(err) } - }() - dstSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - r := io.LimitReader(randbytes.NewRand(), dstSize) - dst := uuid.New().String() + defer func() { + err = store.Delete(src) + if err != nil { + t.Error(err) + } + }() - _, err = store.Write(dst, r, dstSize) - if err != nil { - t.Fatal(err) - } + dstSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + r := io.LimitReader(randbytes.NewRand(), dstSize) + dst := uuid.New().String() - defer func() { - err = store.Delete(dst) + _, err = store.Write(dst, r, dstSize) if err != nil { - t.Error(err) + t.Fatal(err) } - }() - err = store.Copy(src, dst) - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) - - Convey("Read should get dst object data without error", func() { - var buf bytes.Buffer - n, err := store.Read(dst, &buf) + defer func() { + err = store.Delete(dst) + if err != nil { + t.Error(err) + } + }() + err = store.Copy(src, dst) Convey("The error should be nil", func() { So(err, ShouldBeNil) }) - Convey("The content should be match", func() { - So(buf, ShouldNotBeNil) - So(n, ShouldEqual, srcSize) - So(md5.Sum(buf.Bytes()), ShouldResemble, md5.Sum(content)) + Convey("Read should get dst object data without error", func() { + var buf bytes.Buffer + n, err := store.Read(dst, &buf) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("The content should be match", func() { + So(buf, ShouldNotBeNil) + So(n, ShouldEqual, srcSize) + So(md5.Sum(buf.Bytes()), ShouldResemble, md5.Sum(content)) + }) }) }) - }) + } }) } func TestCopierWithDir(t *testing.T, store types.Storager) { Convey("Given a basic Storager", t, func() { - Convey("When Copy to an existing dir", func() { - srcSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - r := io.LimitReader(randbytes.NewRand(), srcSize) - src := uuid.New().String() - - _, err := store.Write(src, r, srcSize) - if err != nil { - t.Fatal(err) - } + f := store.Features() + if f.Copy && f.CreateDir && !f.VirtualDir && f.Write && f.Delete { + Convey("When Copy to an existing dir", func() { + srcSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + r := io.LimitReader(randbytes.NewRand(), srcSize) + src := uuid.New().String() - defer func() { - err = store.Delete(src) + _, err := store.Write(src, r, srcSize) if err != nil { - t.Error(err) + t.Fatal(err) } - }() - dst := uuid.New().String() - _, err = store.CreateDir(dst) - if err != nil { - t.Fatal(err) - } + defer func() { + err = store.Delete(src) + if err != nil { + t.Error(err) + } + }() - defer func() { - err = store.Delete(dst, pairs.WithObjectMode(types.ModeDir)) + dst := uuid.New().String() + _, err = store.CreateDir(dst) if err != nil { - t.Error(err) + t.Fatal(err) } - }() - err = store.Copy(src, dst) - Convey("The error should be ErrObjectModeInvalid", func() { - So(errors.Is(err, services.ErrObjectModeInvalid), ShouldBeTrue) + defer func() { + err = store.Delete(dst, pairs.WithObjectMode(types.ModeDir)) + if err != nil { + t.Error(err) + } + }() + + err = store.Copy(src, dst) + Convey("The error should be ErrObjectModeInvalid", func() { + So(errors.Is(err, services.ErrObjectModeInvalid), ShouldBeTrue) + }) }) - }) + } }) } func TestCopierWithVirtualDir(t *testing.T, store types.Storager) { Convey("Given a basic Storager", t, func() { - Convey("When Copy to an existing dir", func() { - srcSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - r := io.LimitReader(randbytes.NewRand(), srcSize) - src := uuid.New().String() - - _, err := store.Write(src, r, srcSize) - if err != nil { - t.Fatal(err) - } + f := store.Features() + if f.Copy && f.CreateDir && f.VirtualDir && f.Write && f.Delete && f.Stat { + Convey("When Copy to an existing dir", func() { + srcSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + r := io.LimitReader(randbytes.NewRand(), srcSize) + src := uuid.New().String() - defer func() { - err = store.Delete(src) + _, err := store.Write(src, r, srcSize) if err != nil { - t.Error(err) + t.Fatal(err) } - }() - dst := uuid.New().String() - _, err = store.CreateDir(dst) - if err != nil { - t.Fatal(err) - } + defer func() { + err = store.Delete(src) + if err != nil { + t.Error(err) + } + }() - defer func() { - err = store.Delete(dst, pairs.WithObjectMode(types.ModeDir)) + dst := uuid.New().String() + _, err = store.CreateDir(dst) if err != nil { - t.Error(err) + t.Fatal(err) } - }() - err = store.Copy(src, dst) - - defer func() { - err = store.Delete(dst) - if err != nil { - t.Error(err) - } - }() - - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) + defer func() { + err = store.Delete(dst, pairs.WithObjectMode(types.ModeDir)) + if err != nil { + t.Error(err) + } + }() - Convey("Stat should get dst object without error", func() { - o, err := store.Stat(dst) + err = store.Copy(src, dst) - So(err, ShouldBeNil) - So(o, ShouldNotBeNil) + defer func() { + err = store.Delete(dst) + if err != nil { + t.Error(err) + } + }() - Convey("The Object Mode should be read", func() { - So(o.Mode.IsRead(), ShouldBeTrue) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) }) - Convey("The path and size should be match", func() { + Convey("Stat should get dst object without error", func() { + o, err := store.Stat(dst) + + So(err, ShouldBeNil) So(o, ShouldNotBeNil) - So(o.Path, ShouldEqual, dst) - osize, ok := o.GetContentLength() - So(ok, ShouldBeTrue) - So(osize, ShouldEqual, srcSize) + Convey("The Object Mode should be read", func() { + So(o.Mode.IsRead(), ShouldBeTrue) + }) + + Convey("The path and size should be match", func() { + So(o, ShouldNotBeNil) + So(o.Path, ShouldEqual, dst) + + osize, ok := o.GetContentLength() + So(ok, ShouldBeTrue) + So(osize, ShouldEqual, srcSize) + }) }) }) - }) + } }) } diff --git a/tests/direr.go b/tests/direr.go index dabf02030..873582f22 100644 --- a/tests/direr.go +++ b/tests/direr.go @@ -13,103 +13,106 @@ import ( func TestDirer(t *testing.T, store types.Storager) { Convey("Given a basic Storager", t, func() { - Convey("When CreateDir", func() { - path := uuid.New().String() - _, err := store.CreateDir(path) - - defer func() { - err := store.Delete(path, pairs.WithObjectMode(types.ModeDir)) - if err != nil { - t.Error(err) - } - }() - - Convey("The first returned error should be nil", func() { - So(err, ShouldBeNil) + f := store.Features() + if f.CreateDir && f.Delete && f.Stat { + Convey("When CreateDir", func() { + path := uuid.New().String() + _, err := store.CreateDir(path) + + defer func() { + err := store.Delete(path, pairs.WithObjectMode(types.ModeDir)) + if err != nil { + t.Error(err) + } + }() + + Convey("The first returned error should be nil", func() { + So(err, ShouldBeNil) + }) + + o, err := store.CreateDir(path) + Convey("The second returned error also should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("The Object Path should equal to the input path", func() { + So(o.Path, ShouldEqual, path) + }) + + Convey("The Object Mode should be dir", func() { + // Dir object's mode must be Dir. + So(o.Mode.IsDir(), ShouldBeTrue) + }) }) - o, err := store.CreateDir(path) - Convey("The second returned error also should be nil", func() { - So(err, ShouldBeNil) + Convey("When Create with ModeDir", func() { + path := uuid.New().String() + o := store.Create(path, pairs.WithObjectMode(types.ModeDir)) + + defer func() { + err := store.Delete(path, pairs.WithObjectMode(types.ModeDir)) + if err != nil { + t.Error(err) + } + }() + + Convey("The Object Path should equal to the input path", func() { + So(o.Path, ShouldEqual, path) + }) + + Convey("The Object Mode should be dir", func() { + // Dir object's mode must be Dir. + So(o.Mode.IsDir(), ShouldBeTrue) + }) }) - Convey("The Object Path should equal to the input path", func() { - So(o.Path, ShouldEqual, path) - }) - - Convey("The Object Mode should be dir", func() { - // Dir object's mode must be Dir. - So(o.Mode.IsDir(), ShouldBeTrue) - }) - }) - - Convey("When Create with ModeDir", func() { - path := uuid.New().String() - o := store.Create(path, pairs.WithObjectMode(types.ModeDir)) - - defer func() { - err := store.Delete(path, pairs.WithObjectMode(types.ModeDir)) + Convey("When Stat with ModeDir", func() { + path := uuid.New().String() + _, err := store.CreateDir(path) if err != nil { t.Error(err) } - }() - - Convey("The Object Path should equal to the input path", func() { - So(o.Path, ShouldEqual, path) - }) - Convey("The Object Mode should be dir", func() { - // Dir object's mode must be Dir. - So(o.Mode.IsDir(), ShouldBeTrue) - }) - }) + defer func() { + err := store.Delete(path, pairs.WithObjectMode(types.ModeDir)) + if err != nil { + t.Error(err) + } + }() - Convey("When Stat with ModeDir", func() { - path := uuid.New().String() - _, err := store.CreateDir(path) - if err != nil { - t.Error(err) - } + o, err := store.Stat(path, pairs.WithObjectMode(types.ModeDir)) - defer func() { - err := store.Delete(path, pairs.WithObjectMode(types.ModeDir)) - if err != nil { - t.Error(err) - } - }() + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) - o, err := store.Stat(path, pairs.WithObjectMode(types.ModeDir)) + Convey("The Object Path should equal to the input path", func() { + So(o.Path, ShouldEqual, path) + }) - Convey("The error should be nil", func() { - So(err, ShouldBeNil) + Convey("The Object Mode should be dir", func() { + // Dir object's mode must be Dir. + So(o.Mode.IsDir(), ShouldBeTrue) + }) }) - Convey("The Object Path should equal to the input path", func() { - So(o.Path, ShouldEqual, path) - }) + Convey("When Delete with ModeDir", func() { + path := uuid.New().String() + _, err := store.CreateDir(path) + if err != nil { + t.Error(err) + } - Convey("The Object Mode should be dir", func() { - // Dir object's mode must be Dir. - So(o.Mode.IsDir(), ShouldBeTrue) - }) - }) - - Convey("When Delete with ModeDir", func() { - path := uuid.New().String() - _, err := store.CreateDir(path) - if err != nil { - t.Error(err) - } - - err = store.Delete(path, pairs.WithObjectMode(types.ModeDir)) - Convey("The first returned error should be nil", func() { - So(err, ShouldBeNil) - }) + err = store.Delete(path, pairs.WithObjectMode(types.ModeDir)) + Convey("The first returned error should be nil", func() { + So(err, ShouldBeNil) + }) - err = store.Delete(path, pairs.WithObjectMode(types.ModeDir)) - Convey("The second returned error also should be nil", func() { - So(err, ShouldBeNil) + err = store.Delete(path, pairs.WithObjectMode(types.ModeDir)) + Convey("The second returned error also should be nil", func() { + So(err, ShouldBeNil) + }) }) - }) + } }) } diff --git a/tests/linker.go b/tests/linker.go index 9648cd0ed..cf24c8716 100644 --- a/tests/linker.go +++ b/tests/linker.go @@ -16,54 +16,36 @@ import ( func TestLinker(t *testing.T, store types.Storager) { Convey("Given a basic Storager", t, func() { - workDir := store.Metadata().WorkDir + f := store.Features() + if f.CreateLink && f.Write && f.Delete && f.Stat { + workDir := store.Metadata().WorkDir - Convey("When create a link object", func() { - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - r := io.LimitReader(randbytes.NewRand(), size) - target := uuid.New().String() + Convey("When create a link object", func() { + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + r := io.LimitReader(randbytes.NewRand(), size) + target := uuid.New().String() - _, err := store.Write(target, r, size) - if err != nil { - t.Fatal(err) - } - - defer func() { - err = store.Delete(target) - if err != nil { - t.Error(err) - } - }() - - path := uuid.New().String() - o, err := store.CreateLink(path, target) - - defer func() { - err = store.Delete(path) + _, err := store.Write(target, r, size) if err != nil { - t.Error(err) + t.Fatal(err) } - }() - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) - - Convey("The object mode should be link", func() { - // Link object's mode must be link. - So(o.Mode.IsLink(), ShouldBeTrue) - }) + defer func() { + err = store.Delete(target) + if err != nil { + t.Error(err) + } + }() - Convey("The linkTarget of the object must be the same as the target", func() { - // The linkTarget must be the same as the target. - linkTarget, ok := o.GetLinkTarget() - - So(ok, ShouldBeTrue) - So(linkTarget, ShouldEqual, filepath.Join(workDir, target)) - }) + path := uuid.New().String() + o, err := store.CreateLink(path, target) - Convey("Stat should get path object without error", func() { - obj, err := store.Stat(path) + defer func() { + err = store.Delete(path) + if err != nil { + t.Error(err) + } + }() Convey("The error should be nil", func() { So(err, ShouldBeNil) @@ -71,50 +53,51 @@ func TestLinker(t *testing.T, store types.Storager) { Convey("The object mode should be link", func() { // Link object's mode must be link. - So(obj.Mode.IsLink(), ShouldBeTrue) + So(o.Mode.IsLink(), ShouldBeTrue) }) Convey("The linkTarget of the object must be the same as the target", func() { // The linkTarget must be the same as the target. - linkTarget, ok := obj.GetLinkTarget() + linkTarget, ok := o.GetLinkTarget() So(ok, ShouldBeTrue) So(linkTarget, ShouldEqual, filepath.Join(workDir, target)) }) - }) - }) - Convey("When create a link object from a not existing target", func() { - target := uuid.New().String() + Convey("Stat should get path object without error", func() { + obj, err := store.Stat(path) - path := uuid.New().String() - o, err := store.CreateLink(path, target) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) - defer func() { - err = store.Delete(path) - if err != nil { - t.Error(err) - } - }() + Convey("The object mode should be link", func() { + // Link object's mode must be link. + So(obj.Mode.IsLink(), ShouldBeTrue) + }) - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) + Convey("The linkTarget of the object must be the same as the target", func() { + // The linkTarget must be the same as the target. + linkTarget, ok := obj.GetLinkTarget() - Convey("The object mode should be link", func() { - // Link object's mode must be link. - So(o.Mode.IsLink(), ShouldBeTrue) + So(ok, ShouldBeTrue) + So(linkTarget, ShouldEqual, filepath.Join(workDir, target)) + }) + }) }) - Convey("The linkTarget of the object must be the same as the target", func() { - linkTarget, ok := o.GetLinkTarget() + Convey("When create a link object from a not existing target", func() { + target := uuid.New().String() - So(ok, ShouldBeTrue) - So(linkTarget, ShouldEqual, filepath.Join(workDir, target)) - }) + path := uuid.New().String() + o, err := store.CreateLink(path, target) - Convey("Stat should get path object without error", func() { - obj, err := store.Stat(path) + defer func() { + err = store.Delete(path) + if err != nil { + t.Error(err) + } + }() Convey("The error should be nil", func() { So(err, ShouldBeNil) @@ -122,84 +105,104 @@ func TestLinker(t *testing.T, store types.Storager) { Convey("The object mode should be link", func() { // Link object's mode must be link. - So(obj.Mode.IsLink(), ShouldBeTrue) + So(o.Mode.IsLink(), ShouldBeTrue) }) Convey("The linkTarget of the object must be the same as the target", func() { - // The linkTarget must be the same as the target. - linkTarget, ok := obj.GetLinkTarget() + linkTarget, ok := o.GetLinkTarget() So(ok, ShouldBeTrue) So(linkTarget, ShouldEqual, filepath.Join(workDir, target)) }) - }) - }) - Convey("When CreateLink to an existing path", func() { - firstSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - firstR := io.LimitReader(randbytes.NewRand(), firstSize) - firstTarget := uuid.New().String() + Convey("Stat should get path object without error", func() { + obj, err := store.Stat(path) - _, err := store.Write(firstTarget, firstR, firstSize) - if err != nil { - t.Fatal(err) - } + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) - defer func() { - err = store.Delete(firstTarget) - if err != nil { - t.Error(err) - } - }() + Convey("The object mode should be link", func() { + // Link object's mode must be link. + So(obj.Mode.IsLink(), ShouldBeTrue) + }) - path := uuid.New().String() - o, err := store.CreateLink(path, firstTarget) + Convey("The linkTarget of the object must be the same as the target", func() { + // The linkTarget must be the same as the target. + linkTarget, ok := obj.GetLinkTarget() - defer func() { - err = store.Delete(path) + So(ok, ShouldBeTrue) + So(linkTarget, ShouldEqual, filepath.Join(workDir, target)) + }) + }) + }) + + Convey("When CreateLink to an existing path", func() { + firstSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + firstR := io.LimitReader(randbytes.NewRand(), firstSize) + firstTarget := uuid.New().String() + + _, err := store.Write(firstTarget, firstR, firstSize) if err != nil { - t.Error(err) + t.Fatal(err) } - }() - Convey("The first returned error should be nil", func() { - So(err, ShouldBeNil) - }) + defer func() { + err = store.Delete(firstTarget) + if err != nil { + t.Error(err) + } + }() - secondSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - secondR := io.LimitReader(randbytes.NewRand(), secondSize) - secondTarget := uuid.New().String() + path := uuid.New().String() + o, err := store.CreateLink(path, firstTarget) - _, err = store.Write(secondTarget, secondR, secondSize) - if err != nil { - t.Fatal(err) - } + defer func() { + err = store.Delete(path) + if err != nil { + t.Error(err) + } + }() - defer func() { - err = store.Delete(secondTarget) + Convey("The first returned error should be nil", func() { + So(err, ShouldBeNil) + }) + + secondSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + secondR := io.LimitReader(randbytes.NewRand(), secondSize) + secondTarget := uuid.New().String() + + _, err = store.Write(secondTarget, secondR, secondSize) if err != nil { - t.Error(err) + t.Fatal(err) } - }() - o, err = store.CreateLink(path, secondTarget) + defer func() { + err = store.Delete(secondTarget) + if err != nil { + t.Error(err) + } + }() - Convey("The second returned error should also be nil", func() { - So(err, ShouldBeNil) - }) + o, err = store.CreateLink(path, secondTarget) - Convey("The object mode should be link", func() { - // Link object's mode must be link. - So(o.Mode.IsLink(), ShouldBeTrue) - }) + Convey("The second returned error should also be nil", func() { + So(err, ShouldBeNil) + }) - Convey("The linkTarget of the object must be the same as the secondTarget", func() { - // The linkTarget must be the same as the secondTarget. - linkTarget, ok := o.GetLinkTarget() + Convey("The object mode should be link", func() { + // Link object's mode must be link. + So(o.Mode.IsLink(), ShouldBeTrue) + }) + + Convey("The linkTarget of the object must be the same as the secondTarget", func() { + // The linkTarget must be the same as the secondTarget. + linkTarget, ok := o.GetLinkTarget() - So(ok, ShouldBeTrue) - So(linkTarget, ShouldEqual, filepath.Join(workDir, secondTarget)) + So(ok, ShouldBeTrue) + So(linkTarget, ShouldEqual, filepath.Join(workDir, secondTarget)) + }) }) - }) + } }) } diff --git a/tests/mover.go b/tests/mover.go index 470eb4216..282a18502 100644 --- a/tests/mover.go +++ b/tests/mover.go @@ -20,233 +20,240 @@ import ( func TestMover(t *testing.T, store types.Storager) { Convey("Given a basic Storager", t, func() { - Convey("When Move a file", func() { - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - content, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) - src := uuid.New().String() - - _, err := store.Write(src, bytes.NewReader(content), size) - if err != nil { - t.Fatal(err) - } - - defer func() { - err = store.Delete(src) + f := store.Features() + if f.Move && f.Write && f.Read && f.Delete && f.Stat { + Convey("When Move a file", func() { + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + content, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) + src := uuid.New().String() + + _, err := store.Write(src, bytes.NewReader(content), size) if err != nil { - t.Error(err) + t.Fatal(err) } - }() - dst := uuid.New().String() - err = store.Move(src, dst) + defer func() { + err = store.Delete(src) + if err != nil { + t.Error(err) + } + }() - defer func() { - err = store.Delete(dst) - if err != nil { - t.Error(err) - } - }() + dst := uuid.New().String() + err = store.Move(src, dst) - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) + defer func() { + err = store.Delete(dst) + if err != nil { + t.Error(err) + } + }() - Convey("Stat should get src object not exist", func() { - _, err := store.Stat(src) - - Convey("The error should be ErrObjectNotExist", func() { - So(errors.Is(err, services.ErrObjectNotExist), ShouldBeTrue) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) }) - }) - Convey("Read should get dst object data without error", func() { - var buf bytes.Buffer - n, err := store.Read(dst, &buf) + Convey("Stat should get src object not exist", func() { + _, err := store.Stat(src) - Convey("The error should be nil", func() { - So(err, ShouldBeNil) + Convey("The error should be ErrObjectNotExist", func() { + So(errors.Is(err, services.ErrObjectNotExist), ShouldBeTrue) + }) }) - Convey("The content should be match", func() { - So(buf, ShouldNotBeNil) - So(n, ShouldEqual, size) - So(md5.Sum(buf.Bytes()), ShouldResemble, md5.Sum(content)) + Convey("Read should get dst object data without error", func() { + var buf bytes.Buffer + n, err := store.Read(dst, &buf) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("The content should be match", func() { + So(buf, ShouldNotBeNil) + So(n, ShouldEqual, size) + So(md5.Sum(buf.Bytes()), ShouldResemble, md5.Sum(content)) + }) }) }) - }) - - Convey("When Move to an existing file", func() { - srcSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - content, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), srcSize)) - src := uuid.New().String() - _, err := store.Write(src, bytes.NewReader(content), srcSize) - if err != nil { - t.Fatal(err) - } + Convey("When Move to an existing file", func() { + srcSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + content, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), srcSize)) + src := uuid.New().String() - defer func() { - err = store.Delete(src) + _, err := store.Write(src, bytes.NewReader(content), srcSize) if err != nil { - t.Error(err) + t.Fatal(err) } - }() - dstSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - r := io.LimitReader(randbytes.NewRand(), dstSize) - dst := uuid.New().String() + defer func() { + err = store.Delete(src) + if err != nil { + t.Error(err) + } + }() - _, err = store.Write(dst, r, dstSize) - if err != nil { - t.Fatal(err) - } + dstSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + r := io.LimitReader(randbytes.NewRand(), dstSize) + dst := uuid.New().String() - defer func() { - err = store.Delete(dst) + _, err = store.Write(dst, r, dstSize) if err != nil { - t.Error(err) + t.Fatal(err) } - }() - err = store.Move(src, dst) - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) + defer func() { + err = store.Delete(dst) + if err != nil { + t.Error(err) + } + }() - Convey("Stat should get src object not exist", func() { - _, err := store.Stat(src) - - Convey("The error should be ErrObjectNotExist", func() { - So(errors.Is(err, services.ErrObjectNotExist), ShouldBeTrue) + err = store.Move(src, dst) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) }) - }) - Convey("Read should get dst object data without error", func() { - var buf bytes.Buffer - n, err := store.Read(dst, &buf) + Convey("Stat should get src object not exist", func() { + _, err := store.Stat(src) - Convey("The error should be nil", func() { - So(err, ShouldBeNil) + Convey("The error should be ErrObjectNotExist", func() { + So(errors.Is(err, services.ErrObjectNotExist), ShouldBeTrue) + }) }) - Convey("The content should be match", func() { - So(buf, ShouldNotBeNil) - So(n, ShouldEqual, srcSize) - So(md5.Sum(buf.Bytes()), ShouldResemble, md5.Sum(content)) + Convey("Read should get dst object data without error", func() { + var buf bytes.Buffer + n, err := store.Read(dst, &buf) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("The content should be match", func() { + So(buf, ShouldNotBeNil) + So(n, ShouldEqual, srcSize) + So(md5.Sum(buf.Bytes()), ShouldResemble, md5.Sum(content)) + }) }) }) - }) + } }) } func TestMoverWithDir(t *testing.T, store types.Storager) { Convey("Given a basic Storager", t, func() { - Convey("When Move to an existing dir", func() { - - srcSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - r := io.LimitReader(randbytes.NewRand(), srcSize) - src := uuid.New().String() + f := store.Features() + if f.Move && f.CreateDir && !f.VirtualDir && f.Write && f.Delete { + Convey("When Move to an existing dir", func() { + srcSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + r := io.LimitReader(randbytes.NewRand(), srcSize) + src := uuid.New().String() - _, err := store.Write(src, r, srcSize) - if err != nil { - t.Fatal(err) - } - - defer func() { - err = store.Delete(src) + _, err := store.Write(src, r, srcSize) if err != nil { - t.Error(err) + t.Fatal(err) } - }() - dst := uuid.New().String() - _, err = store.CreateDir(dst) - if err != nil { - t.Fatal(err) - } + defer func() { + err = store.Delete(src) + if err != nil { + t.Error(err) + } + }() - defer func() { - err = store.Delete(dst, pairs.WithObjectMode(types.ModeDir)) + dst := uuid.New().String() + _, err = store.CreateDir(dst) if err != nil { - t.Error(err) + t.Fatal(err) } - }() - err = store.Move(src, dst) - Convey("The error should be ErrObjectModeInvalid", func() { - So(errors.Is(err, services.ErrObjectModeInvalid), ShouldBeTrue) + defer func() { + err = store.Delete(dst, pairs.WithObjectMode(types.ModeDir)) + if err != nil { + t.Error(err) + } + }() + + err = store.Move(src, dst) + Convey("The error should be ErrObjectModeInvalid", func() { + So(errors.Is(err, services.ErrObjectModeInvalid), ShouldBeTrue) + }) }) - }) + } }) } func TestMoverWithVirtualDir(t *testing.T, store types.Storager) { Convey("Given a basic Storager", t, func() { - Convey("When Move to an existing dir", func() { - - srcSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - r := io.LimitReader(randbytes.NewRand(), srcSize) - src := uuid.New().String() - - _, err := store.Write(src, r, srcSize) - if err != nil { - t.Fatal(err) - } + f := store.Features() + if f.Move && f.CreateDir && f.VirtualDir && f.Write && f.Delete && f.Stat { + Convey("When Move to an existing dir", func() { + srcSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + r := io.LimitReader(randbytes.NewRand(), srcSize) + src := uuid.New().String() - defer func() { - err = store.Delete(src) + _, err := store.Write(src, r, srcSize) if err != nil { - t.Error(err) + t.Fatal(err) } - }() - dst := uuid.New().String() - _, err = store.CreateDir(dst) - if err != nil { - t.Fatal(err) - } + defer func() { + err = store.Delete(src) + if err != nil { + t.Error(err) + } + }() - defer func() { - err = store.Delete(dst, pairs.WithObjectMode(types.ModeDir)) + dst := uuid.New().String() + _, err = store.CreateDir(dst) if err != nil { - t.Error(err) + t.Fatal(err) } - }() - err = store.Move(src, dst) + defer func() { + err = store.Delete(dst, pairs.WithObjectMode(types.ModeDir)) + if err != nil { + t.Error(err) + } + }() - defer func() { - err = store.Delete(dst) - if err != nil { - t.Error(err) - } - }() + err = store.Move(src, dst) - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) - - Convey("Stat should get dst object without error", func() { - o, err := store.Stat(dst) - - So(err, ShouldBeNil) - So(o, ShouldNotBeNil) + defer func() { + err = store.Delete(dst) + if err != nil { + t.Error(err) + } + }() - Convey("The Object Mode should be read", func() { - So(o.Mode.IsRead(), ShouldBeTrue) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) }) - Convey("The path and size should be match", func() { + Convey("Stat should get dst object without error", func() { + o, err := store.Stat(dst) + + So(err, ShouldBeNil) So(o, ShouldNotBeNil) - So(o.Path, ShouldEqual, dst) - osize, ok := o.GetContentLength() - So(ok, ShouldBeTrue) - So(osize, ShouldEqual, srcSize) + Convey("The Object Mode should be read", func() { + So(o.Mode.IsRead(), ShouldBeTrue) + }) + + Convey("The path and size should be match", func() { + So(o, ShouldNotBeNil) + So(o.Path, ShouldEqual, dst) + + osize, ok := o.GetContentLength() + So(ok, ShouldBeTrue) + So(osize, ShouldEqual, srcSize) + }) }) }) - }) + } }) } diff --git a/tests/multipart_http_signer.go b/tests/multipart_http_signer.go index 27ed8619e..194e98fbe 100644 --- a/tests/multipart_http_signer.go +++ b/tests/multipart_http_signer.go @@ -19,184 +19,194 @@ import ( func TestMultipartHTTPSigner(t *testing.T, store types.Storager) { Convey("Given a basic Storager", t, func() { - Convey("When CreateMultipart via QuerySignHTTPCreateMultipart", func() { - path := uuid.New().String() - req, err := store.QuerySignHTTPCreateMultipart(path, time.Duration(time.Hour)) - - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - - So(req, ShouldNotBeNil) - So(req.URL, ShouldNotBeNil) - }) - - client := http.Client{} - _, err = client.Do(req) - - Convey("The request returned error should be nil", func() { - So(err, ShouldBeNil) + f := store.Features() + + if f.QuerySignHTTPCreateMultipart && f.Delete && f.List { + Convey("When CreateMultipart via QuerySignHTTPCreateMultipart", func() { + path := uuid.New().String() + req, err := store.QuerySignHTTPCreateMultipart(path, time.Duration(time.Hour)) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + + So(req, ShouldNotBeNil) + So(req.URL, ShouldNotBeNil) + }) + + client := http.Client{} + _, err = client.Do(req) + + Convey("The request returned error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("List with ModePart should get the object without error", func() { + it, err := store.List(path, pairs.WithListMode(types.ListModePart)) + + So(err, ShouldBeNil) + + o, err := it.Next() + So(err, ShouldBeNil) + So(o, ShouldNotBeNil) + So(o.Path, ShouldEqual, path) + }) + + defer func() { + it, err := store.List(path, pairs.WithListMode(types.ListModePart)) + if err != nil { + t.Error(err) + } + + o, err := it.Next() + if err != nil { + t.Error(err) + } + + err = store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) + if err != nil { + t.Error(err) + } + }() }) + } - Convey("List with ModePart should get the object without error", func() { - it, err := store.List(path, pairs.WithListMode(types.ListModePart)) - - So(err, ShouldBeNil) - - o, err := it.Next() - So(err, ShouldBeNil) - So(o, ShouldNotBeNil) - So(o.Path, ShouldEqual, path) - }) - - defer func() { - it, err := store.List(path, pairs.WithListMode(types.ListModePart)) + if f.QuerySignHTTPWriteMultipart && f.CreateMultipart && f.Delete { + Convey("When WriteMultipart via QuerySignHTTPWriteMultipart", func() { + path := uuid.New().String() + o, err := store.CreateMultipart(path) if err != nil { t.Error(err) } - o, err := it.Next() - if err != nil { - t.Error(err) - } + defer func() { + err := store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) + if err != nil { + t.Error(err) + } + }() - err = store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) - if err != nil { - t.Error(err) - } - }() - }) - - Convey("When WriteMultipart via QuerySignHTTPWriteMultipart", func() { - path := uuid.New().String() - o, err := store.CreateMultipart(path) - if err != nil { - t.Error(err) - } - - defer func() { - err := store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) + size := rand.Int63n(4 * 1024 * 1024) + content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) if err != nil { t.Error(err) } - }() - size := rand.Int63n(4 * 1024 * 1024) - content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) - if err != nil { - t.Error(err) - } + req, err := store.QuerySignHTTPWriteMultipart(o, size, 0, time.Duration(time.Hour)) - req, err := store.QuerySignHTTPWriteMultipart(o, size, 0, time.Duration(time.Hour)) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) - Convey("The error should be nil", func() { - So(err, ShouldBeNil) + So(req, ShouldNotBeNil) + So(req.URL, ShouldNotBeNil) + }) - So(req, ShouldNotBeNil) - So(req.URL, ShouldNotBeNil) - }) + req.Body = io.NopCloser(bytes.NewReader(content)) - req.Body = io.NopCloser(bytes.NewReader(content)) + client := http.Client{} + resp, err := client.Do(req) - client := http.Client{} - resp, err := client.Do(req) + Convey("The request returned error should be nil", func() { + So(err, ShouldBeNil) + So(resp, ShouldNotBeNil) + }) - Convey("The request returned error should be nil", func() { - So(err, ShouldBeNil) - So(resp, ShouldNotBeNil) + Convey("The size should be match", func() { + So(resp.Request.ContentLength, ShouldEqual, size) + }) }) + } - Convey("The size should be match", func() { - So(resp.Request.ContentLength, ShouldEqual, size) - }) - }) + if f.QuerySignHTTPListMultipart && f.CreateMultipart && f.Delete { + Convey("When ListMultiPart via QuerySignHTTPListMultiPart", func() { + path := uuid.New().String() + o, err := store.CreateMultipart(path) + if err != nil { + t.Error(err) + } + + defer func() { + err := store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) + if err != nil { + t.Error(err) + } + }() - Convey("When ListMultiPart via QuerySignHTTPListMultiPart", func() { - path := uuid.New().String() - o, err := store.CreateMultipart(path) - if err != nil { - t.Error(err) - } + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + partNumber := rand.Intn(1000) // Choose a random part number from [0, 1000) + r := io.LimitReader(randbytes.NewRand(), size) - defer func() { - err := store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) + _, _, err = store.WriteMultipart(o, r, size, partNumber) if err != nil { t.Error(err) } - }() - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - partNumber := rand.Intn(1000) // Choose a random part number from [0, 1000) - r := io.LimitReader(randbytes.NewRand(), size) + req, err := store.QuerySignHTTPListMultipart(o, time.Duration(time.Hour)) - _, _, err = store.WriteMultipart(o, r, size, partNumber) - if err != nil { - t.Error(err) - } + Convey("The error should be nil", func() { + So(err, ShouldBeNil) - req, err := store.QuerySignHTTPListMultipart(o, time.Duration(time.Hour)) + So(req, ShouldNotBeNil) + So(req.URL, ShouldNotBeNil) + }) - Convey("The error should be nil", func() { - So(err, ShouldBeNil) + client := http.Client{} + _, err = client.Do(req) - So(req, ShouldNotBeNil) - So(req.URL, ShouldNotBeNil) + Convey("The request returned error should be nil", func() { + So(err, ShouldBeNil) + }) }) + } - client := http.Client{} - _, err = client.Do(req) + if f.QuerySignHTTPCompleteMultipart && f.CreateMultipart && f.Delete && f.Stat { + Convey("When CompletePart via QuerySignHTTPCompletePart", func() { + path := uuid.New().String() + o, err := store.CreateMultipart(path) + if err != nil { + t.Error(err) + } - Convey("The request returned error should be nil", func() { - So(err, ShouldBeNil) - }) - }) + defer func() { + err := store.Delete(path) + if err != nil { + t.Error(err) + } + }() - Convey("When CompletePart via QuerySignHTTPCompletePart", func() { - path := uuid.New().String() - o, err := store.CreateMultipart(path) - if err != nil { - t.Error(err) - } + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + // Set 0 to `partNumber` here as the part numbers must be continuous for `CompleteMultipartUpload` in `cos` which is different with other storages. + partNumber := 0 + r := io.LimitReader(randbytes.NewRand(), size) - defer func() { - err := store.Delete(path) + _, part, err := store.WriteMultipart(o, r, size, partNumber) if err != nil { t.Error(err) } - }() - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - // Set 0 to `partNumber` here as the part numbers must be continuous for `CompleteMultipartUpload` in `cos` which is different with other storages. - partNumber := 0 - r := io.LimitReader(randbytes.NewRand(), size) + req, err := store.QuerySignHTTPCompleteMultipart(o, []*types.Part{part}, time.Duration(time.Hour)) - _, part, err := store.WriteMultipart(o, r, size, partNumber) - if err != nil { - t.Error(err) - } + Convey("The error should be nil", func() { + So(err, ShouldBeNil) - req, err := store.QuerySignHTTPCompleteMultipart(o, []*types.Part{part}, time.Duration(time.Hour)) + So(req, ShouldNotBeNil) + So(req.URL, ShouldNotBeNil) + }) - Convey("The error should be nil", func() { - So(err, ShouldBeNil) + client := http.Client{} + _, err = client.Do(req) - So(req, ShouldNotBeNil) - So(req.URL, ShouldNotBeNil) - }) - - client := http.Client{} - _, err = client.Do(req) - - Convey("The request returned error should be nil", func() { - So(err, ShouldBeNil) - }) + Convey("The request returned error should be nil", func() { + So(err, ShouldBeNil) + }) - Convey("The object should be readable after complete", func() { - ro, err := store.Stat(path) + Convey("The object should be readable after complete", func() { + ro, err := store.Stat(path) - So(err, ShouldBeNil) - So(ro.Mode.IsRead(), ShouldBeTrue) - So(ro.Mode.IsPart(), ShouldBeFalse) + So(err, ShouldBeNil) + So(ro.Mode.IsRead(), ShouldBeTrue) + So(ro.Mode.IsPart(), ShouldBeFalse) + }) }) - }) + } }) } diff --git a/tests/multiparter.go b/tests/multiparter.go index 781b1dc1a..d9af54c35 100644 --- a/tests/multiparter.go +++ b/tests/multiparter.go @@ -16,294 +16,297 @@ import ( func TestMultiparter(t *testing.T, store types.Storager) { Convey("Given a basic Storager", t, func() { - Convey("When CreateMultipart", func() { - path := uuid.New().String() - o, err := store.CreateMultipart(path) - - Convey("The first returned error should be nil", func() { - So(err, ShouldBeNil) + f := store.Features() + if f.CreateMultipart && f.WriteMultipart && f.ListMultipart && f.CompleteMultipart && f.Create && f.Delete && f.Stat { + Convey("When CreateMultipart", func() { + path := uuid.New().String() + o, err := store.CreateMultipart(path) + + Convey("The first returned error should be nil", func() { + So(err, ShouldBeNil) + }) + + defer func(multipartID string) { + err := store.Delete(path, pairs.WithMultipartID(multipartID)) + if err != nil { + t.Error(err) + } + }(o.MustGetMultipartID()) + + o, err = store.CreateMultipart(path) + + Convey("The second returned error also should be nil", func() { + So(err, ShouldBeNil) + }) + + defer func() { + err := store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) + if err != nil { + t.Error(err) + } + }() + + Convey("The Object Mode should be part", func() { + // Multipart object's mode must be Part. + So(o.Mode.IsPart(), ShouldBeTrue) + // Multipart object's mode must not be Read. + So(o.Mode.IsRead(), ShouldBeFalse) + }) + + Convey("The Object must have multipart id", func() { + // Multipart object must have multipart id. + _, ok := o.GetMultipartID() + So(ok, ShouldBeTrue) + }) }) - defer func(multipartID string) { - err := store.Delete(path, pairs.WithMultipartID(multipartID)) + Convey("When Delete with multipart id", func() { + path := uuid.New().String() + o, err := store.CreateMultipart(path) if err != nil { t.Error(err) } - }(o.MustGetMultipartID()) - o, err = store.CreateMultipart(path) + err = store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) + Convey("The first returned error should be nil", func() { + So(err, ShouldBeNil) + }) - Convey("The second returned error also should be nil", func() { - So(err, ShouldBeNil) + err = store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) + Convey("The second returned error also should be nil", func() { + So(err, ShouldBeNil) + }) }) - defer func() { - err := store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) + Convey("When Stat with multipart id", func() { + path := uuid.New().String() + o, err := store.CreateMultipart(path) if err != nil { t.Error(err) } - }() - Convey("The Object Mode should be part", func() { - // Multipart object's mode must be Part. - So(o.Mode.IsPart(), ShouldBeTrue) - // Multipart object's mode must not be Read. - So(o.Mode.IsRead(), ShouldBeFalse) + multipartId := o.MustGetMultipartID() + + defer func() { + err := store.Delete(path, pairs.WithMultipartID(multipartId)) + if err != nil { + t.Error(err) + } + }() + + mo, err := store.Stat(path, pairs.WithMultipartID(multipartId)) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + So(mo, ShouldNotBeNil) + }) + + Convey("The Object Mode should be part", func() { + // Multipart object's mode must be Part. + So(mo.Mode.IsPart(), ShouldBeTrue) + // Multipart object's mode must not be Read. + So(mo.Mode.IsRead(), ShouldBeFalse) + }) + + Convey("The Object must have multipart id", func() { + // Multipart object must have multipart id. + mid, ok := mo.GetMultipartID() + So(ok, ShouldBeTrue) + So(mid, ShouldEqual, multipartId) + }) }) - Convey("The Object must have multipart id", func() { - // Multipart object must have multipart id. - _, ok := o.GetMultipartID() - So(ok, ShouldBeTrue) - }) - }) - - Convey("When Delete with multipart id", func() { - path := uuid.New().String() - o, err := store.CreateMultipart(path) - if err != nil { - t.Error(err) - } - - err = store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) - Convey("The first returned error should be nil", func() { - So(err, ShouldBeNil) - }) + Convey("When Create with multipart id", func() { + path := uuid.New().String() + o, err := store.CreateMultipart(path) + if err != nil { + t.Error(err) + } - err = store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) - Convey("The second returned error also should be nil", func() { - So(err, ShouldBeNil) + multipartId := o.MustGetMultipartID() + + defer func() { + err := store.Delete(path, pairs.WithMultipartID(multipartId)) + if err != nil { + t.Error(err) + } + }() + + mo := store.Create(path, pairs.WithMultipartID(multipartId)) + + Convey("The Object Mode should be part", func() { + // Multipart object's mode must be Part. + So(mo.Mode.IsPart(), ShouldBeTrue) + // Multipart object's mode must not be Read. + So(mo.Mode.IsRead(), ShouldBeFalse) + }) + + Convey("The Object must have multipart id", func() { + // Multipart object must have multipart id. + mid, ok := mo.GetMultipartID() + So(ok, ShouldBeTrue) + So(mid, ShouldEqual, multipartId) + }) }) - }) - - Convey("When Stat with multipart id", func() { - path := uuid.New().String() - o, err := store.CreateMultipart(path) - if err != nil { - t.Error(err) - } - - multipartId := o.MustGetMultipartID() - defer func() { - err := store.Delete(path, pairs.WithMultipartID(multipartId)) + Convey("When WriteMultipart", func() { + path := uuid.New().String() + o, err := store.CreateMultipart(path) if err != nil { t.Error(err) } - }() - mo, err := store.Stat(path, pairs.WithMultipartID(multipartId)) + defer func() { + err := store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) + if err != nil { + t.Error(err) + } + }() - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - So(mo, ShouldNotBeNil) - }) + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + r := io.LimitReader(randbytes.NewRand(), size) - Convey("The Object Mode should be part", func() { - // Multipart object's mode must be Part. - So(mo.Mode.IsPart(), ShouldBeTrue) - // Multipart object's mode must not be Read. - So(mo.Mode.IsRead(), ShouldBeFalse) - }) + n, part, err := store.WriteMultipart(o, r, size, 0) - Convey("The Object must have multipart id", func() { - // Multipart object must have multipart id. - mid, ok := mo.GetMultipartID() - So(ok, ShouldBeTrue) - So(mid, ShouldEqual, multipartId) - }) - }) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) - Convey("When Create with multipart id", func() { - path := uuid.New().String() - o, err := store.CreateMultipart(path) - if err != nil { - t.Error(err) - } + Convey("The part should not be nil", func() { + So(part, ShouldNotBeNil) + }) - multipartId := o.MustGetMultipartID() + Convey("The size should be match", func() { + So(n, ShouldEqual, size) + }) + }) - defer func() { - err := store.Delete(path, pairs.WithMultipartID(multipartId)) + Convey("When ListMultiPart", func() { + path := uuid.New().String() + o, err := store.CreateMultipart(path) if err != nil { t.Error(err) } - }() - - mo := store.Create(path, pairs.WithMultipartID(multipartId)) - - Convey("The Object Mode should be part", func() { - // Multipart object's mode must be Part. - So(mo.Mode.IsPart(), ShouldBeTrue) - // Multipart object's mode must not be Read. - So(mo.Mode.IsRead(), ShouldBeFalse) - }) - Convey("The Object must have multipart id", func() { - // Multipart object must have multipart id. - mid, ok := mo.GetMultipartID() - So(ok, ShouldBeTrue) - So(mid, ShouldEqual, multipartId) - }) - }) + defer func() { + err := store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) + if err != nil { + t.Error(err) + } + }() - Convey("When WriteMultipart", func() { - path := uuid.New().String() - o, err := store.CreateMultipart(path) - if err != nil { - t.Error(err) - } + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + partNumber := rand.Intn(1000) // Choose a random part number from [0, 1000) + r := io.LimitReader(randbytes.NewRand(), size) - defer func() { - err := store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) + _, _, err = store.WriteMultipart(o, r, size, partNumber) if err != nil { t.Error(err) } - }() - - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - r := io.LimitReader(randbytes.NewRand(), size) - - n, part, err := store.WriteMultipart(o, r, size, 0) - - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) - Convey("The part should not be nil", func() { - So(part, ShouldNotBeNil) + it, err := store.ListMultipart(o) + + Convey("ListMultipart error should be nil", func() { + So(err, ShouldBeNil) + So(it, ShouldNotBeNil) + }) + + p, err := it.Next() + Convey("Next error should be nil", func() { + So(err, ShouldBeNil) + So(p, ShouldNotBeNil) + }) + Convey("The part number and size should be match", func() { + So(p.Index, ShouldEqual, partNumber) + So(p.Size, ShouldEqual, size) + }) }) - Convey("The size should be match", func() { - So(n, ShouldEqual, size) - }) - }) - - Convey("When ListMultiPart", func() { - path := uuid.New().String() - o, err := store.CreateMultipart(path) - if err != nil { - t.Error(err) - } - - defer func() { - err := store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) + Convey("When List with part type", func() { + path := uuid.New().String() + o, err := store.CreateMultipart(path) if err != nil { t.Error(err) } - }() - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - partNumber := rand.Intn(1000) // Choose a random part number from [0, 1000) - r := io.LimitReader(randbytes.NewRand(), size) + defer func() { + err := store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) + if err != nil { + t.Error(err) + } + }() - _, _, err = store.WriteMultipart(o, r, size, partNumber) - if err != nil { - t.Error(err) - } + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + partNumber := rand.Intn(1000) // Choose a random part number from [0, 1000) + r := io.LimitReader(randbytes.NewRand(), size) - it, err := store.ListMultipart(o) - - Convey("ListMultipart error should be nil", func() { - So(err, ShouldBeNil) - So(it, ShouldNotBeNil) - }) + _, _, err = store.WriteMultipart(o, r, size, partNumber) + if err != nil { + t.Error(err) + } - p, err := it.Next() - Convey("Next error should be nil", func() { - So(err, ShouldBeNil) - So(p, ShouldNotBeNil) + it, err := store.List("", pairs.WithListMode(types.ListModePart)) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + Convey("The iterator should not be nil", func() { + So(it, ShouldNotBeNil) + }) + + mo, err := it.Next() + Convey("Next error should be nil", func() { + So(err, ShouldBeNil) + So(mo, ShouldNotBeNil) + }) + Convey("The path and multipart id should be match", func() { + So(mo.Path, ShouldEqual, path) + So(mo.Mode.IsPart(), ShouldBeTrue) + + // Multipart object must have multipart id. + mid, ok := mo.GetMultipartID() + So(ok, ShouldBeTrue) + So(mid, ShouldEqual, o.MustGetMultipartID()) + }) }) - Convey("The part number and size should be match", func() { - So(p.Index, ShouldEqual, partNumber) - So(p.Size, ShouldEqual, size) - }) - }) - - Convey("When List with part type", func() { - path := uuid.New().String() - o, err := store.CreateMultipart(path) - if err != nil { - t.Error(err) - } - defer func() { - err := store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) + Convey("When CompletePart", func() { + path := uuid.New().String() + o, err := store.CreateMultipart(path) if err != nil { t.Error(err) } - }() - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - partNumber := rand.Intn(1000) // Choose a random part number from [0, 1000) - r := io.LimitReader(randbytes.NewRand(), size) + defer func() { + err := store.Delete(path) + if err != nil { + t.Error(err) + } + }() - _, _, err = store.WriteMultipart(o, r, size, partNumber) - if err != nil { - t.Error(err) - } + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + // Set 0 to `partNumber` here as the part numbers must be continuous for `CompleteMultipartUpload` in `cos` which is different with other storages. + partNumber := 0 + r := io.LimitReader(randbytes.NewRand(), size) - it, err := store.List("", pairs.WithListMode(types.ListModePart)) - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) - Convey("The iterator should not be nil", func() { - So(it, ShouldNotBeNil) - }) - - mo, err := it.Next() - Convey("Next error should be nil", func() { - So(err, ShouldBeNil) - So(mo, ShouldNotBeNil) - }) - Convey("The path and multipart id should be match", func() { - So(mo.Path, ShouldEqual, path) - So(mo.Mode.IsPart(), ShouldBeTrue) - - // Multipart object must have multipart id. - mid, ok := mo.GetMultipartID() - So(ok, ShouldBeTrue) - So(mid, ShouldEqual, o.MustGetMultipartID()) - }) - }) - - Convey("When CompletePart", func() { - path := uuid.New().String() - o, err := store.CreateMultipart(path) - if err != nil { - t.Error(err) - } - - defer func() { - err := store.Delete(path) + _, part, err := store.WriteMultipart(o, r, size, partNumber) if err != nil { t.Error(err) } - }() - - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - // Set 0 to `partNumber` here as the part numbers must be continuous for `CompleteMultipartUpload` in `cos` which is different with other storages. - partNumber := 0 - r := io.LimitReader(randbytes.NewRand(), size) - _, part, err := store.WriteMultipart(o, r, size, partNumber) - if err != nil { - t.Error(err) - } + err = store.CompleteMultipart(o, []*types.Part{part}) - err = store.CompleteMultipart(o, []*types.Part{part}) - - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) - Convey("The object should be readable after complete", func() { - ro, err := store.Stat(path) + Convey("The object should be readable after complete", func() { + ro, err := store.Stat(path) - So(err, ShouldBeNil) - So(ro.Mode.IsRead(), ShouldBeTrue) - So(ro.Mode.IsPart(), ShouldBeFalse) + So(err, ShouldBeNil) + So(ro.Mode.IsRead(), ShouldBeTrue) + So(ro.Mode.IsPart(), ShouldBeFalse) + }) }) - }) + } }) } diff --git a/tests/storage_http_signer.go b/tests/storage_http_signer.go index ad0dd9620..ec335e995 100644 --- a/tests/storage_http_signer.go +++ b/tests/storage_http_signer.go @@ -21,171 +21,185 @@ import ( func TestStorageHTTPSignerRead(t *testing.T, store types.Storager) { Convey("Given a basic Storager", t, func() { + So(store, ShouldNotBeNil) - Convey("When Read via QuerySignHTTPRead", func() { - size := rand.Int63n(4 * 1024 * 1024) - content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) - if err != nil { - t.Error(err) - } - - path := uuid.New().String() - _, err = store.Write(path, bytes.NewReader(content), size) - if err != nil { - t.Error(err) - } - defer func() { - err := store.Delete(path) + f := store.Features() + if f.QuerySignHTTPRead && f.Write && f.Delete { + Convey("When Read via QuerySignHTTPRead", func() { + size := rand.Int63n(4 * 1024 * 1024) + content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) if err != nil { t.Error(err) } - }() - req, err := store.QuerySignHTTPRead(path, time.Duration(time.Hour)) + path := uuid.New().String() + _, err = store.Write(path, bytes.NewReader(content), size) + if err != nil { + t.Error(err) + } + defer func() { + err := store.Delete(path) + if err != nil { + t.Error(err) + } + }() - Convey("The error should be nil", func() { - So(err, ShouldBeNil) + req, err := store.QuerySignHTTPRead(path, time.Duration(time.Hour)) - So(req, ShouldNotBeNil) - So(req.URL, ShouldNotBeNil) - }) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) - client := http.Client{} - resp, err := client.Do(req) - Convey("The request returned error should be nil", func() { - So(err, ShouldBeNil) - So(resp, ShouldNotBeNil) - }) + So(req, ShouldNotBeNil) + So(req.URL, ShouldNotBeNil) + }) - defer resp.Body.Close() + client := http.Client{} + resp, err := client.Do(req) + Convey("The request returned error should be nil", func() { + So(err, ShouldBeNil) + So(resp, ShouldNotBeNil) + }) + + defer resp.Body.Close() - buf, err := io.ReadAll(resp.Body) - Convey("The content should be match", func() { - So(err, ShouldBeNil) - So(buf, ShouldNotBeNil) + buf, err := io.ReadAll(resp.Body) + Convey("The content should be match", func() { + So(err, ShouldBeNil) + So(buf, ShouldNotBeNil) - So(resp.ContentLength, ShouldEqual, size) - So(sha256.Sum256(buf), ShouldResemble, sha256.Sum256(content)) + So(resp.ContentLength, ShouldEqual, size) + So(sha256.Sum256(buf), ShouldResemble, sha256.Sum256(content)) + }) }) - }) + } }) } func TestStorageHTTPSignerWrite(t *testing.T, store types.Storager) { Convey("Given a basic Storager", t, func() { + So(store, ShouldNotBeNil) - Convey("When Write via QuerySignHTTPWrite", func() { - size := rand.Int63n(4 * 1024 * 1024) - content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) - if err != nil { - t.Error(err) - } + f := store.Features() + if f.QuerySignHTTPWrite && f.Read && f.Delete { + Convey("When Write via QuerySignHTTPWrite", func() { + size := rand.Int63n(4 * 1024 * 1024) + content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) + if err != nil { + t.Error(err) + } - path := uuid.New().String() - req, err := store.QuerySignHTTPWrite(path, size, time.Duration(time.Hour)) + path := uuid.New().String() + req, err := store.QuerySignHTTPWrite(path, size, time.Duration(time.Hour)) - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - So(req, ShouldNotBeNil) - So(req.URL, ShouldNotBeNil) - }) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + So(req, ShouldNotBeNil) + So(req.URL, ShouldNotBeNil) + }) - req.Body = io.NopCloser(bytes.NewReader(content)) + req.Body = io.NopCloser(bytes.NewReader(content)) - client := http.Client{} - _, err = client.Do(req) - Convey("The request returned error should be nil", func() { - So(err, ShouldBeNil) - }) + client := http.Client{} + _, err = client.Do(req) + Convey("The request returned error should be nil", func() { + So(err, ShouldBeNil) + }) - defer func() { - err := store.Delete(path) - if err != nil { - t.Error(err) - } - }() + defer func() { + err := store.Delete(path) + if err != nil { + t.Error(err) + } + }() - Convey("Read should get object data without error", func() { - var buf bytes.Buffer - n, err := store.Read(path, &buf) + Convey("Read should get object data without error", func() { + var buf bytes.Buffer + n, err := store.Read(path, &buf) - Convey("The content should be match", func() { - So(err, ShouldBeNil) - So(buf, ShouldNotBeNil) + Convey("The content should be match", func() { + So(err, ShouldBeNil) + So(buf, ShouldNotBeNil) - So(n, ShouldEqual, size) - So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(content)) + So(n, ShouldEqual, size) + So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(content)) + }) }) }) - }) + } }) } func TestStorageHTTPSignerDelete(t *testing.T, store types.Storager) { Convey("Given a basic Storager", t, func() { - Convey("When Delete via QuerySignHTTPDelete", func() { - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - r := io.LimitReader(randbytes.NewRand(), size) + f := store.Features() - path := uuid.New().String() - _, err := store.Write(path, r, size) - if err != nil { - t.Error(err) - } + if f.QuerySignHTTPDelete && f.Write && f.Stat { + Convey("When Delete via QuerySignHTTPDelete", func() { + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + r := io.LimitReader(randbytes.NewRand(), size) - req, err := store.QuerySignHTTPDelete(path, time.Duration(time.Hour)) + path := uuid.New().String() + _, err := store.Write(path, r, size) + if err != nil { + t.Error(err) + } - Convey("The error should be nil", func() { - So(err, ShouldBeNil) + req, err := store.QuerySignHTTPDelete(path, time.Duration(time.Hour)) - So(req, ShouldNotBeNil) - So(req.URL, ShouldNotBeNil) - }) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) - client := http.Client{} - _, err = client.Do(req) + So(req, ShouldNotBeNil) + So(req.URL, ShouldNotBeNil) + }) - Convey("The request returned error should be nil", func() { - So(err, ShouldBeNil) - }) + client := http.Client{} + _, err = client.Do(req) + + Convey("The request returned error should be nil", func() { + So(err, ShouldBeNil) + }) - Convey("Stat should get nil Object and ObjectNotFound error", func() { - o, err := store.Stat(path) + Convey("Stat should get nil Object and ObjectNotFound error", func() { + o, err := store.Stat(path) - So(errors.Is(err, services.ErrObjectNotExist), ShouldBeTrue) - So(o, ShouldBeNil) + So(errors.Is(err, services.ErrObjectNotExist), ShouldBeTrue) + So(o, ShouldBeNil) + }) }) - }) + } - Convey("When Delete with multipart id via QuerySignHTTPDelete", func() { - path := uuid.New().String() - o, err := store.CreateMultipart(path) - if err != nil { - t.Error(err) - } + if f.CreateMultipart && f.QuerySignHTTPDelete { + Convey("When Delete with multipart id via QuerySignHTTPDelete", func() { + path := uuid.New().String() + o, err := store.CreateMultipart(path) + if err != nil { + t.Error(err) + } - req, err := store.QuerySignHTTPDelete(path, time.Duration(time.Hour), pairs.WithMultipartID(o.MustGetMultipartID())) + req, err := store.QuerySignHTTPDelete(path, time.Duration(time.Hour), pairs.WithMultipartID(o.MustGetMultipartID())) - Convey("The error should be nil", func() { - So(err, ShouldBeNil) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) - So(req, ShouldNotBeNil) - So(req.URL, ShouldNotBeNil) - }) + So(req, ShouldNotBeNil) + So(req.URL, ShouldNotBeNil) + }) - client := http.Client{} - _, err = client.Do(req) + client := http.Client{} + _, err = client.Do(req) - Convey("The first request returned error should be nil", func() { - So(err, ShouldBeNil) - }) + Convey("The first request returned error should be nil", func() { + So(err, ShouldBeNil) + }) - _, err = client.Do(req) + _, err = client.Do(req) - Convey("The second request returned error should be nil", func() { - So(err, ShouldBeNil) + Convey("The second request returned error should be nil", func() { + So(err, ShouldBeNil) + }) }) - }) + } }) } diff --git a/tests/storager.go b/tests/storager.go index 20fd643f9..fada15933 100644 --- a/tests/storager.go +++ b/tests/storager.go @@ -19,87 +19,96 @@ import ( "go.beyondstorage.io/v5/types" ) -func TestStorager(t *testing.T, store types.Storager) { +func TestStorage(t *testing.T, store types.Storager) { Convey("Given a basic Storager", t, func() { So(store, ShouldNotBeNil) - Convey("When String called", func() { - s := store.String() + Convey("Test basic operations for storage service", func() { + TestStorager(t, store) + }) - Convey("The string should not be empty", func() { - So(s, ShouldNotBeEmpty) - }) + Convey("Test Append related operations", func() { + TestAppender(t, store) }) - Convey("When Metadata called", func() { - m := store.Metadata() + Convey("Test Copy operation", func() { + TestCopier(t, store) + }) - Convey("The metadata should not be empty", func() { - So(m, ShouldNotBeEmpty) - }) + Convey("Test CreateDir operation", func() { + TestDirer(t, store) }) - workDir := store.Metadata().WorkDir + Convey("Test CreateLink operation", func() { + TestLinker(t, store) + }) - Convey("When Read a file", func() { - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) - if err != nil { - t.Error(err) - } + Convey("Test Move operation", func() { + TestMover(t, store) + }) - path := uuid.New().String() - _, err = store.Write(path, bytes.NewReader(content), size) - if err != nil { - t.Error(err) - } - defer func() { - err := store.Delete(path) - if err != nil { - t.Error(err) - } - }() + Convey("Test multipart related operations which support authentication", func() { + TestMultipartHTTPSigner(t, store) + }) - var buf bytes.Buffer + Convey("Test Multipart related operations", func() { + TestMultiparter(t, store) + }) - n, err := store.Read(path, &buf) + Convey("Test basic operations which support authentication", func() { + TestStorageHTTPSignerDelete(t, store) + TestStorageHTTPSignerRead(t, store) + TestStorageHTTPSignerWrite(t, store) + }) + }) +} - Convey("The error should be nil", func() { - So(err, ShouldBeNil) +func TestStorager(t *testing.T, store types.Storager) { + Convey("Given a basic Storager", t, func() { + So(store, ShouldNotBeNil) + + f := store.Features() + if f.Create && f.Delete && f.Metadata && f.List && f.Read && f.Stat && f.Write { + Convey("When String called", func() { + s := store.String() + + Convey("The string should not be empty", func() { + So(s, ShouldNotBeEmpty) + }) }) - Convey("The content should be match", func() { - So(buf, ShouldNotBeNil) + Convey("When Metadata called", func() { + m := store.Metadata() - So(n, ShouldEqual, size) - So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(content)) + Convey("The metadata should not be empty", func() { + So(m, ShouldNotBeEmpty) + }) }) - }) - Convey("When Read a file with offset or size", func() { - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) - if err != nil { - t.Error(err) - } + workDir := store.Metadata().WorkDir - path := uuid.New().String() - _, err = store.Write(path, bytes.NewReader(content), size) - if err != nil { - t.Error(err) - } - defer func() { - err := store.Delete(path) + Convey("When Read a file", func() { + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) if err != nil { t.Error(err) } - }() - Convey("When Read with offset", func() { - offset := rand.Int63n(size) + path := uuid.New().String() + _, err = store.Write(path, bytes.NewReader(content), size) + if err != nil { + t.Error(err) + } + defer func() { + err := store.Delete(path) + if err != nil { + t.Error(err) + } + }() var buf bytes.Buffer - n, err := store.Read(path, &buf, ps.WithOffset(offset)) + + n, err := store.Read(path, &buf) Convey("The error should be nil", func() { So(err, ShouldBeNil) @@ -108,279 +117,371 @@ func TestStorager(t *testing.T, store types.Storager) { Convey("The content should be match", func() { So(buf, ShouldNotBeNil) - So(n, ShouldEqual, size-offset) - So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(content[offset:])) + So(n, ShouldEqual, size) + So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(content)) }) }) - Convey("When Read with size", func() { - len := rand.Int63n(size) + Convey("When Read a file with offset or size", func() { + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) + if err != nil { + t.Error(err) + } - var buf bytes.Buffer - n, err := store.Read(path, &buf, ps.WithSize(len)) + path := uuid.New().String() + _, err = store.Write(path, bytes.NewReader(content), size) + if err != nil { + t.Error(err) + } + defer func() { + err := store.Delete(path) + if err != nil { + t.Error(err) + } + }() - Convey("The error should be nil", func() { - So(err, ShouldBeNil) + Convey("When Read with offset", func() { + offset := rand.Int63n(size) + + var buf bytes.Buffer + n, err := store.Read(path, &buf, ps.WithOffset(offset)) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("The content should be match", func() { + So(buf, ShouldNotBeNil) + + So(n, ShouldEqual, size-offset) + So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(content[offset:])) + }) }) - Convey("The content should be match", func() { - So(buf, ShouldNotBeNil) + Convey("When Read with size", func() { + len := rand.Int63n(size) + + var buf bytes.Buffer + n, err := store.Read(path, &buf, ps.WithSize(len)) - So(n, ShouldEqual, len) - So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(content[:len])) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("The content should be match", func() { + So(buf, ShouldNotBeNil) + + So(n, ShouldEqual, len) + So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(content[:len])) + }) + }) + + Convey("When Read with offset and size", func() { + offset := rand.Int63n(size) + len := rand.Int63n(size - offset) + + var buf bytes.Buffer + n, err := store.Read(path, &buf, ps.WithOffset(offset), ps.WithSize(len)) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("The content should be match", func() { + So(buf, ShouldNotBeNil) + + So(n, ShouldEqual, len) + So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(content[offset:offset+len])) + }) }) }) - Convey("When Read with offset and size", func() { - offset := rand.Int63n(size) - len := rand.Int63n(size - offset) + Convey("When Write a file", func() { + firstSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + r := io.LimitReader(randbytes.NewRand(), firstSize) + path := uuid.New().String() - var buf bytes.Buffer - n, err := store.Read(path, &buf, ps.WithOffset(offset), ps.WithSize(len)) + _, err := store.Write(path, r, firstSize) - Convey("The error should be nil", func() { + defer func() { + err := store.Delete(path) + if err != nil { + t.Error(err) + } + }() + + Convey("The first returned error should be nil", func() { So(err, ShouldBeNil) }) - Convey("The content should be match", func() { - So(buf, ShouldNotBeNil) + secondSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + content, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), secondSize)) - So(n, ShouldEqual, len) - So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(content[offset:offset+len])) + _, err = store.Write(path, bytes.NewReader(content), secondSize) + + Convey("The second returned error also should be nil", func() { + So(err, ShouldBeNil) }) - }) - }) - Convey("When Write a file", func() { - firstSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - r := io.LimitReader(randbytes.NewRand(), firstSize) - path := uuid.New().String() + Convey("Stat should get Object without error", func() { + o, err := store.Stat(path) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) - _, err := store.Write(path, r, firstSize) + Convey("The name and size should be match", func() { + So(o, ShouldNotBeNil) + So(o.Path, ShouldEqual, path) - defer func() { - err := store.Delete(path) - if err != nil { - t.Error(err) - } - }() + osize, ok := o.GetContentLength() + So(ok, ShouldBeTrue) + So(osize, ShouldEqual, secondSize) + }) + }) - Convey("The first returned error should be nil", func() { - So(err, ShouldBeNil) - }) + Convey("Read should get Object data without error", func() { + var buf bytes.Buffer + n, err := store.Read(path, &buf) - secondSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - content, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), secondSize)) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) - _, err = store.Write(path, bytes.NewReader(content), secondSize) + Convey("The content should be match", func() { + So(buf, ShouldNotBeNil) - Convey("The second returned error also should be nil", func() { - So(err, ShouldBeNil) + So(n, ShouldEqual, secondSize) + So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(content)) + }) + }) }) - Convey("Stat should get Object without error", func() { - o, err := store.Stat(path) + Convey("When Write and Read a file with IoCallback", func() { + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) + if err != nil { + t.Error(err) + } - Convey("The error should be nil", func() { + path := uuid.New().String() + + curWrite := int64(0) + writeFn := func(bs []byte) { + curWrite += int64(len(bs)) + } + _, err = store.Write(path, bytes.NewReader(content), size, ps.WithIoCallback(writeFn)) + defer func() { + err := store.Delete(path) + if err != nil { + t.Error(err) + } + }() + + Convey("The error returned by Write should be nil", func() { So(err, ShouldBeNil) }) - Convey("The name and size should be match", func() { - So(o, ShouldNotBeNil) - So(o.Path, ShouldEqual, path) - - osize, ok := o.GetContentLength() - So(ok, ShouldBeTrue) - So(osize, ShouldEqual, secondSize) + Convey("The write size should be match", func() { + So(curWrite, ShouldEqual, size) }) - }) - Convey("Read should get Object data without error", func() { + curRead := int64(0) + readFn := func(bs []byte) { + curRead += int64(len(bs)) + } var buf bytes.Buffer - n, err := store.Read(path, &buf) + n, err := store.Read(path, &buf, ps.WithIoCallback(readFn)) - Convey("The error should be nil", func() { + Convey("The error returned be Read should be nil", func() { So(err, ShouldBeNil) }) + Convey("The read size should be match", func() { + So(curRead, ShouldEqual, n) + }) + Convey("The content should be match", func() { So(buf, ShouldNotBeNil) - So(n, ShouldEqual, secondSize) + So(n, ShouldEqual, size) So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(content)) }) }) - }) - Convey("When Write and Read a file with IoCallback", func() { - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) - if err != nil { - t.Error(err) - } + if f.WriteEmptyObject { + Convey("When write a file with a nil io.Reader and 0 size", func() { + path := uuid.New().String() + var size int64 = 0 - path := uuid.New().String() + _, err := store.Write(path, nil, size) - curWrite := int64(0) - writeFn := func(bs []byte) { - curWrite += int64(len(bs)) - } - _, err = store.Write(path, bytes.NewReader(content), size, ps.WithIoCallback(writeFn)) - defer func() { - err := store.Delete(path) - if err != nil { - t.Error(err) - } - }() + defer func() { + err := store.Delete(path) + if err != nil { + t.Error(err) + } + }() - Convey("The error returned by Write should be nil", func() { - So(err, ShouldBeNil) - }) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) - Convey("The write size should be match", func() { - So(curWrite, ShouldEqual, size) - }) + Convey("Stat should get Object without error", func() { + o, err := store.Stat(path) - curRead := int64(0) - readFn := func(bs []byte) { - curRead += int64(len(bs)) - } - var buf bytes.Buffer - n, err := store.Read(path, &buf, ps.WithIoCallback(readFn)) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) - Convey("The error returned be Read should be nil", func() { - So(err, ShouldBeNil) - }) + Convey("The name and size should be match", func() { + So(o, ShouldNotBeNil) + So(o.Path, ShouldEqual, path) - Convey("The read size should be match", func() { - So(curRead, ShouldEqual, n) - }) + osize, ok := o.GetContentLength() + So(ok, ShouldBeTrue) + So(osize, ShouldEqual, size) + }) + }) + }) - Convey("The content should be match", func() { - So(buf, ShouldNotBeNil) + Convey("When write a file with a nil io.Reader and valid size", func() { + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + path := uuid.New().String() - So(n, ShouldEqual, size) - So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(content)) - }) - }) + _, err := store.Write(path, nil, size) - Convey("When write a file with a nil io.Reader and 0 size", func() { - path := uuid.New().String() - var size int64 = 0 + Convey("The error should not be nil", func() { + So(err, ShouldNotBeNil) + }) - _, err := store.Write(path, nil, size) + Convey("Stat should get nil Object and ObjectNotFound error", func() { + o, err := store.Stat(path) - defer func() { - err := store.Delete(path) - if err != nil { - t.Error(err) - } - }() + So(errors.Is(err, services.ErrObjectNotExist), ShouldBeTrue) + So(o, ShouldBeNil) + }) + }) - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) + Convey("When write a file with a valid io.Reader and 0 size", func() { + var size int64 = 0 + n := rand.Int63n(4 * 1024 * 1024) + r := io.LimitReader(randbytes.NewRand(), n) + path := uuid.New().String() - Convey("Stat should get Object without error", func() { - o, err := store.Stat(path) + _, err := store.Write(path, r, size) - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) + defer func() { + err := store.Delete(path) + if err != nil { + t.Error(err) + } + }() - Convey("The name and size should be match", func() { - So(o, ShouldNotBeNil) - So(o.Path, ShouldEqual, path) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) - osize, ok := o.GetContentLength() - So(ok, ShouldBeTrue) - So(osize, ShouldEqual, size) - }) - }) - }) + Convey("Stat should get Object without error", func() { + o, err := store.Stat(path) - Convey("When write a file with a nil io.Reader and valid size", func() { - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - path := uuid.New().String() + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) - _, err := store.Write(path, nil, size) + Convey("The name and size should be match", func() { + So(o, ShouldNotBeNil) + So(o.Path, ShouldEqual, path) - Convey("The error should not be nil", func() { - So(err, ShouldNotBeNil) - }) + osize, ok := o.GetContentLength() + So(ok, ShouldBeTrue) + So(osize, ShouldEqual, size) + }) + }) + }) - Convey("Stat should get nil Object and ObjectNotFound error", func() { - o, err := store.Stat(path) + Convey("When write a file with a valid io.Reader and length greater than size", func() { + n := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + size := rand.Int63n(n) + r, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), n)) + path := uuid.New().String() - So(errors.Is(err, services.ErrObjectNotExist), ShouldBeTrue) - So(o, ShouldBeNil) - }) - }) + _, err := store.Write(path, bytes.NewReader(r), size) - Convey("When write a file with a valid io.Reader and 0 size", func() { - var size int64 = 0 - n := rand.Int63n(4 * 1024 * 1024) - r := io.LimitReader(randbytes.NewRand(), n) - path := uuid.New().String() + defer func() { + err := store.Delete(path) + if err != nil { + t.Error(err) + } + }() - _, err := store.Write(path, r, size) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) - defer func() { - err := store.Delete(path) - if err != nil { - t.Error(err) - } - }() + Convey("Stat should get Object without error", func() { + o, err := store.Stat(path) - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) - Convey("Stat should get Object without error", func() { - o, err := store.Stat(path) + Convey("The name and size should be match", func() { + So(o, ShouldNotBeNil) + So(o.Path, ShouldEqual, path) - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) + osize, ok := o.GetContentLength() + So(ok, ShouldBeTrue) + So(osize, ShouldEqual, size) + }) + }) - Convey("The name and size should be match", func() { - So(o, ShouldNotBeNil) - So(o.Path, ShouldEqual, path) + Convey("Read should get Object without error", func() { + content, _ := io.ReadAll(io.LimitReader(bytes.NewReader(r), size)) + var buf bytes.Buffer + n, err := store.Read(path, &buf) - osize, ok := o.GetContentLength() - So(ok, ShouldBeTrue) - So(osize, ShouldEqual, size) - }) - }) - }) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) - Convey("When write a file with a valid io.Reader and length greater than size", func() { - n := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - size := rand.Int63n(n) - r, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), n)) - path := uuid.New().String() + Convey("The content should match the size limit of the content", func() { + So(buf, ShouldNotBeNil) - _, err := store.Write(path, bytes.NewReader(r), size) + So(n, ShouldEqual, size) + So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(content)) + }) + }) + }) + } - defer func() { - err := store.Delete(path) + Convey("When Stat a file", func() { + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) if err != nil { t.Error(err) } - }() - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) + path := uuid.New().String() + _, err = store.Write(path, bytes.NewReader(content), size) + if err != nil { + t.Error(err) + } + defer func() { + err := store.Delete(path) + if err != nil { + t.Error(err) + } + }() - Convey("Stat should get Object without error", func() { o, err := store.Stat(path) Convey("The error should be nil", func() { So(err, ShouldBeNil) }) - Convey("The name and size should be match", func() { + Convey("The Object name and size should be match", func() { So(o, ShouldNotBeNil) So(o.Path, ShouldEqual, path) @@ -390,273 +491,221 @@ func TestStorager(t *testing.T, store types.Storager) { }) }) - Convey("Read should get Object without error", func() { - content, _ := io.ReadAll(io.LimitReader(bytes.NewReader(r), size)) - var buf bytes.Buffer - n, err := store.Read(path, &buf) - - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) - - Convey("The content should match the size limit of the content", func() { - So(buf, ShouldNotBeNil) - - So(n, ShouldEqual, size) - So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(content)) - }) - }) - }) - - Convey("When Stat a file", func() { - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) - if err != nil { - t.Error(err) - } - - path := uuid.New().String() - _, err = store.Write(path, bytes.NewReader(content), size) - if err != nil { - t.Error(err) - } - defer func() { - err := store.Delete(path) + Convey("When Delete a file", func() { + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) if err != nil { t.Error(err) } - }() - - o, err := store.Stat(path) - - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) - - Convey("The Object name and size should be match", func() { - So(o, ShouldNotBeNil) - So(o.Path, ShouldEqual, path) - - osize, ok := o.GetContentLength() - So(ok, ShouldBeTrue) - So(osize, ShouldEqual, size) - }) - }) - - Convey("When Delete a file", func() { - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) - if err != nil { - t.Error(err) - } - - path := uuid.New().String() - _, err = store.Write(path, bytes.NewReader(content), size) - if err != nil { - t.Error(err) - } - err = store.Delete(path) - - Convey("The first returned error should be nil", func() { - So(err, ShouldBeNil) - }) + path := uuid.New().String() + _, err = store.Write(path, bytes.NewReader(content), size) + if err != nil { + t.Error(err) + } - err = store.Delete(path) + err = store.Delete(path) - Convey("The second returned error also should be nil", func() { - So(err, ShouldBeNil) - }) + Convey("The first returned error should be nil", func() { + So(err, ShouldBeNil) + }) - Convey("Stat should get nil Object and ObjectNotFound error", func() { - o, err := store.Stat(path) + err = store.Delete(path) - So(errors.Is(err, services.ErrObjectNotExist), ShouldBeTrue) - So(o, ShouldBeNil) - }) - }) + Convey("The second returned error also should be nil", func() { + So(err, ShouldBeNil) + }) - Convey("When List an empty dir", func() { - it, err := store.List("", ps.WithListMode(types.ListModeDir)) + Convey("Stat should get nil Object and ObjectNotFound error", func() { + o, err := store.Stat(path) - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) - Convey("The iterator should not be nil", func() { - So(it, ShouldNotBeNil) + So(errors.Is(err, services.ErrObjectNotExist), ShouldBeTrue) + So(o, ShouldBeNil) + }) }) - o, err := it.Next() + Convey("When List an empty dir", func() { + it, err := store.List("", ps.WithListMode(types.ListModeDir)) - Convey("The next should be done", func() { - So(err, ShouldBeError, types.IterateDone) - }) - Convey("The object should be nil", func() { - So(o, ShouldBeNil) - }) - }) - - Convey("When List a dir within files", func() { - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - r := io.LimitReader(randbytes.NewRand(), size) - path := uuid.New().String() - _, err := store.Write(path, r, size) - if err != nil { - t.Error(err) - } - defer func() { - err := store.Delete(path) - if err != nil { - t.Error(err) - } - }() - - it, err := store.List("", ps.WithListMode(types.ListModeDir)) - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) - Convey("The iterator should not be nil", func() { - So(it, ShouldNotBeNil) - }) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + Convey("The iterator should not be nil", func() { + So(it, ShouldNotBeNil) + }) - o, err := it.Next() - Convey("The name and size should be match", func() { - So(o, ShouldNotBeNil) - So(o.Path, ShouldEqual, path) + o, err := it.Next() - osize, ok := o.GetContentLength() - So(ok, ShouldBeTrue) - So(osize, ShouldEqual, size) + Convey("The next should be done", func() { + So(err, ShouldBeError, types.IterateDone) + }) + Convey("The object should be nil", func() { + So(o, ShouldBeNil) + }) }) - }) - Convey("When List without ListMode", func() { - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - r := io.LimitReader(randbytes.NewRand(), size) - path := uuid.New().String() - _, err := store.Write(path, r, size) - if err != nil { - t.Error(err) - } - defer func() { - err := store.Delete(path) + Convey("When List a dir within files", func() { + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + r := io.LimitReader(randbytes.NewRand(), size) + path := uuid.New().String() + _, err := store.Write(path, r, size) if err != nil { t.Error(err) } - }() + defer func() { + err := store.Delete(path) + if err != nil { + t.Error(err) + } + }() - it, err := store.List("") - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) - Convey("The iterator should not be nil", func() { - So(it, ShouldNotBeNil) - }) + it, err := store.List("", ps.WithListMode(types.ListModeDir)) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + Convey("The iterator should not be nil", func() { + So(it, ShouldNotBeNil) + }) - o, err := it.Next() - Convey("The name and size should be match", func() { - So(o, ShouldNotBeNil) - So(o.Path, ShouldEqual, path) + o, err := it.Next() + Convey("The name and size should be match", func() { + So(o, ShouldNotBeNil) + So(o.Path, ShouldEqual, path) - osize, ok := o.GetContentLength() - So(ok, ShouldBeTrue) - So(osize, ShouldEqual, size) + osize, ok := o.GetContentLength() + So(ok, ShouldBeTrue) + So(osize, ShouldEqual, size) + }) }) - }) - Convey("When testing GSP-749 unify path behavior", func() { - Convey("When using absolute path", func() { + Convey("When List without ListMode", func() { size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) - if err != nil { - t.Error(err) - } - + r := io.LimitReader(randbytes.NewRand(), size) path := uuid.New().String() - absPath := filepath.Join(workDir, path) - _, err = store.Write(absPath, bytes.NewReader(content), size) + _, err := store.Write(path, r, size) if err != nil { t.Error(err) } defer func() { - err := store.Delete(absPath) + err := store.Delete(path) if err != nil { t.Error(err) } }() - Convey("Stat should get Object without error", func() { - o, err := store.Stat(absPath) - - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - So(o, ShouldNotBeNil) - So(o.Path, ShouldEqual, strings.ReplaceAll(absPath, "\\", "/")) - }) + it, err := store.List("") + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + Convey("The iterator should not be nil", func() { + So(it, ShouldNotBeNil) }) - Convey("Read should get Object content without error", func() { - var buf bytes.Buffer - n, err := store.Read(absPath, &buf) - - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) - - Convey("The content should be match", func() { - So(buf, ShouldNotBeNil) + o, err := it.Next() + Convey("The name and size should be match", func() { + So(o, ShouldNotBeNil) + So(o.Path, ShouldEqual, path) - So(n, ShouldEqual, size) - So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(content)) - }) + osize, ok := o.GetContentLength() + So(ok, ShouldBeTrue) + So(osize, ShouldEqual, size) }) }) - Convey("When using backslash in path", func() { - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) - if err != nil { - t.Error(err) - } + Convey("When testing GSP-749 unify path behavior", func() { + Convey("When using absolute path", func() { + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) + if err != nil { + t.Error(err) + } - path := uuid.New().String() + "\\" + uuid.New().String() - _, err = store.Write(path, bytes.NewReader(content), size) - if err != nil { - t.Error(err) - } - defer func() { - err := store.Delete(path) + path := uuid.New().String() + absPath := filepath.Join(workDir, path) + _, err = store.Write(absPath, bytes.NewReader(content), size) if err != nil { t.Error(err) } - }() + defer func() { + err := store.Delete(absPath) + if err != nil { + t.Error(err) + } + }() + + Convey("Stat should get Object without error", func() { + o, err := store.Stat(absPath) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + So(o, ShouldNotBeNil) + So(o.Path, ShouldEqual, strings.ReplaceAll(absPath, "\\", "/")) + }) + }) - Convey("Stat should get Object without error", func() { - o, err := store.Stat(path) + Convey("Read should get Object content without error", func() { + var buf bytes.Buffer + n, err := store.Read(absPath, &buf) - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - So(o, ShouldNotBeNil) - So(o.Path, ShouldEqual, strings.ReplaceAll(path, "\\", "/")) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("The content should be match", func() { + So(buf, ShouldNotBeNil) + + So(n, ShouldEqual, size) + So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(content)) + }) }) }) - Convey("Read should get Object content without error", func() { - var buf bytes.Buffer - n, err := store.Read(path, &buf) + Convey("When using backslash in path", func() { + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) + if err != nil { + t.Error(err) + } - Convey("The error should be nil", func() { - So(err, ShouldBeNil) + path := uuid.New().String() + "\\" + uuid.New().String() + _, err = store.Write(path, bytes.NewReader(content), size) + if err != nil { + t.Error(err) + } + defer func() { + err := store.Delete(path) + if err != nil { + t.Error(err) + } + }() + + Convey("Stat should get Object without error", func() { + o, err := store.Stat(path) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + So(o, ShouldNotBeNil) + So(o.Path, ShouldEqual, strings.ReplaceAll(path, "\\", "/")) + }) }) - Convey("The content should be match", func() { - So(buf, ShouldNotBeNil) + Convey("Read should get Object content without error", func() { + var buf bytes.Buffer + n, err := store.Read(path, &buf) - So(n, ShouldEqual, size) - So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(content)) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("The content should be match", func() { + So(buf, ShouldNotBeNil) + + So(n, ShouldEqual, size) + So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(content)) + }) }) }) }) - }) + } }) } From 97177b8d176390d7a325221b8d7c076cbb6fbc90 Mon Sep 17 00:00:00 2001 From: JinnyYi Date: Sun, 31 Oct 2021 19:13:00 +0800 Subject: [PATCH 2/2] Move deprecated tests to seperate file --- tests/appender.go | 222 ++--- tests/copier.go | 329 ++++--- tests/deprecated.go | 1592 ++++++++++++++++++++++++++++++++ tests/direr.go | 90 +- tests/linker.go | 252 +++-- tests/mover.go | 353 ++++--- tests/multipart_http_signer.go | 229 ++--- tests/multiparter.go | 312 ++++--- tests/storage_http_signer.go | 180 ++-- tests/storager.go | 607 ++++++------ 10 files changed, 2868 insertions(+), 1298 deletions(-) create mode 100644 tests/deprecated.go diff --git a/tests/appender.go b/tests/appender.go index cd877d349..35546fa9f 100644 --- a/tests/appender.go +++ b/tests/appender.go @@ -15,94 +15,48 @@ import ( "go.beyondstorage.io/v5/types" ) -func TestAppender(t *testing.T, store types.Storager) { - Convey("Given a basic Storager", t, func() { - - f := store.Features() - if f.CreateAppend && f.WriteAppend && f.CommitAppend && f.Write && f.Read && f.Delete && f.Stat { - Convey("When CreateAppend", func() { - path := uuid.NewString() - o, err := store.CreateAppend(path) - - defer func() { - err := store.Delete(path) - if err != nil { - t.Error(err) - } - }() - - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) - - Convey("The Object Mode should be appendable", func() { - // Append object's mode must be appendable. - So(o.Mode.IsAppend(), ShouldBeTrue) - }) - }) - - Convey("When CreateAppend with an existing object", func() { - path := uuid.NewString() - o, err := store.CreateAppend(path) - - defer func() { - err := store.Delete(path) - if err != nil { - t.Error(err) - } - }() - - Convey("The first returned error should be nil", func() { - So(err, ShouldBeNil) - }) - - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - r := io.LimitReader(randbytes.NewRand(), size) - - _, err = store.WriteAppend(o, r, size) - if err != nil { - t.Fatal(err) - } - - err = store.CommitAppend(o) +func testAppender(t *testing.T, store types.Storager, f types.StorageFeatures) { + if f.CreateAppend && f.Delete { + Convey("When CreateAppend", func() { + path := uuid.NewString() + o, err := store.CreateAppend(path) + + defer func() { + err := store.Delete(path) if err != nil { - t.Fatal(err) + t.Error(err) } + }() - o, err = store.CreateAppend(path) - - Convey("The second returned error also should be nil", func() { - So(err, ShouldBeNil) - }) - - Convey("The Object Mode should be appendable", func() { - // Append object's mode must be appendable. - So(o.Mode.IsAppend(), ShouldBeTrue) - }) - - Convey("The object append offset should be 0", func() { - So(o.MustGetAppendOffset(), ShouldBeZeroValue) - }) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) }) - Convey("When Delete", func() { - path := uuid.NewString() - _, err := store.CreateAppend(path) - if err != nil { - t.Error(err) - } - - err = store.Delete(path) - Convey("The first returned error should be nil", func() { - So(err, ShouldBeNil) - }) + Convey("The Object Mode should be appendable", func() { + // Append object's mode must be appendable. + So(o.Mode.IsAppend(), ShouldBeTrue) + }) + }) + + Convey("When Delete", func() { + path := uuid.NewString() + _, err := store.CreateAppend(path) + if err != nil { + t.Error(err) + } + + err = store.Delete(path) + Convey("The first returned error should be nil", func() { + So(err, ShouldBeNil) + }) - err = store.Delete(path) - Convey("The second returned error also should be nil", func() { - So(err, ShouldBeNil) - }) + err = store.Delete(path) + Convey("The second returned error also should be nil", func() { + So(err, ShouldBeNil) }) + }) + if f.WriteAppend { Convey("When WriteAppend", func() { path := uuid.NewString() o, err := store.CreateAppend(path) @@ -131,49 +85,95 @@ func TestAppender(t *testing.T, store types.Storager) { }) }) - Convey("When CommitAppend", func() { - path := uuid.NewString() - o, err := store.CreateAppend(path) - if err != nil { - t.Error(err) - } + if f.CommitAppend { + Convey("When CommitAppend", func() { + path := uuid.NewString() + o, err := store.CreateAppend(path) + if err != nil { + t.Error(err) + } - defer func() { - err := store.Delete(path) + defer func() { + err := store.Delete(path) + if err != nil { + t.Error(err) + } + }() + + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + content, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) + + _, err = store.WriteAppend(o, bytes.NewReader(content), size) if err != nil { t.Error(err) } - }() - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - content, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) + _, err = store.WriteAppend(o, bytes.NewReader(content), size) + if err != nil { + t.Error(err) + } - _, err = store.WriteAppend(o, bytes.NewReader(content), size) - if err != nil { - t.Error(err) - } + err = store.CommitAppend(o) - _, err = store.WriteAppend(o, bytes.NewReader(content), size) - if err != nil { - t.Error(err) - } + Convey("CommitAppend error should be nil", func() { + So(err, ShouldBeNil) + }) - err = store.CommitAppend(o) + var buf bytes.Buffer + _, err = store.Read(path, &buf, pairs.WithSize(size*2)) - Convey("CommitAppend error should be nil", func() { - So(err, ShouldBeNil) + Convey("Read error should be nil", func() { + So(err, ShouldBeNil) + }) + Convey("The content should be match", func() { + So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(bytes.Repeat(content, 2))) + }) }) - var buf bytes.Buffer - _, err = store.Read(path, &buf, pairs.WithSize(size*2)) + Convey("When CreateAppend with an existing object", func() { + path := uuid.NewString() + o, err := store.CreateAppend(path) - Convey("Read error should be nil", func() { - So(err, ShouldBeNil) - }) - Convey("The content should be match", func() { - So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(bytes.Repeat(content, 2))) + defer func() { + err := store.Delete(path) + if err != nil { + t.Error(err) + } + }() + + Convey("The first returned error should be nil", func() { + So(err, ShouldBeNil) + }) + + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + r := io.LimitReader(randbytes.NewRand(), size) + + _, err = store.WriteAppend(o, r, size) + if err != nil { + t.Fatal(err) + } + + err = store.CommitAppend(o) + if err != nil { + t.Fatal(err) + } + + o, err = store.CreateAppend(path) + + Convey("The second returned error also should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("The Object Mode should be appendable", func() { + // Append object's mode must be appendable. + So(o.Mode.IsAppend(), ShouldBeTrue) + }) + + Convey("The object append offset should be 0", func() { + So(o.MustGetAppendOffset(), ShouldBeZeroValue) + }) }) - }) + } } - }) + } } diff --git a/tests/copier.go b/tests/copier.go index c2be1132c..d58ecb29f 100644 --- a/tests/copier.go +++ b/tests/copier.go @@ -17,227 +17,218 @@ import ( "go.beyondstorage.io/v5/types" ) -func TestCopier(t *testing.T, store types.Storager) { - Convey("Given a basic Storager", t, func() { +func testCopier(t *testing.T, store types.Storager, f types.StorageFeatures) { + if f.Copy && f.Write && f.Read && f.Delete { + // copy a file to a non-existent file + Convey("When Copy a file", func() { + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + content, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) + src := uuid.New().String() + + _, err := store.Write(src, bytes.NewReader(content), size) + if err != nil { + t.Fatal(err) + } + + defer func() { + err = store.Delete(src) + if err != nil { + t.Error(err) + } + }() - f := store.Features() - if f.Copy && f.Write && f.Read && f.Delete { - Convey("When Copy a file", func() { - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - content, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) - src := uuid.New().String() + dst := uuid.New().String() + err = store.Copy(src, dst) - _, err := store.Write(src, bytes.NewReader(content), size) + defer func() { + err = store.Delete(dst) if err != nil { - t.Fatal(err) + t.Error(err) } + }() - defer func() { - err = store.Delete(src) - if err != nil { - t.Error(err) - } - }() - - dst := uuid.New().String() - err = store.Copy(src, dst) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) - defer func() { - err = store.Delete(dst) - if err != nil { - t.Error(err) - } - }() + Convey("Read should get dst object data without error", func() { + var buf bytes.Buffer + n, err := store.Read(dst, &buf) Convey("The error should be nil", func() { So(err, ShouldBeNil) }) - Convey("Read should get dst object data without error", func() { - var buf bytes.Buffer - n, err := store.Read(dst, &buf) - - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) - - Convey("The content should be match", func() { - So(buf, ShouldNotBeNil) - So(n, ShouldEqual, size) - So(md5.Sum(buf.Bytes()), ShouldResemble, md5.Sum(content)) - }) + Convey("The content should be match", func() { + So(buf, ShouldNotBeNil) + So(n, ShouldEqual, size) + So(md5.Sum(buf.Bytes()), ShouldResemble, md5.Sum(content)) }) }) + }) - Convey("When Copy to an existing file", func() { - srcSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - content, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), srcSize)) - src := uuid.New().String() + // copy to an existing file + Convey("When Copy to an existing file", func() { + srcSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + content, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), srcSize)) + src := uuid.New().String() - _, err := store.Write(src, bytes.NewReader(content), srcSize) + _, err := store.Write(src, bytes.NewReader(content), srcSize) + if err != nil { + t.Fatal(err) + } + + defer func() { + err = store.Delete(src) if err != nil { - t.Fatal(err) + t.Error(err) } + }() - defer func() { - err = store.Delete(src) - if err != nil { - t.Error(err) - } - }() + dstSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + r := io.LimitReader(randbytes.NewRand(), dstSize) + dst := uuid.New().String() - dstSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - r := io.LimitReader(randbytes.NewRand(), dstSize) - dst := uuid.New().String() + _, err = store.Write(dst, r, dstSize) + if err != nil { + t.Fatal(err) + } - _, err = store.Write(dst, r, dstSize) + defer func() { + err = store.Delete(dst) if err != nil { - t.Fatal(err) + t.Error(err) } + }() - defer func() { - err = store.Delete(dst) - if err != nil { - t.Error(err) - } - }() + err = store.Copy(src, dst) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("Read should get dst object data without error", func() { + var buf bytes.Buffer + n, err := store.Read(dst, &buf) - err = store.Copy(src, dst) Convey("The error should be nil", func() { So(err, ShouldBeNil) }) - Convey("Read should get dst object data without error", func() { - var buf bytes.Buffer - n, err := store.Read(dst, &buf) - - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) - - Convey("The content should be match", func() { - So(buf, ShouldNotBeNil) - So(n, ShouldEqual, srcSize) - So(md5.Sum(buf.Bytes()), ShouldResemble, md5.Sum(content)) - }) + Convey("The content should be match", func() { + So(buf, ShouldNotBeNil) + So(n, ShouldEqual, srcSize) + So(md5.Sum(buf.Bytes()), ShouldResemble, md5.Sum(content)) }) }) - } - }) -} - -func TestCopierWithDir(t *testing.T, store types.Storager) { - Convey("Given a basic Storager", t, func() { - - f := store.Features() - if f.Copy && f.CreateDir && !f.VirtualDir && f.Write && f.Delete { - Convey("When Copy to an existing dir", func() { - srcSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - r := io.LimitReader(randbytes.NewRand(), srcSize) - src := uuid.New().String() - - _, err := store.Write(src, r, srcSize) - if err != nil { - t.Fatal(err) - } - - defer func() { - err = store.Delete(src) + }) + + // copy to a dir + if f.CreateDir { + // native supported dir + if !f.VirtualDir { + Convey("When Copy to an existing dir", func() { + srcSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + r := io.LimitReader(randbytes.NewRand(), srcSize) + src := uuid.New().String() + + _, err := store.Write(src, r, srcSize) if err != nil { - t.Error(err) + t.Fatal(err) } - }() - dst := uuid.New().String() - _, err = store.CreateDir(dst) - if err != nil { - t.Fatal(err) - } + defer func() { + err = store.Delete(src) + if err != nil { + t.Error(err) + } + }() - defer func() { - err = store.Delete(dst, pairs.WithObjectMode(types.ModeDir)) + dst := uuid.New().String() + _, err = store.CreateDir(dst) if err != nil { - t.Error(err) + t.Fatal(err) } - }() - - err = store.Copy(src, dst) - Convey("The error should be ErrObjectModeInvalid", func() { - So(errors.Is(err, services.ErrObjectModeInvalid), ShouldBeTrue) - }) - }) - } - }) -} - -func TestCopierWithVirtualDir(t *testing.T, store types.Storager) { - Convey("Given a basic Storager", t, func() { - - f := store.Features() - if f.Copy && f.CreateDir && f.VirtualDir && f.Write && f.Delete && f.Stat { - Convey("When Copy to an existing dir", func() { - srcSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - r := io.LimitReader(randbytes.NewRand(), srcSize) - src := uuid.New().String() - _, err := store.Write(src, r, srcSize) - if err != nil { - t.Fatal(err) - } + defer func() { + err = store.Delete(dst, pairs.WithObjectMode(types.ModeDir)) + if err != nil { + t.Error(err) + } + }() - defer func() { - err = store.Delete(src) + err = store.Copy(src, dst) + Convey("The error should be ErrObjectModeInvalid", func() { + So(errors.Is(err, services.ErrObjectModeInvalid), ShouldBeTrue) + }) + }) + } else { + // virtual dir + Convey("When Copy to an existing virtual dir", func() { + srcSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + r := io.LimitReader(randbytes.NewRand(), srcSize) + src := uuid.New().String() + + _, err := store.Write(src, r, srcSize) if err != nil { - t.Error(err) + t.Fatal(err) } - }() - dst := uuid.New().String() - _, err = store.CreateDir(dst) - if err != nil { - t.Fatal(err) - } + defer func() { + err = store.Delete(src) + if err != nil { + t.Error(err) + } + }() - defer func() { - err = store.Delete(dst, pairs.WithObjectMode(types.ModeDir)) + dst := uuid.New().String() + _, err = store.CreateDir(dst) if err != nil { - t.Error(err) + t.Fatal(err) } - }() - err = store.Copy(src, dst) + defer func() { + err = store.Delete(dst, pairs.WithObjectMode(types.ModeDir)) + if err != nil { + t.Error(err) + } + }() - defer func() { - err = store.Delete(dst) - if err != nil { - t.Error(err) - } - }() + err = store.Copy(src, dst) - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) + defer func() { + err = store.Delete(dst) + if err != nil { + t.Error(err) + } + }() + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) - Convey("Stat should get dst object without error", func() { - o, err := store.Stat(dst) + if f.Stat { + Convey("Stat should get dst object without error", func() { + o, err := store.Stat(dst) - So(err, ShouldBeNil) - So(o, ShouldNotBeNil) + So(err, ShouldBeNil) + So(o, ShouldNotBeNil) - Convey("The Object Mode should be read", func() { - So(o.Mode.IsRead(), ShouldBeTrue) - }) + Convey("The Object Mode should be read", func() { + So(o.Mode.IsRead(), ShouldBeTrue) + }) - Convey("The path and size should be match", func() { - So(o, ShouldNotBeNil) - So(o.Path, ShouldEqual, dst) + Convey("The path and size should be match", func() { + So(o, ShouldNotBeNil) + So(o.Path, ShouldEqual, dst) - osize, ok := o.GetContentLength() - So(ok, ShouldBeTrue) - So(osize, ShouldEqual, srcSize) - }) + osize, ok := o.GetContentLength() + So(ok, ShouldBeTrue) + So(osize, ShouldEqual, srcSize) + }) + }) + } }) - }) + } } - }) + } } diff --git a/tests/deprecated.go b/tests/deprecated.go new file mode 100644 index 000000000..25f3bf0ba --- /dev/null +++ b/tests/deprecated.go @@ -0,0 +1,1592 @@ +package tests + +import ( + "bytes" + "crypto/md5" + "crypto/sha256" + "errors" + "io" + "math/rand" + "net/http" + "path/filepath" + "testing" + "time" + + "github.com/google/uuid" + . "github.com/smartystreets/goconvey/convey" + + "go.beyondstorage.io/v5/pairs" + "go.beyondstorage.io/v5/pkg/randbytes" + "go.beyondstorage.io/v5/services" + "go.beyondstorage.io/v5/types" +) + +// Deprecated: Moved to TestStorager. +func TestAppender(t *testing.T, store types.Storager) { + Convey("Given a basic Storager", t, func() { + + Convey("When CreateAppend", func() { + path := uuid.NewString() + o, err := store.CreateAppend(path) + + defer func() { + err := store.Delete(path) + if err != nil { + t.Error(err) + } + }() + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("The Object Mode should be appendable", func() { + // Append object's mode must be appendable. + So(o.Mode.IsAppend(), ShouldBeTrue) + }) + }) + + Convey("When CreateAppend with an existing object", func() { + path := uuid.NewString() + o, err := store.CreateAppend(path) + + defer func() { + err := store.Delete(path) + if err != nil { + t.Error(err) + } + }() + + Convey("The first returned error should be nil", func() { + So(err, ShouldBeNil) + }) + + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + r := io.LimitReader(randbytes.NewRand(), size) + + _, err = store.WriteAppend(o, r, size) + if err != nil { + t.Fatal(err) + } + + err = store.CommitAppend(o) + if err != nil { + t.Fatal(err) + } + + o, err = store.CreateAppend(path) + + Convey("The second returned error also should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("The Object Mode should be appendable", func() { + // Append object's mode must be appendable. + So(o.Mode.IsAppend(), ShouldBeTrue) + }) + + Convey("The object append offset should be 0", func() { + So(o.MustGetAppendOffset(), ShouldBeZeroValue) + }) + }) + + Convey("When Delete", func() { + path := uuid.NewString() + _, err := store.CreateAppend(path) + if err != nil { + t.Error(err) + } + + err = store.Delete(path) + Convey("The first returned error should be nil", func() { + So(err, ShouldBeNil) + }) + + err = store.Delete(path) + Convey("The second returned error also should be nil", func() { + So(err, ShouldBeNil) + }) + }) + + Convey("When WriteAppend", func() { + path := uuid.NewString() + o, err := store.CreateAppend(path) + if err != nil { + t.Error(err) + } + + defer func() { + err := store.Delete(path) + if err != nil { + t.Error(err) + } + }() + + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + content, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) + r := bytes.NewReader(content) + + n, err := store.WriteAppend(o, r, size) + + Convey("WriteAppend error should be nil", func() { + So(err, ShouldBeNil) + }) + Convey("WriteAppend size should be equal to n", func() { + So(n, ShouldEqual, size) + }) + }) + + Convey("When CommitAppend", func() { + path := uuid.NewString() + o, err := store.CreateAppend(path) + if err != nil { + t.Error(err) + } + + defer func() { + err := store.Delete(path) + if err != nil { + t.Error(err) + } + }() + + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + content, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) + + _, err = store.WriteAppend(o, bytes.NewReader(content), size) + if err != nil { + t.Error(err) + } + + _, err = store.WriteAppend(o, bytes.NewReader(content), size) + if err != nil { + t.Error(err) + } + + err = store.CommitAppend(o) + + Convey("CommitAppend error should be nil", func() { + So(err, ShouldBeNil) + }) + + var buf bytes.Buffer + _, err = store.Read(path, &buf, pairs.WithSize(size*2)) + + Convey("Read error should be nil", func() { + So(err, ShouldBeNil) + }) + Convey("The content should be match", func() { + So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(bytes.Repeat(content, 2))) + }) + }) + }) +} + +// Deprecated: Moved to TestStorager. +func TestCopier(t *testing.T, store types.Storager) { + Convey("Given a basic Storager", t, func() { + + Convey("When Copy a file", func() { + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + content, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) + src := uuid.New().String() + + _, err := store.Write(src, bytes.NewReader(content), size) + if err != nil { + t.Fatal(err) + } + + defer func() { + err = store.Delete(src) + if err != nil { + t.Error(err) + } + }() + + dst := uuid.New().String() + err = store.Copy(src, dst) + + defer func() { + err = store.Delete(dst) + if err != nil { + t.Error(err) + } + }() + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("Read should get dst object data without error", func() { + var buf bytes.Buffer + n, err := store.Read(dst, &buf) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("The content should be match", func() { + So(buf, ShouldNotBeNil) + So(n, ShouldEqual, size) + So(md5.Sum(buf.Bytes()), ShouldResemble, md5.Sum(content)) + }) + }) + }) + + Convey("When Copy to an existing file", func() { + srcSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + content, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), srcSize)) + src := uuid.New().String() + + _, err := store.Write(src, bytes.NewReader(content), srcSize) + if err != nil { + t.Fatal(err) + } + + defer func() { + err = store.Delete(src) + if err != nil { + t.Error(err) + } + }() + + dstSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + r := io.LimitReader(randbytes.NewRand(), dstSize) + dst := uuid.New().String() + + _, err = store.Write(dst, r, dstSize) + if err != nil { + t.Fatal(err) + } + + defer func() { + err = store.Delete(dst) + if err != nil { + t.Error(err) + } + }() + + err = store.Copy(src, dst) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("Read should get dst object data without error", func() { + var buf bytes.Buffer + n, err := store.Read(dst, &buf) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("The content should be match", func() { + So(buf, ShouldNotBeNil) + So(n, ShouldEqual, srcSize) + So(md5.Sum(buf.Bytes()), ShouldResemble, md5.Sum(content)) + }) + }) + }) + }) +} + +// Deprecated: Moved to TestStorager. +func TestCopierWithDir(t *testing.T, store types.Storager) { + Convey("Given a basic Storager", t, func() { + + Convey("When Copy to an existing dir", func() { + srcSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + r := io.LimitReader(randbytes.NewRand(), srcSize) + src := uuid.New().String() + + _, err := store.Write(src, r, srcSize) + if err != nil { + t.Fatal(err) + } + + defer func() { + err = store.Delete(src) + if err != nil { + t.Error(err) + } + }() + + dst := uuid.New().String() + _, err = store.CreateDir(dst) + if err != nil { + t.Fatal(err) + } + + defer func() { + err = store.Delete(dst, pairs.WithObjectMode(types.ModeDir)) + if err != nil { + t.Error(err) + } + }() + + err = store.Copy(src, dst) + Convey("The error should be ErrObjectModeInvalid", func() { + So(errors.Is(err, services.ErrObjectModeInvalid), ShouldBeTrue) + }) + }) + }) +} + +// Deprecated: Moved to TestStorager. +func TestCopierWithVirtualDir(t *testing.T, store types.Storager) { + Convey("Given a basic Storager", t, func() { + + Convey("When Copy to an existing dir", func() { + srcSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + r := io.LimitReader(randbytes.NewRand(), srcSize) + src := uuid.New().String() + + _, err := store.Write(src, r, srcSize) + if err != nil { + t.Fatal(err) + } + + defer func() { + err = store.Delete(src) + if err != nil { + t.Error(err) + } + }() + + dst := uuid.New().String() + _, err = store.CreateDir(dst) + if err != nil { + t.Fatal(err) + } + + defer func() { + err = store.Delete(dst, pairs.WithObjectMode(types.ModeDir)) + if err != nil { + t.Error(err) + } + }() + + err = store.Copy(src, dst) + + defer func() { + err = store.Delete(dst) + if err != nil { + t.Error(err) + } + }() + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("Stat should get dst object without error", func() { + o, err := store.Stat(dst) + + So(err, ShouldBeNil) + So(o, ShouldNotBeNil) + + Convey("The Object Mode should be read", func() { + So(o.Mode.IsRead(), ShouldBeTrue) + }) + + Convey("The path and size should be match", func() { + So(o, ShouldNotBeNil) + So(o.Path, ShouldEqual, dst) + + osize, ok := o.GetContentLength() + So(ok, ShouldBeTrue) + So(osize, ShouldEqual, srcSize) + }) + }) + }) + }) +} + +// Deprecated: Moved to TestStorager. +func TestDirer(t *testing.T, store types.Storager) { + Convey("Given a basic Storager", t, func() { + + Convey("When CreateDir", func() { + path := uuid.New().String() + _, err := store.CreateDir(path) + + defer func() { + err := store.Delete(path, pairs.WithObjectMode(types.ModeDir)) + if err != nil { + t.Error(err) + } + }() + + Convey("The first returned error should be nil", func() { + So(err, ShouldBeNil) + }) + + o, err := store.CreateDir(path) + Convey("The second returned error also should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("The Object Path should equal to the input path", func() { + So(o.Path, ShouldEqual, path) + }) + + Convey("The Object Mode should be dir", func() { + // Dir object's mode must be Dir. + So(o.Mode.IsDir(), ShouldBeTrue) + }) + }) + + Convey("When Create with ModeDir", func() { + path := uuid.New().String() + o := store.Create(path, pairs.WithObjectMode(types.ModeDir)) + + defer func() { + err := store.Delete(path, pairs.WithObjectMode(types.ModeDir)) + if err != nil { + t.Error(err) + } + }() + + Convey("The Object Path should equal to the input path", func() { + So(o.Path, ShouldEqual, path) + }) + + Convey("The Object Mode should be dir", func() { + // Dir object's mode must be Dir. + So(o.Mode.IsDir(), ShouldBeTrue) + }) + }) + + Convey("When Stat with ModeDir", func() { + path := uuid.New().String() + _, err := store.CreateDir(path) + if err != nil { + t.Error(err) + } + + defer func() { + err := store.Delete(path, pairs.WithObjectMode(types.ModeDir)) + if err != nil { + t.Error(err) + } + }() + + o, err := store.Stat(path, pairs.WithObjectMode(types.ModeDir)) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("The Object Path should equal to the input path", func() { + So(o.Path, ShouldEqual, path) + }) + + Convey("The Object Mode should be dir", func() { + // Dir object's mode must be Dir. + So(o.Mode.IsDir(), ShouldBeTrue) + }) + }) + + Convey("When Delete with ModeDir", func() { + path := uuid.New().String() + _, err := store.CreateDir(path) + if err != nil { + t.Error(err) + } + + err = store.Delete(path, pairs.WithObjectMode(types.ModeDir)) + Convey("The first returned error should be nil", func() { + So(err, ShouldBeNil) + }) + + err = store.Delete(path, pairs.WithObjectMode(types.ModeDir)) + Convey("The second returned error also should be nil", func() { + So(err, ShouldBeNil) + }) + }) + }) +} + +// Deprecated: Moved to TestStorager. +func TestLinker(t *testing.T, store types.Storager) { + Convey("Given a basic Storager", t, func() { + + workDir := store.Metadata().WorkDir + + Convey("When create a link object", func() { + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + r := io.LimitReader(randbytes.NewRand(), size) + target := uuid.New().String() + + _, err := store.Write(target, r, size) + if err != nil { + t.Fatal(err) + } + + defer func() { + err = store.Delete(target) + if err != nil { + t.Error(err) + } + }() + + path := uuid.New().String() + o, err := store.CreateLink(path, target) + + defer func() { + err = store.Delete(path) + if err != nil { + t.Error(err) + } + }() + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("The object mode should be link", func() { + // Link object's mode must be link. + So(o.Mode.IsLink(), ShouldBeTrue) + }) + + Convey("The linkTarget of the object must be the same as the target", func() { + // The linkTarget must be the same as the target. + linkTarget, ok := o.GetLinkTarget() + + So(ok, ShouldBeTrue) + So(linkTarget, ShouldEqual, filepath.Join(workDir, target)) + }) + + Convey("Stat should get path object without error", func() { + obj, err := store.Stat(path) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("The object mode should be link", func() { + // Link object's mode must be link. + So(obj.Mode.IsLink(), ShouldBeTrue) + }) + + Convey("The linkTarget of the object must be the same as the target", func() { + // The linkTarget must be the same as the target. + linkTarget, ok := obj.GetLinkTarget() + + So(ok, ShouldBeTrue) + So(linkTarget, ShouldEqual, filepath.Join(workDir, target)) + }) + }) + }) + + Convey("When create a link object from a not existing target", func() { + target := uuid.New().String() + + path := uuid.New().String() + o, err := store.CreateLink(path, target) + + defer func() { + err = store.Delete(path) + if err != nil { + t.Error(err) + } + }() + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("The object mode should be link", func() { + // Link object's mode must be link. + So(o.Mode.IsLink(), ShouldBeTrue) + }) + + Convey("The linkTarget of the object must be the same as the target", func() { + linkTarget, ok := o.GetLinkTarget() + + So(ok, ShouldBeTrue) + So(linkTarget, ShouldEqual, filepath.Join(workDir, target)) + }) + + Convey("Stat should get path object without error", func() { + obj, err := store.Stat(path) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("The object mode should be link", func() { + // Link object's mode must be link. + So(obj.Mode.IsLink(), ShouldBeTrue) + }) + + Convey("The linkTarget of the object must be the same as the target", func() { + // The linkTarget must be the same as the target. + linkTarget, ok := obj.GetLinkTarget() + + So(ok, ShouldBeTrue) + So(linkTarget, ShouldEqual, filepath.Join(workDir, target)) + }) + }) + }) + + Convey("When CreateLink to an existing path", func() { + firstSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + firstR := io.LimitReader(randbytes.NewRand(), firstSize) + firstTarget := uuid.New().String() + + _, err := store.Write(firstTarget, firstR, firstSize) + if err != nil { + t.Fatal(err) + } + + defer func() { + err = store.Delete(firstTarget) + if err != nil { + t.Error(err) + } + }() + + path := uuid.New().String() + o, err := store.CreateLink(path, firstTarget) + + defer func() { + err = store.Delete(path) + if err != nil { + t.Error(err) + } + }() + + Convey("The first returned error should be nil", func() { + So(err, ShouldBeNil) + }) + + secondSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + secondR := io.LimitReader(randbytes.NewRand(), secondSize) + secondTarget := uuid.New().String() + + _, err = store.Write(secondTarget, secondR, secondSize) + if err != nil { + t.Fatal(err) + } + + defer func() { + err = store.Delete(secondTarget) + if err != nil { + t.Error(err) + } + }() + + o, err = store.CreateLink(path, secondTarget) + + Convey("The second returned error should also be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("The object mode should be link", func() { + // Link object's mode must be link. + So(o.Mode.IsLink(), ShouldBeTrue) + }) + + Convey("The linkTarget of the object must be the same as the secondTarget", func() { + // The linkTarget must be the same as the secondTarget. + linkTarget, ok := o.GetLinkTarget() + + So(ok, ShouldBeTrue) + So(linkTarget, ShouldEqual, filepath.Join(workDir, secondTarget)) + }) + }) + }) +} + +// Deprecated: Moved to TestStorager. +func TestMover(t *testing.T, store types.Storager) { + Convey("Given a basic Storager", t, func() { + + Convey("When Move a file", func() { + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + content, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) + src := uuid.New().String() + + _, err := store.Write(src, bytes.NewReader(content), size) + if err != nil { + t.Fatal(err) + } + + defer func() { + err = store.Delete(src) + if err != nil { + t.Error(err) + } + }() + + dst := uuid.New().String() + err = store.Move(src, dst) + + defer func() { + err = store.Delete(dst) + if err != nil { + t.Error(err) + } + }() + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("Stat should get src object not exist", func() { + _, err := store.Stat(src) + + Convey("The error should be ErrObjectNotExist", func() { + So(errors.Is(err, services.ErrObjectNotExist), ShouldBeTrue) + }) + }) + + Convey("Read should get dst object data without error", func() { + var buf bytes.Buffer + n, err := store.Read(dst, &buf) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("The content should be match", func() { + So(buf, ShouldNotBeNil) + So(n, ShouldEqual, size) + So(md5.Sum(buf.Bytes()), ShouldResemble, md5.Sum(content)) + }) + }) + }) + + Convey("When Move to an existing file", func() { + srcSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + content, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), srcSize)) + src := uuid.New().String() + + _, err := store.Write(src, bytes.NewReader(content), srcSize) + if err != nil { + t.Fatal(err) + } + + defer func() { + err = store.Delete(src) + if err != nil { + t.Error(err) + } + }() + + dstSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + r := io.LimitReader(randbytes.NewRand(), dstSize) + dst := uuid.New().String() + + _, err = store.Write(dst, r, dstSize) + if err != nil { + t.Fatal(err) + } + + defer func() { + err = store.Delete(dst) + if err != nil { + t.Error(err) + } + }() + + err = store.Move(src, dst) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("Stat should get src object not exist", func() { + _, err := store.Stat(src) + + Convey("The error should be ErrObjectNotExist", func() { + So(errors.Is(err, services.ErrObjectNotExist), ShouldBeTrue) + }) + }) + + Convey("Read should get dst object data without error", func() { + var buf bytes.Buffer + n, err := store.Read(dst, &buf) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("The content should be match", func() { + So(buf, ShouldNotBeNil) + So(n, ShouldEqual, srcSize) + So(md5.Sum(buf.Bytes()), ShouldResemble, md5.Sum(content)) + }) + }) + }) + }) +} + +// Deprecated: Moved to TestStorager. +func TestMoverWithDir(t *testing.T, store types.Storager) { + Convey("Given a basic Storager", t, func() { + + Convey("When Move to an existing dir", func() { + + srcSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + r := io.LimitReader(randbytes.NewRand(), srcSize) + src := uuid.New().String() + + _, err := store.Write(src, r, srcSize) + if err != nil { + t.Fatal(err) + } + + defer func() { + err = store.Delete(src) + if err != nil { + t.Error(err) + } + }() + + dst := uuid.New().String() + _, err = store.CreateDir(dst) + if err != nil { + t.Fatal(err) + } + + defer func() { + err = store.Delete(dst, pairs.WithObjectMode(types.ModeDir)) + if err != nil { + t.Error(err) + } + }() + + err = store.Move(src, dst) + Convey("The error should be ErrObjectModeInvalid", func() { + So(errors.Is(err, services.ErrObjectModeInvalid), ShouldBeTrue) + }) + }) + }) +} + +// Deprecated: Moved to TestStorager. +func TestMoverWithVirtualDir(t *testing.T, store types.Storager) { + Convey("Given a basic Storager", t, func() { + + Convey("When Move to an existing dir", func() { + + srcSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + r := io.LimitReader(randbytes.NewRand(), srcSize) + src := uuid.New().String() + + _, err := store.Write(src, r, srcSize) + if err != nil { + t.Fatal(err) + } + + defer func() { + err = store.Delete(src) + if err != nil { + t.Error(err) + } + }() + + dst := uuid.New().String() + _, err = store.CreateDir(dst) + if err != nil { + t.Fatal(err) + } + + defer func() { + err = store.Delete(dst, pairs.WithObjectMode(types.ModeDir)) + if err != nil { + t.Error(err) + } + }() + + err = store.Move(src, dst) + + defer func() { + err = store.Delete(dst) + if err != nil { + t.Error(err) + } + }() + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("Stat should get dst object without error", func() { + o, err := store.Stat(dst) + + So(err, ShouldBeNil) + So(o, ShouldNotBeNil) + + Convey("The Object Mode should be read", func() { + So(o.Mode.IsRead(), ShouldBeTrue) + }) + + Convey("The path and size should be match", func() { + So(o, ShouldNotBeNil) + So(o.Path, ShouldEqual, dst) + + osize, ok := o.GetContentLength() + So(ok, ShouldBeTrue) + So(osize, ShouldEqual, srcSize) + }) + }) + }) + }) +} + +// Deprecated: Moved to TestStorager. +func TestMultipartHTTPSigner(t *testing.T, store types.Storager) { + Convey("Given a basic Storager", t, func() { + + Convey("When CreateMultipart via QuerySignHTTPCreateMultipart", func() { + path := uuid.New().String() + req, err := store.QuerySignHTTPCreateMultipart(path, time.Duration(time.Hour)) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + + So(req, ShouldNotBeNil) + So(req.URL, ShouldNotBeNil) + }) + + client := http.Client{} + _, err = client.Do(req) + + Convey("The request returned error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("List with ModePart should get the object without error", func() { + it, err := store.List(path, pairs.WithListMode(types.ListModePart)) + + So(err, ShouldBeNil) + + o, err := it.Next() + So(err, ShouldBeNil) + So(o, ShouldNotBeNil) + So(o.Path, ShouldEqual, path) + }) + + defer func() { + it, err := store.List(path, pairs.WithListMode(types.ListModePart)) + if err != nil { + t.Error(err) + } + + o, err := it.Next() + if err != nil { + t.Error(err) + } + + err = store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) + if err != nil { + t.Error(err) + } + }() + }) + + Convey("When WriteMultipart via QuerySignHTTPWriteMultipart", func() { + path := uuid.New().String() + o, err := store.CreateMultipart(path) + if err != nil { + t.Error(err) + } + + defer func() { + err := store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) + if err != nil { + t.Error(err) + } + }() + + size := rand.Int63n(4 * 1024 * 1024) + content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) + if err != nil { + t.Error(err) + } + + req, err := store.QuerySignHTTPWriteMultipart(o, size, 0, time.Duration(time.Hour)) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + + So(req, ShouldNotBeNil) + So(req.URL, ShouldNotBeNil) + }) + + req.Body = io.NopCloser(bytes.NewReader(content)) + + client := http.Client{} + resp, err := client.Do(req) + + Convey("The request returned error should be nil", func() { + So(err, ShouldBeNil) + So(resp, ShouldNotBeNil) + }) + + Convey("The size should be match", func() { + So(resp.Request.ContentLength, ShouldEqual, size) + }) + }) + + Convey("When ListMultiPart via QuerySignHTTPListMultiPart", func() { + path := uuid.New().String() + o, err := store.CreateMultipart(path) + if err != nil { + t.Error(err) + } + + defer func() { + err := store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) + if err != nil { + t.Error(err) + } + }() + + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + partNumber := rand.Intn(1000) // Choose a random part number from [0, 1000) + r := io.LimitReader(randbytes.NewRand(), size) + + _, _, err = store.WriteMultipart(o, r, size, partNumber) + if err != nil { + t.Error(err) + } + + req, err := store.QuerySignHTTPListMultipart(o, time.Duration(time.Hour)) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + + So(req, ShouldNotBeNil) + So(req.URL, ShouldNotBeNil) + }) + + client := http.Client{} + _, err = client.Do(req) + + Convey("The request returned error should be nil", func() { + So(err, ShouldBeNil) + }) + }) + + Convey("When CompletePart via QuerySignHTTPCompletePart", func() { + path := uuid.New().String() + o, err := store.CreateMultipart(path) + if err != nil { + t.Error(err) + } + + defer func() { + err := store.Delete(path) + if err != nil { + t.Error(err) + } + }() + + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + // Set 0 to `partNumber` here as the part numbers must be continuous for `CompleteMultipartUpload` in `cos` which is different with other storages. + partNumber := 0 + r := io.LimitReader(randbytes.NewRand(), size) + + _, part, err := store.WriteMultipart(o, r, size, partNumber) + if err != nil { + t.Error(err) + } + + req, err := store.QuerySignHTTPCompleteMultipart(o, []*types.Part{part}, time.Duration(time.Hour)) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + + So(req, ShouldNotBeNil) + So(req.URL, ShouldNotBeNil) + }) + + client := http.Client{} + _, err = client.Do(req) + + Convey("The request returned error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("The object should be readable after complete", func() { + ro, err := store.Stat(path) + + So(err, ShouldBeNil) + So(ro.Mode.IsRead(), ShouldBeTrue) + So(ro.Mode.IsPart(), ShouldBeFalse) + }) + }) + }) +} + +// Deprecated: Moved to TestStorager. +func TestMultiparter(t *testing.T, store types.Storager) { + Convey("Given a basic Storager", t, func() { + + Convey("When CreateMultipart", func() { + path := uuid.New().String() + o, err := store.CreateMultipart(path) + + Convey("The first returned error should be nil", func() { + So(err, ShouldBeNil) + }) + + defer func(multipartID string) { + err := store.Delete(path, pairs.WithMultipartID(multipartID)) + if err != nil { + t.Error(err) + } + }(o.MustGetMultipartID()) + + o, err = store.CreateMultipart(path) + + Convey("The second returned error also should be nil", func() { + So(err, ShouldBeNil) + }) + + defer func() { + err := store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) + if err != nil { + t.Error(err) + } + }() + + Convey("The Object Mode should be part", func() { + // Multipart object's mode must be Part. + So(o.Mode.IsPart(), ShouldBeTrue) + // Multipart object's mode must not be Read. + So(o.Mode.IsRead(), ShouldBeFalse) + }) + + Convey("The Object must have multipart id", func() { + // Multipart object must have multipart id. + _, ok := o.GetMultipartID() + So(ok, ShouldBeTrue) + }) + }) + + Convey("When Delete with multipart id", func() { + path := uuid.New().String() + o, err := store.CreateMultipart(path) + if err != nil { + t.Error(err) + } + + err = store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) + Convey("The first returned error should be nil", func() { + So(err, ShouldBeNil) + }) + + err = store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) + Convey("The second returned error also should be nil", func() { + So(err, ShouldBeNil) + }) + }) + + Convey("When Stat with multipart id", func() { + path := uuid.New().String() + o, err := store.CreateMultipart(path) + if err != nil { + t.Error(err) + } + + multipartId := o.MustGetMultipartID() + + defer func() { + err := store.Delete(path, pairs.WithMultipartID(multipartId)) + if err != nil { + t.Error(err) + } + }() + + mo, err := store.Stat(path, pairs.WithMultipartID(multipartId)) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + So(mo, ShouldNotBeNil) + }) + + Convey("The Object Mode should be part", func() { + // Multipart object's mode must be Part. + So(mo.Mode.IsPart(), ShouldBeTrue) + // Multipart object's mode must not be Read. + So(mo.Mode.IsRead(), ShouldBeFalse) + }) + + Convey("The Object must have multipart id", func() { + // Multipart object must have multipart id. + mid, ok := mo.GetMultipartID() + So(ok, ShouldBeTrue) + So(mid, ShouldEqual, multipartId) + }) + }) + + Convey("When Create with multipart id", func() { + path := uuid.New().String() + o, err := store.CreateMultipart(path) + if err != nil { + t.Error(err) + } + + multipartId := o.MustGetMultipartID() + + defer func() { + err := store.Delete(path, pairs.WithMultipartID(multipartId)) + if err != nil { + t.Error(err) + } + }() + + mo := store.Create(path, pairs.WithMultipartID(multipartId)) + + Convey("The Object Mode should be part", func() { + // Multipart object's mode must be Part. + So(mo.Mode.IsPart(), ShouldBeTrue) + // Multipart object's mode must not be Read. + So(mo.Mode.IsRead(), ShouldBeFalse) + }) + + Convey("The Object must have multipart id", func() { + // Multipart object must have multipart id. + mid, ok := mo.GetMultipartID() + So(ok, ShouldBeTrue) + So(mid, ShouldEqual, multipartId) + }) + }) + + Convey("When WriteMultipart", func() { + path := uuid.New().String() + o, err := store.CreateMultipart(path) + if err != nil { + t.Error(err) + } + + defer func() { + err := store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) + if err != nil { + t.Error(err) + } + }() + + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + r := io.LimitReader(randbytes.NewRand(), size) + + n, part, err := store.WriteMultipart(o, r, size, 0) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("The part should not be nil", func() { + So(part, ShouldNotBeNil) + }) + + Convey("The size should be match", func() { + So(n, ShouldEqual, size) + }) + }) + + Convey("When ListMultiPart", func() { + path := uuid.New().String() + o, err := store.CreateMultipart(path) + if err != nil { + t.Error(err) + } + + defer func() { + err := store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) + if err != nil { + t.Error(err) + } + }() + + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + partNumber := rand.Intn(1000) // Choose a random part number from [0, 1000) + r := io.LimitReader(randbytes.NewRand(), size) + + _, _, err = store.WriteMultipart(o, r, size, partNumber) + if err != nil { + t.Error(err) + } + + it, err := store.ListMultipart(o) + + Convey("ListMultipart error should be nil", func() { + So(err, ShouldBeNil) + So(it, ShouldNotBeNil) + }) + + p, err := it.Next() + Convey("Next error should be nil", func() { + So(err, ShouldBeNil) + So(p, ShouldNotBeNil) + }) + Convey("The part number and size should be match", func() { + So(p.Index, ShouldEqual, partNumber) + So(p.Size, ShouldEqual, size) + }) + }) + + Convey("When List with part type", func() { + path := uuid.New().String() + o, err := store.CreateMultipart(path) + if err != nil { + t.Error(err) + } + + defer func() { + err := store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) + if err != nil { + t.Error(err) + } + }() + + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + partNumber := rand.Intn(1000) // Choose a random part number from [0, 1000) + r := io.LimitReader(randbytes.NewRand(), size) + + _, _, err = store.WriteMultipart(o, r, size, partNumber) + if err != nil { + t.Error(err) + } + + it, err := store.List("", pairs.WithListMode(types.ListModePart)) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + Convey("The iterator should not be nil", func() { + So(it, ShouldNotBeNil) + }) + + mo, err := it.Next() + Convey("Next error should be nil", func() { + So(err, ShouldBeNil) + So(mo, ShouldNotBeNil) + }) + Convey("The path and multipart id should be match", func() { + So(mo.Path, ShouldEqual, path) + So(mo.Mode.IsPart(), ShouldBeTrue) + + // Multipart object must have multipart id. + mid, ok := mo.GetMultipartID() + So(ok, ShouldBeTrue) + So(mid, ShouldEqual, o.MustGetMultipartID()) + }) + }) + + Convey("When CompletePart", func() { + path := uuid.New().String() + o, err := store.CreateMultipart(path) + if err != nil { + t.Error(err) + } + + defer func() { + err := store.Delete(path) + if err != nil { + t.Error(err) + } + }() + + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + // Set 0 to `partNumber` here as the part numbers must be continuous for `CompleteMultipartUpload` in `cos` which is different with other storages. + partNumber := 0 + r := io.LimitReader(randbytes.NewRand(), size) + + _, part, err := store.WriteMultipart(o, r, size, partNumber) + if err != nil { + t.Error(err) + } + + err = store.CompleteMultipart(o, []*types.Part{part}) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("The object should be readable after complete", func() { + ro, err := store.Stat(path) + + So(err, ShouldBeNil) + So(ro.Mode.IsRead(), ShouldBeTrue) + So(ro.Mode.IsPart(), ShouldBeFalse) + }) + }) + }) +} + +// Deprecated: Moved to TestStorager. +func TestStorageHTTPSignerRead(t *testing.T, store types.Storager) { + Convey("Given a basic Storager", t, func() { + + Convey("When Read via QuerySignHTTPRead", func() { + size := rand.Int63n(4 * 1024 * 1024) + content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) + if err != nil { + t.Error(err) + } + + path := uuid.New().String() + _, err = store.Write(path, bytes.NewReader(content), size) + if err != nil { + t.Error(err) + } + defer func() { + err := store.Delete(path) + if err != nil { + t.Error(err) + } + }() + + req, err := store.QuerySignHTTPRead(path, time.Hour) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + + So(req, ShouldNotBeNil) + So(req.URL, ShouldNotBeNil) + }) + + client := http.Client{} + resp, err := client.Do(req) + Convey("The request returned error should be nil", func() { + So(err, ShouldBeNil) + So(resp, ShouldNotBeNil) + }) + + defer resp.Body.Close() + + buf, err := io.ReadAll(resp.Body) + Convey("The content should be match", func() { + So(err, ShouldBeNil) + So(buf, ShouldNotBeNil) + + So(resp.ContentLength, ShouldEqual, size) + So(sha256.Sum256(buf), ShouldResemble, sha256.Sum256(content)) + }) + }) + }) +} + +// Deprecated: Moved to TestStorager. +func TestStorageHTTPSignerWrite(t *testing.T, store types.Storager) { + Convey("Given a basic Storager", t, func() { + + Convey("When Write via QuerySignHTTPWrite", func() { + size := rand.Int63n(4 * 1024 * 1024) + content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) + if err != nil { + t.Error(err) + } + + path := uuid.New().String() + req, err := store.QuerySignHTTPWrite(path, size, time.Hour) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + So(req, ShouldNotBeNil) + So(req.URL, ShouldNotBeNil) + }) + + req.Body = io.NopCloser(bytes.NewReader(content)) + + client := http.Client{} + _, err = client.Do(req) + Convey("The request returned error should be nil", func() { + So(err, ShouldBeNil) + }) + + defer func() { + err := store.Delete(path) + if err != nil { + t.Error(err) + } + }() + + Convey("Read should get object data without error", func() { + var buf bytes.Buffer + n, err := store.Read(path, &buf) + + Convey("The content should be match", func() { + So(err, ShouldBeNil) + So(buf, ShouldNotBeNil) + + So(n, ShouldEqual, size) + So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(content)) + }) + }) + }) + }) +} + +// Deprecated: Moved to TestStorager. +func TestStorageHTTPSignerDelete(t *testing.T, store types.Storager) { + Convey("Given a basic Storager", t, func() { + + Convey("When Delete via QuerySignHTTPDelete", func() { + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + r := io.LimitReader(randbytes.NewRand(), size) + + path := uuid.New().String() + _, err := store.Write(path, r, size) + if err != nil { + t.Error(err) + } + + req, err := store.QuerySignHTTPDelete(path, time.Hour) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + + So(req, ShouldNotBeNil) + So(req.URL, ShouldNotBeNil) + }) + + client := http.Client{} + _, err = client.Do(req) + + Convey("The request returned error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("Stat should get nil Object and ObjectNotFound error", func() { + o, err := store.Stat(path) + + So(errors.Is(err, services.ErrObjectNotExist), ShouldBeTrue) + So(o, ShouldBeNil) + }) + }) + + Convey("When Delete with multipart id via QuerySignHTTPDelete", func() { + path := uuid.New().String() + o, err := store.CreateMultipart(path) + if err != nil { + t.Error(err) + } + + req, err := store.QuerySignHTTPDelete(path, time.Hour, pairs.WithMultipartID(o.MustGetMultipartID())) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + + So(req, ShouldNotBeNil) + So(req.URL, ShouldNotBeNil) + }) + + client := http.Client{} + _, err = client.Do(req) + + Convey("The first request returned error should be nil", func() { + So(err, ShouldBeNil) + }) + + _, err = client.Do(req) + + Convey("The second request returned error should be nil", func() { + So(err, ShouldBeNil) + }) + }) + }) +} diff --git a/tests/direr.go b/tests/direr.go index 873582f22..604283fc0 100644 --- a/tests/direr.go +++ b/tests/direr.go @@ -10,41 +10,39 @@ import ( "go.beyondstorage.io/v5/types" ) -func TestDirer(t *testing.T, store types.Storager) { - Convey("Given a basic Storager", t, func() { - - f := store.Features() - if f.CreateDir && f.Delete && f.Stat { - Convey("When CreateDir", func() { - path := uuid.New().String() - _, err := store.CreateDir(path) - - defer func() { - err := store.Delete(path, pairs.WithObjectMode(types.ModeDir)) - if err != nil { - t.Error(err) - } - }() +func testDirer(t *testing.T, store types.Storager, f types.StorageFeatures) { + if f.CreateDir && f.Delete { + Convey("When CreateDir", func() { + path := uuid.New().String() + _, err := store.CreateDir(path) + + defer func() { + err := store.Delete(path, pairs.WithObjectMode(types.ModeDir)) + if err != nil { + t.Error(err) + } + }() - Convey("The first returned error should be nil", func() { - So(err, ShouldBeNil) - }) + Convey("The first returned error should be nil", func() { + So(err, ShouldBeNil) + }) - o, err := store.CreateDir(path) - Convey("The second returned error also should be nil", func() { - So(err, ShouldBeNil) - }) + o, err := store.CreateDir(path) + Convey("The second returned error also should be nil", func() { + So(err, ShouldBeNil) + }) - Convey("The Object Path should equal to the input path", func() { - So(o.Path, ShouldEqual, path) - }) + Convey("The Object Path should equal to the input path", func() { + So(o.Path, ShouldEqual, path) + }) - Convey("The Object Mode should be dir", func() { - // Dir object's mode must be Dir. - So(o.Mode.IsDir(), ShouldBeTrue) - }) + Convey("The Object Mode should be dir", func() { + // Dir object's mode must be Dir. + So(o.Mode.IsDir(), ShouldBeTrue) }) + }) + if f.Create { Convey("When Create with ModeDir", func() { path := uuid.New().String() o := store.Create(path, pairs.WithObjectMode(types.ModeDir)) @@ -65,7 +63,9 @@ func TestDirer(t *testing.T, store types.Storager) { So(o.Mode.IsDir(), ShouldBeTrue) }) }) + } + if f.Stat { Convey("When Stat with ModeDir", func() { path := uuid.New().String() _, err := store.CreateDir(path) @@ -95,24 +95,24 @@ func TestDirer(t *testing.T, store types.Storager) { So(o.Mode.IsDir(), ShouldBeTrue) }) }) + } - Convey("When Delete with ModeDir", func() { - path := uuid.New().String() - _, err := store.CreateDir(path) - if err != nil { - t.Error(err) - } + Convey("When Delete with ModeDir", func() { + path := uuid.New().String() + _, err := store.CreateDir(path) + if err != nil { + t.Error(err) + } - err = store.Delete(path, pairs.WithObjectMode(types.ModeDir)) - Convey("The first returned error should be nil", func() { - So(err, ShouldBeNil) - }) + err = store.Delete(path, pairs.WithObjectMode(types.ModeDir)) + Convey("The first returned error should be nil", func() { + So(err, ShouldBeNil) + }) - err = store.Delete(path, pairs.WithObjectMode(types.ModeDir)) - Convey("The second returned error also should be nil", func() { - So(err, ShouldBeNil) - }) + err = store.Delete(path, pairs.WithObjectMode(types.ModeDir)) + Convey("The second returned error also should be nil", func() { + So(err, ShouldBeNil) }) - } - }) + }) + } } diff --git a/tests/linker.go b/tests/linker.go index cf24c8716..0b66c58d8 100644 --- a/tests/linker.go +++ b/tests/linker.go @@ -13,39 +13,56 @@ import ( "go.beyondstorage.io/v5/types" ) -func TestLinker(t *testing.T, store types.Storager) { - Convey("Given a basic Storager", t, func() { - - f := store.Features() - if f.CreateLink && f.Write && f.Delete && f.Stat { - workDir := store.Metadata().WorkDir +func testLinker(t *testing.T, store types.Storager, f types.StorageFeatures) { + if f.CreateLink && f.Metadata && f.Write && f.Delete && f.Stat { + workDir := store.Metadata().WorkDir + + Convey("When create a link object", func() { + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + r := io.LimitReader(randbytes.NewRand(), size) + target := uuid.New().String() + + _, err := store.Write(target, r, size) + if err != nil { + t.Fatal(err) + } + + defer func() { + err = store.Delete(target) + if err != nil { + t.Error(err) + } + }() - Convey("When create a link object", func() { - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - r := io.LimitReader(randbytes.NewRand(), size) - target := uuid.New().String() + path := uuid.New().String() + o, err := store.CreateLink(path, target) - _, err := store.Write(target, r, size) + defer func() { + err = store.Delete(path) if err != nil { - t.Fatal(err) + t.Error(err) } + }() + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) - defer func() { - err = store.Delete(target) - if err != nil { - t.Error(err) - } - }() + Convey("The object mode should be link", func() { + // Link object's mode must be link. + So(o.Mode.IsLink(), ShouldBeTrue) + }) + + Convey("The linkTarget of the object must be the same as the target", func() { + // The linkTarget must be the same as the target. + linkTarget, ok := o.GetLinkTarget() - path := uuid.New().String() - o, err := store.CreateLink(path, target) + So(ok, ShouldBeTrue) + So(linkTarget, ShouldEqual, filepath.Join(workDir, target)) + }) - defer func() { - err = store.Delete(path) - if err != nil { - t.Error(err) - } - }() + Convey("Stat should get path object without error", func() { + obj, err := store.Stat(path) Convey("The error should be nil", func() { So(err, ShouldBeNil) @@ -53,51 +70,50 @@ func TestLinker(t *testing.T, store types.Storager) { Convey("The object mode should be link", func() { // Link object's mode must be link. - So(o.Mode.IsLink(), ShouldBeTrue) + So(obj.Mode.IsLink(), ShouldBeTrue) }) Convey("The linkTarget of the object must be the same as the target", func() { // The linkTarget must be the same as the target. - linkTarget, ok := o.GetLinkTarget() + linkTarget, ok := obj.GetLinkTarget() So(ok, ShouldBeTrue) So(linkTarget, ShouldEqual, filepath.Join(workDir, target)) }) + }) + }) - Convey("Stat should get path object without error", func() { - obj, err := store.Stat(path) + Convey("When create a link object from a not existing target", func() { + target := uuid.New().String() - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) + path := uuid.New().String() + o, err := store.CreateLink(path, target) - Convey("The object mode should be link", func() { - // Link object's mode must be link. - So(obj.Mode.IsLink(), ShouldBeTrue) - }) + defer func() { + err = store.Delete(path) + if err != nil { + t.Error(err) + } + }() - Convey("The linkTarget of the object must be the same as the target", func() { - // The linkTarget must be the same as the target. - linkTarget, ok := obj.GetLinkTarget() + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) - So(ok, ShouldBeTrue) - So(linkTarget, ShouldEqual, filepath.Join(workDir, target)) - }) - }) + Convey("The object mode should be link", func() { + // Link object's mode must be link. + So(o.Mode.IsLink(), ShouldBeTrue) }) - Convey("When create a link object from a not existing target", func() { - target := uuid.New().String() + Convey("The linkTarget of the object must be the same as the target", func() { + linkTarget, ok := o.GetLinkTarget() - path := uuid.New().String() - o, err := store.CreateLink(path, target) + So(ok, ShouldBeTrue) + So(linkTarget, ShouldEqual, filepath.Join(workDir, target)) + }) - defer func() { - err = store.Delete(path) - if err != nil { - t.Error(err) - } - }() + Convey("Stat should get path object without error", func() { + obj, err := store.Stat(path) Convey("The error should be nil", func() { So(err, ShouldBeNil) @@ -105,104 +121,84 @@ func TestLinker(t *testing.T, store types.Storager) { Convey("The object mode should be link", func() { // Link object's mode must be link. - So(o.Mode.IsLink(), ShouldBeTrue) + So(obj.Mode.IsLink(), ShouldBeTrue) }) Convey("The linkTarget of the object must be the same as the target", func() { - linkTarget, ok := o.GetLinkTarget() + // The linkTarget must be the same as the target. + linkTarget, ok := obj.GetLinkTarget() So(ok, ShouldBeTrue) So(linkTarget, ShouldEqual, filepath.Join(workDir, target)) }) - - Convey("Stat should get path object without error", func() { - obj, err := store.Stat(path) - - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) - - Convey("The object mode should be link", func() { - // Link object's mode must be link. - So(obj.Mode.IsLink(), ShouldBeTrue) - }) - - Convey("The linkTarget of the object must be the same as the target", func() { - // The linkTarget must be the same as the target. - linkTarget, ok := obj.GetLinkTarget() - - So(ok, ShouldBeTrue) - So(linkTarget, ShouldEqual, filepath.Join(workDir, target)) - }) - }) }) + }) + + Convey("When CreateLink to an existing path", func() { + firstSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + firstR := io.LimitReader(randbytes.NewRand(), firstSize) + firstTarget := uuid.New().String() - Convey("When CreateLink to an existing path", func() { - firstSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - firstR := io.LimitReader(randbytes.NewRand(), firstSize) - firstTarget := uuid.New().String() + _, err := store.Write(firstTarget, firstR, firstSize) + if err != nil { + t.Fatal(err) + } - _, err := store.Write(firstTarget, firstR, firstSize) + defer func() { + err = store.Delete(firstTarget) if err != nil { - t.Fatal(err) + t.Error(err) } + }() - defer func() { - err = store.Delete(firstTarget) - if err != nil { - t.Error(err) - } - }() + path := uuid.New().String() + o, err := store.CreateLink(path, firstTarget) - path := uuid.New().String() - o, err := store.CreateLink(path, firstTarget) + defer func() { + err = store.Delete(path) + if err != nil { + t.Error(err) + } + }() - defer func() { - err = store.Delete(path) - if err != nil { - t.Error(err) - } - }() + Convey("The first returned error should be nil", func() { + So(err, ShouldBeNil) + }) - Convey("The first returned error should be nil", func() { - So(err, ShouldBeNil) - }) + secondSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + secondR := io.LimitReader(randbytes.NewRand(), secondSize) + secondTarget := uuid.New().String() - secondSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - secondR := io.LimitReader(randbytes.NewRand(), secondSize) - secondTarget := uuid.New().String() + _, err = store.Write(secondTarget, secondR, secondSize) + if err != nil { + t.Fatal(err) + } - _, err = store.Write(secondTarget, secondR, secondSize) + defer func() { + err = store.Delete(secondTarget) if err != nil { - t.Fatal(err) + t.Error(err) } + }() - defer func() { - err = store.Delete(secondTarget) - if err != nil { - t.Error(err) - } - }() - - o, err = store.CreateLink(path, secondTarget) + o, err = store.CreateLink(path, secondTarget) - Convey("The second returned error should also be nil", func() { - So(err, ShouldBeNil) - }) + Convey("The second returned error should also be nil", func() { + So(err, ShouldBeNil) + }) - Convey("The object mode should be link", func() { - // Link object's mode must be link. - So(o.Mode.IsLink(), ShouldBeTrue) - }) + Convey("The object mode should be link", func() { + // Link object's mode must be link. + So(o.Mode.IsLink(), ShouldBeTrue) + }) - Convey("The linkTarget of the object must be the same as the secondTarget", func() { - // The linkTarget must be the same as the secondTarget. - linkTarget, ok := o.GetLinkTarget() + Convey("The linkTarget of the object must be the same as the secondTarget", func() { + // The linkTarget must be the same as the secondTarget. + linkTarget, ok := o.GetLinkTarget() - So(ok, ShouldBeTrue) - So(linkTarget, ShouldEqual, filepath.Join(workDir, secondTarget)) - }) + So(ok, ShouldBeTrue) + So(linkTarget, ShouldEqual, filepath.Join(workDir, secondTarget)) }) - } - }) + }) + } } diff --git a/tests/mover.go b/tests/mover.go index 282a18502..1b47c60a2 100644 --- a/tests/mover.go +++ b/tests/mover.go @@ -17,243 +17,232 @@ import ( "go.beyondstorage.io/v5/types" ) -func TestMover(t *testing.T, store types.Storager) { - Convey("Given a basic Storager", t, func() { +func testMover(t *testing.T, store types.Storager, f types.StorageFeatures) { + if f.Move && f.Write && f.Read && f.Delete && f.Stat { + // move a file to a non-existent file + Convey("When Move a file", func() { + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + content, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) + src := uuid.New().String() + + _, err := store.Write(src, bytes.NewReader(content), size) + if err != nil { + t.Fatal(err) + } + + defer func() { + err = store.Delete(src) + if err != nil { + t.Error(err) + } + }() - f := store.Features() - if f.Move && f.Write && f.Read && f.Delete && f.Stat { - Convey("When Move a file", func() { - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - content, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) - src := uuid.New().String() + dst := uuid.New().String() + err = store.Move(src, dst) - _, err := store.Write(src, bytes.NewReader(content), size) + defer func() { + err = store.Delete(dst) if err != nil { - t.Fatal(err) + t.Error(err) } + }() - defer func() { - err = store.Delete(src) - if err != nil { - t.Error(err) - } - }() - - dst := uuid.New().String() - err = store.Move(src, dst) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) - defer func() { - err = store.Delete(dst) - if err != nil { - t.Error(err) - } - }() + Convey("Stat should get src object not exist", func() { + _, err := store.Stat(src) - Convey("The error should be nil", func() { - So(err, ShouldBeNil) + Convey("The error should be ErrObjectNotExist", func() { + So(errors.Is(err, services.ErrObjectNotExist), ShouldBeTrue) }) + }) - Convey("Stat should get src object not exist", func() { - _, err := store.Stat(src) + Convey("Read should get dst object data without error", func() { + var buf bytes.Buffer + n, err := store.Read(dst, &buf) - Convey("The error should be ErrObjectNotExist", func() { - So(errors.Is(err, services.ErrObjectNotExist), ShouldBeTrue) - }) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) }) - Convey("Read should get dst object data without error", func() { - var buf bytes.Buffer - n, err := store.Read(dst, &buf) - - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) - - Convey("The content should be match", func() { - So(buf, ShouldNotBeNil) - So(n, ShouldEqual, size) - So(md5.Sum(buf.Bytes()), ShouldResemble, md5.Sum(content)) - }) + Convey("The content should be match", func() { + So(buf, ShouldNotBeNil) + So(n, ShouldEqual, size) + So(md5.Sum(buf.Bytes()), ShouldResemble, md5.Sum(content)) }) }) + }) - Convey("When Move to an existing file", func() { - srcSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - content, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), srcSize)) - src := uuid.New().String() + // move a file to an existing file + Convey("When Move to an existing file", func() { + srcSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + content, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), srcSize)) + src := uuid.New().String() - _, err := store.Write(src, bytes.NewReader(content), srcSize) + _, err := store.Write(src, bytes.NewReader(content), srcSize) + if err != nil { + t.Fatal(err) + } + + defer func() { + err = store.Delete(src) if err != nil { - t.Fatal(err) + t.Error(err) } + }() - defer func() { - err = store.Delete(src) - if err != nil { - t.Error(err) - } - }() + dstSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + r := io.LimitReader(randbytes.NewRand(), dstSize) + dst := uuid.New().String() - dstSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - r := io.LimitReader(randbytes.NewRand(), dstSize) - dst := uuid.New().String() + _, err = store.Write(dst, r, dstSize) + if err != nil { + t.Fatal(err) + } - _, err = store.Write(dst, r, dstSize) + defer func() { + err = store.Delete(dst) if err != nil { - t.Fatal(err) + t.Error(err) } + }() - defer func() { - err = store.Delete(dst) - if err != nil { - t.Error(err) - } - }() - - err = store.Move(src, dst) - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) + err = store.Move(src, dst) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) - Convey("Stat should get src object not exist", func() { - _, err := store.Stat(src) + Convey("Stat should get src object not exist", func() { + _, err := store.Stat(src) - Convey("The error should be ErrObjectNotExist", func() { - So(errors.Is(err, services.ErrObjectNotExist), ShouldBeTrue) - }) + Convey("The error should be ErrObjectNotExist", func() { + So(errors.Is(err, services.ErrObjectNotExist), ShouldBeTrue) }) + }) - Convey("Read should get dst object data without error", func() { - var buf bytes.Buffer - n, err := store.Read(dst, &buf) + Convey("Read should get dst object data without error", func() { + var buf bytes.Buffer + n, err := store.Read(dst, &buf) - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) - Convey("The content should be match", func() { - So(buf, ShouldNotBeNil) - So(n, ShouldEqual, srcSize) - So(md5.Sum(buf.Bytes()), ShouldResemble, md5.Sum(content)) - }) + Convey("The content should be match", func() { + So(buf, ShouldNotBeNil) + So(n, ShouldEqual, srcSize) + So(md5.Sum(buf.Bytes()), ShouldResemble, md5.Sum(content)) }) }) - } - }) -} - -func TestMoverWithDir(t *testing.T, store types.Storager) { - Convey("Given a basic Storager", t, func() { - - f := store.Features() - if f.Move && f.CreateDir && !f.VirtualDir && f.Write && f.Delete { - Convey("When Move to an existing dir", func() { - srcSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - r := io.LimitReader(randbytes.NewRand(), srcSize) - src := uuid.New().String() - - _, err := store.Write(src, r, srcSize) - if err != nil { - t.Fatal(err) - } - - defer func() { - err = store.Delete(src) + }) + + // move a file to an dir + if f.CreateDir { + if !f.VirtualDir { + // native supported dir + Convey("When Move to an existing dir", func() { + srcSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + r := io.LimitReader(randbytes.NewRand(), srcSize) + src := uuid.New().String() + + _, err := store.Write(src, r, srcSize) if err != nil { - t.Error(err) + t.Fatal(err) } - }() - - dst := uuid.New().String() - _, err = store.CreateDir(dst) - if err != nil { - t.Fatal(err) - } - - defer func() { - err = store.Delete(dst, pairs.WithObjectMode(types.ModeDir)) - if err != nil { - t.Error(err) - } - }() - - err = store.Move(src, dst) - Convey("The error should be ErrObjectModeInvalid", func() { - So(errors.Is(err, services.ErrObjectModeInvalid), ShouldBeTrue) - }) - }) - } - }) -} -func TestMoverWithVirtualDir(t *testing.T, store types.Storager) { - Convey("Given a basic Storager", t, func() { + defer func() { + err = store.Delete(src) + if err != nil { + t.Error(err) + } + }() - f := store.Features() - if f.Move && f.CreateDir && f.VirtualDir && f.Write && f.Delete && f.Stat { - Convey("When Move to an existing dir", func() { - srcSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - r := io.LimitReader(randbytes.NewRand(), srcSize) - src := uuid.New().String() - - _, err := store.Write(src, r, srcSize) - if err != nil { - t.Fatal(err) - } - - defer func() { - err = store.Delete(src) + dst := uuid.New().String() + _, err = store.CreateDir(dst) if err != nil { - t.Error(err) + t.Fatal(err) } - }() - dst := uuid.New().String() - _, err = store.CreateDir(dst) - if err != nil { - t.Fatal(err) - } + defer func() { + err = store.Delete(dst, pairs.WithObjectMode(types.ModeDir)) + if err != nil { + t.Error(err) + } + }() - defer func() { - err = store.Delete(dst, pairs.WithObjectMode(types.ModeDir)) + err = store.Move(src, dst) + Convey("The error should be ErrObjectModeInvalid", func() { + So(errors.Is(err, services.ErrObjectModeInvalid), ShouldBeTrue) + }) + }) + } else { + // virtual dir + Convey("When Move to an existing virtual dir", func() { + srcSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + r := io.LimitReader(randbytes.NewRand(), srcSize) + src := uuid.New().String() + + _, err := store.Write(src, r, srcSize) if err != nil { - t.Error(err) + t.Fatal(err) } - }() - err = store.Move(src, dst) + defer func() { + err = store.Delete(src) + if err != nil { + t.Error(err) + } + }() - defer func() { - err = store.Delete(dst) + dst := uuid.New().String() + _, err = store.CreateDir(dst) if err != nil { - t.Error(err) + t.Fatal(err) } - }() - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) + defer func() { + err = store.Delete(dst, pairs.WithObjectMode(types.ModeDir)) + if err != nil { + t.Error(err) + } + }() - Convey("Stat should get dst object without error", func() { - o, err := store.Stat(dst) + err = store.Move(src, dst) - So(err, ShouldBeNil) - So(o, ShouldNotBeNil) + defer func() { + err = store.Delete(dst) + if err != nil { + t.Error(err) + } + }() - Convey("The Object Mode should be read", func() { - So(o.Mode.IsRead(), ShouldBeTrue) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) }) - Convey("The path and size should be match", func() { + Convey("Stat should get dst object without error", func() { + o, err := store.Stat(dst) + + So(err, ShouldBeNil) So(o, ShouldNotBeNil) - So(o.Path, ShouldEqual, dst) - osize, ok := o.GetContentLength() - So(ok, ShouldBeTrue) - So(osize, ShouldEqual, srcSize) + Convey("The Object Mode should be read", func() { + So(o.Mode.IsRead(), ShouldBeTrue) + }) + + Convey("The path and size should be match", func() { + So(o, ShouldNotBeNil) + So(o.Path, ShouldEqual, dst) + + osize, ok := o.GetContentLength() + So(ok, ShouldBeTrue) + So(osize, ShouldEqual, srcSize) + }) }) }) - }) + } } - }) + } } diff --git a/tests/multipart_http_signer.go b/tests/multipart_http_signer.go index 194e98fbe..19e2ca7cc 100644 --- a/tests/multipart_http_signer.go +++ b/tests/multipart_http_signer.go @@ -16,61 +16,60 @@ import ( "go.beyondstorage.io/v5/types" ) -func TestMultipartHTTPSigner(t *testing.T, store types.Storager) { - Convey("Given a basic Storager", t, func() { - - f := store.Features() - - if f.QuerySignHTTPCreateMultipart && f.Delete && f.List { - Convey("When CreateMultipart via QuerySignHTTPCreateMultipart", func() { - path := uuid.New().String() - req, err := store.QuerySignHTTPCreateMultipart(path, time.Duration(time.Hour)) - - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - - So(req, ShouldNotBeNil) - So(req.URL, ShouldNotBeNil) - }) +func testMultipartHTTPSigner(t *testing.T, store types.Storager, f types.StorageFeatures) { + // createMultipart + if f.QuerySignHTTPCreateMultipart && f.Delete && f.List { + Convey("When CreateMultipart via QuerySignHTTPCreateMultipart", func() { + path := uuid.New().String() + req, err := store.QuerySignHTTPCreateMultipart(path, time.Duration(time.Hour)) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + + So(req, ShouldNotBeNil) + So(req.URL, ShouldNotBeNil) + }) - client := http.Client{} - _, err = client.Do(req) + client := http.Client{} + _, err = client.Do(req) - Convey("The request returned error should be nil", func() { - So(err, ShouldBeNil) - }) + Convey("The request returned error should be nil", func() { + So(err, ShouldBeNil) + }) - Convey("List with ModePart should get the object without error", func() { - it, err := store.List(path, pairs.WithListMode(types.ListModePart)) + Convey("List with ModePart should get the object without error", func() { + it, err := store.List(path, pairs.WithListMode(types.ListModePart)) - So(err, ShouldBeNil) + So(err, ShouldBeNil) - o, err := it.Next() - So(err, ShouldBeNil) - So(o, ShouldNotBeNil) - So(o.Path, ShouldEqual, path) - }) + o, err := it.Next() + So(err, ShouldBeNil) + So(o, ShouldNotBeNil) + So(o.Path, ShouldEqual, path) + }) - defer func() { - it, err := store.List(path, pairs.WithListMode(types.ListModePart)) - if err != nil { - t.Error(err) - } + defer func() { + it, err := store.List(path, pairs.WithListMode(types.ListModePart)) + if err != nil { + t.Error(err) + } - o, err := it.Next() - if err != nil { - t.Error(err) - } + o, err := it.Next() + if err != nil { + t.Error(err) + } - err = store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) - if err != nil { - t.Error(err) - } - }() - }) - } + err = store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) + if err != nil { + t.Error(err) + } + }() + }) + } - if f.QuerySignHTTPWriteMultipart && f.CreateMultipart && f.Delete { + if f.CreateMultipart && f.Delete { + // writeMultipart + if f.QuerySignHTTPWriteMultipart { Convey("When WriteMultipart via QuerySignHTTPWriteMultipart", func() { path := uuid.New().String() o, err := store.CreateMultipart(path) @@ -116,97 +115,101 @@ func TestMultipartHTTPSigner(t *testing.T, store types.Storager) { }) } - if f.QuerySignHTTPListMultipart && f.CreateMultipart && f.Delete { - Convey("When ListMultiPart via QuerySignHTTPListMultiPart", func() { - path := uuid.New().String() - o, err := store.CreateMultipart(path) - if err != nil { - t.Error(err) - } - - defer func() { - err := store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) + if f.WriteMultipart { + // listMultipart + if f.QuerySignHTTPListMultipart { + Convey("When ListMultiPart via QuerySignHTTPListMultiPart", func() { + path := uuid.New().String() + o, err := store.CreateMultipart(path) if err != nil { t.Error(err) } - }() - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - partNumber := rand.Intn(1000) // Choose a random part number from [0, 1000) - r := io.LimitReader(randbytes.NewRand(), size) + defer func() { + err := store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) + if err != nil { + t.Error(err) + } + }() - _, _, err = store.WriteMultipart(o, r, size, partNumber) - if err != nil { - t.Error(err) - } + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + partNumber := rand.Intn(1000) // Choose a random part number from [0, 1000) + r := io.LimitReader(randbytes.NewRand(), size) - req, err := store.QuerySignHTTPListMultipart(o, time.Duration(time.Hour)) + _, _, err = store.WriteMultipart(o, r, size, partNumber) + if err != nil { + t.Error(err) + } - Convey("The error should be nil", func() { - So(err, ShouldBeNil) + req, err := store.QuerySignHTTPListMultipart(o, time.Duration(time.Hour)) - So(req, ShouldNotBeNil) - So(req.URL, ShouldNotBeNil) - }) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) - client := http.Client{} - _, err = client.Do(req) + So(req, ShouldNotBeNil) + So(req.URL, ShouldNotBeNil) + }) - Convey("The request returned error should be nil", func() { - So(err, ShouldBeNil) - }) - }) - } + client := http.Client{} + _, err = client.Do(req) - if f.QuerySignHTTPCompleteMultipart && f.CreateMultipart && f.Delete && f.Stat { - Convey("When CompletePart via QuerySignHTTPCompletePart", func() { - path := uuid.New().String() - o, err := store.CreateMultipart(path) - if err != nil { - t.Error(err) - } + Convey("The request returned error should be nil", func() { + So(err, ShouldBeNil) + }) + }) + } - defer func() { - err := store.Delete(path) + // completeMultipart + if f.QuerySignHTTPCompleteMultipart && f.Stat { + Convey("When CompletePart via QuerySignHTTPCompletePart", func() { + path := uuid.New().String() + o, err := store.CreateMultipart(path) if err != nil { t.Error(err) } - }() - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - // Set 0 to `partNumber` here as the part numbers must be continuous for `CompleteMultipartUpload` in `cos` which is different with other storages. - partNumber := 0 - r := io.LimitReader(randbytes.NewRand(), size) + defer func() { + err := store.Delete(path) + if err != nil { + t.Error(err) + } + }() - _, part, err := store.WriteMultipart(o, r, size, partNumber) - if err != nil { - t.Error(err) - } + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + // Set 0 to `partNumber` here as the part numbers must be continuous for `CompleteMultipartUpload` in `cos` which is different with other storages. + partNumber := 0 + r := io.LimitReader(randbytes.NewRand(), size) - req, err := store.QuerySignHTTPCompleteMultipart(o, []*types.Part{part}, time.Duration(time.Hour)) + _, part, err := store.WriteMultipart(o, r, size, partNumber) + if err != nil { + t.Error(err) + } - Convey("The error should be nil", func() { - So(err, ShouldBeNil) + req, err := store.QuerySignHTTPCompleteMultipart(o, []*types.Part{part}, time.Duration(time.Hour)) - So(req, ShouldNotBeNil) - So(req.URL, ShouldNotBeNil) - }) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) - client := http.Client{} - _, err = client.Do(req) + So(req, ShouldNotBeNil) + So(req.URL, ShouldNotBeNil) + }) - Convey("The request returned error should be nil", func() { - So(err, ShouldBeNil) - }) + client := http.Client{} + _, err = client.Do(req) - Convey("The object should be readable after complete", func() { - ro, err := store.Stat(path) + Convey("The request returned error should be nil", func() { + So(err, ShouldBeNil) + }) - So(err, ShouldBeNil) - So(ro.Mode.IsRead(), ShouldBeTrue) - So(ro.Mode.IsPart(), ShouldBeFalse) + Convey("The object should be readable after complete", func() { + ro, err := store.Stat(path) + + So(err, ShouldBeNil) + So(ro.Mode.IsRead(), ShouldBeTrue) + So(ro.Mode.IsPart(), ShouldBeFalse) + }) }) - }) + } } - }) + } } diff --git a/tests/multiparter.go b/tests/multiparter.go index d9af54c35..e32975239 100644 --- a/tests/multiparter.go +++ b/tests/multiparter.go @@ -13,71 +13,69 @@ import ( "go.beyondstorage.io/v5/types" ) -func TestMultiparter(t *testing.T, store types.Storager) { - Convey("Given a basic Storager", t, func() { - - f := store.Features() - if f.CreateMultipart && f.WriteMultipart && f.ListMultipart && f.CompleteMultipart && f.Create && f.Delete && f.Stat { - Convey("When CreateMultipart", func() { - path := uuid.New().String() - o, err := store.CreateMultipart(path) - - Convey("The first returned error should be nil", func() { - So(err, ShouldBeNil) - }) - - defer func(multipartID string) { - err := store.Delete(path, pairs.WithMultipartID(multipartID)) - if err != nil { - t.Error(err) - } - }(o.MustGetMultipartID()) - - o, err = store.CreateMultipart(path) - - Convey("The second returned error also should be nil", func() { - So(err, ShouldBeNil) - }) +func testMultiparter(t *testing.T, store types.Storager, f types.StorageFeatures) { + if f.CreateMultipart && f.Delete { + Convey("When CreateMultipart", func() { + path := uuid.New().String() + o, err := store.CreateMultipart(path) + + Convey("The first returned error should be nil", func() { + So(err, ShouldBeNil) + }) - defer func() { - err := store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) - if err != nil { - t.Error(err) - } - }() + defer func(multipartID string) { + err := store.Delete(path, pairs.WithMultipartID(multipartID)) + if err != nil { + t.Error(err) + } + }(o.MustGetMultipartID()) - Convey("The Object Mode should be part", func() { - // Multipart object's mode must be Part. - So(o.Mode.IsPart(), ShouldBeTrue) - // Multipart object's mode must not be Read. - So(o.Mode.IsRead(), ShouldBeFalse) - }) + o, err = store.CreateMultipart(path) - Convey("The Object must have multipart id", func() { - // Multipart object must have multipart id. - _, ok := o.GetMultipartID() - So(ok, ShouldBeTrue) - }) + Convey("The second returned error also should be nil", func() { + So(err, ShouldBeNil) }) - Convey("When Delete with multipart id", func() { - path := uuid.New().String() - o, err := store.CreateMultipart(path) + defer func() { + err := store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) if err != nil { t.Error(err) } + }() - err = store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) - Convey("The first returned error should be nil", func() { - So(err, ShouldBeNil) - }) + Convey("The Object Mode should be part", func() { + // Multipart object's mode must be Part. + So(o.Mode.IsPart(), ShouldBeTrue) + // Multipart object's mode must not be Read. + So(o.Mode.IsRead(), ShouldBeFalse) + }) - err = store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) - Convey("The second returned error also should be nil", func() { - So(err, ShouldBeNil) - }) + Convey("The Object must have multipart id", func() { + // Multipart object must have multipart id. + _, ok := o.GetMultipartID() + So(ok, ShouldBeTrue) + }) + }) + + Convey("When Delete with multipart id", func() { + path := uuid.New().String() + o, err := store.CreateMultipart(path) + if err != nil { + t.Error(err) + } + + err = store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) + Convey("The first returned error should be nil", func() { + So(err, ShouldBeNil) + }) + + err = store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) + Convey("The second returned error also should be nil", func() { + So(err, ShouldBeNil) }) + }) + if f.Stat { Convey("When Stat with multipart id", func() { path := uuid.New().String() o, err := store.CreateMultipart(path) @@ -115,7 +113,9 @@ func TestMultiparter(t *testing.T, store types.Storager) { So(mid, ShouldEqual, multipartId) }) }) + } + if f.Create { Convey("When Create with multipart id", func() { path := uuid.New().String() o, err := store.CreateMultipart(path) @@ -148,7 +148,9 @@ func TestMultiparter(t *testing.T, store types.Storager) { So(mid, ShouldEqual, multipartId) }) }) + } + if f.WriteMultipart { Convey("When WriteMultipart", func() { path := uuid.New().String() o, err := store.CreateMultipart(path) @@ -181,132 +183,138 @@ func TestMultiparter(t *testing.T, store types.Storager) { }) }) - Convey("When ListMultiPart", func() { - path := uuid.New().String() - o, err := store.CreateMultipart(path) - if err != nil { - t.Error(err) - } - - defer func() { - err := store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) + if f.ListMultipart { + Convey("When ListMultiPart", func() { + path := uuid.New().String() + o, err := store.CreateMultipart(path) if err != nil { t.Error(err) } - }() - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - partNumber := rand.Intn(1000) // Choose a random part number from [0, 1000) - r := io.LimitReader(randbytes.NewRand(), size) + defer func() { + err := store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) + if err != nil { + t.Error(err) + } + }() - _, _, err = store.WriteMultipart(o, r, size, partNumber) - if err != nil { - t.Error(err) - } - - it, err := store.ListMultipart(o) + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + partNumber := rand.Intn(1000) // Choose a random part number from [0, 1000) + r := io.LimitReader(randbytes.NewRand(), size) - Convey("ListMultipart error should be nil", func() { - So(err, ShouldBeNil) - So(it, ShouldNotBeNil) - }) + _, _, err = store.WriteMultipart(o, r, size, partNumber) + if err != nil { + t.Error(err) + } - p, err := it.Next() - Convey("Next error should be nil", func() { - So(err, ShouldBeNil) - So(p, ShouldNotBeNil) - }) - Convey("The part number and size should be match", func() { - So(p.Index, ShouldEqual, partNumber) - So(p.Size, ShouldEqual, size) + it, err := store.ListMultipart(o) + + Convey("ListMultipart error should be nil", func() { + So(err, ShouldBeNil) + So(it, ShouldNotBeNil) + }) + + p, err := it.Next() + Convey("Next error should be nil", func() { + So(err, ShouldBeNil) + So(p, ShouldNotBeNil) + }) + Convey("The part number and size should be match", func() { + So(p.Index, ShouldEqual, partNumber) + So(p.Size, ShouldEqual, size) + }) }) - }) + } - Convey("When List with part type", func() { - path := uuid.New().String() - o, err := store.CreateMultipart(path) - if err != nil { - t.Error(err) - } - - defer func() { - err := store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) + if f.List { + Convey("When List with part type", func() { + path := uuid.New().String() + o, err := store.CreateMultipart(path) if err != nil { t.Error(err) } - }() - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - partNumber := rand.Intn(1000) // Choose a random part number from [0, 1000) - r := io.LimitReader(randbytes.NewRand(), size) + defer func() { + err := store.Delete(path, pairs.WithMultipartID(o.MustGetMultipartID())) + if err != nil { + t.Error(err) + } + }() - _, _, err = store.WriteMultipart(o, r, size, partNumber) - if err != nil { - t.Error(err) - } + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + partNumber := rand.Intn(1000) // Choose a random part number from [0, 1000) + r := io.LimitReader(randbytes.NewRand(), size) - it, err := store.List("", pairs.WithListMode(types.ListModePart)) - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) - Convey("The iterator should not be nil", func() { - So(it, ShouldNotBeNil) - }) - - mo, err := it.Next() - Convey("Next error should be nil", func() { - So(err, ShouldBeNil) - So(mo, ShouldNotBeNil) - }) - Convey("The path and multipart id should be match", func() { - So(mo.Path, ShouldEqual, path) - So(mo.Mode.IsPart(), ShouldBeTrue) + _, _, err = store.WriteMultipart(o, r, size, partNumber) + if err != nil { + t.Error(err) + } - // Multipart object must have multipart id. - mid, ok := mo.GetMultipartID() - So(ok, ShouldBeTrue) - So(mid, ShouldEqual, o.MustGetMultipartID()) + it, err := store.List("", pairs.WithListMode(types.ListModePart)) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + Convey("The iterator should not be nil", func() { + So(it, ShouldNotBeNil) + }) + + mo, err := it.Next() + Convey("Next error should be nil", func() { + So(err, ShouldBeNil) + So(mo, ShouldNotBeNil) + }) + Convey("The path and multipart id should be match", func() { + So(mo.Path, ShouldEqual, path) + So(mo.Mode.IsPart(), ShouldBeTrue) + + // Multipart object must have multipart id. + mid, ok := mo.GetMultipartID() + So(ok, ShouldBeTrue) + So(mid, ShouldEqual, o.MustGetMultipartID()) + }) }) - }) + } - Convey("When CompletePart", func() { - path := uuid.New().String() - o, err := store.CreateMultipart(path) - if err != nil { - t.Error(err) - } - - defer func() { - err := store.Delete(path) + if f.CompleteMultipart { + Convey("When CompletePart", func() { + path := uuid.New().String() + o, err := store.CreateMultipart(path) if err != nil { t.Error(err) } - }() - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - // Set 0 to `partNumber` here as the part numbers must be continuous for `CompleteMultipartUpload` in `cos` which is different with other storages. - partNumber := 0 - r := io.LimitReader(randbytes.NewRand(), size) + defer func() { + err := store.Delete(path) + if err != nil { + t.Error(err) + } + }() - _, part, err := store.WriteMultipart(o, r, size, partNumber) - if err != nil { - t.Error(err) - } + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + // Set 0 to `partNumber` here as the part numbers must be continuous for `CompleteMultipartUpload` in `cos` which is different with other storages. + partNumber := 0 + r := io.LimitReader(randbytes.NewRand(), size) + + _, part, err := store.WriteMultipart(o, r, size, partNumber) + if err != nil { + t.Error(err) + } - err = store.CompleteMultipart(o, []*types.Part{part}) + err = store.CompleteMultipart(o, []*types.Part{part}) - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) - Convey("The object should be readable after complete", func() { - ro, err := store.Stat(path) + Convey("The object should be readable after complete", func() { + ro, err := store.Stat(path) - So(err, ShouldBeNil) - So(ro.Mode.IsRead(), ShouldBeTrue) - So(ro.Mode.IsPart(), ShouldBeFalse) + So(err, ShouldBeNil) + So(ro.Mode.IsRead(), ShouldBeTrue) + So(ro.Mode.IsPart(), ShouldBeFalse) + }) }) - }) + } } - }) + } } diff --git a/tests/storage_http_signer.go b/tests/storage_http_signer.go index ec335e995..a5deff92b 100644 --- a/tests/storage_http_signer.go +++ b/tests/storage_http_signer.go @@ -19,122 +19,108 @@ import ( "go.beyondstorage.io/v5/types" ) -func TestStorageHTTPSignerRead(t *testing.T, store types.Storager) { - Convey("Given a basic Storager", t, func() { - So(store, ShouldNotBeNil) - - f := store.Features() - if f.QuerySignHTTPRead && f.Write && f.Delete { - Convey("When Read via QuerySignHTTPRead", func() { - size := rand.Int63n(4 * 1024 * 1024) - content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) +func testStorageHTTPSigner(t *testing.T, store types.Storager, f types.StorageFeatures) { + // read + if f.QuerySignHTTPRead && f.Write && f.Delete { + Convey("When Read via QuerySignHTTPRead", func() { + size := rand.Int63n(4 * 1024 * 1024) + content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) + if err != nil { + t.Error(err) + } + + path := uuid.New().String() + _, err = store.Write(path, bytes.NewReader(content), size) + if err != nil { + t.Error(err) + } + defer func() { + err := store.Delete(path) if err != nil { t.Error(err) } + }() - path := uuid.New().String() - _, err = store.Write(path, bytes.NewReader(content), size) - if err != nil { - t.Error(err) - } - defer func() { - err := store.Delete(path) - if err != nil { - t.Error(err) - } - }() - - req, err := store.QuerySignHTTPRead(path, time.Duration(time.Hour)) + req, err := store.QuerySignHTTPRead(path, time.Hour) - Convey("The error should be nil", func() { - So(err, ShouldBeNil) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) - So(req, ShouldNotBeNil) - So(req.URL, ShouldNotBeNil) - }) + So(req, ShouldNotBeNil) + So(req.URL, ShouldNotBeNil) + }) - client := http.Client{} - resp, err := client.Do(req) - Convey("The request returned error should be nil", func() { - So(err, ShouldBeNil) - So(resp, ShouldNotBeNil) - }) + client := http.Client{} + resp, err := client.Do(req) + Convey("The request returned error should be nil", func() { + So(err, ShouldBeNil) + So(resp, ShouldNotBeNil) + }) - defer resp.Body.Close() + defer resp.Body.Close() - buf, err := io.ReadAll(resp.Body) - Convey("The content should be match", func() { - So(err, ShouldBeNil) - So(buf, ShouldNotBeNil) + buf, err := io.ReadAll(resp.Body) + Convey("The content should be match", func() { + So(err, ShouldBeNil) + So(buf, ShouldNotBeNil) - So(resp.ContentLength, ShouldEqual, size) - So(sha256.Sum256(buf), ShouldResemble, sha256.Sum256(content)) - }) + So(resp.ContentLength, ShouldEqual, size) + So(sha256.Sum256(buf), ShouldResemble, sha256.Sum256(content)) + }) + }) + } + + // write + if f.QuerySignHTTPWrite && f.Read && f.Delete { + Convey("When Write via QuerySignHTTPWrite", func() { + size := rand.Int63n(4 * 1024 * 1024) + content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) + if err != nil { + t.Error(err) + } + + path := uuid.New().String() + req, err := store.QuerySignHTTPWrite(path, size, time.Hour) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + So(req, ShouldNotBeNil) + So(req.URL, ShouldNotBeNil) }) - } - }) -} -func TestStorageHTTPSignerWrite(t *testing.T, store types.Storager) { - Convey("Given a basic Storager", t, func() { - So(store, ShouldNotBeNil) + req.Body = io.NopCloser(bytes.NewReader(content)) - f := store.Features() - if f.QuerySignHTTPWrite && f.Read && f.Delete { - Convey("When Write via QuerySignHTTPWrite", func() { - size := rand.Int63n(4 * 1024 * 1024) - content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) + client := http.Client{} + _, err = client.Do(req) + Convey("The request returned error should be nil", func() { + So(err, ShouldBeNil) + }) + + defer func() { + err := store.Delete(path) if err != nil { t.Error(err) } + }() - path := uuid.New().String() - req, err := store.QuerySignHTTPWrite(path, size, time.Duration(time.Hour)) - - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - So(req, ShouldNotBeNil) - So(req.URL, ShouldNotBeNil) - }) - - req.Body = io.NopCloser(bytes.NewReader(content)) + Convey("Read should get object data without error", func() { + var buf bytes.Buffer + n, err := store.Read(path, &buf) - client := http.Client{} - _, err = client.Do(req) - Convey("The request returned error should be nil", func() { + Convey("The content should be match", func() { So(err, ShouldBeNil) - }) - - defer func() { - err := store.Delete(path) - if err != nil { - t.Error(err) - } - }() - - Convey("Read should get object data without error", func() { - var buf bytes.Buffer - n, err := store.Read(path, &buf) - - Convey("The content should be match", func() { - So(err, ShouldBeNil) - So(buf, ShouldNotBeNil) + So(buf, ShouldNotBeNil) - So(n, ShouldEqual, size) - So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(content)) - }) + So(n, ShouldEqual, size) + So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(content)) }) }) - } - }) -} - -func TestStorageHTTPSignerDelete(t *testing.T, store types.Storager) { - Convey("Given a basic Storager", t, func() { - - f := store.Features() + }) + } - if f.QuerySignHTTPDelete && f.Write && f.Stat { + // delete + if f.QuerySignHTTPDelete { + if f.Write && f.Stat { Convey("When Delete via QuerySignHTTPDelete", func() { size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB r := io.LimitReader(randbytes.NewRand(), size) @@ -145,7 +131,7 @@ func TestStorageHTTPSignerDelete(t *testing.T, store types.Storager) { t.Error(err) } - req, err := store.QuerySignHTTPDelete(path, time.Duration(time.Hour)) + req, err := store.QuerySignHTTPDelete(path, time.Hour) Convey("The error should be nil", func() { So(err, ShouldBeNil) @@ -170,7 +156,7 @@ func TestStorageHTTPSignerDelete(t *testing.T, store types.Storager) { }) } - if f.CreateMultipart && f.QuerySignHTTPDelete { + if f.CreateMultipart { Convey("When Delete with multipart id via QuerySignHTTPDelete", func() { path := uuid.New().String() o, err := store.CreateMultipart(path) @@ -178,7 +164,7 @@ func TestStorageHTTPSignerDelete(t *testing.T, store types.Storager) { t.Error(err) } - req, err := store.QuerySignHTTPDelete(path, time.Duration(time.Hour), pairs.WithMultipartID(o.MustGetMultipartID())) + req, err := store.QuerySignHTTPDelete(path, time.Hour, pairs.WithMultipartID(o.MustGetMultipartID())) Convey("The error should be nil", func() { So(err, ShouldBeNil) @@ -201,5 +187,5 @@ func TestStorageHTTPSignerDelete(t *testing.T, store types.Storager) { }) }) } - }) + } } diff --git a/tests/storager.go b/tests/storager.go index fada15933..40f04ebf8 100644 --- a/tests/storager.go +++ b/tests/storager.go @@ -19,74 +19,71 @@ import ( "go.beyondstorage.io/v5/types" ) -func TestStorage(t *testing.T, store types.Storager) { +func TestStorager(t *testing.T, store types.Storager) { Convey("Given a basic Storager", t, func() { So(store, ShouldNotBeNil) + features := store.Features() + Convey("Test basic operations for storage service", func() { - TestStorager(t, store) + testStorager(t, store, features) }) Convey("Test Append related operations", func() { - TestAppender(t, store) + testAppender(t, store, features) }) Convey("Test Copy operation", func() { - TestCopier(t, store) + testCopier(t, store, features) }) Convey("Test CreateDir operation", func() { - TestDirer(t, store) + testDirer(t, store, features) }) Convey("Test CreateLink operation", func() { - TestLinker(t, store) + testLinker(t, store, features) }) Convey("Test Move operation", func() { - TestMover(t, store) + testMover(t, store, features) }) Convey("Test multipart related operations which support authentication", func() { - TestMultipartHTTPSigner(t, store) + testMultipartHTTPSigner(t, store, features) }) Convey("Test Multipart related operations", func() { - TestMultiparter(t, store) + testMultiparter(t, store, features) }) Convey("Test basic operations which support authentication", func() { - TestStorageHTTPSignerDelete(t, store) - TestStorageHTTPSignerRead(t, store) - TestStorageHTTPSignerWrite(t, store) + testStorageHTTPSigner(t, store, features) }) }) } -func TestStorager(t *testing.T, store types.Storager) { - Convey("Given a basic Storager", t, func() { - So(store, ShouldNotBeNil) - - f := store.Features() - if f.Create && f.Delete && f.Metadata && f.List && f.Read && f.Stat && f.Write { - Convey("When String called", func() { - s := store.String() +func testStorager(t *testing.T, store types.Storager, f types.StorageFeatures) { + Convey("When String called", func() { + s := store.String() - Convey("The string should not be empty", func() { - So(s, ShouldNotBeEmpty) - }) - }) + Convey("The string should not be empty", func() { + So(s, ShouldNotBeEmpty) + }) + }) - Convey("When Metadata called", func() { - m := store.Metadata() + if f.Metadata { + Convey("When Metadata called", func() { + m := store.Metadata() - Convey("The metadata should not be empty", func() { - So(m, ShouldNotBeEmpty) - }) + Convey("The metadata should not be empty", func() { + So(m, ShouldNotBeEmpty) }) + }) + } - workDir := store.Metadata().WorkDir - + if f.Write && f.Delete { + if f.Read { Convey("When Read a file", func() { size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) @@ -197,67 +194,6 @@ func TestStorager(t *testing.T, store types.Storager) { }) }) - Convey("When Write a file", func() { - firstSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - r := io.LimitReader(randbytes.NewRand(), firstSize) - path := uuid.New().String() - - _, err := store.Write(path, r, firstSize) - - defer func() { - err := store.Delete(path) - if err != nil { - t.Error(err) - } - }() - - Convey("The first returned error should be nil", func() { - So(err, ShouldBeNil) - }) - - secondSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - content, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), secondSize)) - - _, err = store.Write(path, bytes.NewReader(content), secondSize) - - Convey("The second returned error also should be nil", func() { - So(err, ShouldBeNil) - }) - - Convey("Stat should get Object without error", func() { - o, err := store.Stat(path) - - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) - - Convey("The name and size should be match", func() { - So(o, ShouldNotBeNil) - So(o.Path, ShouldEqual, path) - - osize, ok := o.GetContentLength() - So(ok, ShouldBeTrue) - So(osize, ShouldEqual, secondSize) - }) - }) - - Convey("Read should get Object data without error", func() { - var buf bytes.Buffer - n, err := store.Read(path, &buf) - - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) - - Convey("The content should be match", func() { - So(buf, ShouldNotBeNil) - - So(n, ShouldEqual, secondSize) - So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(content)) - }) - }) - }) - Convey("When Write and Read a file with IoCallback", func() { size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) @@ -310,12 +246,13 @@ func TestStorager(t *testing.T, store types.Storager) { }) }) - if f.WriteEmptyObject { - Convey("When write a file with a nil io.Reader and 0 size", func() { + if f.Stat { + Convey("When Write a file", func() { + firstSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + r := io.LimitReader(randbytes.NewRand(), firstSize) path := uuid.New().String() - var size int64 = 0 - _, err := store.Write(path, nil, size) + _, err := store.Write(path, r, firstSize) defer func() { err := store.Delete(path) @@ -324,7 +261,16 @@ func TestStorager(t *testing.T, store types.Storager) { } }() - Convey("The error should be nil", func() { + Convey("The first returned error should be nil", func() { + So(err, ShouldBeNil) + }) + + secondSize := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + content, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), secondSize)) + + _, err = store.Write(path, bytes.NewReader(content), secondSize) + + Convey("The second returned error also should be nil", func() { So(err, ShouldBeNil) }) @@ -341,19 +287,50 @@ func TestStorager(t *testing.T, store types.Storager) { osize, ok := o.GetContentLength() So(ok, ShouldBeTrue) - So(osize, ShouldEqual, size) + So(osize, ShouldEqual, secondSize) + }) + }) + + Convey("Read should get Object data without error", func() { + var buf bytes.Buffer + n, err := store.Read(path, &buf) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("The content should be match", func() { + So(buf, ShouldNotBeNil) + + So(n, ShouldEqual, secondSize) + So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(content)) }) }) }) - Convey("When write a file with a nil io.Reader and valid size", func() { + Convey("When Delete a file", func() { size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) + if err != nil { + t.Error(err) + } + path := uuid.New().String() + _, err = store.Write(path, bytes.NewReader(content), size) + if err != nil { + t.Error(err) + } - _, err := store.Write(path, nil, size) + err = store.Delete(path) - Convey("The error should not be nil", func() { - So(err, ShouldNotBeNil) + Convey("The first returned error should be nil", func() { + So(err, ShouldBeNil) + }) + + err = store.Delete(path) + + Convey("The second returned error also should be nil", func() { + So(err, ShouldBeNil) }) Convey("Stat should get nil Object and ObjectNotFound error", func() { @@ -364,14 +341,18 @@ func TestStorager(t *testing.T, store types.Storager) { }) }) - Convey("When write a file with a valid io.Reader and 0 size", func() { - var size int64 = 0 - n := rand.Int63n(4 * 1024 * 1024) - r := io.LimitReader(randbytes.NewRand(), n) - path := uuid.New().String() - - _, err := store.Write(path, r, size) + Convey("When Stat a file", func() { + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) + if err != nil { + t.Error(err) + } + path := uuid.New().String() + _, err = store.Write(path, bytes.NewReader(content), size) + if err != nil { + t.Error(err) + } defer func() { err := store.Delete(path) if err != nil { @@ -379,151 +360,270 @@ func TestStorager(t *testing.T, store types.Storager) { } }() + o, err := store.Stat(path) + Convey("The error should be nil", func() { So(err, ShouldBeNil) }) - Convey("Stat should get Object without error", func() { - o, err := store.Stat(path) + Convey("The Object name and size should be match", func() { + So(o, ShouldNotBeNil) + So(o.Path, ShouldEqual, path) + + osize, ok := o.GetContentLength() + So(ok, ShouldBeTrue) + So(osize, ShouldEqual, size) + }) + }) + + if f.WriteEmptyObject { + Convey("When write a file with a nil io.Reader and 0 size", func() { + path := uuid.New().String() + var size int64 = 0 + + _, err := store.Write(path, nil, size) + + defer func() { + err := store.Delete(path) + if err != nil { + t.Error(err) + } + }() Convey("The error should be nil", func() { So(err, ShouldBeNil) }) - Convey("The name and size should be match", func() { - So(o, ShouldNotBeNil) - So(o.Path, ShouldEqual, path) + Convey("Stat should get Object without error", func() { + o, err := store.Stat(path) - osize, ok := o.GetContentLength() - So(ok, ShouldBeTrue) - So(osize, ShouldEqual, size) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("The name and size should be match", func() { + So(o, ShouldNotBeNil) + So(o.Path, ShouldEqual, path) + + osize, ok := o.GetContentLength() + So(ok, ShouldBeTrue) + So(osize, ShouldEqual, size) + }) }) }) - }) - Convey("When write a file with a valid io.Reader and length greater than size", func() { - n := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - size := rand.Int63n(n) - r, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), n)) - path := uuid.New().String() + Convey("When write a file with a nil io.Reader and valid size", func() { + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + path := uuid.New().String() - _, err := store.Write(path, bytes.NewReader(r), size) + _, err := store.Write(path, nil, size) - defer func() { - err := store.Delete(path) - if err != nil { - t.Error(err) - } - }() + Convey("The error should not be nil", func() { + So(err, ShouldNotBeNil) + }) - Convey("The error should be nil", func() { - So(err, ShouldBeNil) + Convey("Stat should get nil Object and ObjectNotFound error", func() { + o, err := store.Stat(path) + + So(errors.Is(err, services.ErrObjectNotExist), ShouldBeTrue) + So(o, ShouldBeNil) + }) }) - Convey("Stat should get Object without error", func() { - o, err := store.Stat(path) + Convey("When write a file with a valid io.Reader and 0 size", func() { + var size int64 = 0 + n := rand.Int63n(4 * 1024 * 1024) + r := io.LimitReader(randbytes.NewRand(), n) + path := uuid.New().String() + + _, err := store.Write(path, r, size) + + defer func() { + err := store.Delete(path) + if err != nil { + t.Error(err) + } + }() Convey("The error should be nil", func() { So(err, ShouldBeNil) }) - Convey("The name and size should be match", func() { - So(o, ShouldNotBeNil) - So(o.Path, ShouldEqual, path) + Convey("Stat should get Object without error", func() { + o, err := store.Stat(path) - osize, ok := o.GetContentLength() - So(ok, ShouldBeTrue) - So(osize, ShouldEqual, size) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("The name and size should be match", func() { + So(o, ShouldNotBeNil) + So(o.Path, ShouldEqual, path) + + osize, ok := o.GetContentLength() + So(ok, ShouldBeTrue) + So(osize, ShouldEqual, size) + }) }) }) - Convey("Read should get Object without error", func() { - content, _ := io.ReadAll(io.LimitReader(bytes.NewReader(r), size)) - var buf bytes.Buffer - n, err := store.Read(path, &buf) + Convey("When write a file with a valid io.Reader and length greater than size", func() { + n := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + size := rand.Int63n(n) + r, _ := io.ReadAll(io.LimitReader(randbytes.NewRand(), n)) + path := uuid.New().String() + + _, err := store.Write(path, bytes.NewReader(r), size) + + defer func() { + err := store.Delete(path) + if err != nil { + t.Error(err) + } + }() Convey("The error should be nil", func() { So(err, ShouldBeNil) }) - Convey("The content should match the size limit of the content", func() { - So(buf, ShouldNotBeNil) + Convey("Stat should get Object without error", func() { + o, err := store.Stat(path) - So(n, ShouldEqual, size) - So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(content)) - }) - }) - }) - } + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) - Convey("When Stat a file", func() { - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) - if err != nil { - t.Error(err) - } - - path := uuid.New().String() - _, err = store.Write(path, bytes.NewReader(content), size) - if err != nil { - t.Error(err) - } - defer func() { - err := store.Delete(path) - if err != nil { - t.Error(err) - } - }() + Convey("The name and size should be match", func() { + So(o, ShouldNotBeNil) + So(o.Path, ShouldEqual, path) - o, err := store.Stat(path) + osize, ok := o.GetContentLength() + So(ok, ShouldBeTrue) + So(osize, ShouldEqual, size) + }) + }) - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) + Convey("Read should get Object without error", func() { + content, _ := io.ReadAll(io.LimitReader(bytes.NewReader(r), size)) + var buf bytes.Buffer + n, err := store.Read(path, &buf) - Convey("The Object name and size should be match", func() { - So(o, ShouldNotBeNil) - So(o.Path, ShouldEqual, path) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) - osize, ok := o.GetContentLength() - So(ok, ShouldBeTrue) - So(osize, ShouldEqual, size) - }) - }) + Convey("The content should match the size limit of the content", func() { + So(buf, ShouldNotBeNil) - Convey("When Delete a file", func() { - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) - if err != nil { - t.Error(err) + So(n, ShouldEqual, size) + So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(content)) + }) + }) + }) } - path := uuid.New().String() - _, err = store.Write(path, bytes.NewReader(content), size) - if err != nil { - t.Error(err) - } + Convey("When testing GSP-749 unify path behavior", func() { + if f.Metadata { + Convey("When using absolute path", func() { + workDir := store.Metadata().WorkDir + + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) + if err != nil { + t.Error(err) + } + + path := uuid.New().String() + absPath := filepath.Join(workDir, path) + _, err = store.Write(absPath, bytes.NewReader(content), size) + if err != nil { + t.Error(err) + } + defer func() { + err := store.Delete(absPath) + if err != nil { + t.Error(err) + } + }() + + Convey("Stat should get Object without error", func() { + o, err := store.Stat(absPath) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + So(o, ShouldNotBeNil) + So(o.Path, ShouldEqual, strings.ReplaceAll(absPath, "\\", "/")) + }) + }) + + Convey("Read should get Object content without error", func() { + var buf bytes.Buffer + n, err := store.Read(absPath, &buf) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) + + Convey("The content should be match", func() { + So(buf, ShouldNotBeNil) + + So(n, ShouldEqual, size) + So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(content)) + }) + }) + }) + } - err = store.Delete(path) + Convey("When using backslash in path", func() { + size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB + content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) + if err != nil { + t.Error(err) + } - Convey("The first returned error should be nil", func() { - So(err, ShouldBeNil) - }) + path := uuid.New().String() + "\\" + uuid.New().String() + _, err = store.Write(path, bytes.NewReader(content), size) + if err != nil { + t.Error(err) + } + defer func() { + err := store.Delete(path) + if err != nil { + t.Error(err) + } + }() + + Convey("Stat should get Object without error", func() { + o, err := store.Stat(path) + + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + So(o, ShouldNotBeNil) + So(o.Path, ShouldEqual, strings.ReplaceAll(path, "\\", "/")) + }) + }) - err = store.Delete(path) + Convey("Read should get Object content without error", func() { + var buf bytes.Buffer + n, err := store.Read(path, &buf) - Convey("The second returned error also should be nil", func() { - So(err, ShouldBeNil) - }) + Convey("The error should be nil", func() { + So(err, ShouldBeNil) + }) - Convey("Stat should get nil Object and ObjectNotFound error", func() { - o, err := store.Stat(path) + Convey("The content should be match", func() { + So(buf, ShouldNotBeNil) - So(errors.Is(err, services.ErrObjectNotExist), ShouldBeTrue) - So(o, ShouldBeNil) + So(n, ShouldEqual, size) + So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(content)) + }) + }) + }) }) - }) + } + } + if f.List { Convey("When List an empty dir", func() { it, err := store.List("", ps.WithListMode(types.ListModeDir)) @@ -611,101 +711,6 @@ func TestStorager(t *testing.T, store types.Storager) { So(osize, ShouldEqual, size) }) }) - - Convey("When testing GSP-749 unify path behavior", func() { - Convey("When using absolute path", func() { - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) - if err != nil { - t.Error(err) - } - - path := uuid.New().String() - absPath := filepath.Join(workDir, path) - _, err = store.Write(absPath, bytes.NewReader(content), size) - if err != nil { - t.Error(err) - } - defer func() { - err := store.Delete(absPath) - if err != nil { - t.Error(err) - } - }() - - Convey("Stat should get Object without error", func() { - o, err := store.Stat(absPath) - - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - So(o, ShouldNotBeNil) - So(o.Path, ShouldEqual, strings.ReplaceAll(absPath, "\\", "/")) - }) - }) - - Convey("Read should get Object content without error", func() { - var buf bytes.Buffer - n, err := store.Read(absPath, &buf) - - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) - - Convey("The content should be match", func() { - So(buf, ShouldNotBeNil) - - So(n, ShouldEqual, size) - So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(content)) - }) - }) - }) - - Convey("When using backslash in path", func() { - size := rand.Int63n(4 * 1024 * 1024) // Max file size is 4MB - content, err := io.ReadAll(io.LimitReader(randbytes.NewRand(), size)) - if err != nil { - t.Error(err) - } - - path := uuid.New().String() + "\\" + uuid.New().String() - _, err = store.Write(path, bytes.NewReader(content), size) - if err != nil { - t.Error(err) - } - defer func() { - err := store.Delete(path) - if err != nil { - t.Error(err) - } - }() - - Convey("Stat should get Object without error", func() { - o, err := store.Stat(path) - - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - So(o, ShouldNotBeNil) - So(o.Path, ShouldEqual, strings.ReplaceAll(path, "\\", "/")) - }) - }) - - Convey("Read should get Object content without error", func() { - var buf bytes.Buffer - n, err := store.Read(path, &buf) - - Convey("The error should be nil", func() { - So(err, ShouldBeNil) - }) - - Convey("The content should be match", func() { - So(buf, ShouldNotBeNil) - - So(n, ShouldEqual, size) - So(sha256.Sum256(buf.Bytes()), ShouldResemble, sha256.Sum256(content)) - }) - }) - }) - }) } - }) + } }