github.com/artpar/rclone@v1.67.3/fs/object/object_test.go (about)

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