github.com/rclone/rclone@v1.66.1-0.20240517100346-7b89735ae726/fs/metadata_test.go (about) 1 package fs_test 2 3 import ( 4 "context" 5 "fmt" 6 "testing" 7 "time" 8 9 "github.com/rclone/rclone/fs" 10 "github.com/rclone/rclone/fs/object" 11 "github.com/rclone/rclone/fstest/mockfs" 12 "github.com/stretchr/testify/assert" 13 "github.com/stretchr/testify/require" 14 ) 15 16 func TestMetadataSet(t *testing.T) { 17 var m fs.Metadata 18 assert.Nil(t, m) 19 m.Set("key", "value") 20 assert.NotNil(t, m) 21 assert.Equal(t, "value", m["key"]) 22 m.Set("key", "value2") 23 assert.Equal(t, "value2", m["key"]) 24 } 25 26 func TestMetadataMerge(t *testing.T) { 27 for _, test := range []struct { 28 in fs.Metadata 29 merge fs.Metadata 30 want fs.Metadata 31 }{ 32 { 33 in: fs.Metadata{}, 34 merge: fs.Metadata{}, 35 want: fs.Metadata{}, 36 }, { 37 in: nil, 38 merge: nil, 39 want: nil, 40 }, { 41 in: nil, 42 merge: fs.Metadata{}, 43 want: nil, 44 }, { 45 in: nil, 46 merge: fs.Metadata{"a": "1", "b": "2"}, 47 want: fs.Metadata{"a": "1", "b": "2"}, 48 }, { 49 in: fs.Metadata{"a": "1", "b": "2"}, 50 merge: nil, 51 want: fs.Metadata{"a": "1", "b": "2"}, 52 }, { 53 in: fs.Metadata{"a": "1", "b": "2"}, 54 merge: fs.Metadata{"b": "B", "c": "3"}, 55 want: fs.Metadata{"a": "1", "b": "B", "c": "3"}, 56 }, 57 } { 58 what := fmt.Sprintf("in=%v, merge=%v", test.in, test.merge) 59 test.in.Merge(test.merge) 60 assert.Equal(t, test.want, test.in, what) 61 } 62 } 63 64 func TestMetadataMergeOptions(t *testing.T) { 65 for _, test := range []struct { 66 in fs.Metadata 67 opts []fs.OpenOption 68 want fs.Metadata 69 }{ 70 { 71 opts: []fs.OpenOption{}, 72 want: nil, 73 }, { 74 opts: []fs.OpenOption{&fs.HTTPOption{}}, 75 want: nil, 76 }, { 77 opts: []fs.OpenOption{fs.MetadataOption{"a": "1", "b": "2"}}, 78 want: fs.Metadata{"a": "1", "b": "2"}, 79 }, { 80 opts: []fs.OpenOption{ 81 &fs.HTTPOption{}, 82 fs.MetadataOption{"a": "1", "b": "2"}, 83 fs.MetadataOption{"b": "B", "c": "3"}, 84 &fs.HTTPOption{}, 85 }, 86 want: fs.Metadata{"a": "1", "b": "B", "c": "3"}, 87 }, { 88 in: fs.Metadata{"a": "first", "z": "OK"}, 89 opts: []fs.OpenOption{ 90 &fs.HTTPOption{}, 91 fs.MetadataOption{"a": "1", "b": "2"}, 92 fs.MetadataOption{"b": "B", "c": "3"}, 93 &fs.HTTPOption{}, 94 }, 95 want: fs.Metadata{"a": "1", "b": "B", "c": "3", "z": "OK"}, 96 }, 97 } { 98 what := fmt.Sprintf("in=%v, opts=%v", test.in, test.opts) 99 test.in.MergeOptions(test.opts) 100 assert.Equal(t, test.want, test.in, what) 101 } 102 } 103 104 func TestMetadataMapper(t *testing.T) { 105 ctx := context.Background() 106 ctx, ci := fs.AddConfig(ctx) 107 ci.Metadata = true 108 require.NoError(t, ci.MetadataMapper.Set("go run metadata_mapper_code.go")) 109 now := time.Date(2001, 2, 3, 4, 5, 6, 7, time.UTC) 110 f, err := mockfs.NewFs(ctx, "dstFs", "dstFsRoot", nil) 111 require.NoError(t, err) 112 113 t.Run("Normal", func(t *testing.T) { 114 o := object.NewMemoryObject("file.txt", now, []byte("hello")).WithMetadata(fs.Metadata{ 115 "key1": "potato", 116 "key2": "sausage", 117 "key3": "gravy", 118 }) 119 metadata, err := fs.GetMetadataOptions(ctx, f, o, nil) 120 require.NoError(t, err) 121 assert.Equal(t, fs.Metadata{ 122 "key0": "cabbage", 123 "key1": "two potato", 124 "key2": "sausage", 125 }, metadata) 126 }) 127 128 t.Run("Error", func(t *testing.T) { 129 o := object.NewMemoryObject("file.txt", now, []byte("hello")).WithMetadata(fs.Metadata{ 130 "error": "Red Alert", 131 }) 132 metadata, err := fs.GetMetadataOptions(ctx, f, o, nil) 133 require.Error(t, err) 134 assert.ErrorContains(t, err, "Red Alert") 135 require.Nil(t, metadata) 136 }) 137 138 t.Run("Merge", func(t *testing.T) { 139 o := object.NewMemoryObject("file.txt", now, []byte("hello")).WithMetadata(fs.Metadata{ 140 "key1": "potato", 141 "key2": "sausage", 142 "key3": "gravy", 143 }) 144 metadata, err := fs.GetMetadataOptions(ctx, f, o, []fs.OpenOption{fs.MetadataOption(fs.Metadata{ 145 "option": "optionValue", 146 "key1": "new potato", 147 "key2": "salami", 148 })}) 149 require.NoError(t, err) 150 assert.Equal(t, fs.Metadata{ 151 "key0": "cabbage", 152 "key1": "two new potato", 153 "key2": "salami", 154 "option": "optionValue", 155 }, metadata) 156 }) 157 }