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  }