2018-10-26 15:48:22 +02:00
|
|
|
package rc
|
|
|
|
|
|
|
|
import (
|
2019-06-17 10:34:30 +02:00
|
|
|
"context"
|
2019-08-10 17:22:17 +02:00
|
|
|
"encoding/json"
|
2021-11-04 11:12:57 +01:00
|
|
|
"errors"
|
2019-03-06 13:36:51 +01:00
|
|
|
"fmt"
|
2018-10-26 15:48:22 +02:00
|
|
|
"testing"
|
|
|
|
|
2019-08-10 17:22:17 +02:00
|
|
|
"github.com/rclone/rclone/cmd/serve/httplib"
|
|
|
|
"github.com/rclone/rclone/fs"
|
2018-10-26 15:48:22 +02:00
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
2019-08-10 17:22:17 +02:00
|
|
|
func clearOptionBlock() func() {
|
|
|
|
oldOptionBlock := optionBlock
|
2018-10-26 15:48:22 +02:00
|
|
|
optionBlock = map[string]interface{}{}
|
2019-08-10 17:22:17 +02:00
|
|
|
return func() {
|
|
|
|
optionBlock = oldOptionBlock
|
|
|
|
}
|
2018-10-26 15:48:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
var testOptions = struct {
|
|
|
|
String string
|
|
|
|
Int int
|
|
|
|
}{
|
|
|
|
String: "hello",
|
|
|
|
Int: 42,
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestAddOption(t *testing.T) {
|
2019-08-10 17:22:17 +02:00
|
|
|
defer clearOptionBlock()()
|
2018-10-26 15:48:22 +02:00
|
|
|
assert.Equal(t, len(optionBlock), 0)
|
|
|
|
AddOption("potato", &testOptions)
|
|
|
|
assert.Equal(t, len(optionBlock), 1)
|
2019-03-06 13:36:51 +01:00
|
|
|
assert.Equal(t, len(optionReload), 0)
|
2018-10-26 15:48:22 +02:00
|
|
|
assert.Equal(t, &testOptions, optionBlock["potato"])
|
|
|
|
}
|
|
|
|
|
2019-03-06 13:36:51 +01:00
|
|
|
func TestAddOptionReload(t *testing.T) {
|
2019-08-10 17:22:17 +02:00
|
|
|
defer clearOptionBlock()()
|
2019-03-06 13:36:51 +01:00
|
|
|
assert.Equal(t, len(optionBlock), 0)
|
2020-11-26 18:15:52 +01:00
|
|
|
reload := func(ctx context.Context) error { return nil }
|
2019-03-06 13:36:51 +01:00
|
|
|
AddOptionReload("potato", &testOptions, reload)
|
|
|
|
assert.Equal(t, len(optionBlock), 1)
|
|
|
|
assert.Equal(t, len(optionReload), 1)
|
|
|
|
assert.Equal(t, &testOptions, optionBlock["potato"])
|
|
|
|
assert.Equal(t, fmt.Sprintf("%p", reload), fmt.Sprintf("%p", optionReload["potato"]))
|
|
|
|
}
|
|
|
|
|
2018-10-26 15:48:22 +02:00
|
|
|
func TestOptionsBlocks(t *testing.T) {
|
2019-08-10 17:22:17 +02:00
|
|
|
defer clearOptionBlock()()
|
2018-10-26 15:48:22 +02:00
|
|
|
AddOption("potato", &testOptions)
|
|
|
|
call := Calls.Get("options/blocks")
|
|
|
|
require.NotNil(t, call)
|
|
|
|
in := Params{}
|
2019-06-17 10:34:30 +02:00
|
|
|
out, err := call.Fn(context.Background(), in)
|
2018-10-26 15:48:22 +02:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, out)
|
|
|
|
assert.Equal(t, Params{"options": []string{"potato"}}, out)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestOptionsGet(t *testing.T) {
|
2019-08-10 17:22:17 +02:00
|
|
|
defer clearOptionBlock()()
|
2018-10-26 15:48:22 +02:00
|
|
|
AddOption("potato", &testOptions)
|
|
|
|
call := Calls.Get("options/get")
|
|
|
|
require.NotNil(t, call)
|
|
|
|
in := Params{}
|
2019-06-17 10:34:30 +02:00
|
|
|
out, err := call.Fn(context.Background(), in)
|
2018-10-26 15:48:22 +02:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, out)
|
|
|
|
assert.Equal(t, Params{"potato": &testOptions}, out)
|
|
|
|
}
|
|
|
|
|
2019-08-10 17:22:17 +02:00
|
|
|
func TestOptionsGetMarshal(t *testing.T) {
|
|
|
|
defer clearOptionBlock()()
|
2020-11-05 12:33:32 +01:00
|
|
|
ctx := context.Background()
|
|
|
|
ci := fs.GetConfig(ctx)
|
2019-08-10 17:22:17 +02:00
|
|
|
|
|
|
|
// Add some real options
|
|
|
|
AddOption("http", &httplib.DefaultOpt)
|
2020-11-05 12:33:32 +01:00
|
|
|
AddOption("main", ci)
|
2019-08-10 17:22:17 +02:00
|
|
|
AddOption("rc", &DefaultOpt)
|
|
|
|
|
|
|
|
// get them
|
|
|
|
call := Calls.Get("options/get")
|
|
|
|
require.NotNil(t, call)
|
|
|
|
in := Params{}
|
|
|
|
out, err := call.Fn(context.Background(), in)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, out)
|
|
|
|
|
|
|
|
// Check that they marshal
|
|
|
|
_, err = json.Marshal(out)
|
|
|
|
require.NoError(t, err)
|
|
|
|
}
|
|
|
|
|
2018-10-26 15:48:22 +02:00
|
|
|
func TestOptionsSet(t *testing.T) {
|
2019-08-10 17:22:17 +02:00
|
|
|
defer clearOptionBlock()()
|
2019-03-06 13:36:51 +01:00
|
|
|
var reloaded int
|
2020-11-26 18:15:52 +01:00
|
|
|
AddOptionReload("potato", &testOptions, func(ctx context.Context) error {
|
2019-03-06 13:36:51 +01:00
|
|
|
if reloaded > 0 {
|
|
|
|
return errors.New("error while reloading")
|
|
|
|
}
|
|
|
|
reloaded++
|
|
|
|
return nil
|
|
|
|
})
|
2018-10-26 15:48:22 +02:00
|
|
|
call := Calls.Get("options/set")
|
|
|
|
require.NotNil(t, call)
|
|
|
|
|
|
|
|
in := Params{
|
|
|
|
"potato": Params{
|
|
|
|
"Int": 50,
|
|
|
|
},
|
|
|
|
}
|
2019-06-17 10:34:30 +02:00
|
|
|
out, err := call.Fn(context.Background(), in)
|
2018-10-26 15:48:22 +02:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.Nil(t, out)
|
|
|
|
assert.Equal(t, 50, testOptions.Int)
|
|
|
|
assert.Equal(t, "hello", testOptions.String)
|
2019-03-06 13:36:51 +01:00
|
|
|
assert.Equal(t, 1, reloaded)
|
|
|
|
|
|
|
|
// error from reload
|
2019-06-17 10:34:30 +02:00
|
|
|
_, err = call.Fn(context.Background(), in)
|
2019-03-06 13:36:51 +01:00
|
|
|
require.Error(t, err)
|
|
|
|
assert.Contains(t, err.Error(), "error while reloading")
|
2018-10-26 15:48:22 +02:00
|
|
|
|
|
|
|
// unknown option block
|
|
|
|
in = Params{
|
|
|
|
"sausage": Params{
|
|
|
|
"Int": 50,
|
|
|
|
},
|
|
|
|
}
|
2019-06-17 10:34:30 +02:00
|
|
|
_, err = call.Fn(context.Background(), in)
|
2018-10-26 15:48:22 +02:00
|
|
|
require.Error(t, err)
|
|
|
|
assert.Contains(t, err.Error(), "unknown option block")
|
|
|
|
|
|
|
|
// bad shape
|
|
|
|
in = Params{
|
|
|
|
"potato": []string{"a", "b"},
|
|
|
|
}
|
2019-06-17 10:34:30 +02:00
|
|
|
_, err = call.Fn(context.Background(), in)
|
2018-10-26 15:48:22 +02:00
|
|
|
require.Error(t, err)
|
|
|
|
assert.Contains(t, err.Error(), "failed to write options")
|
2019-03-06 13:36:51 +01:00
|
|
|
|
2018-10-26 15:48:22 +02:00
|
|
|
}
|