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  }