github.com/xhghs/rclone@v1.51.1-0.20200430155106-e186a28cced8/fs/rc/config_test.go (about) 1 package rc 2 3 import ( 4 "context" 5 "encoding/json" 6 "fmt" 7 "testing" 8 9 "github.com/pkg/errors" 10 "github.com/rclone/rclone/cmd/serve/httplib" 11 "github.com/rclone/rclone/fs" 12 "github.com/stretchr/testify/assert" 13 "github.com/stretchr/testify/require" 14 ) 15 16 func clearOptionBlock() func() { 17 oldOptionBlock := optionBlock 18 optionBlock = map[string]interface{}{} 19 return func() { 20 optionBlock = oldOptionBlock 21 } 22 } 23 24 var testOptions = struct { 25 String string 26 Int int 27 }{ 28 String: "hello", 29 Int: 42, 30 } 31 32 func TestAddOption(t *testing.T) { 33 defer clearOptionBlock()() 34 assert.Equal(t, len(optionBlock), 0) 35 AddOption("potato", &testOptions) 36 assert.Equal(t, len(optionBlock), 1) 37 assert.Equal(t, len(optionReload), 0) 38 assert.Equal(t, &testOptions, optionBlock["potato"]) 39 } 40 41 func TestAddOptionReload(t *testing.T) { 42 defer clearOptionBlock()() 43 assert.Equal(t, len(optionBlock), 0) 44 reload := func() error { return nil } 45 AddOptionReload("potato", &testOptions, reload) 46 assert.Equal(t, len(optionBlock), 1) 47 assert.Equal(t, len(optionReload), 1) 48 assert.Equal(t, &testOptions, optionBlock["potato"]) 49 assert.Equal(t, fmt.Sprintf("%p", reload), fmt.Sprintf("%p", optionReload["potato"])) 50 } 51 52 func TestOptionsBlocks(t *testing.T) { 53 defer clearOptionBlock()() 54 AddOption("potato", &testOptions) 55 call := Calls.Get("options/blocks") 56 require.NotNil(t, call) 57 in := Params{} 58 out, err := call.Fn(context.Background(), in) 59 require.NoError(t, err) 60 require.NotNil(t, out) 61 assert.Equal(t, Params{"options": []string{"potato"}}, out) 62 } 63 64 func TestOptionsGet(t *testing.T) { 65 defer clearOptionBlock()() 66 AddOption("potato", &testOptions) 67 call := Calls.Get("options/get") 68 require.NotNil(t, call) 69 in := Params{} 70 out, err := call.Fn(context.Background(), in) 71 require.NoError(t, err) 72 require.NotNil(t, out) 73 assert.Equal(t, Params{"potato": &testOptions}, out) 74 } 75 76 func TestOptionsGetMarshal(t *testing.T) { 77 defer clearOptionBlock()() 78 79 // Add some real options 80 AddOption("http", &httplib.DefaultOpt) 81 AddOption("main", fs.Config) 82 AddOption("rc", &DefaultOpt) 83 84 // get them 85 call := Calls.Get("options/get") 86 require.NotNil(t, call) 87 in := Params{} 88 out, err := call.Fn(context.Background(), in) 89 require.NoError(t, err) 90 require.NotNil(t, out) 91 92 // Check that they marshal 93 _, err = json.Marshal(out) 94 require.NoError(t, err) 95 } 96 97 func TestOptionsSet(t *testing.T) { 98 defer clearOptionBlock()() 99 var reloaded int 100 AddOptionReload("potato", &testOptions, func() error { 101 if reloaded > 0 { 102 return errors.New("error while reloading") 103 } 104 reloaded++ 105 return nil 106 }) 107 call := Calls.Get("options/set") 108 require.NotNil(t, call) 109 110 in := Params{ 111 "potato": Params{ 112 "Int": 50, 113 }, 114 } 115 out, err := call.Fn(context.Background(), in) 116 require.NoError(t, err) 117 require.Nil(t, out) 118 assert.Equal(t, 50, testOptions.Int) 119 assert.Equal(t, "hello", testOptions.String) 120 assert.Equal(t, 1, reloaded) 121 122 // error from reload 123 _, err = call.Fn(context.Background(), in) 124 require.Error(t, err) 125 assert.Contains(t, err.Error(), "error while reloading") 126 127 // unknown option block 128 in = Params{ 129 "sausage": Params{ 130 "Int": 50, 131 }, 132 } 133 _, err = call.Fn(context.Background(), in) 134 require.Error(t, err) 135 assert.Contains(t, err.Error(), "unknown option block") 136 137 // bad shape 138 in = Params{ 139 "potato": []string{"a", "b"}, 140 } 141 _, err = call.Fn(context.Background(), in) 142 require.Error(t, err) 143 assert.Contains(t, err.Error(), "failed to write options") 144 145 }