@@ -23,14 +23,18 @@ import (
2323 "testing"
2424
2525 "github.com/compose-spec/compose-go/v2/types"
26+ "github.com/docker/cli/cli/config/configfile"
2627 moby "github.com/docker/docker/api/types"
2728 containerType "github.com/docker/docker/api/types/container"
2829 "github.com/docker/docker/api/types/filters"
30+ "github.com/docker/docker/api/types/network"
31+ "github.com/docker/go-connections/nat"
2932 "go.uber.org/mock/gomock"
3033 "gotest.tools/v3/assert"
3134
3235 "github.com/docker/compose/v2/pkg/api"
3336 "github.com/docker/compose/v2/pkg/mocks"
37+ "github.com/docker/compose/v2/pkg/progress"
3438)
3539
3640func TestContainerName (t * testing.T ) {
@@ -251,3 +255,182 @@ func TestWaitDependencies(t *testing.T) {
251255 assert .NilError (t , tested .waitDependencies (context .Background (), & project , "" , dependencies , nil ))
252256 })
253257}
258+
259+ func TestCreateMobyContainer (t * testing.T ) {
260+ t .Run ("connects container networks one by one if API <1.44" , func (t * testing.T ) {
261+ mockCtrl := gomock .NewController (t )
262+ defer mockCtrl .Finish ()
263+ apiClient := mocks .NewMockAPIClient (mockCtrl )
264+ cli := mocks .NewMockCli (mockCtrl )
265+ tested := composeService {
266+ dockerCli : cli ,
267+ }
268+ cli .EXPECT ().Client ().Return (apiClient ).AnyTimes ()
269+ cli .EXPECT ().ConfigFile ().Return (& configfile.ConfigFile {}).AnyTimes ()
270+ apiClient .EXPECT ().DaemonHost ().Return ("" ).AnyTimes ()
271+ apiClient .EXPECT ().ImageInspectWithRaw (gomock .Any (), gomock .Any ()).Return (moby.ImageInspect {}, nil , nil ).AnyTimes ()
272+ // force `RuntimeVersion` to fetch again
273+ runtimeVersion = runtimeVersionCache {}
274+ apiClient .EXPECT ().ServerVersion (gomock .Any ()).Return (moby.Version {
275+ APIVersion : "1.43" ,
276+ }, nil ).AnyTimes ()
277+
278+ service := types.ServiceConfig {
279+ Name : "test" ,
280+ Networks : map [string ]* types.ServiceNetworkConfig {
281+ "a" : {
282+ Priority : 10 ,
283+ },
284+ "b" : {
285+ Priority : 100 ,
286+ },
287+ },
288+ }
289+ project := types.Project {
290+ Name : "bork" ,
291+ Services : types.Services {
292+ "test" : service ,
293+ },
294+ Networks : types.Networks {
295+ "a" : types.NetworkConfig {
296+ Name : "a-moby-name" ,
297+ },
298+ "b" : types.NetworkConfig {
299+ Name : "b-moby-name" ,
300+ },
301+ },
302+ }
303+
304+ var falseBool bool
305+ apiClient .EXPECT ().ContainerCreate (gomock .Any (), gomock .Any (), gomock .Eq (
306+ & containerType.HostConfig {
307+ PortBindings : nat.PortMap {},
308+ ExtraHosts : []string {},
309+ Tmpfs : map [string ]string {},
310+ Resources : containerType.Resources {
311+ OomKillDisable : & falseBool ,
312+ },
313+ NetworkMode : "b-moby-name" ,
314+ }), gomock .Eq (
315+ & network.NetworkingConfig {
316+ EndpointsConfig : map [string ]* network.EndpointSettings {
317+ "b-moby-name" : {
318+ IPAMConfig : & network.EndpointIPAMConfig {},
319+ Aliases : []string {"bork-test-0" },
320+ },
321+ },
322+ }), gomock .Any (), gomock .Any ()).Times (1 ).Return (
323+ containerType.CreateResponse {
324+ ID : "an-id" ,
325+ }, nil )
326+
327+ apiClient .EXPECT ().ContainerInspect (gomock .Any (), gomock .Eq ("an-id" )).Times (1 ).Return (
328+ moby.ContainerJSON {
329+ ContainerJSONBase : & moby.ContainerJSONBase {
330+ ID : "an-id" ,
331+ Name : "a-name" ,
332+ },
333+ Config : & containerType.Config {},
334+ NetworkSettings : & moby.NetworkSettings {},
335+ }, nil )
336+
337+ apiClient .EXPECT ().NetworkConnect (gomock .Any (), "a-moby-name" , "an-id" , gomock .Eq (
338+ & network.EndpointSettings {
339+ IPAMConfig : & network.EndpointIPAMConfig {},
340+ Aliases : []string {"bork-test-0" },
341+ }))
342+
343+ _ , err := tested .createMobyContainer (context .Background (), & project , service , "test" , 0 , nil , createOptions {
344+ Labels : make (types.Labels ),
345+ }, progress .ContextWriter (context .TODO ()))
346+ assert .NilError (t , err )
347+ })
348+
349+ t .Run ("includes all container networks in ContainerCreate call if API >=1.44" , func (t * testing.T ) {
350+ mockCtrl := gomock .NewController (t )
351+ defer mockCtrl .Finish ()
352+ apiClient := mocks .NewMockAPIClient (mockCtrl )
353+ cli := mocks .NewMockCli (mockCtrl )
354+ tested := composeService {
355+ dockerCli : cli ,
356+ }
357+ cli .EXPECT ().Client ().Return (apiClient ).AnyTimes ()
358+ cli .EXPECT ().ConfigFile ().Return (& configfile.ConfigFile {}).AnyTimes ()
359+ apiClient .EXPECT ().DaemonHost ().Return ("" ).AnyTimes ()
360+ apiClient .EXPECT ().ImageInspectWithRaw (gomock .Any (), gomock .Any ()).Return (moby.ImageInspect {}, nil , nil ).AnyTimes ()
361+ // force `RuntimeVersion` to fetch fresh version
362+ runtimeVersion = runtimeVersionCache {}
363+ apiClient .EXPECT ().ServerVersion (gomock .Any ()).Return (moby.Version {
364+ APIVersion : "1.44" ,
365+ }, nil ).AnyTimes ()
366+
367+ service := types.ServiceConfig {
368+ Name : "test" ,
369+ Networks : map [string ]* types.ServiceNetworkConfig {
370+ "a" : {
371+ Priority : 10 ,
372+ },
373+ "b" : {
374+ Priority : 100 ,
375+ },
376+ },
377+ }
378+ project := types.Project {
379+ Name : "bork" ,
380+ Services : types.Services {
381+ "test" : service ,
382+ },
383+ Networks : types.Networks {
384+ "a" : types.NetworkConfig {
385+ Name : "a-moby-name" ,
386+ },
387+ "b" : types.NetworkConfig {
388+ Name : "b-moby-name" ,
389+ },
390+ },
391+ }
392+
393+ var falseBool bool
394+ apiClient .EXPECT ().ContainerCreate (gomock .Any (), gomock .Any (), gomock .Eq (
395+ & containerType.HostConfig {
396+ PortBindings : nat.PortMap {},
397+ ExtraHosts : []string {},
398+ Tmpfs : map [string ]string {},
399+ Resources : containerType.Resources {
400+ OomKillDisable : & falseBool ,
401+ },
402+ NetworkMode : "b-moby-name" ,
403+ }), gomock .Eq (
404+ & network.NetworkingConfig {
405+ EndpointsConfig : map [string ]* network.EndpointSettings {
406+ "a-moby-name" : {
407+ IPAMConfig : & network.EndpointIPAMConfig {},
408+ Aliases : []string {"bork-test-0" },
409+ },
410+ "b-moby-name" : {
411+ IPAMConfig : & network.EndpointIPAMConfig {},
412+ Aliases : []string {"bork-test-0" },
413+ },
414+ },
415+ }), gomock .Any (), gomock .Any ()).Times (1 ).Return (
416+ containerType.CreateResponse {
417+ ID : "an-id" ,
418+ }, nil )
419+
420+ apiClient .EXPECT ().ContainerInspect (gomock .Any (), gomock .Eq ("an-id" )).Times (1 ).Return (
421+ moby.ContainerJSON {
422+ ContainerJSONBase : & moby.ContainerJSONBase {
423+ ID : "an-id" ,
424+ Name : "a-name" ,
425+ },
426+ Config : & containerType.Config {},
427+ NetworkSettings : & moby.NetworkSettings {},
428+ }, nil )
429+
430+ _ , err := tested .createMobyContainer (context .Background (), & project , service , "test" , 0 , nil , createOptions {
431+ Labels : make (types.Labels ),
432+ }, progress .ContextWriter (context .TODO ()))
433+ assert .NilError (t , err )
434+ })
435+
436+ }
0 commit comments