Skip to content

Commit

Permalink
add integration test
Browse files Browse the repository at this point in the history
  • Loading branch information
creativeprojects committed Aug 6, 2021
1 parent 8218e70 commit d59a1ff
Show file tree
Hide file tree
Showing 7 changed files with 312 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
/lock/locktest
/mock
/mock.exe
/echo
/echo.exe

# test output
/coverage.out
Expand Down
44 changes: 44 additions & 0 deletions examples/integration_test.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
default {
repository = "rest:http://user:password@localhost:8000/path"
password-file = "key"
}

simple {
inherit = "default"
backup {
exclude = "/**/.git"
source = "/source"
}
}

spaces {
inherit = "default"
backup {
exclude = "My Documents"
source = "/source dir"
}
}

quotes {
inherit = "default"
backup {
exclude = ["My'Documents", "My\"Documents"]
source = ["/source'dir", "/source\"dir"]
}
}

glob {
inherit = "default"
backup {
exclude = ["examples/integration*"]
source = ["examples/integration*"]
}
}

mixed {
inherit = "default"
backup {
exclude = ["examples/integration*"]
source = ["/Côte d'Ivoire"]
}
}
41 changes: 41 additions & 0 deletions examples/integration_test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"default": {
"password-file": "key",
"repository": "rest:http://user:password@localhost:8000/path"
},
"simple": {
"inherit": "default",
"backup": {
"exclude": "/**/.git",
"source": "/source"
}
},
"spaces": {
"inherit": "default",
"backup": {
"exclude": "My Documents",
"source": "/source dir"
}
},
"quotes": {
"inherit": "default",
"backup": {
"exclude": ["My'Documents", "My\"Documents"],
"source": ["/source'dir", "/source\"dir"]
}
},
"glob": {
"inherit": "default",
"backup": {
"exclude": ["examples/integration*"],
"source": ["examples/integration*"]
}
},
"mixed": {
"inherit": "default",
"backup": {
"exclude": ["examples/integration*"],
"source": ["/Côte d'Ivoire"]
}
}
}
33 changes: 33 additions & 0 deletions examples/integration_test.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
[default]
repository = "rest:http://user:password@localhost:8000/path"
password-file = "key"

[simple]
inherit = "default"
[simple.backup]
exclude = "/**/.git"
source = "/source"

[spaces]
inherit = "default"
[spaces.backup]
exclude = "My Documents"
source = "/source dir"

[quotes]
inherit = "default"
[quotes.backup]
exclude = ["My'Documents", "My\"Documents"]
source = ["/source'dir", "/source\"dir"]

[glob]
inherit = "default"
[glob.backup]
exclude = ["examples/integration*"]
source = ["examples/integration*"]

[mixed]
inherit = "default"
[mixed.backup]
exclude = ["examples/integration*"]
source = ["/Côte d'Ivoire"]
42 changes: 42 additions & 0 deletions examples/integration_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
default:
password-file: key
repository: "rest:http://user:password@localhost:8000/path"

simple:
inherit: default
backup:
exclude: "/**/.git"
source: /source

spaces:
inherit: default
backup:
exclude: "My Documents"
source: /source dir

quotes:
inherit: default
backup:
exclude:
- "My'Documents"
- "My\"Documents"
source:
- "/source'dir"
- "/source\"dir"

glob:
inherit: default
backup:
exclude:
- "examples/integration*"
source:
- "examples/integration*"

mixed:
inherit: default
backup:
exclude:
- "examples/integration*"
source:
- "/Côte d'Ivoire"
139 changes: 139 additions & 0 deletions integration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package main

