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  }