123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327 |
- // environment_test tests the use and precedence of environment variables
- //
- // The tests rely on functions defined in cmdtest_test.go
- package cmdtest
- import (
- "os"
- "runtime"
- "testing"
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
- )
- // TestCmdTest demonstrates and verifies the test functions for end-to-end testing of rclone
- func TestEnvironmentVariables(t *testing.T) {
- createTestEnvironment(t)
- testdataPath := createSimpleTestData(t)
- // Non backend flags
- // =================
- // First verify default behaviour of the implicit max_depth=-1
- env := ""
- out, err := rcloneEnv(env, "lsl", testFolder)
- //t.Logf("\n" + out)
- if assert.NoError(t, err) {
- assert.Contains(t, out, "rclone.config") // depth 1
- assert.Contains(t, out, "file1.txt") // depth 2
- assert.Contains(t, out, "fileA1.txt") // depth 3
- assert.Contains(t, out, "fileAA1.txt") // depth 4
- }
- // Test of flag.Value
- env = "RCLONE_MAX_DEPTH=2"
- out, err = rcloneEnv(env, "lsl", testFolder)
- if assert.NoError(t, err) {
- assert.Contains(t, out, "file1.txt") // depth 2
- assert.NotContains(t, out, "fileA1.txt") // depth 3
- }
- // Test of flag.Changed (tests #5341 Issue1)
- env = "RCLONE_LOG_LEVEL=DEBUG"
- out, err = rcloneEnv(env, "version", "--quiet")
- if assert.Error(t, err) {
- assert.Contains(t, out, " DEBUG : ")
- assert.Contains(t, out, "Can't set -q and --log-level")
- assert.Contains(t, "exit status 1", err.Error())
- }
- // Test of flag.DefValue
- env = "RCLONE_STATS=173ms"
- out, err = rcloneEnv(env, "help", "flags")
- if assert.NoError(t, err) {
- assert.Contains(t, out, "(default 173ms)")
- }
- // Test of command line flags overriding environment flags
- env = "RCLONE_MAX_DEPTH=2"
- out, err = rcloneEnv(env, "lsl", testFolder, "--max-depth", "3")
- if assert.NoError(t, err) {
- assert.Contains(t, out, "fileA1.txt") // depth 3
- assert.NotContains(t, out, "fileAA1.txt") // depth 4
- }
- // Test of debug logging while initialising flags from environment (tests #5241 Enhance1)
- env = "RCLONE_STATS=173ms"
- out, err = rcloneEnv(env, "version", "-vv")
- if assert.NoError(t, err) {
- assert.Contains(t, out, " DEBUG : ")
- assert.Contains(t, out, "--stats")
- assert.Contains(t, out, "173ms")
- assert.Contains(t, out, "RCLONE_STATS=")
- }
- // Backend flags and remote name
- // - The listremotes command includes names from environment variables,
- // the part between "RCLONE_CONFIG_" and "_TYPE", converted to lowercase.
- // - When using a remote created from env, e.g. with lsd command,
- // the name is case insensitive in contrast to remotes in config file
- // (fs.ConfigToEnv converts to uppercase before checking environment).
- // - Previously using a remote created from env, e.g. with lsd command,
- // would not be possible for remotes with '-' in names, and remote names
- // with '_' could be referred to with both '-' and '_', because any '-'
- // were replaced with '_' before lookup.
- // ===================================
- env = "RCLONE_CONFIG_MY-LOCAL_TYPE=local"
- out, err = rcloneEnv(env, "listremotes")
- if assert.NoError(t, err) {
- assert.Contains(t, out, "my-local:")
- }
- out, err = rcloneEnv(env, "lsl", "my-local:"+testFolder)
- if assert.NoError(t, err) {
- assert.Contains(t, out, "rclone.config")
- assert.Contains(t, out, "file1.txt")
- assert.Contains(t, out, "fileA1.txt")
- assert.Contains(t, out, "fileAA1.txt")
- }
- out, err = rcloneEnv(env, "lsl", "mY-LoCaL:"+testFolder)
- if assert.NoError(t, err) {
- assert.Contains(t, out, "rclone.config")
- assert.Contains(t, out, "file1.txt")
- assert.Contains(t, out, "fileA1.txt")
- assert.Contains(t, out, "fileAA1.txt")
- }
- out, err = rcloneEnv(env, "lsl", "my_local:"+testFolder)
- if assert.Error(t, err) {
- assert.Contains(t, out, "Failed to create file system")
- }
- env = "RCLONE_CONFIG_MY_LOCAL_TYPE=local"
- out, err = rcloneEnv(env, "listremotes")
- if assert.NoError(t, err) {
- assert.Contains(t, out, "my_local:")
- }
- out, err = rcloneEnv(env, "lsl", "my_local:"+testFolder)
- if assert.NoError(t, err) {
- assert.Contains(t, out, "rclone.config")
- assert.Contains(t, out, "file1.txt")
- assert.Contains(t, out, "fileA1.txt")
- assert.Contains(t, out, "fileAA1.txt")
- }
- out, err = rcloneEnv(env, "lsl", "my-local:"+testFolder)
- if assert.Error(t, err) {
- assert.Contains(t, out, "Failed to create file system")
- }
- // Backend flags and option precedence
- // ===================================
- // Test approach:
- // Verify no symlink warning when skip_links=true one the level with highest precedence
- // and skip_links=false on all levels with lower precedence
- //
- // Reference: https://rclone.org/docs/#precedence
- // Create a symlink in test data
- err = os.Symlink(testdataPath+"/folderA", testdataPath+"/symlinkA")
- if runtime.GOOS == "windows" {
- errNote := "The policy settings on Windows often prohibit the creation of symlinks due to security issues.\n"
- errNote += "You can safely ignore this test, if your change didn't affect environment variables."
- require.NoError(t, err, errNote)
- } else {
- require.NoError(t, err)
- }
- // Create a local remote with explicit skip_links=false
- out, err = rclone("config", "create", "myLocal", "local", "skip_links", "false")
- if assert.NoError(t, err) {
- assert.Contains(t, out, "[myLocal]")
- assert.Contains(t, out, "type = local")
- assert.Contains(t, out, "skip_links = false")
- }
- // Verify symlink warning when skip_links=false on all levels
- env = "RCLONE_SKIP_LINKS=false;RCLONE_LOCAL_SKIP_LINKS=false;RCLONE_CONFIG_MYLOCAL_SKIP_LINKS=false"
- out, err = rcloneEnv(env, "lsd", "myLocal,skip_links=false:"+testdataPath, "--skip-links=false")
- //t.Logf("\n" + out)
- if assert.NoError(t, err) {
- assert.Contains(t, out, "NOTICE: symlinkA:")
- assert.Contains(t, out, "folderA")
- }
- // Test precedence of connection strings
- env = "RCLONE_SKIP_LINKS=false;RCLONE_LOCAL_SKIP_LINKS=false;RCLONE_CONFIG_MYLOCAL_SKIP_LINKS=false"
- out, err = rcloneEnv(env, "lsd", "myLocal,skip_links:"+testdataPath, "--skip-links=false")
- if assert.NoError(t, err) {
- assert.NotContains(t, out, "symlinkA")
- assert.Contains(t, out, "folderA")
- }
- // Test precedence of command line flags
- env = "RCLONE_SKIP_LINKS=false;RCLONE_LOCAL_SKIP_LINKS=false;RCLONE_CONFIG_MYLOCAL_SKIP_LINKS=false"
- out, err = rcloneEnv(env, "lsd", "myLocal:"+testdataPath, "--skip-links")
- if assert.NoError(t, err) {
- assert.NotContains(t, out, "symlinkA")
- assert.Contains(t, out, "folderA")
- }
- // Test precedence of remote specific environment variables (tests #5341 Issue2)
- env = "RCLONE_SKIP_LINKS=false;RCLONE_LOCAL_SKIP_LINKS=false;RCLONE_CONFIG_MYLOCAL_SKIP_LINKS=true"
- out, err = rcloneEnv(env, "lsd", "myLocal:"+testdataPath)
- if assert.NoError(t, err) {
- assert.NotContains(t, out, "symlinkA")
- assert.Contains(t, out, "folderA")
- }
- // Test precedence of backend specific environment variables (tests #5341 Issue3)
- env = "RCLONE_SKIP_LINKS=false;RCLONE_LOCAL_SKIP_LINKS=true"
- out, err = rcloneEnv(env, "lsd", "myLocal:"+testdataPath)
- if assert.NoError(t, err) {
- assert.NotContains(t, out, "symlinkA")
- assert.Contains(t, out, "folderA")
- }
- // Test precedence of backend generic environment variables
- env = "RCLONE_SKIP_LINKS=true"
- out, err = rcloneEnv(env, "lsd", "myLocal:"+testdataPath)
- if assert.NoError(t, err) {
- assert.NotContains(t, out, "symlinkA")
- assert.Contains(t, out, "folderA")
- }
- // Recreate the test remote with explicit skip_links=true
- out, err = rclone("config", "create", "myLocal", "local", "skip_links", "true")
- if assert.NoError(t, err) {
- assert.Contains(t, out, "[myLocal]")
- assert.Contains(t, out, "type = local")
- assert.Contains(t, out, "skip_links = true")
- }
- // Test precedence of config file options
- env = ""
- out, err = rcloneEnv(env, "lsd", "myLocal:"+testdataPath)
- if assert.NoError(t, err) {
- assert.NotContains(t, out, "symlinkA")
- assert.Contains(t, out, "folderA")
- }
- // Recreate the test remote with rclone defaults, that is implicit skip_links=false
- out, err = rclone("config", "create", "myLocal", "local")
- if assert.NoError(t, err) {
- assert.Contains(t, out, "[myLocal]")
- assert.Contains(t, out, "type = local")
- assert.NotContains(t, out, "skip_links")
- }
- // Verify the rclone default value (implicit skip_links=false)
- env = ""
- out, err = rcloneEnv(env, "lsd", "myLocal:"+testdataPath)
- if assert.NoError(t, err) {
- assert.Contains(t, out, "NOTICE: symlinkA:")
- assert.Contains(t, out, "folderA")
- }
- // Display of backend defaults (tests #4659)
- //------------------------------------------
- env = "RCLONE_DRIVE_CHUNK_SIZE=111M"
- out, err = rcloneEnv(env, "help", "flags")
- if assert.NoError(t, err) {
- assert.Regexp(t, "--drive-chunk-size[^\\(]+\\(default 111M\\)", out)
- }
- // Options on referencing remotes (alias, crypt, etc.)
- //----------------------------------------------------
- // Create alias remote on myLocal having implicit skip_links=false
- out, err = rclone("config", "create", "myAlias", "alias", "remote", "myLocal:"+testdataPath)
- if assert.NoError(t, err) {
- assert.Contains(t, out, "[myAlias]")
- assert.Contains(t, out, "type = alias")
- assert.Contains(t, out, "remote = myLocal:")
- }
- // Verify symlink warnings on the alias
- env = ""
- out, err = rcloneEnv(env, "lsd", "myAlias:")
- if assert.NoError(t, err) {
- assert.Contains(t, out, "NOTICE: symlinkA:")
- assert.Contains(t, out, "folderA")
- }
- // Test backend generic flags
- // having effect on the underlying local remote
- env = "RCLONE_SKIP_LINKS=true"
- out, err = rcloneEnv(env, "lsd", "myAlias:")
- if assert.NoError(t, err) {
- assert.NotContains(t, out, "symlinkA")
- assert.Contains(t, out, "folderA")
- }
- // Test backend specific flags
- // having effect on the underlying local remote
- env = "RCLONE_LOCAL_SKIP_LINKS=true"
- out, err = rcloneEnv(env, "lsd", "myAlias:")
- if assert.NoError(t, err) {
- assert.NotContains(t, out, "symlinkA")
- assert.Contains(t, out, "folderA")
- }
- // Test remote specific flags
- // having no effect unless supported by the immediate remote (alias)
- env = "RCLONE_CONFIG_MYALIAS_SKIP_LINKS=true"
- out, err = rcloneEnv(env, "lsd", "myAlias:")
- if assert.NoError(t, err) {
- assert.Contains(t, out, "NOTICE: symlinkA:")
- assert.Contains(t, out, "folderA")
- }
- env = "RCLONE_CONFIG_MYALIAS_REMOTE=" + "myLocal:" + testdataPath + "/folderA"
- out, err = rcloneEnv(env, "lsl", "myAlias:")
- if assert.NoError(t, err) {
- assert.Contains(t, out, "fileA1.txt")
- assert.NotContains(t, out, "fileB1.txt")
- }
- // Test command line flags
- // having effect on the underlying local remote
- env = ""
- out, err = rcloneEnv(env, "lsd", "myAlias:", "--skip-links")
- if assert.NoError(t, err) {
- assert.NotContains(t, out, "symlinkA")
- assert.Contains(t, out, "folderA")
- }
- // Test connection specific flags
- // having no effect unless supported by the immediate remote (alias)
- env = ""
- out, err = rcloneEnv(env, "lsd", "myAlias,skip_links:")
- if assert.NoError(t, err) {
- assert.Contains(t, out, "NOTICE: symlinkA:")
- assert.Contains(t, out, "folderA")
- }
- env = ""
- out, err = rcloneEnv(env, "lsl", "myAlias,remote='myLocal:"+testdataPath+"/folderA':", "-vv")
- if assert.NoError(t, err) {
- assert.Contains(t, out, "fileA1.txt")
- assert.NotContains(t, out, "fileB1.txt")
- }
- }
|