import (
"bytes"
"fmt"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
"testing"

"github.com/creativeprojects/resticprofile/config"
"github.com/creativeprojects/resticprofile/term"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

var (
echoBinary string
)

func init() {
// build restic mock
cmd := exec.Command("go", "build", "./shell/echo")
cmd.Run()
if runtime.GOOS == "windows" {
echoBinary = "echo.exe"
} else {
echoBinary = "./echo"
}
}

// TestFromConfigFileToCommandLine loads all examples/integration_test.* configuration files
// and run some commands to display all the arguments that were sent
func TestFromConfigFileToCommandLine(t *testing.T) {
files, err := filepath.Glob("./examples/integration_test.*")
require.NoError(t, err)
require.Greater(t, len(files), 0)

// we can use the same files to test a glob pattern
globFiles := "\"" + strings.Join(files, "\" \"") + "\""

integrationData := []struct {
profileName string
commandName string
cmdlineArgs []string
expected string
expectedOnWindows string
}{
{
"default",
"snapshots",
[]string{},
`"snapshots" "--password-file" "key" "--repo" "rest:http://user:password@localhost:8000/path"`,
"",
},
{
"simple",
"backup",
[]string{"--option"},
`"backup" "--exclude" "/**/.git" "--password-file" "key" "--repo" "rest:http://user:password@localhost:8000/path" "--option" "/source"`,
"",
},
{
"spaces",
"backup",
[]string{"some path"},
`"backup" "--exclude" "My Documents" "--password-file" "key" "--repo" "rest:http://user:password@localhost:8000/path" "some" "path" "/source" "dir"`,
`"backup" "--exclude" "My Documents" "--password-file" "key" "--repo" "rest:http://user:password@localhost:8000/path" "some path" "/source dir"`,
},
{
"quotes",
"backup",
[]string{"quo'te", "quo\"te"},
`"backup" "--exclude" "MyDocuments --exclude My\"Documents --password-file key --repo rest:http://user:password@localhost:8000/path quote" "quote /source'dir /sourcedir"`,
`"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"`,
},
{
"glob",
"backup",
[]string{"examples/integration*"},
`"backup" "--exclude" ` + globFiles + ` "--password-file" "key" "--repo" "rest:http://user:password@localhost:8000/path" ` + globFiles + " " + globFiles,
`"backup" "--exclude" "examples/integration*" "--password-file" "key" "--repo" "rest:http://user:password@localhost:8000/path" "examples/integration*" "examples/integration*"`,
},
{
"mixed",
"backup",
[]string{"/path/with space; echo foo"},
`"backup" "--exclude" "examples/integration*" "--password-file" "key" "--repo" "rest:http://user:password@localhost:8000/path" ` + globFiles + " " + globFiles,
`"backup" "--exclude" "examples/integration*" "--password-file" "key" "--repo" "rest:http://user:password@localhost:8000/path" "/path/with space; echo foo" "/Côte d'Ivoire"`,
},
}

// try all the config files one by one
for _, configFile := range files {
t.Run(configFile, func(t *testing.T) {
cfg, err := config.LoadFile(configFile, "")
require.NoError(t, err)
require.NotNil(t, cfg)

// try all the fixtures one by one (on each file)
for _, fixture := range integrationData {
t.Run(fixture.profileName+"/"+fixture.commandName, func(t *testing.T) {
profile, err := cfg.GetProfile(fixture.profileName)
require.NoError(t, err)
require.NotNil(t, profile)

wrapper := newResticWrapper(
echoBinary,
false,
profile,
fixture.commandName,
fixture.cmdlineArgs,
nil,
)
buffer := &bytes.Buffer{}
// setting the output via the package global setter could lead to some issues
// when some tests are running in parallel. I should fix that at some point :-/
term.SetOutput(buffer)
err = wrapper.runCommand(fixture.commandName)
term.SetOutput(os.Stdout)

// allow a fail temporarily
if err != nil && err.Error() == fmt.Sprintf("%s on profile '%s': exit status 2", fixture.commandName, fixture.profileName) {
t.Skip("shell failed to interpret command line")
}
require.NoError(t, err)

expected := "[" + fixture.expected + "]"
if fixture.expectedOnWindows != "" && runtime.GOOS == "windows" {
expected = "[" + fixture.expectedOnWindows + "]"
}
assert.Equal(t, expected, strings.TrimSpace(buffer.String()))
})
}
})
}
}
11 changes: 11 additions & 0 deletions shell/echo/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package main

import (
"fmt"
"os"
)

// displays all the parameters received on the command line
func main() {
fmt.Printf("%q\n", os.Args[1:])
}

0 comments on commit d59a1ff

Please sign in to comment.