2018-01-12 16:30:54 +00:00
|
|
|
package object_test
|
2017-12-01 15:15:44 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
2019-06-17 08:34:30 +00:00
|
|
|
"context"
|
2017-12-01 15:15:44 +00:00
|
|
|
"io"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
2019-07-28 17:47:38 +00:00
|
|
|
"github.com/rclone/rclone/fs"
|
|
|
|
"github.com/rclone/rclone/fs/hash"
|
|
|
|
"github.com/rclone/rclone/fs/object"
|
2017-12-01 15:15:44 +00:00
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestStaticObject(t *testing.T) {
|
|
|
|
now := time.Now()
|
|
|
|
remote := "path/to/object"
|
|
|
|
size := int64(1024)
|
|
|
|
|
2018-01-12 16:30:54 +00:00
|
|
|
o := object.NewStaticObjectInfo(remote, now, size, true, nil, object.MemoryFs)
|
2017-12-01 15:15:44 +00:00
|
|
|
|
2018-01-12 16:30:54 +00:00
|
|
|
assert.Equal(t, object.MemoryFs, o.Fs())
|
2017-12-01 15:15:44 +00:00
|
|
|
assert.Equal(t, remote, o.Remote())
|
|
|
|
assert.Equal(t, remote, o.String())
|
2019-06-17 08:34:30 +00:00
|
|
|
assert.Equal(t, now, o.ModTime(context.Background()))
|
2017-12-01 15:15:44 +00:00
|
|
|
assert.Equal(t, size, o.Size())
|
|
|
|
assert.Equal(t, true, o.Storable())
|
|
|
|
|
2019-06-17 08:34:30 +00:00
|
|
|
Hash, err := o.Hash(context.Background(), hash.MD5)
|
2017-12-01 15:15:44 +00:00
|
|
|
assert.NoError(t, err)
|
2018-01-12 16:30:54 +00:00
|
|
|
assert.Equal(t, "", Hash)
|
2017-12-01 15:15:44 +00:00
|
|
|
|
2018-01-12 16:30:54 +00:00
|
|
|
o = object.NewStaticObjectInfo(remote, now, size, true, nil, nil)
|
2019-06-17 08:34:30 +00:00
|
|
|
_, err = o.Hash(context.Background(), hash.MD5)
|
2018-01-18 20:27:52 +00:00
|
|
|
assert.Equal(t, hash.ErrUnsupported, err)
|
2024-05-15 14:55:05 +00:00
|
|
|
assert.Equal(t, object.MemoryFs, o.Fs())
|
2017-12-01 15:15:44 +00:00
|
|
|
|
2018-01-12 16:30:54 +00:00
|
|
|
hs := map[hash.Type]string{
|
2018-01-18 20:27:52 +00:00
|
|
|
hash.MD5: "potato",
|
2017-12-01 15:15:44 +00:00
|
|
|
}
|
2018-01-12 16:30:54 +00:00
|
|
|
o = object.NewStaticObjectInfo(remote, now, size, true, hs, nil)
|
2019-06-17 08:34:30 +00:00
|
|
|
Hash, err = o.Hash(context.Background(), hash.MD5)
|
2017-12-01 15:15:44 +00:00
|
|
|
assert.NoError(t, err)
|
2018-01-12 16:30:54 +00:00
|
|
|
assert.Equal(t, "potato", Hash)
|
2019-06-17 08:34:30 +00:00
|
|
|
_, err = o.Hash(context.Background(), hash.SHA1)
|
2018-01-18 20:27:52 +00:00
|
|
|
assert.Equal(t, hash.ErrUnsupported, err)
|
2017-12-01 15:15:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestMemoryFs(t *testing.T) {
|
2018-01-12 16:30:54 +00:00
|
|
|
f := object.MemoryFs
|
2017-12-01 15:15:44 +00:00
|
|
|
assert.Equal(t, "memory", f.Name())
|
|
|
|
assert.Equal(t, "", f.Root())
|
|
|
|
assert.Equal(t, "memory", f.String())
|
|
|
|
assert.Equal(t, time.Nanosecond, f.Precision())
|
2019-09-23 13:32:36 +00:00
|
|
|
assert.Equal(t, hash.Supported(), f.Hashes())
|
2017-12-01 15:15:44 +00:00
|
|
|
assert.Equal(t, &fs.Features{}, f.Features())
|
|
|
|
|
2019-06-17 08:34:30 +00:00
|
|
|
entries, err := f.List(context.Background(), "")
|
2017-12-01 15:15:44 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Nil(t, entries)
|
|
|
|
|
2019-06-17 08:34:30 +00:00
|
|
|
o, err := f.NewObject(context.Background(), "obj")
|
2017-12-01 15:15:44 +00:00
|
|
|
assert.Equal(t, fs.ErrorObjectNotFound, err)
|
|
|
|
assert.Nil(t, o)
|
|
|
|
|
|
|
|
buf := bytes.NewBufferString("potato")
|
|
|
|
now := time.Now()
|
2018-01-12 16:30:54 +00:00
|
|
|
src := object.NewStaticObjectInfo("remote", now, int64(buf.Len()), true, nil, nil)
|
2019-06-17 08:34:30 +00:00
|
|
|
o, err = f.Put(context.Background(), buf, src)
|
2017-12-01 15:15:44 +00:00
|
|
|
assert.NoError(t, err)
|
2019-06-17 08:34:30 +00:00
|
|
|
hash, err := o.Hash(context.Background(), hash.SHA1)
|
2017-12-01 15:15:44 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, "3e2e95f5ad970eadfa7e17eaf73da97024aa5359", hash)
|
|
|
|
|
2019-06-17 08:34:30 +00:00
|
|
|
err = f.Mkdir(context.Background(), "dir")
|
2017-12-01 15:15:44 +00:00
|
|
|
assert.Error(t, err)
|
|
|
|
|
2019-06-17 08:34:30 +00:00
|
|
|
err = f.Rmdir(context.Background(), "dir")
|
2018-05-04 14:19:50 +00:00
|
|
|
assert.Equal(t, fs.ErrorDirNotFound, err)
|
2017-12-01 15:15:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestMemoryObject(t *testing.T) {
|
|
|
|
remote := "path/to/object"
|
|
|
|
now := time.Now()
|
|
|
|
content := []byte("potatoXXXXXXXXXXXXX")
|
|
|
|
content = content[:6] // make some extra cap
|
|
|
|
|
2018-01-12 16:30:54 +00:00
|
|
|
o := object.NewMemoryObject(remote, now, content)
|
2017-12-01 15:15:44 +00:00
|
|
|
|
|
|
|
assert.Equal(t, content, o.Content())
|
2018-01-12 16:30:54 +00:00
|
|
|
assert.Equal(t, object.MemoryFs, o.Fs())
|
2017-12-01 15:15:44 +00:00
|
|
|
assert.Equal(t, remote, o.Remote())
|
|
|
|
assert.Equal(t, remote, o.String())
|
2019-06-17 08:34:30 +00:00
|
|
|
assert.Equal(t, now, o.ModTime(context.Background()))
|
2017-12-01 15:15:44 +00:00
|
|
|
assert.Equal(t, int64(len(content)), o.Size())
|
|
|
|
assert.Equal(t, true, o.Storable())
|
|
|
|
|
2019-06-17 08:34:30 +00:00
|
|
|
Hash, err := o.Hash(context.Background(), hash.MD5)
|
2017-12-01 15:15:44 +00:00
|
|
|
assert.NoError(t, err)
|
2018-01-12 16:30:54 +00:00
|
|
|
assert.Equal(t, "8ee2027983915ec78acc45027d874316", Hash)
|
2017-12-01 15:15:44 +00:00
|
|
|
|
2019-06-17 08:34:30 +00:00
|
|
|
Hash, err = o.Hash(context.Background(), hash.SHA1)
|
2017-12-01 15:15:44 +00:00
|
|
|
assert.NoError(t, err)
|
2018-01-12 16:30:54 +00:00
|
|
|
assert.Equal(t, "3e2e95f5ad970eadfa7e17eaf73da97024aa5359", Hash)
|
2017-12-01 15:15:44 +00:00
|
|
|
|
|
|
|
newNow := now.Add(time.Minute)
|
2019-06-17 08:34:30 +00:00
|
|
|
err = o.SetModTime(context.Background(), newNow)
|
2017-12-01 15:15:44 +00:00
|
|
|
assert.NoError(t, err)
|
2019-06-17 08:34:30 +00:00
|
|
|
assert.Equal(t, newNow, o.ModTime(context.Background()))
|
2017-12-01 15:15:44 +00:00
|
|
|
|
|
|
|
checkOpen := func(rc io.ReadCloser, expected string) {
|
2022-08-20 14:38:02 +00:00
|
|
|
actual, err := io.ReadAll(rc)
|
2017-12-01 15:15:44 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
err = rc.Close()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, expected, string(actual))
|
|
|
|
}
|
|
|
|
|
|
|
|
checkContent := func(o fs.Object, expected string) {
|
2019-06-17 08:34:30 +00:00
|
|
|
rc, err := o.Open(context.Background())
|
2017-12-01 15:15:44 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
checkOpen(rc, expected)
|
|
|
|
}
|
|
|
|
|
|
|
|
checkContent(o, string(content))
|
|
|
|
|
2019-06-17 08:34:30 +00:00
|
|
|
rc, err := o.Open(context.Background(), &fs.RangeOption{Start: 1, End: 3})
|
2017-12-01 15:15:44 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
checkOpen(rc, "ot")
|
|
|
|
|
2019-06-17 08:34:30 +00:00
|
|
|
rc, err = o.Open(context.Background(), &fs.SeekOption{Offset: 3})
|
2017-12-01 15:15:44 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
checkOpen(rc, "ato")
|
|
|
|
|
|
|
|
// check it fits within the buffer
|
|
|
|
newNow = now.Add(2 * time.Minute)
|
|
|
|
newContent := bytes.NewBufferString("Rutabaga")
|
|
|
|
assert.True(t, newContent.Len() < cap(content)) // fits within cap(content)
|
2018-01-12 16:30:54 +00:00
|
|
|
src := object.NewStaticObjectInfo(remote, newNow, int64(newContent.Len()), true, nil, nil)
|
2019-06-17 08:34:30 +00:00
|
|
|
err = o.Update(context.Background(), newContent, src)
|
2017-12-01 15:15:44 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
checkContent(o, "Rutabaga")
|
2019-06-17 08:34:30 +00:00
|
|
|
assert.Equal(t, newNow, o.ModTime(context.Background()))
|
2017-12-01 15:15:44 +00:00
|
|
|
assert.Equal(t, "Rutaba", string(content)) // check we re-used the buffer
|
|
|
|
|
|
|
|
// not within the buffer
|
|
|
|
newStr := "0123456789"
|
|
|
|
newStr = newStr + newStr + newStr + newStr + newStr + newStr + newStr + newStr + newStr + newStr
|
|
|
|
newContent = bytes.NewBufferString(newStr)
|
|
|
|
assert.True(t, newContent.Len() > cap(content)) // does not fit within cap(content)
|
2018-01-12 16:30:54 +00:00
|
|
|
src = object.NewStaticObjectInfo(remote, newNow, int64(newContent.Len()), true, nil, nil)
|
2019-06-17 08:34:30 +00:00
|
|
|
err = o.Update(context.Background(), newContent, src)
|
2017-12-01 15:15:44 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
checkContent(o, newStr)
|
2023-09-23 11:20:01 +00:00
|
|
|
assert.Equal(t, "Rutaba", string(content)) // check we didn't reuse the buffer
|
2017-12-01 15:15:44 +00:00
|
|
|
|
|
|
|
// now try streaming
|
|
|
|
newStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
|
|
newContent = bytes.NewBufferString(newStr)
|
2018-01-12 16:30:54 +00:00
|
|
|
src = object.NewStaticObjectInfo(remote, newNow, -1, true, nil, nil)
|
2019-06-17 08:34:30 +00:00
|
|
|
err = o.Update(context.Background(), newContent, src)
|
2017-12-01 15:15:44 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
checkContent(o, newStr)
|
|
|
|
|
|
|
|
// and zero length
|
|
|
|
newStr = ""
|
|
|
|
newContent = bytes.NewBufferString(newStr)
|
2018-01-12 16:30:54 +00:00
|
|
|
src = object.NewStaticObjectInfo(remote, newNow, 0, true, nil, nil)
|
2019-06-17 08:34:30 +00:00
|
|
|
err = o.Update(context.Background(), newContent, src)
|
2017-12-01 15:15:44 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
checkContent(o, newStr)
|
|
|
|
|
2019-06-17 08:34:30 +00:00
|
|
|
err = o.Remove(context.Background())
|
2017-12-01 15:15:44 +00:00
|
|
|
assert.Error(t, err)
|
|
|
|
}
|