gopkg.in/docker/libcompose.v0@v0.4.0/project/project_test.go (about) 1 package project 2 3 import ( 4 "fmt" 5 "reflect" 6 "strings" 7 "testing" 8 9 "golang.org/x/net/context" 10 11 "github.com/docker/libcompose/config" 12 "github.com/docker/libcompose/project/options" 13 "github.com/docker/libcompose/yaml" 14 "github.com/stretchr/testify/assert" 15 ) 16 17 type TestServiceFactory struct { 18 Counts map[string]int 19 } 20 21 type TestService struct { 22 factory *TestServiceFactory 23 name string 24 config *config.ServiceConfig 25 EmptyService 26 Count int 27 } 28 29 func (t *TestService) Config() *config.ServiceConfig { 30 return t.config 31 } 32 33 func (t *TestService) Name() string { 34 return t.name 35 } 36 37 func (t *TestService) Run(ctx context.Context, commandParts []string, opts options.Run) (int, error) { 38 return 0, nil 39 } 40 41 func (t *TestService) Create(ctx context.Context, options options.Create) error { 42 key := t.name + ".create" 43 t.factory.Counts[key] = t.factory.Counts[key] + 1 44 return nil 45 } 46 47 func (t *TestService) DependentServices() []ServiceRelationship { 48 return nil 49 } 50 51 func (t *TestServiceFactory) Create(project *Project, name string, serviceConfig *config.ServiceConfig) (Service, error) { 52 return &TestService{ 53 factory: t, 54 config: serviceConfig, 55 name: name, 56 }, nil 57 } 58 59 func TestTwoCall(t *testing.T) { 60 factory := &TestServiceFactory{ 61 Counts: map[string]int{}, 62 } 63 64 p := NewProject(&Context{ 65 ServiceFactory: factory, 66 }, nil, nil) 67 p.ServiceConfigs = config.NewServiceConfigs() 68 p.ServiceConfigs.Add("foo", &config.ServiceConfig{}) 69 70 if err := p.Create(context.Background(), options.Create{}, "foo"); err != nil { 71 t.Fatal(err) 72 } 73 74 if err := p.Create(context.Background(), options.Create{}, "foo"); err != nil { 75 t.Fatal(err) 76 } 77 78 if factory.Counts["foo.create"] != 2 { 79 t.Fatal("Failed to create twice") 80 } 81 } 82 83 func TestGetServiceConfig(t *testing.T) { 84 85 p := NewProject(&Context{}, nil, nil) 86 p.ServiceConfigs = config.NewServiceConfigs() 87 fooService := &config.ServiceConfig{} 88 p.ServiceConfigs.Add("foo", fooService) 89 90 config, ok := p.GetServiceConfig("foo") 91 if !ok { 92 t.Fatal("Foo service not found") 93 } 94 95 if config != fooService { 96 t.Fatal("Incorrect Service Config returned") 97 } 98 99 config, ok = p.GetServiceConfig("unknown") 100 if ok { 101 t.Fatal("Found service incorrectly") 102 } 103 104 if config != nil { 105 t.Fatal("Incorrect Service Config returned") 106 } 107 } 108 109 func TestParseWithBadContent(t *testing.T) { 110 p := NewProject(&Context{ 111 ComposeBytes: [][]byte{ 112 []byte("garbage"), 113 }, 114 }, nil, nil) 115 116 err := p.Parse() 117 if err == nil { 118 t.Fatal("Should have failed parse") 119 } 120 121 if !strings.Contains(err.Error(), "cannot unmarshal !!str `garbage` into config.Config") { 122 t.Fatalf("Should have failed parse: %#v", err) 123 } 124 } 125 126 func TestParseWithGoodContent(t *testing.T) { 127 p := NewProject(&Context{ 128 ComposeBytes: [][]byte{ 129 []byte("not-garbage:\n image: foo"), 130 }, 131 }, nil, nil) 132 133 err := p.Parse() 134 if err != nil { 135 t.Fatal(err) 136 } 137 } 138 139 func TestParseWithDefaultEnvironmentLookup(t *testing.T) { 140 p := NewProject(&Context{ 141 ComposeBytes: [][]byte{ 142 []byte("not-garbage:\n image: foo:${version}"), 143 }, 144 }, nil, nil) 145 146 err := p.Parse() 147 if err != nil { 148 t.Fatal(err) 149 } 150 } 151 152 type TestEnvironmentLookup struct { 153 } 154 155 func (t *TestEnvironmentLookup) Lookup(key string, config *config.ServiceConfig) []string { 156 return []string{fmt.Sprintf("%s=X", key)} 157 } 158 159 func TestEnvironmentResolve(t *testing.T) { 160 factory := &TestServiceFactory{ 161 Counts: map[string]int{}, 162 } 163 164 p := NewProject(&Context{ 165 ServiceFactory: factory, 166 EnvironmentLookup: &TestEnvironmentLookup{}, 167 }, nil, nil) 168 p.ServiceConfigs = config.NewServiceConfigs() 169 p.ServiceConfigs.Add("foo", &config.ServiceConfig{ 170 Environment: yaml.MaporEqualSlice([]string{ 171 "A", 172 "A=", 173 "A=B", 174 }), 175 }) 176 177 service, err := p.CreateService("foo") 178 if err != nil { 179 t.Fatal(err) 180 } 181 182 if !reflect.DeepEqual(service.Config().Environment, yaml.MaporEqualSlice{"A=X", "A=", "A=B"}) { 183 t.Fatal("Invalid environment", service.Config().Environment) 184 } 185 } 186 187 func TestParseWithMultipleComposeFiles(t *testing.T) { 188 configOne := []byte(` 189 multiple: 190 image: tianon/true 191 ports: 192 - 8000`) 193 194 configTwo := []byte(` 195 multiple: 196 image: busybox 197 container_name: multi 198 ports: 199 - 9000`) 200 201 configThree := []byte(` 202 multiple: 203 image: busybox 204 mem_limit: "40m" 205 memswap_limit: 40000000 206 ports: 207 - 10000`) 208 209 p := NewProject(&Context{ 210 ComposeBytes: [][]byte{configOne, configTwo}, 211 }, nil, nil) 212 213 err := p.Parse() 214 215 assert.Nil(t, err) 216 217 multipleConfig, _ := p.ServiceConfigs.Get("multiple") 218 assert.Equal(t, "busybox", multipleConfig.Image) 219 assert.Equal(t, "multi", multipleConfig.ContainerName) 220 assert.Equal(t, []string{"8000", "9000"}, multipleConfig.Ports) 221 222 p = NewProject(&Context{ 223 ComposeBytes: [][]byte{configTwo, configOne}, 224 }, nil, nil) 225 226 err = p.Parse() 227 228 assert.Nil(t, err) 229 230 multipleConfig, _ = p.ServiceConfigs.Get("multiple") 231 assert.Equal(t, "tianon/true", multipleConfig.Image) 232 assert.Equal(t, "multi", multipleConfig.ContainerName) 233 assert.Equal(t, []string{"9000", "8000"}, multipleConfig.Ports) 234 235 p = NewProject(&Context{ 236 ComposeBytes: [][]byte{configOne, configTwo, configThree}, 237 }, nil, nil) 238 239 err = p.Parse() 240 241 assert.Nil(t, err) 242 243 multipleConfig, _ = p.ServiceConfigs.Get("multiple") 244 assert.Equal(t, "busybox", multipleConfig.Image) 245 assert.Equal(t, "multi", multipleConfig.ContainerName) 246 assert.Equal(t, []string{"8000", "9000", "10000"}, multipleConfig.Ports) 247 assert.Equal(t, yaml.MemStringorInt(41943040), multipleConfig.MemLimit) 248 assert.Equal(t, yaml.MemStringorInt(40000000), multipleConfig.MemSwapLimit) 249 }