Skip to content
This repository was archived by the owner on Jul 18, 2025. It is now read-only.

Commit e95182e

Browse files
author
Matthieu Nottale
committed
e2e tests using binary: render and init.
Signed-off-by: Matthieu Nottale <[email protected]>
1 parent 74dd14e commit e95182e

File tree

3 files changed

+174
-32
lines changed

3 files changed

+174
-32
lines changed

cmd/render.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ Override is provided in three different ways:
4444
fmt.Printf("%v\n", err)
4545
os.Exit(1)
4646
}
47-
fmt.Println(string(res))
47+
fmt.Printf("%s", string(res))
4848
},
4949
}
5050

e2e/binary_test.go

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
package e2e
2+
3+
import (
4+
"crypto/rand"
5+
"encoding/hex"
6+
"fmt"
7+
"io/ioutil"
8+
"os"
9+
"os/exec"
10+
"path"
11+
"runtime"
12+
"testing"
13+
14+
"github.com/gotestyourself/gotestyourself/assert"
15+
"github.com/gotestyourself/gotestyourself/fs"
16+
17+
"github.com/docker/lunchbox/utils"
18+
)
19+
20+
var (
21+
dockerApp = ""
22+
)
23+
24+
func getBinary(t *testing.T) string {
25+
if dockerApp != "" {
26+
return dockerApp
27+
}
28+
dockerApp = os.Getenv("DOCKERAPP_BINARY")
29+
if dockerApp == "" {
30+
binName := "docker-app"
31+
if runtime.GOOS == "windows" {
32+
binName += ".exe"
33+
}
34+
locations := []string{".", "../_build"}
35+
for _, l := range locations {
36+
b := path.Join(l, binName)
37+
if _, err := os.Stat(b); err == nil {
38+
dockerApp = b
39+
break
40+
}
41+
}
42+
}
43+
if dockerApp == "" {
44+
t.Error("cannot locate docker-app binary")
45+
}
46+
cmd := exec.Command(dockerApp, "version")
47+
_, err := cmd.CombinedOutput()
48+
assert.NilError(t, err, "failed to execute docker-app binary")
49+
return dockerApp
50+
}
51+
52+
func TestRenderBinary(t *testing.T) {
53+
getBinary(t)
54+
apps, err := ioutil.ReadDir("render")
55+
assert.NilError(t, err, "unable to get apps")
56+
for _, app := range apps {
57+
t.Log("testing", app.Name())
58+
settings, overrides, env := gather(t, path.Join("render", app.Name()))
59+
args := []string{
60+
"render",
61+
path.Join("render", app.Name()),
62+
}
63+
for _, s := range settings {
64+
args = append(args, "-s", s)
65+
}
66+
for _, c := range overrides {
67+
args = append(args, "-c", c)
68+
}
69+
for k, v := range env {
70+
args = append(args, "-e", fmt.Sprintf("%s=%s", k, v))
71+
}
72+
t.Logf("executing with %v", args)
73+
cmd := exec.Command(dockerApp, args...)
74+
output, err := cmd.CombinedOutput()
75+
checkResult(t, string(output), err, path.Join("render", app.Name()))
76+
}
77+
}
78+
79+
func randomName(prefix string) string {
80+
b := make([]byte, 16)
81+
_, err := rand.Read(b)
82+
if err != nil {
83+
panic(err)
84+
}
85+
return prefix + hex.EncodeToString(b)
86+
}
87+
88+
func TestInitBinary(t *testing.T) {
89+
getBinary(t)
90+
composeData := `services:
91+
nginx:
92+
image: nginx:${NGINX_VERSION}
93+
command: nginx $NGINX_ARGS
94+
`
95+
envData := "# some comment\nNGINX_VERSION=latest"
96+
inputDir := randomName("app_input_")
97+
os.Mkdir(inputDir, 0755)
98+
ioutil.WriteFile(path.Join(inputDir, "docker-compose.yml"), []byte(composeData), 0644)
99+
ioutil.WriteFile(path.Join(inputDir, ".env"), []byte(envData), 0644)
100+
defer os.RemoveAll(inputDir)
101+
102+
testAppName := randomName("app_")
103+
dirName := utils.DirNameFromAppName(testAppName)
104+
defer os.RemoveAll(dirName)
105+
106+
args := []string{
107+
"init",
108+
testAppName,
109+
"-c",
110+
path.Join(inputDir, "docker-compose.yml"),
111+
}
112+
cmd := exec.Command(dockerApp, args...)
113+
output, err := cmd.CombinedOutput()
114+
if err != nil {
115+
fmt.Println(string(output))
116+
}
117+
assert.NilError(t, err)
118+
meta, err := ioutil.ReadFile(path.Join(dirName, "metadata.yml"))
119+
assert.NilError(t, err)
120+
manifest := fs.Expected(
121+
t,
122+
fs.WithMode(0755),
123+
fs.WithFile("metadata.yml", string(meta), fs.WithMode(0644)), // too many variables, cheating
124+
fs.WithFile("docker-compose.yml", composeData, fs.WithMode(0644)),
125+
fs.WithFile("settings.yml", "NGINX_ARGS: FILL ME\nNGINX_VERSION: latest\n", fs.WithMode(0644)),
126+
)
127+
128+
assert.Assert(t, fs.Equal(dirName, manifest))
129+
}

