rclone/fs/config/config_test.go
Nick Craig-Wood 8c3740c2c5 config: Improve the Provider matching to have a negated match #2140
This makes it easier to make classes of provider in the config.
2018-04-13 16:06:37 +01:00

230 lines
5.5 KiB
Go

package config
import (
"fmt"
"io/ioutil"
"os"
"testing"
"github.com/ncw/rclone/fs"
"github.com/ncw/rclone/fs/config/obscure"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestCRUD(t *testing.T) {
configKey = nil // reset password
// create temp config file
tempFile, err := ioutil.TempFile("", "crud.conf")
assert.NoError(t, err)
path := tempFile.Name()
defer func() {
err := os.Remove(path)
assert.NoError(t, err)
}()
assert.NoError(t, tempFile.Close())
// temporarily adapt configuration
oldOsStdout := os.Stdout
oldConfigPath := ConfigPath
oldConfig := fs.Config
oldConfigFile := configFile
oldReadLine := ReadLine
os.Stdout = nil
ConfigPath = path
fs.Config = &fs.ConfigInfo{}
configFile = nil
defer func() {
os.Stdout = oldOsStdout
ConfigPath = oldConfigPath
ReadLine = oldReadLine
fs.Config = oldConfig
configFile = oldConfigFile
}()
LoadConfig()
assert.Equal(t, []string{}, getConfigData().GetSectionList())
// Fake a remote
fs.Register(&fs.RegInfo{Name: "config_test_remote"})
// add new remote
i := 0
ReadLine = func() string {
answers := []string{
"config_test_remote", // type
"y", // looks good, save
}
i = i + 1
return answers[i-1]
}
NewRemote("test")
assert.Equal(t, []string{"test"}, configFile.GetSectionList())
// Reload the config file to workaround this bug
// https://github.com/Unknwon/goconfig/issues/39
configFile, err = loadConfigFile()
require.NoError(t, err)
// normal rename, test → asdf
ReadLine = func() string { return "asdf" }
RenameRemote("test")
assert.Equal(t, []string{"asdf"}, configFile.GetSectionList())
// no-op rename, asdf → asdf
RenameRemote("asdf")
assert.Equal(t, []string{"asdf"}, configFile.GetSectionList())
// delete remote
DeleteRemote("asdf")
assert.Equal(t, []string{}, configFile.GetSectionList())
}
// Test some error cases
func TestReveal(t *testing.T) {
for _, test := range []struct {
in string
wantErr string
}{
{"YmJiYmJiYmJiYmJiYmJiYp*gcEWbAw", "base64 decode failed when revealing password - is it obscured?: illegal base64 data at input byte 22"},
{"aGVsbG8", "input too short when revealing password - is it obscured?"},
{"", "input too short when revealing password - is it obscured?"},
} {
gotString, gotErr := obscure.Reveal(test.in)
assert.Equal(t, "", gotString)
assert.Equal(t, test.wantErr, gotErr.Error())
}
}
func TestConfigLoad(t *testing.T) {
oldConfigPath := ConfigPath
ConfigPath = "./testdata/plain.conf"
defer func() {
ConfigPath = oldConfigPath
}()
configKey = nil // reset password
c, err := loadConfigFile()
if err != nil {
t.Fatal(err)
}
sections := c.GetSectionList()
var expect = []string{"RCLONE_ENCRYPT_V0", "nounc", "unc"}
assert.Equal(t, expect, sections)
keys := c.GetKeyList("nounc")
expect = []string{"type", "nounc"}
assert.Equal(t, expect, keys)
}
func TestConfigLoadEncrypted(t *testing.T) {
var err error
oldConfigPath := ConfigPath
ConfigPath = "./testdata/encrypted.conf"
defer func() {
ConfigPath = oldConfigPath
configKey = nil // reset password
}()
// Set correct password
err = setConfigPassword("asdf")
require.NoError(t, err)
c, err := loadConfigFile()
require.NoError(t, err)
sections := c.GetSectionList()
var expect = []string{"nounc", "unc"}
assert.Equal(t, expect, sections)
keys := c.GetKeyList("nounc")
expect = []string{"type", "nounc"}
assert.Equal(t, expect, keys)
}
func TestConfigLoadEncryptedFailures(t *testing.T) {
var err error
// This file should be too short to be decoded.
oldConfigPath := ConfigPath
ConfigPath = "./testdata/enc-short.conf"
defer func() { ConfigPath = oldConfigPath }()
_, err = loadConfigFile()
require.Error(t, err)
// This file contains invalid base64 characters.
ConfigPath = "./testdata/enc-invalid.conf"
_, err = loadConfigFile()
require.Error(t, err)
// This file contains invalid base64 characters.
ConfigPath = "./testdata/enc-too-new.conf"
_, err = loadConfigFile()
require.Error(t, err)
// This file does not exist.
ConfigPath = "./testdata/filenotfound.conf"
c, err := loadConfigFile()
assert.Equal(t, errorConfigFileNotFound, err)
assert.Nil(t, c)
}
func TestPassword(t *testing.T) {
defer func() {
configKey = nil // reset password
}()
var err error
// Empty password should give error
err = setConfigPassword(" \t ")
require.Error(t, err)
// Test invalid utf8 sequence
err = setConfigPassword(string([]byte{0xff, 0xfe, 0xfd}) + "abc")
require.Error(t, err)
// Simple check of wrong passwords
hashedKeyCompare(t, "mis", "match", false)
// Check that passwords match after unicode normalization
hashedKeyCompare(t, "ff\u0041\u030A", "ffÅ", true)
// Check that passwords preserves case
hashedKeyCompare(t, "abcdef", "ABCDEF", false)
}
func hashedKeyCompare(t *testing.T, a, b string, shouldMatch bool) {
err := setConfigPassword(a)
require.NoError(t, err)
k1 := configKey
err = setConfigPassword(b)
require.NoError(t, err)
k2 := configKey
if shouldMatch {
assert.Equal(t, k1, k2)
} else {
assert.NotEqual(t, k1, k2)
}
}
func TestMatchProvider(t *testing.T) {
for _, test := range []struct {
config string
provider string
want bool
}{
{"", "", true},
{"one", "one", true},
{"one,two", "two", true},
{"one,two,three", "two", true},
{"one", "on", false},
{"one,two,three", "tw", false},
{"!one,two,three", "two", false},
{"!one,two,three", "four", true},
} {
what := fmt.Sprintf("%q,%q", test.config, test.provider)
got := matchProvider(test.config, test.provider)
assert.Equal(t, test.want, got, what)
}
}