Skip to content

Commit d59a1ff

Browse files
add integration test
1 parent 8218e70 commit d59a1ff

File tree

7 files changed

+312
-0
lines changed

7 files changed

+312
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
/lock/locktest
2222
/mock
2323
/mock.exe
24+
/echo
25+
/echo.exe
2426

2527
# test output
2628
/coverage.out

examples/integration_test.hcl

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
default {
2+
repository = "rest:http://user:password@localhost:8000/path"
3+
password-file = "key"
4+
}
5+
6+
simple {
7+
inherit = "default"
8+
backup {
9+
exclude = "/**/.git"
10+
source = "/source"
11+
}
12+
}
13+
14+
spaces {
15+
inherit = "default"
16+
backup {
17+
exclude = "My Documents"
18+
source = "/source dir"
19+
}
20+
}
21+
22+
quotes {
23+
inherit = "default"
24+
backup {
25+
exclude = ["My'Documents", "My\"Documents"]
26+
source = ["/source'dir", "/source\"dir"]
27+
}
28+
}
29+
30+
glob {
31+
inherit = "default"
32+
backup {
33+
exclude = ["examples/integration*"]
34+
source = ["examples/integration*"]
35+
}
36+
}
37+
38+
mixed {
39+
inherit = "default"
40+
backup {
41+
exclude = ["examples/integration*"]
42+
source = ["/Côte d'Ivoire"]
43+
}
44+
}

examples/integration_test.json

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"default": {
3+
"password-file": "key",
4+
"repository": "rest:http://user:password@localhost:8000/path"
5+
},
6+
"simple": {
7+
"inherit": "default",
8+
"backup": {
9+
"exclude": "/**/.git",
10+
"source": "/source"
11+
}
12+
},
13+
"spaces": {
14+
"inherit": "default",
15+
"backup": {
16+
"exclude": "My Documents",
17+
"source": "/source dir"
18+
}
19+
},
20+
"quotes": {
21+
"inherit": "default",
22+
"backup": {
23+
"exclude": ["My'Documents", "My\"Documents"],
24+
"source": ["/source'dir", "/source\"dir"]
25+
}
26+
},
27+
"glob": {
28+
"inherit": "default",
29+
"backup": {
30+
"exclude": ["examples/integration*"],
31+
"source": ["examples/integration*"]
32+
}
33+
},
34+
"mixed": {
35+
"inherit": "default",
36+
"backup": {
37+
"exclude": ["examples/integration*"],
38+
"source": ["/Côte d'Ivoire"]
39+
}
40+
}
41+
}

examples/integration_test.toml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
[default]
2+
repository = "rest:http://user:password@localhost:8000/path"
3+
password-file = "key"
4+
5+
[simple]
6+
inherit = "default"
7+
[simple.backup]
8+
exclude = "/**/.git"
9+
source = "/source"
10+
11+
[spaces]
12+
inherit = "default"
13+
[spaces.backup]
14+
exclude = "My Documents"
15+
source = "/source dir"
16+
17+
[quotes]
18+
inherit = "default"
19+
[quotes.backup]
20+
exclude = ["My'Documents", "My\"Documents"]
21+
source = ["/source'dir", "/source\"dir"]
22+
23+
[glob]
24+
inherit = "default"
25+
[glob.backup]
26+
exclude = ["examples/integration*"]
27+
source = ["examples/integration*"]
28+
29+
[mixed]
30+
inherit = "default"
31+
[mixed.backup]
32+
exclude = ["examples/integration*"]
33+
source = ["/Côte d'Ivoire"]

examples/integration_test.yaml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
---
2+
default:
3+
password-file: key
4+
repository: "rest:http://user:password@localhost:8000/path"
5+
6+
simple:
7+
inherit: default
8+
backup:
9+
exclude: "/**/.git"
10+
source: /source
11+
12+
spaces:
13+
inherit: default
14+
backup:
15+
exclude: "My Documents"
16+
source: /source dir
17+
18+
quotes:
19+
inherit: default
20+
backup:
21+
exclude:
22+
- "My'Documents"
23+
- "My\"Documents"
24+
source:
25+
- "/source'dir"
26+
- "/source\"dir"
27+
28+
glob:
29+
inherit: default
30+
backup:
31+
exclude:
32+
- "examples/integration*"
33+
source:
34+
- "examples/integration*"
35+
36+
mixed:
37+
inherit: default
38+
backup:
39+
exclude:
40+
- "examples/integration*"
41+
source:
42+
- "/Côte d'Ivoire"

