Skip to content

Commit cc83d53

Browse files
Refactor tests and add platform-specific test cases (#623)
* Refactor tests and add platform-specific test cases - Removed the TestFilteredArgumentsRegression from wrapper_test.go and added it to wrapper_unix_test.go for Unix-specific testing. - Added new test files for Unix and Windows configurations, including path handling, profile settings, and command execution. - Implemented tests for handling environment variables in Unix and Windows. - Created tests for path fixing and symlink evaluation in Unix. - Added tests for scheduling mechanisms across different platforms (crond, launchd, systemd, and Windows). - Introduced tests for shell command execution and argument escaping specific to Unix. - Ensured that all tests are properly organized and follow the build constraints for platform-specific execution. * refactor(tests): streamline path handling in Unix path tests and adjust command timeout checks
1 parent 7a64653 commit cc83d53

35 files changed

Lines changed: 1090 additions & 1035 deletions

.vscode/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,5 @@
2020
"master"
2121
],
2222
"makefile.configureOnOpen": false,
23-
"go.buildTags": "ssh"
23+
"go.buildTags": "ssh fuse"
2424
}

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ test: $(GOBIN)/gotestsum prepare_test ## Run unit tests
184184

185185
test-ci: $(GOBIN)/gotestsum prepare_test ## Run unit tests with coverage (for CI)
186186
@echo "[*] $@"
187-
$(GOBIN)/gotestsum --junitfile $(JUNIT_FILE) -- -race -short -coverprofile='$(COVERAGE_FILE)' ./...
187+
$(GOBIN)/gotestsum --junitfile $(JUNIT_FILE) -- -race -short -tags=fuse -coverprofile='$(COVERAGE_FILE)' ./...
188188

189189
coverage: ## Generate coverage report
190190
@echo "[*] $@"

config/confidential_test.go

Lines changed: 0 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -304,37 +304,6 @@ profile:
304304
assert.Equal(t, []string{"--repo=" + expectedPublic}, result.GetAll())
305305
}
306306

307-
func TestGetNonConfidentialArgsFromEnvironmentVariable(t *testing.T) {
308-
t.Parallel()
309-
310-
if platform.IsWindows() {
311-
t.Skip()
312-
}
313-
repo := "local:user:%s@host/path with space"
314-
environment := []string{
315-
"MY_REPOSITORY=" + fmt.Sprintf(repo, "password"),
316-
}
317-
testConfig := `
318-
global:
319-
prevent-auto-repository-file: true
320-
profile:
321-
repository: $MY_REPOSITORY
322-
`
323-
profile, err := getProfile("yaml", testConfig, "profile", "")
324-
assert.NoError(t, err)
325-
assert.NotNil(t, profile)
326-
327-
args := profile.GetCommandFlags(constants.CommandBackup)
328-
args = args.Modify(shell.NewExpandEnvModifier(environment))
329-
result := GetNonConfidentialArgs(profile, args)
330-
331-
expectedSecret := shell.NewArg(fmt.Sprintf(repo, "password"), shell.ArgConfigEscape).String()
332-
expectedPublic := shell.NewArg(fmt.Sprintf(repo, ConfidentialReplacement), shell.ArgConfigEscape).String()
333-
334-
assert.Equal(t, []string{"--repo=" + expectedSecret}, args.GetAll())
335-
assert.Equal(t, []string{"--repo=" + expectedPublic}, result.GetAll())
336-
}
337-
338307
func TestGetAutoRepositoryFile(t *testing.T) {
339308
require.NoError(t, os.Unsetenv("RESTIC_REPOSITORY"))
340309
require.NoError(t, os.Unsetenv("RESTIC_REPOSITORY_FILE"))
@@ -377,55 +346,6 @@ func TestGetAutoRepositoryFile(t *testing.T) {
377346
}
378347
}
379348