e2e/render_test.go

Lines changed: 44 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -13,35 +13,54 @@ import (
1313
"gopkg.in/yaml.v2"
1414
)
1515

16+
func gather(t *testing.T, dir string) ([]string, []string, map[string]string) {
17+
var (
18+
overrides []string
19+
settings []string
20+
)
21+
content, err := ioutil.ReadDir(dir)
22+
assert.NilError(t, err, "unable to get app: %q", dir)
23+
// look for overrides and settings file to inject in the rendering process
24+
for _, f := range content {
25+
split := strings.SplitN(f.Name(), "-", 2)
26+
if split[0] == "settings" {
27+
settings = append(settings, path.Join(dir, f.Name()))
28+
}
29+
if split[0] == "override" {
30+
overrides = append(overrides, path.Join(dir, f.Name()))
31+
}
32+
}
33+
// look for emulated command line env
34+
env := make(map[string]string)
35+
if _, err = os.Stat(path.Join(dir, "env.yml")); err == nil {
36+
envRaw, err := ioutil.ReadFile(path.Join(dir, "env.yml"))
37+
assert.NilError(t, err, "unable to read file")
38+
err = yaml.Unmarshal(envRaw, &env)
39+
assert.NilError(t, err, "unable to unmarshal env")
40+
}
41+
return settings, overrides, env
42+
}
43+
44+
func checkResult(t *testing.T, result string, resultErr error, dir string) {
45+
if resultErr != nil {
46+
ee := path.Join(dir, "expectedError.txt")
47+
if _, err := os.Stat(ee); err != nil {
48+
assert.NilError(t, resultErr, "unexpected render error")
49+
}
50+
expectedErr := readFile(t, ee)
51+
assert.ErrorContains(t, resultErr, expectedErr)
52+
} else {
53+
expectedRender := readFile(t, path.Join(dir, "expected.txt"))
54+
assert.Equal(t, string(expectedRender), result, "rendering missmatch")
55+
}
56+
}
57+
1658
func TestRender(t *testing.T) {
1759
apps, err := ioutil.ReadDir("render")
1860
assert.NilError(t, err, "unable to get apps")
1961
for _, app := range apps {
2062
t.Log("testing", app.Name())
21-
var (
22-
overrides []string
23-
settings []string
24-
)
25-
content, err := ioutil.ReadDir(path.Join("render", app.Name()))
26-
assert.NilError(t, err, "unable to get app: %q", app.Name())
27-
// look for overrides and settings file to inject in the rendering process
28-
for _, f := range content {
29-
split := strings.SplitN(f.Name(), "-", 2)
30-
if split[0] == "settings" {
31-
settings = append(settings, path.Join("render", app.Name(), f.Name()))
32-
}
33-
if split[0] == "override" {
34-
overrides = append(overrides, path.Join("render", app.Name(), f.Name()))
35-
}
36-
}
37-
// look for emulated command line env
38-
env := make(map[string]string)
39-
if _, err = os.Stat(path.Join("render", app.Name(), "env.yml")); err == nil {
40-
envRaw, err := ioutil.ReadFile(path.Join("render", app.Name(), "env.yml"))
41-
assert.NilError(t, err, "unable to read file")
42-
err = yaml.Unmarshal(envRaw, &env)
43-
assert.NilError(t, err, "unable to unmarshal env")
44-
}
63+
settings, overrides, env := gather(t, path.Join("render", app.Name()))
4564
// run the render
4665
config, resultErr := renderer.Render(path.Join("render", app.Name()), overrides, settings, env)
4766
var result string
@@ -50,13 +69,7 @@ func TestRender(t *testing.T) {
5069
bytes, resultErr = yaml.Marshal(config)
5170
result = string(bytes)
5271
}
53-
if resultErr != nil {
54-
expectedErr := readFile(t, path.Join("render", app.Name(), "expectedError.txt"))
55-
assert.ErrorContains(t, resultErr, expectedErr)
56-
} else {
57-
expectedRender := readFile(t, path.Join("render", app.Name(), "expected.txt"))
58-
assert.Equal(t, string(expectedRender), result, "rendering missmatch")
59-
}
72+
checkResult(t, result, resultErr, path.Join("render", app.Name()))
6073
}
6174
}
6275

0 commit comments

Comments
 (0)