integration_test.go

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
"os"
7+
"os/exec"
8+
"path/filepath"
9+
"runtime"
10+
"strings"
11+
"testing"
12+
13+
"github.com/creativeprojects/resticprofile/config"
14+
"github.com/creativeprojects/resticprofile/term"
15+
"github.com/stretchr/testify/assert"
16+
"github.com/stretchr/testify/require"
17+
)
18+
19+
var (
20+
echoBinary string
21+
)
22+
23+
func init() {
24+
// build restic mock
25+
cmd := exec.Command("go", "build", "./shell/echo")
26+
cmd.Run()
27+
if runtime.GOOS == "windows" {
28+
echoBinary = "echo.exe"
29+
} else {
30+
echoBinary = "./echo"
31+
}
32+
}
33+
34+
// TestFromConfigFileToCommandLine loads all examples/integration_test.* configuration files
35+
// and run some commands to display all the arguments that were sent
36+
func TestFromConfigFileToCommandLine(t *testing.T) {
37+
files, err := filepath.Glob("./examples/integration_test.*")
38+
require.NoError(t, err)
39+
require.Greater(t, len(files), 0)
40+
41+
// we can use the same files to test a glob pattern
42+
globFiles := "\"" + strings.Join(files, "\" \"") + "\""
43+
44+
integrationData := []struct {
45+
profileName string
46+
commandName string
47+
cmdlineArgs []string
48+
expected string
49+
expectedOnWindows string
50+
}{
51+
{
52+
"default",
53+
"snapshots",
54+
[]string{},
55+
`"snapshots" "--password-file" "key" "--repo" "rest:http://user:password@localhost:8000/path"`,
56+
"",
57+
},
58+
{
59+
"simple",
60+
"backup",
61+
[]string{"--option"},
62+
`"backup" "--exclude" "/**/.git" "--password-file" "key" "--repo" "rest:http://user:password@localhost:8000/path" "--option" "/source"`,
63+
"",
64+
},
65+
{
66+
"spaces",
67+
"backup",
68+
[]string{"some path"},
69+
`"backup" "--exclude" "My Documents" "--password-file" "key" "--repo" "rest:http://user:password@localhost:8000/path" "some" "path" "/source" "dir"`,
70+
`"backup" "--exclude" "My Documents" "--password-file" "key" "--repo" "rest:http://user:password@localhost:8000/path" "some path" "/source dir"`,
71+
},
72+
{
73+
"quotes",
74+
"backup",
75+
[]string{"quo'te", "quo\"te"},
76+
`"backup" "--exclude" "MyDocuments --exclude My\"Documents --password-file key --repo rest:http://user:password@localhost:8000/path quote" "quote /source'dir /sourcedir"`,
77+
`"backup" "--exclude" "My'Documents" "--exclude" "My\"Documents" "--password-file" "key" "--repo" "rest:http://user:password@localhost:8000/path" "quo'te" "quo\"te" "/source'dir" "/source\"dir"`,
78+
},
79+
{
80+
"glob",
81+
"backup",
82+
[]string{"examples/integration*"},
83+
`"backup" "--exclude" ` + globFiles + ` "--password-file" "key" "--repo" "rest:http://user:password@localhost:8000/path" ` + globFiles + " " + globFiles,
84+
`"backup" "--exclude" "examples/integration*" "--password-file" "key" "--repo" "rest:http://user:password@localhost:8000/path" "examples/integration*" "examples/integration*"`,
85+
},
86+
{
87+
"mixed",
88+
"backup",
89+
[]string{"/path/with space; echo foo"},
90+
`"backup" "--exclude" "examples/integration*" "--password-file" "key" "--repo" "rest:http://user:password@localhost:8000/path" ` + globFiles + " " + globFiles,
91+
`"backup" "--exclude" "examples/integration*" "--password-file" "key" "--repo" "rest:http://user:password@localhost:8000/path" "/path/with space; echo foo" "/Côte d'Ivoire"`,
92+
},
93+
}
94+
95+
// try all the config files one by one
96+
for _, configFile := range files {
97+
t.Run(configFile, func(t *testing.T) {
98+
cfg, err := config.LoadFile(configFile, "")
99+
require.NoError(t, err)
100+
require.NotNil(t, cfg)
101+
102+
// try all the fixtures one by one (on each file)
103+
for _, fixture := range integrationData {
104+
t.Run(fixture.profileName+"/"+fixture.commandName, func(t *testing.T) {
105+
profile, err := cfg.GetProfile(fixture.profileName)
106+
require.NoError(t, err)
107+
require.NotNil(t, profile)
108+
109+
wrapper := newResticWrapper(
110+
echoBinary,
111+
false,
112+
profile,
113+
fixture.commandName,
114+
fixture.cmdlineArgs,
115+
nil,
116+
)
117+
buffer := &bytes.Buffer{}
118+
// setting the output via the package global setter could lead to some issues
119+
// when some tests are running in parallel. I should fix that at some point :-/
120+
term.SetOutput(buffer)
121+
err = wrapper.runCommand(fixture.commandName)
122+
term.SetOutput(os.Stdout)
123+
124+
// allow a fail temporarily
125+
if err != nil && err.Error() == fmt.Sprintf("%s on profile '%s': exit status 2", fixture.commandName, fixture.profileName) {
126+
t.Skip("shell failed to interpret command line")
127+
}
128+
require.NoError(t, err)
129+
130+
expected := "[" + fixture.expected + "]"
131+
if fixture.expectedOnWindows != "" && runtime.GOOS == "windows" {
132+
expected = "[" + fixture.expectedOnWindows + "]"
133+
}
134+
assert.Equal(t, expected, strings.TrimSpace(buffer.String()))
135+
})
136+
}
137+
})
138+
}
139+
}

shell/echo/main.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"os"
6+
)
7+
8+
// displays all the parameters received on the command line
9+
func main() {
10+
fmt.Printf("%q\n", os.Args[1:])
11+
}

0 commit comments

Comments
 (0)