github.com/xhghs/rclone@v1.51.1-0.20200430155106-e186a28cced8/fs/object/object_test.go (about) 1 package object_test 2 3 import ( 4 "bytes" 5 "context" 6 "io" 7 "io/ioutil" 8 "testing" 9 "time" 10 11 "github.com/rclone/rclone/fs" 12 "github.com/rclone/rclone/fs/hash" 13 "github.com/rclone/rclone/fs/object" 14 "github.com/stretchr/testify/assert" 15 ) 16 17 func TestStaticObject(t *testing.T) { 18 now := time.Now() 19 remote := "path/to/object" 20 size := int64(1024) 21 22 o := object.NewStaticObjectInfo(remote, now, size, true, nil, object.MemoryFs) 23 24 assert.Equal(t, object.MemoryFs, o.Fs()) 25 assert.Equal(t, remote, o.Remote()) 26 assert.Equal(t, remote, o.String()) 27 assert.Equal(t, now, o.ModTime(context.Background())) 28 assert.Equal(t, size, o.Size()) 29 assert.Equal(t, true, o.Storable()) 30 31 Hash, err := o.Hash(context.Background(), hash.MD5) 32 assert.NoError(t, err) 33 assert.Equal(t, "", Hash) 34 35 o = object.NewStaticObjectInfo(remote, now, size, true, nil, nil) 36 _, err = o.Hash(context.Background(), hash.MD5) 37 assert.Equal(t, hash.ErrUnsupported, err) 38 39 hs := map[hash.Type]string{ 40 hash.MD5: "potato", 41 } 42 o = object.NewStaticObjectInfo(remote, now, size, true, hs, nil) 43 Hash, err = o.Hash(context.Background(), hash.MD5) 44 assert.NoError(t, err) 45 assert.Equal(t, "potato", Hash) 46 _, err = o.Hash(context.Background(), hash.SHA1) 47 assert.Equal(t, hash.ErrUnsupported, err) 48 } 49 50 func TestMemoryFs(t *testing.T) { 51 f := object.MemoryFs 52 assert.Equal(t, "memory", f.Name()) 53 assert.Equal(t, "", f.Root()) 54 assert.Equal(t, "memory", f.String()) 55 assert.Equal(t, time.Nanosecond, f.Precision()) 56 assert.Equal(t, hash.Supported(), f.Hashes()) 57 assert.Equal(t, &fs.Features{}, f.Features()) 58 59 entries, err := f.List(context.Background(), "") 60 assert.NoError(t, err) 61 assert.Nil(t, entries) 62 63 o, err := f.NewObject(context.Background(), "obj") 64 assert.Equal(t, fs.ErrorObjectNotFound, err) 65 assert.Nil(t, o) 66 67 buf := bytes.NewBufferString("potato") 68 now := time.Now() 69 src := object.NewStaticObjectInfo("remote", now, int64(buf.Len()), true, nil, nil) 70 o, err = f.Put(context.Background(), buf, src) 71 assert.NoError(t, err) 72 hash, err := o.Hash(context.Background(), hash.SHA1) 73 assert.NoError(t, err) 74 assert.Equal(t, "3e2e95f5ad970eadfa7e17eaf73da97024aa5359", hash) 75 76 err = f.Mkdir(context.Background(), "dir") 77 assert.Error(t, err) 78 79 err = f.Rmdir(context.Background(), "dir") 80 assert.Equal(t, fs.ErrorDirNotFound, err) 81 } 82 83 func TestMemoryObject(t *testing.T) { 84 remote := "path/to/object" 85 now := time.Now() 86 content := []byte("potatoXXXXXXXXXXXXX") 87 content = content[:6] // make some extra cap 88 89 o := object.NewMemoryObject(remote, now, content) 90 91 assert.Equal(t, content, o.Content()) 92 assert.Equal(t, object.MemoryFs, o.Fs()) 93 assert.Equal(t, remote, o.Remote()) 94 assert.Equal(t, remote, o.String()) 95 assert.Equal(t, now, o.ModTime(context.Background())) 96 assert.Equal(t, int64(len(content)), o.Size()) 97 assert.Equal(t, true, o.Storable()) 98 99 Hash, err := o.Hash(context.Background(), hash.MD5) 100 assert.NoError(t, err) 101 assert.Equal(t, "8ee2027983915ec78acc45027d874316", Hash) 102 103 Hash, err = o.Hash(context.Background(), hash.SHA1) 104 assert.NoError(t, err) 105 assert.Equal(t, "3e2e95f5ad970eadfa7e17eaf73da97024aa5359", Hash) 106 107 newNow := now.Add(time.Minute) 108 err = o.SetModTime(context.Background(), newNow) 109 assert.NoError(t, err) 110 assert.Equal(t, newNow, o.ModTime(context.Background())) 111 112 checkOpen := func(rc io.ReadCloser, expected string) { 113 actual, err := ioutil.ReadAll(rc) 114 assert.NoError(t, err) 115 err = rc.Close() 116 assert.NoError(t, err) 117 assert.Equal(t, expected, string(actual)) 118 } 119 120 checkContent := func(o fs.Object, expected string) { 121 rc, err := o.Open(context.Background()) 122 assert.NoError(t, err) 123 checkOpen(rc, expected) 124 } 125 126 checkContent(o, string(content)) 127 128 rc, err := o.Open(context.Background(), &fs.RangeOption{Start: 1, End: 3}) 129 assert.NoError(t, err) 130 checkOpen(rc, "ot") 131 132 rc, err = o.Open(context.Background(), &fs.SeekOption{Offset: 3}) 133 assert.NoError(t, err) 134 checkOpen(rc, "ato") 135 136 // check it fits within the buffer 137 newNow = now.Add(2 * time.Minute) 138 newContent := bytes.NewBufferString("Rutabaga") 139 assert.True(t, newContent.Len() < cap(content)) // fits within cap(content) 140 src := object.NewStaticObjectInfo(remote, newNow, int64(newContent.Len()), true, nil, nil) 141 err = o.Update(context.Background(), newContent, src) 142 assert.NoError(t, err) 143 checkContent(o, "Rutabaga") 144 assert.Equal(t, newNow, o.ModTime(context.Background())) 145 assert.Equal(t, "Rutaba", string(content)) // check we re-used the buffer 146 147 // not within the buffer 148 newStr := "0123456789" 149 newStr = newStr + newStr + newStr + newStr + newStr + newStr + newStr + newStr + newStr + newStr 150 newContent = bytes.NewBufferString(newStr) 151 assert.True(t, newContent.Len() > cap(content)) // does not fit within cap(content) 152 src = object.NewStaticObjectInfo(remote, newNow, int64(newContent.Len()), true, nil, nil) 153 err = o.Update(context.Background(), newContent, src) 154 assert.NoError(t, err) 155 checkContent(o, newStr) 156 assert.Equal(t, "Rutaba", string(content)) // check we didn't re-use the buffer 157 158 // now try streaming 159 newStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 160 newContent = bytes.NewBufferString(newStr) 161 src = object.NewStaticObjectInfo(remote, newNow, -1, true, nil, nil) 162 err = o.Update(context.Background(), newContent, src) 163 assert.NoError(t, err) 164 checkContent(o, newStr) 165 166 // and zero length 167 newStr = "" 168 newContent = bytes.NewBufferString(newStr) 169 src = object.NewStaticObjectInfo(remote, newNow, 0, true, nil, nil) 170 err = o.Update(context.Background(), newContent, src) 171 assert.NoError(t, err) 172 checkContent(o, newStr) 173 174 err = o.Remove(context.Background()) 175 assert.Error(t, err) 176 }