|  | @@ -23,14 +23,18 @@ import (
 | 
	
		
			
				|  |  |  	"testing"
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	"github.com/compose-spec/compose-go/v2/types"
 | 
	
		
			
				|  |  | +	"github.com/docker/cli/cli/config/configfile"
 | 
	
		
			
				|  |  |  	moby "github.com/docker/docker/api/types"
 | 
	
		
			
				|  |  |  	containerType "github.com/docker/docker/api/types/container"
 | 
	
		
			
				|  |  |  	"github.com/docker/docker/api/types/filters"
 | 
	
		
			
				|  |  | +	"github.com/docker/docker/api/types/network"
 | 
	
		
			
				|  |  | +	"github.com/docker/go-connections/nat"
 | 
	
		
			
				|  |  |  	"go.uber.org/mock/gomock"
 | 
	
		
			
				|  |  |  	"gotest.tools/v3/assert"
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	"github.com/docker/compose/v2/pkg/api"
 | 
	
		
			
				|  |  |  	"github.com/docker/compose/v2/pkg/mocks"
 | 
	
		
			
				|  |  | +	"github.com/docker/compose/v2/pkg/progress"
 | 
	
		
			
				|  |  |  )
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  func TestContainerName(t *testing.T) {
 | 
	
	
		
			
				|  | @@ -251,3 +255,182 @@ func TestWaitDependencies(t *testing.T) {
 | 
	
		
			
				|  |  |  		assert.NilError(t, tested.waitDependencies(context.Background(), &project, "", dependencies, nil))
 | 
	
		
			
				|  |  |  	})
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +func TestCreateMobyContainer(t *testing.T) {
 | 
	
		
			
				|  |  | +	t.Run("connects container networks one by one if API <1.44", func(t *testing.T) {
 | 
	
		
			
				|  |  | +		mockCtrl := gomock.NewController(t)
 | 
	
		
			
				|  |  | +		defer mockCtrl.Finish()
 | 
	
		
			
				|  |  | +		apiClient := mocks.NewMockAPIClient(mockCtrl)
 | 
	
		
			
				|  |  | +		cli := mocks.NewMockCli(mockCtrl)
 | 
	
		
			
				|  |  | +		tested := composeService{
 | 
	
		
			
				|  |  | +			dockerCli: cli,
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		cli.EXPECT().Client().Return(apiClient).AnyTimes()
 | 
	
		
			
				|  |  | +		cli.EXPECT().ConfigFile().Return(&configfile.ConfigFile{}).AnyTimes()
 | 
	
		
			
				|  |  | +		apiClient.EXPECT().DaemonHost().Return("").AnyTimes()
 | 
	
		
			
				|  |  | +		apiClient.EXPECT().ImageInspectWithRaw(gomock.Any(), gomock.Any()).Return(moby.ImageInspect{}, nil, nil).AnyTimes()
 | 
	
		
			
				|  |  | +		// force `RuntimeVersion` to fetch again
 | 
	
		
			
				|  |  | +		runtimeVersion = runtimeVersionCache{}
 | 
	
		
			
				|  |  | +		apiClient.EXPECT().ServerVersion(gomock.Any()).Return(moby.Version{
 | 
	
		
			
				|  |  | +			APIVersion: "1.43",
 | 
	
		
			
				|  |  | +		}, nil).AnyTimes()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		service := types.ServiceConfig{
 | 
	
		
			
				|  |  | +			Name: "test",
 | 
	
		
			
				|  |  | +			Networks: map[string]*types.ServiceNetworkConfig{
 | 
	
		
			
				|  |  | +				"a": {
 | 
	
		
			
				|  |  | +					Priority: 10,
 | 
	
		
			
				|  |  | +				},
 | 
	
		
			
				|  |  | +				"b": {
 | 
	
		
			
				|  |  | +					Priority: 100,
 | 
	
		
			
				|  |  | +				},
 | 
	
		
			
				|  |  | +			},
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		project := types.Project{
 | 
	
		
			
				|  |  | +			Name: "bork",
 | 
	
		
			
				|  |  | +			Services: types.Services{
 | 
	
		
			
				|  |  | +				"test": service,
 | 
	
		
			
				|  |  | +			},
 | 
	
		
			
				|  |  | +			Networks: types.Networks{
 | 
	
		
			
				|  |  | +				"a": types.NetworkConfig{
 | 
	
		
			
				|  |  | +					Name: "a-moby-name",
 | 
	
		
			
				|  |  | +				},
 | 
	
		
			
				|  |  | +				"b": types.NetworkConfig{
 | 
	
		
			
				|  |  | +					Name: "b-moby-name",
 | 
	
		
			
				|  |  | +				},
 | 
	
		
			
				|  |  | +			},
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		var falseBool bool
 | 
	
		
			
				|  |  | +		apiClient.EXPECT().ContainerCreate(gomock.Any(), gomock.Any(), gomock.Eq(
 | 
	
		
			
				|  |  | +			&containerType.HostConfig{
 | 
	
		
			
				|  |  | +				PortBindings: nat.PortMap{},
 | 
	
		
			
				|  |  | +				ExtraHosts:   []string{},
 | 
	
		
			
				|  |  | +				Tmpfs:        map[string]string{},
 | 
	
		
			
				|  |  | +				Resources: containerType.Resources{
 | 
	
		
			
				|  |  | +					OomKillDisable: &falseBool,
 | 
	
		
			
				|  |  | +				},
 | 
	
		
			
				|  |  | +				NetworkMode: "b-moby-name",
 | 
	
		
			
				|  |  | +			}), gomock.Eq(
 | 
	
		
			
				|  |  | +			&network.NetworkingConfig{
 | 
	
		
			
				|  |  | +				EndpointsConfig: map[string]*network.EndpointSettings{
 | 
	
		
			
				|  |  | +					"b-moby-name": {
 | 
	
		
			
				|  |  | +						IPAMConfig: &network.EndpointIPAMConfig{},
 | 
	
		
			
				|  |  | +						Aliases:    []string{"bork-test-0"},
 | 
	
		
			
				|  |  | +					},
 | 
	
		
			
				|  |  | +				},
 | 
	
		
			
				|  |  | +			}), gomock.Any(), gomock.Any()).Times(1).Return(
 | 
	
		
			
				|  |  | +			containerType.CreateResponse{
 | 
	
		
			
				|  |  | +				ID: "an-id",
 | 
	
		
			
				|  |  | +			}, nil)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		apiClient.EXPECT().ContainerInspect(gomock.Any(), gomock.Eq("an-id")).Times(1).Return(
 | 
	
		
			
				|  |  | +			moby.ContainerJSON{
 | 
	
		
			
				|  |  | +				ContainerJSONBase: &moby.ContainerJSONBase{
 | 
	
		
			
				|  |  | +					ID:   "an-id",
 | 
	
		
			
				|  |  | +					Name: "a-name",
 | 
	
		
			
				|  |  | +				},
 | 
	
		
			
				|  |  | +				Config:          &containerType.Config{},
 | 
	
		
			
				|  |  | +				NetworkSettings: &moby.NetworkSettings{},
 | 
	
		
			
				|  |  | +			}, nil)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		apiClient.EXPECT().NetworkConnect(gomock.Any(), "a-moby-name", "an-id", gomock.Eq(
 | 
	
		
			
				|  |  | +			&network.EndpointSettings{
 | 
	
		
			
				|  |  | +				IPAMConfig: &network.EndpointIPAMConfig{},
 | 
	
		
			
				|  |  | +				Aliases:    []string{"bork-test-0"},
 | 
	
		
			
				|  |  | +			}))
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		_, err := tested.createMobyContainer(context.Background(), &project, service, "test", 0, nil, createOptions{
 | 
	
		
			
				|  |  | +			Labels: make(types.Labels),
 | 
	
		
			
				|  |  | +		}, progress.ContextWriter(context.TODO()))
 | 
	
		
			
				|  |  | +		assert.NilError(t, err)
 | 
	
		
			
				|  |  | +	})
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	t.Run("includes all container networks in ContainerCreate call if API >=1.44", func(t *testing.T) {
 | 
	
		
			
				|  |  | +		mockCtrl := gomock.NewController(t)
 | 
	
		
			
				|  |  | +		defer mockCtrl.Finish()
 | 
	
		
			
				|  |  | +		apiClient := mocks.NewMockAPIClient(mockCtrl)
 | 
	
		
			
				|  |  | +		cli := mocks.NewMockCli(mockCtrl)
 | 
	
		
			
				|  |  | +		tested := composeService{
 | 
	
		
			
				|  |  | +			dockerCli: cli,
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		cli.EXPECT().Client().Return(apiClient).AnyTimes()
 | 
	
		
			
				|  |  | +		cli.EXPECT().ConfigFile().Return(&configfile.ConfigFile{}).AnyTimes()
 | 
	
		
			
				|  |  | +		apiClient.EXPECT().DaemonHost().Return("").AnyTimes()
 | 
	
		
			
				|  |  | +		apiClient.EXPECT().ImageInspectWithRaw(gomock.Any(), gomock.Any()).Return(moby.ImageInspect{}, nil, nil).AnyTimes()
 | 
	
		
			
				|  |  | +		// force `RuntimeVersion` to fetch fresh version
 | 
	
		
			
				|  |  | +		runtimeVersion = runtimeVersionCache{}
 | 
	
		
			
				|  |  | +		apiClient.EXPECT().ServerVersion(gomock.Any()).Return(moby.Version{
 | 
	
		
			
				|  |  | +			APIVersion: "1.44",
 | 
	
		
			
				|  |  | +		}, nil).AnyTimes()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		service := types.ServiceConfig{
 | 
	
		
			
				|  |  | +			Name: "test",
 | 
	
		
			
				|  |  | +			Networks: map[string]*types.ServiceNetworkConfig{
 | 
	
		
			
				|  |  | +				"a": {
 | 
	
		
			
				|  |  | +					Priority: 10,
 | 
	
		
			
				|  |  | +				},
 | 
	
		
			
				|  |  | +				"b": {
 | 
	
		
			
				|  |  | +					Priority: 100,
 | 
	
		
			
				|  |  | +				},
 | 
	
		
			
				|  |  | +			},
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		project := types.Project{
 | 
	
		
			
				|  |  | +			Name: "bork",
 | 
	
		
			
				|  |  | +			Services: types.Services{
 | 
	
		
			
				|  |  | +				"test": service,
 | 
	
		
			
				|  |  | +			},
 | 
	
		
			
				|  |  | +			Networks: types.Networks{
 | 
	
		
			
				|  |  | +				"a": types.NetworkConfig{
 | 
	
		
			
				|  |  | +					Name: "a-moby-name",
 | 
	
		
			
				|  |  | +				},
 | 
	
		
			
				|  |  | +				"b": types.NetworkConfig{
 | 
	
		
			
				|  |  | +					Name: "b-moby-name",
 | 
	
		
			
				|  |  | +				},
 | 
	
		
			
				|  |  | +			},
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		var falseBool bool
 | 
	
		
			
				|  |  | +		apiClient.EXPECT().ContainerCreate(gomock.Any(), gomock.Any(), gomock.Eq(
 | 
	
		
			
				|  |  | +			&containerType.HostConfig{
 | 
	
		
			
				|  |  | +				PortBindings: nat.PortMap{},
 | 
	
		
			
				|  |  | +				ExtraHosts:   []string{},
 | 
	
		
			
				|  |  | +				Tmpfs:        map[string]string{},
 | 
	
		
			
				|  |  | +				Resources: containerType.Resources{
 | 
	
		
			
				|  |  | +					OomKillDisable: &falseBool,
 | 
	
		
			
				|  |  | +				},
 | 
	
		
			
				|  |  | +				NetworkMode: "b-moby-name",
 | 
	
		
			
				|  |  | +			}), gomock.Eq(
 | 
	
		
			
				|  |  | +			&network.NetworkingConfig{
 | 
	
		
			
				|  |  | +				EndpointsConfig: map[string]*network.EndpointSettings{
 | 
	
		
			
				|  |  | +					"a-moby-name": {
 | 
	
		
			
				|  |  | +						IPAMConfig: &network.EndpointIPAMConfig{},
 | 
	
		
			
				|  |  | +						Aliases:    []string{"bork-test-0"},
 | 
	
		
			
				|  |  | +					},
 | 
	
		
			
				|  |  | +					"b-moby-name": {
 | 
	
		
			
				|  |  | +						IPAMConfig: &network.EndpointIPAMConfig{},
 | 
	
		
			
				|  |  | +						Aliases:    []string{"bork-test-0"},
 | 
	
		
			
				|  |  | +					},
 | 
	
		
			
				|  |  | +				},
 | 
	
		
			
				|  |  | +			}), gomock.Any(), gomock.Any()).Times(1).Return(
 | 
	
		
			
				|  |  | +			containerType.CreateResponse{
 | 
	
		
			
				|  |  | +				ID: "an-id",
 | 
	
		
			
				|  |  | +			}, nil)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		apiClient.EXPECT().ContainerInspect(gomock.Any(), gomock.Eq("an-id")).Times(1).Return(
 | 
	
		
			
				|  |  | +			moby.ContainerJSON{
 | 
	
		
			
				|  |  | +				ContainerJSONBase: &moby.ContainerJSONBase{
 | 
	
		
			
				|  |  | +					ID:   "an-id",
 | 
	
		
			
				|  |  | +					Name: "a-name",
 | 
	
		
			
				|  |  | +				},
 | 
	
		
			
				|  |  | +				Config:          &containerType.Config{},
 | 
	
		
			
				|  |  | +				NetworkSettings: &moby.NetworkSettings{},
 | 
	
		
			
				|  |  | +			}, nil)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		_, err := tested.createMobyContainer(context.Background(), &project, service, "test", 0, nil, createOptions{
 | 
	
		
			
				|  |  | +			Labels: make(types.Labels),
 | 
	
		
			
				|  |  | +		}, progress.ContextWriter(context.TODO()))
 | 
	
		
			
				|  |  | +		assert.NilError(t, err)
 | 
	
		
			
				|  |  | +	})
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +}
 |