380-
func TestGetAutoRepositoryFileDisabledWithEnv(t *testing.T) {
381-
if platform.IsWindows() {
382-
t.Skip()
383-
}
384-
385-
tests := []string{
386-
"RESTIC_REPOSITORY",
387-
"RESTIC_REPOSITORY_FILE",
388-
}
389-
390-
for _, envKey := range tests {
391-
t.Run(envKey, func(t *testing.T) {
392-
config := fmt.Sprintf(`
393-
[my-profile]
394-
repository = %q
395-
`, defaultHttpUrl)
396-
397-
defer os.Unsetenv(envKey)
398-
profile, err := getResolvedProfile("toml", config, "my-profile")
399-
require.NoError(t, err)
400-
401-
hasRepoFlag := func() (found bool) {
402-
_, found = profile.GetCommandFlags(constants.CommandBackup).Get("repo")
403-
return
404-
}
405-
406-
t.Run("no-env", func(t *testing.T) {
407-
require.NoError(t, os.Unsetenv(envKey))
408-
profile.Environment = nil
409-
assert.False(t, hasRepoFlag())
410-
})
411-
412-
t.Run("profile-env", func(t *testing.T) {
413-
require.NoError(t, os.Unsetenv(envKey))
414-
profile.Environment = map[string]ConfidentialValue{
415-
envKey: NewConfidentialValue("1"),
416-
}
417-
assert.True(t, hasRepoFlag())
418-
})
419-
420-
t.Run("os-env", func(t *testing.T) {
421-
require.NoError(t, os.Setenv(envKey, "1"))
422-
profile.Environment = nil
423-
assert.True(t, hasRepoFlag())
424-
})
425-
})
426-
}
427-
}
428-
429349
func TestConfidentialToJSON(t *testing.T) {
430350
t.Parallel()
431351

config/confidential_unix_test.go

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
//go:build !windows
2+
3+
package config
4+
5+
import (
6+
"fmt"
7+
"os"
8+
"testing"
9+
10+
"github.com/creativeprojects/resticprofile/constants"
11+
"github.com/creativeprojects/resticprofile/shell"
12+
"github.com/stretchr/testify/assert"
13+
"github.com/stretchr/testify/require"
14+
)
15+
16+
func TestGetNonConfidentialArgsFromEnvironmentVariable(t *testing.T) {
17+
t.Parallel()
18+
19+
repo := "local:user:%s@host/path with space"
20+
environment := []string{
21+
"MY_REPOSITORY=" + fmt.Sprintf(repo, "password"),
22+
}
23+
testConfig := `
24+
global:
25+
prevent-auto-repository-file: true
26+
profile:
27+
repository: $MY_REPOSITORY
28+
`
29+
profile, err := getProfile("yaml", testConfig, "profile", "")
30+
assert.NoError(t, err)
31+
assert.NotNil(t, profile)
32+
33+
args := profile.GetCommandFlags(constants.CommandBackup)
34+
args = args.Modify(shell.NewExpandEnvModifier(environment))
35+
result := GetNonConfidentialArgs(profile, args)
36+
37+
expectedSecret := shell.NewArg(fmt.Sprintf(repo, "password"), shell.ArgConfigEscape).String()
38+
expectedPublic := shell.NewArg(fmt.Sprintf(repo, ConfidentialReplacement), shell.ArgConfigEscape).String()
39+
40+
assert.Equal(t, []string{"--repo=" + expectedSecret}, args.GetAll())
41+
assert.Equal(t, []string{"--repo=" + expectedPublic}, result.GetAll())
42+
}
43+
44+
func TestGetAutoRepositoryFileDisabledWithEnv(t *testing.T) {
45+
tests := []string{
46+
"RESTIC_REPOSITORY",
47+
"RESTIC_REPOSITORY_FILE",
48+
}
49+
50+
for _, envKey := range tests {
51+
t.Run(envKey, func(t *testing.T) {
52+
config := fmt.Sprintf(`
53+
[my-profile]
54+
repository = %q
55+
`, defaultHttpUrl)
56+
57+
defer os.Unsetenv(envKey)
58+
profile, err := getResolvedProfile("toml", config, "my-profile")
59+
require.NoError(t, err)
60+
61+
hasRepoFlag := func() (found bool) {
62+
_, found = profile.GetCommandFlags(constants.CommandBackup).Get("repo")
63+
return
64+
}
65+
66+
t.Run("no-env", func(t *testing.T) {
67+
require.NoError(t, os.Unsetenv(envKey))
68+
profile.Environment = nil
69+
assert.False(t, hasRepoFlag())
70+
})
71+
72+
t.Run("profile-env", func(t *testing.T) {
73+
require.NoError(t, os.Unsetenv(envKey))
74+
profile.Environment = map[string]ConfidentialValue{
75+
envKey: NewConfidentialValue("1"),
76+
}
77+
assert.True(t, hasRepoFlag())
78+
})
79+
80+
t.Run("os-env", func(t *testing.T) {
81+
require.NoError(t, os.Setenv(envKey, "1"))
82+
profile.Environment = nil
83+
assert.True(t, hasRepoFlag())
84+
})
85+
})
86+
}
87+
}

config/jsonschema/schema_test.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
//go:build !ajv_test
2-
31
package jsonschema
42

53
import (

config/path_test.go

Lines changed: 0 additions & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,12 @@
11
package config
22

33
import (
4-
"fmt"
54
"os"
6-
"os/user"
7-
"path/filepath"
8-
"runtime"
95
"testing"
106

11-
"github.com/creativeprojects/resticprofile/platform"
127
"github.com/stretchr/testify/assert"
13-
"github.com/stretchr/testify/require"
148
)
159

16-
func TestFixUnixPaths(t *testing.T) {
17-
if platform.IsWindows() {
18-
t.SkipNow()
19-
}
20-
21-
home, err := os.UserHomeDir()
22-
require.NoError(t, err)
23-
24-
usr, err := user.Current()
25-
require.NoError(t, err)
26-
27-
paths := []struct {
28-
source string
29-
expected string
30-
}{
31-
{"", ""},
32-
{"dir", "/prefix/dir"},
33-
{"/dir", "/dir"},
34-
{"~/dir", filepath.Join(home, "dir")},
35-
{"~" + usr.Username + "/dir", filepath.Join(home, "dir")},
36-
{"~" + usr.Username, home},
37-
{"~", home},
38-
{"~file", "/prefix/~file"},
39-
{"$TEMP_TEST_DIR/dir", "/home/dir"},
40-
{"some file.txt", "/prefix/some file.txt"},
41-
}
42-
43-
err = os.Setenv("TEMP_TEST_DIR", "/home")
44-
require.NoError(t, err)
45-
46-
for _, testPath := range paths {
47-
fixed := fixPath(testPath.source, expandEnv, absolutePrefix("/prefix"), expandUserHome)
48-
assert.Equalf(t, testPath.expected, fixed, "source was '%s'", testPath.source)
49-
// running it again should not change the value
50-
fixed = fixPath(fixed, expandEnv, absolutePrefix("/prefix"))
51-
assert.Equalf(t, testPath.expected, fixed, "source was '%s'", testPath.source)
52-
}
53-
}
54-
55-
func TestFixWindowsPaths(t *testing.T) {
56-
if runtime.GOOS != "windows" {
57-
t.Skip("only testing Windows paths on Windows")
58-
}
59-
60-
home, err := os.UserHomeDir()
61-
require.NoError(t, err)
62-
63-
paths := []struct {
64-
source string
65-
expected string
66-
}{
67-
{``, ``},
68-
{`dir`, `c:\prefix\dir`},
69-
{`\dir`, `c:\prefix\dir`},
70-
{`c:\dir`, `c:\dir`},
71-
{`~\dir`, filepath.Join(home, "dir")},
72-
{`~/dir`, home + `/dir`},
73-
{`~`, home},
74-
{`~file`, `c:\prefix\~file`},
75-
{`%TEMP_TEST_DIR%\dir`, `%TEMP_TEST_DIR%\dir`},
76-
{`${TEMP_TEST_DIR}\dir`, `c:\home\dir`},
77-
{"some file.txt", `c:\prefix\some file.txt`},
78-
}
79-
80-
err = os.Setenv("TEMP_TEST_DIR", "c:\\home")
81-
require.NoError(t, err)
82-
83-
for _, testPath := range paths {
84-
fixed := fixPath(testPath.source, expandEnv, absolutePrefix("c:\\prefix"), expandUserHome)
85-
assert.Equalf(t, testPath.expected, fixed, "source was '%s'", testPath.source)
86-
// running it again should not change the value
87-
fixed = fixPath(fixed, expandEnv, absolutePrefix("c:\\prefix"))
88-
assert.Equalf(t, testPath.expected, fixed, "source was '%s'", testPath.source)
89-
}
90-
}
91-
9210
func TestExpandEnv(t *testing.T) {
9311
path := os.Getenv("PATH")
9412
assert.Equal(t, path, expandEnv("$PATH"))
@@ -98,82 +16,3 @@ func TestExpandEnv(t *testing.T) {
9816
assert.Equal(t, "", expandEnv("${__UNDEFINED_ENV_VAR__}"))
9917
assert.Equal(t, "", expandEnv("$__UNDEFINED_ENV_VAR__"))
10018
}
101-
102-
func TestEvaluateSymlinks(t *testing.T) {
103-
if platform.IsWindows() {
104-
t.SkipNow()
105-
}
106-
107-
var rawDir, dir string
108-
setup := func(t *testing.T) {
109-
t.Helper()
110-
var err error
111-
rawDir = t.TempDir()
112-
dir, err = filepath.EvalSymlinks(rawDir)
113-
require.NoError(t, err)
114-
}
115-
116-
link := func(t *testing.T, path, linkname string) {
117-
t.Helper()
118-
_ = os.Mkdir(filepath.Join(rawDir, path), 0700)
119-
require.NoError(t, os.Symlink(filepath.Join(rawDir, path), filepath.Join(rawDir, linkname)))
120-
}
121-
122-
t.Run("existing-target", func(t *testing.T) {
123-
setup(t)
124-
link(t, "a", "b")
125-
assert.Equal(t, filepath.Join(dir, "a"), evaluateSymlinks(filepath.Join(rawDir, "b")))
126-
assert.Equal(t, filepath.Join(dir, "a"), evaluateSymlinks(filepath.Join(rawDir, "a")))
127-
assert.Equal(t, filepath.Join(dir, "a"), evaluateSymlinks(filepath.Join(dir, "a")))
128-
})
129-
130-
t.Run("non-existing-target", func(t *testing.T) {
131-
setup(t)
132-
link(t, "a", "b")
133-
assert.Equal(t, filepath.Join(dir, "a", "missing"), evaluateSymlinks(filepath.Join(rawDir, "b", "missing")))
134-
assert.Equal(t, filepath.Join(dir, "missing/path"), evaluateSymlinks(filepath.Join(rawDir, "missing/path")))
135-
})
136-
137-
t.Run("non-existing-targets", func(t *testing.T) {
138-
setup(t)
139-
link(t, "a", "b")
140-
assert.Equal(t, filepath.Join(dir, "a/mis/s/ing"), evaluateSymlinks(filepath.Join(rawDir, "b/mis/s/ing")))
141-
})
142-
143-
t.Run("nested", func(t *testing.T) {
144-
setup(t)
145-
link(t, "a", "b")
146-
link(t, "d", "c")
147-
link(t, "a/nested", "b/c")
148-
link(t, "d", "b/c/toD")
149-
assert.Equal(t, filepath.Join(dir, "a/nested"), evaluateSymlinks(filepath.Join(rawDir, "b/c")))
150-
assert.Equal(t, filepath.Join(dir, "d"), evaluateSymlinks(filepath.Join(rawDir, "b/c/toD")))
151-
assert.Equal(t, filepath.Join(dir, "d"), evaluateSymlinks(filepath.Join(rawDir, "a/nested/toD")))
152-
})
153-
154-
t.Run("usage-in-profile", func(t *testing.T) {
155-
setup(t)
156-
link(t, "my-base", "linked-base")
157-
baseDir := filepath.Join(rawDir, "linked-base")
158-
159-
config := func(relative bool) string {
160-
return fmt.Sprintf(`
161-
[profile]
162-
base-dir = %q
163-
[profile.backup]
164-
source-relative = %v
165-
source-base = %q
166-
`, baseDir, relative, baseDir)
167-
}
168-
169-
profile, err := getResolvedProfile("toml", config(false), "profile")
170-
require.NoError(t, err)
171-
assert.Equal(t, baseDir, profile.BaseDir)
172-
assert.Equal(t, profile.BaseDir, profile.Backup.SourceBase)
173-
174-
profile, err = getResolvedProfile("toml", config(true), "profile")
175-
require.NoError(t, err)
176-
assert.Equal(t, evaluateSymlinks(baseDir), profile.BaseDir)
177-
assert.Equal(t, profile.BaseDir, profile.Backup.SourceBase)
178-
})
179-
}

0 commit comments

Comments
 (0)