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

Commit d97c80d

Browse files
committed
More init tests
Signed-off-by: Joffrey F <[email protected]>
1 parent 2f4e949 commit d97c80d

File tree

3 files changed

+128
-21
lines changed

3 files changed

+128
-21
lines changed

packager/init.go

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,17 @@ func Init(name string, composeFiles []string) error {
2727
return err
2828
}
2929

30+
merger := NewPythonComposeConfigMerger()
3031
if len(composeFiles) == 0 {
3132
if _, err := os.Stat("./docker-compose.yml"); os.IsNotExist(err) {
3233
log.Println("no compose file detected")
3334
return initFromScratch(name)
3435
} else if err != nil {
3536
return err
3637
}
37-
return initFromComposeFiles(name, []string{"./docker-compose.yml"})
38+
return initFromComposeFiles(name, []string{"./docker-compose.yml"}, merger)
3839
}
39-
return initFromComposeFiles(name, composeFiles)
40+
return initFromComposeFiles(name, composeFiles, merger)
4041
}
4142

4243
func initFromScratch(name string) error {
@@ -60,11 +61,11 @@ Examples of possible values: java, mysql, redis, ruby, postgres, rabbitmq...`)
6061
return utils.CreateFileWithData(path.Join(dirName, "settings.yml"), []byte{'\n'})
6162
}
6263

63-
func initFromComposeFiles(name string, composeFiles []string) error {
64+
func initFromComposeFiles(name string, composeFiles []string, merger ComposeConfigMerger) error {
6465
log.Println("init from compose")
6566

6667
dirName := utils.DirNameFromAppName(name)
67-
composeConfig, err := mergeComposeConfig(composeFiles)
68+
composeConfig, err := merger.MergeComposeConfig(composeFiles)
6869
if err != nil {
6970
return err
7071
}
@@ -74,21 +75,6 @@ func initFromComposeFiles(name string, composeFiles []string) error {
7475
return utils.CreateFileWithData(path.Join(dirName, "settings.yml"), []byte{'\n'})
7576
}
7677

77-
func mergeComposeConfig(composeFiles []string) ([]byte, error) {
78-
var args []string
79-
for _, filename := range composeFiles {
80-
args = append(args, fmt.Sprintf("--file=%v", filename))
81-
}
82-
args = append(args, "config")
83-
cmd := exec.Command("docker-compose", args...)
84-
cmd.Stderr = nil
85-
out, err := cmd.Output()
86-
if err != nil {
87-
log.Fatalln(string(err.(*exec.ExitError).Stderr))
88-
}
89-
return out, err
90-
}
91-
9278
func composeFileFromScratch(services []string) ([]byte, error) {
9379
fileStruct := types.NewInitialComposeFile()
9480
serviceMap := *fileStruct.Services
@@ -130,3 +116,35 @@ func newMetadata(name string) types.AppMetadata {
130116
Application: info,
131117
}
132118
}
119+
120+
// ComposeConfigMerger is an interface exposing methods to merge
121+
// multiple compose files into one configuration
122+
type ComposeConfigMerger interface {
123+
MergeComposeConfig(composeFiles []string) ([]byte, error)
124+
}
125+
126+
// PythonComposeConfigMerger implements the ComposeConfigMerger interface and
127+
// executes a `docker-compose` command to merge configs
128+
type PythonComposeConfigMerger struct{}
129+
130+
// NewPythonComposeConfigMerger returns a ComposeConfigMerger implementor
131+
func NewPythonComposeConfigMerger() ComposeConfigMerger {
132+
return &PythonComposeConfigMerger{}
133+
}
134+
135+
// MergeComposeConfig takes a list of paths and merges the Compose files
136+
// at those paths into a single configuration
137+
func (m *PythonComposeConfigMerger) MergeComposeConfig(composeFiles []string) ([]byte, error) {
138+
var args []string
139+
for _, filename := range composeFiles {
140+
args = append(args, fmt.Sprintf("--file=%v", filename))
141+
}
142+
args = append(args, "config")
143+
cmd := exec.Command("docker-compose", args...)
144+
cmd.Stderr = nil
145+
out, err := cmd.Output()
146+
if err != nil {
147+
log.Fatalln(string(err.(*exec.ExitError).Stderr))
148+
}
149+
return out, err
150+
}

packager/init_test.go

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,50 @@
11
package packager
22

33
import (
4+
"crypto/rand"
5+
"encoding/hex"
6+
"fmt"
7+
"os"
48
"testing"
59

610
"github.com/gotestyourself/gotestyourself/assert"
11+
"github.com/gotestyourself/gotestyourself/fs"
712

813
"github.com/docker/lunchbox/types"
14+
"github.com/docker/lunchbox/utils"
915
yaml "gopkg.in/yaml.v2"
1016
)
1117

18+
func randomName(prefix string) string {
19+
b := make([]byte, 16)
20+
_, err := rand.Read(b)
21+
if err != nil {
22+
panic(err)
23+
}
24+
return prefix + hex.EncodeToString(b)
25+
}
26+
27+
type DummyConfigMerger struct{}
28+
29+
func NewDummyConfigMerger() ComposeConfigMerger {
30+
return &DummyConfigMerger{}
31+
}
32+
33+
var dummyComposeData = `
34+
version: '3.6'
35+
services:
36+
foo:
37+
image: bar
38+
command: baz
39+
`
40+
41+
func (m *DummyConfigMerger) MergeComposeConfig(composeFiles []string) ([]byte, error) {
42+
if composeFiles[0] == "doesnotexist" {
43+
return []byte{}, fmt.Errorf("no file named %q", composeFiles[0])
44+
}
45+
return []byte(dummyComposeData), nil
46+
}
47+
1248
func TestComposeFileFromScratch(t *testing.T) {
1349
services := []string{
1450
"redis", "mysql", "python",
@@ -27,3 +63,57 @@ func TestComposeFileFromScratch(t *testing.T) {
2763
assert.NilError(t, err)
2864
assert.DeepEqual(t, result, expectedBytes)
2965
}
66+
67+
func TestInitFromComposeFiles(t *testing.T) {
68+
testAppName := randomName("app_")
69+
merger := NewDummyConfigMerger()
70+
dirName := utils.DirNameFromAppName(testAppName)
71+
err := os.Mkdir(dirName, 0755)
72+
assert.NilError(t, err)
73+
defer os.RemoveAll(dirName)
74+
75+
err = initFromComposeFiles(testAppName, []string{"docker-compose.yml"}, merger)
76+
assert.NilError(t, err)
77+
78+
manifest := fs.Expected(
79+
t,
80+
fs.WithMode(0755),
81+
fs.WithFile("services.yml", dummyComposeData, fs.WithMode(0644)),
82+
fs.WithFile("settings.yml", "\n", fs.WithMode(0644)),
83+
)
84+
85+
assert.Assert(t, fs.Equal(dirName, manifest))
86+
}
87+
88+
func TestInitFromInvalidComposeFile(t *testing.T) {
89+
testAppName := randomName("app_")
90+
merger := NewDummyConfigMerger()
91+
dirName := utils.DirNameFromAppName(testAppName)
92+
err := os.Mkdir(dirName, 0755)
93+
assert.NilError(t, err)
94+
defer os.RemoveAll(dirName)
95+
96+
err = initFromComposeFiles(testAppName, []string{"doesnotexist"}, merger)
97+
assert.ErrorContains(t, err, "no file named \"doesnotexist\"")
98+
}
99+
100+
func TestWriteMetadataFile(t *testing.T) {
101+
appName := "writemetadata_test"
102+
tmpdir := fs.NewDir(t, appName)
103+
defer tmpdir.Remove()
104+
105+
err := writeMetadataFile(appName, tmpdir.Path())
106+
assert.NilError(t, err)
107+
108+
data, err := yaml.Marshal(newMetadata(appName))
109+
assert.NilError(t, err)
110+
111+
manifest := fs.Expected(
112+
t,
113+
fs.WithFile("metadata.yml", "",
114+
fs.WithMode(0644),
115+
fs.WithBytes(data),
116+
),
117+
)
118+
assert.Assert(t, fs.Equal(tmpdir.Path(), manifest))
119+
}

utils/io_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ func TestCreateFileWithData(t *testing.T) {
2424
fs.WithMode(0644),
2525
),
2626
)
27-
comp := fs.Equal(tmpdir.Path(), manifest)()
28-
assert.Assert(t, comp.Success())
27+
assert.Assert(t, fs.Equal(tmpdir.Path(), manifest))
2928
}
3029

3130
func TestCreateFileWithDataOverride(t *testing.T) {

0 commit comments

Comments
 (0)