func TestEngineSpecs(t *testing.T) { engine := NewEngine("test", 0, engOpts) engine.setState(stateUnhealthy) assert.False(t, engine.isConnected()) client := mockclient.NewMockClient() apiClient := engineapimock.NewMockClient() apiClient.On("Info", mock.Anything).Return(mockInfo, nil) apiClient.On("ServerVersion", mock.Anything).Return(mockVersion, nil) apiClient.On("NetworkList", mock.Anything, mock.AnythingOfType("NetworkListOptions"), ).Return([]types.NetworkResource{}, nil) apiClient.On("VolumeList", mock.Anything, mock.AnythingOfType("Args"), ).Return(types.VolumesListResponse{}, nil) apiClient.On("ImageList", mock.Anything, mock.AnythingOfType("ImageListOptions")).Return([]types.Image{}, nil) apiClient.On("ContainerList", mock.Anything, types.ContainerListOptions{All: true, Size: false}).Return([]types.Container{}, nil) apiClient.On("Events", mock.Anything, mock.AnythingOfType("EventsOptions")).Return(&nopCloser{infiniteRead{}}, nil) assert.NoError(t, engine.ConnectWithClient(client, apiClient)) assert.True(t, engine.isConnected()) assert.True(t, engine.IsHealthy()) assert.Equal(t, engine.Cpus, int64(mockInfo.NCPU)) assert.Equal(t, engine.Memory, mockInfo.MemTotal) assert.Equal(t, engine.Labels["storagedriver"], mockInfo.Driver) assert.Equal(t, engine.Labels["executiondriver"], mockInfo.ExecutionDriver) assert.Equal(t, engine.Labels["kernelversion"], mockInfo.KernelVersion) assert.Equal(t, engine.Labels["operatingsystem"], mockInfo.OperatingSystem) assert.Equal(t, engine.Labels["foo"], "bar") client.Mock.AssertExpectations(t) apiClient.Mock.AssertExpectations(t) }
func TestEngineCpusMemory(t *testing.T) { engine := NewEngine("test", 0, engOpts) engine.setState(stateUnhealthy) assert.False(t, engine.isConnected()) client := mockclient.NewMockClient() apiClient := engineapimock.NewMockClient() apiClient.On("Info", mock.Anything).Return(mockInfo, nil) apiClient.On("ServerVersion", mock.Anything).Return(mockVersion, nil) apiClient.On("NetworkList", mock.Anything, mock.AnythingOfType("NetworkListOptions"), ).Return([]types.NetworkResource{}, nil) apiClient.On("VolumeList", mock.Anything, mock.AnythingOfType("Args"), ).Return(types.VolumesListResponse{}, nil) apiClient.On("ImageList", mock.Anything, mock.AnythingOfType("ImageListOptions")).Return([]types.Image{}, nil) apiClient.On("ContainerList", mock.Anything, types.ContainerListOptions{All: true, Size: false}).Return([]types.Container{}, nil) apiClient.On("Events", mock.Anything, mock.AnythingOfType("EventsOptions")).Return(&nopCloser{infiniteRead{}}, nil) assert.NoError(t, engine.ConnectWithClient(client, apiClient)) assert.True(t, engine.isConnected()) assert.True(t, engine.IsHealthy()) assert.Equal(t, engine.UsedCpus(), int64(0)) assert.Equal(t, engine.UsedMemory(), int64(0)) client.Mock.AssertExpectations(t) apiClient.Mock.AssertExpectations(t) }
func TestImportImage(t *testing.T) { // create cluster c := &Cluster{ engines: make(map[string]*cluster.Engine), } // create engione id := "test-engine" engine := cluster.NewEngine(id, 0, engOpts) engine.Name = id engine.ID = id // create mock client client := mockclient.NewMockClient() apiClient := engineapimock.NewMockClient() apiClient.On("Info", mock.Anything).Return(mockInfo, nil) apiClient.On("ServerVersion", mock.Anything).Return(mockVersion, nil) apiClient.On("NetworkList", mock.Anything, mock.AnythingOfType("NetworkListOptions"), ).Return([]types.NetworkResource{}, nil) apiClient.On("VolumeList", mock.Anything, mock.Anything).Return(types.VolumesListResponse{}, nil) apiClient.On("Events", mock.Anything, mock.AnythingOfType("EventsOptions")).Return(&nopCloser{bytes.NewBufferString("")}, nil) apiClient.On("ImageList", mock.Anything, mock.AnythingOfType("ImageListOptions")).Return([]types.Image{}, nil) apiClient.On("ContainerList", mock.Anything, types.ContainerListOptions{All: true, Size: false}).Return([]types.Container{}, nil).Once() // connect client engine.ConnectWithClient(client, apiClient) // add engine to cluster c.engines[engine.ID] = engine // import success readCloser := nopCloser{bytes.NewBufferString("ok")} apiClient.On("ImageImport", mock.Anything, mock.AnythingOfType("types.ImageImportSource"), mock.Anything, mock.AnythingOfType("types.ImageImportOptions")).Return(readCloser, nil).Once() callback := func(what, status string, err error) { // import success assert.Nil(t, err) } c.Import("-", "testImageOK", "latest", bytes.NewReader(nil), callback) // import error readCloser = nopCloser{bytes.NewBufferString("error")} err := fmt.Errorf("Import error") apiClient.On("ImageImport", mock.Anything, mock.AnythingOfType("types.ImageImportSource"), mock.Anything, mock.AnythingOfType("types.ImageImportOptions")).Return(readCloser, err).Once() callback = func(what, status string, err error) { // import error assert.NotNil(t, err) } c.Import("-", "testImageError", "latest", bytes.NewReader(nil), callback) }
func TestEngineState(t *testing.T) { engine := NewEngine("test", 0, engOpts) engine.setState(stateUnhealthy) assert.False(t, engine.isConnected()) client := mockclient.NewMockClient() apiClient := engineapimock.NewMockClient() apiClient.On("Info", mock.Anything).Return(mockInfo, nil) apiClient.On("ServerVersion", mock.Anything).Return(mockVersion, nil) apiClient.On("NetworkList", mock.Anything, mock.AnythingOfType("NetworkListOptions"), ).Return([]types.NetworkResource{}, nil) apiClient.On("VolumeList", mock.Anything, mock.AnythingOfType("Args"), ).Return(types.VolumesListResponse{}, nil) apiClient.On("Events", mock.Anything, mock.AnythingOfType("EventsOptions")).Return(&nopCloser{infiniteRead{}}, nil) // The client will return one container at first, then a second one will appear. apiClient.On("ImageList", mock.Anything, mock.AnythingOfType("ImageListOptions")).Return([]types.Image{}, nil).Once() apiClient.On("ContainerList", mock.Anything, types.ContainerListOptions{All: true, Size: false}).Return([]types.Container{{ID: "one"}}, nil).Once() apiClient.On("ContainerInspect", mock.Anything, "one").Return(types.ContainerJSON{ContainerJSONBase: &types.ContainerJSONBase{HostConfig: &containertypes.HostConfig{Resources: containertypes.Resources{CPUShares: 100}}}, Config: &containertypes.Config{}, NetworkSettings: &types.NetworkSettings{Networks: nil}}, nil).Once() filterArgs := filters.NewArgs() filterArgs.Add("id", "two") apiClient.On("ContainerList", mock.Anything, types.ContainerListOptions{All: true, Size: false, Filter: filterArgs}).Return([]types.Container{{ID: "two"}}, nil).Once() apiClient.On("ContainerInspect", mock.Anything, "two").Return(types.ContainerJSON{ContainerJSONBase: &types.ContainerJSONBase{HostConfig: &containertypes.HostConfig{Resources: containertypes.Resources{CPUShares: 100}}}, Config: &containertypes.Config{}, NetworkSettings: &types.NetworkSettings{Networks: nil}}, nil).Once() assert.NoError(t, engine.ConnectWithClient(client, apiClient)) assert.True(t, engine.isConnected()) // The engine should only have a single container at this point. containers := engine.Containers() assert.Len(t, containers, 1) if containers[0].ID != "one" { t.Fatalf("Missing container: one") } // Fake an event which will trigger a refresh. The second container will appear. engine.handler(events.Message{ID: "two", Status: "created"}) containers = engine.Containers() assert.Len(t, containers, 2) if containers[0].ID != "one" && containers[1].ID != "one" { t.Fatalf("Missing container: one") } if containers[0].ID != "two" && containers[1].ID != "two" { t.Fatalf("Missing container: two") } client.Mock.AssertExpectations(t) apiClient.Mock.AssertExpectations(t) }
func TestLoadImage(t *testing.T) { // create cluster c := &Cluster{ engines: make(map[string]*cluster.Engine), } // create engione id := "test-engine" engine := cluster.NewEngine(id, 0, engOpts) engine.Name = id engine.ID = id // create mock client client := mockclient.NewMockClient() apiClient := engineapimock.NewMockClient() apiClient.On("Info", mock.Anything).Return(mockInfo, nil) apiClient.On("ServerVersion", mock.Anything).Return(mockVersion, nil) apiClient.On("NetworkList", mock.Anything, mock.AnythingOfType("NetworkListOptions"), ).Return([]types.NetworkResource{}, nil) apiClient.On("VolumeList", mock.Anything, mock.Anything).Return(types.VolumesListResponse{}, nil) apiClient.On("Events", mock.Anything, mock.AnythingOfType("EventsOptions")).Return(&nopCloser{bytes.NewBufferString("")}, nil) apiClient.On("ImageList", mock.Anything, mock.AnythingOfType("ImageListOptions")).Return([]types.Image{}, nil) apiClient.On("ContainerList", mock.Anything, types.ContainerListOptions{All: true, Size: false}).Return([]types.Container{}, nil).Once() // connect client engine.ConnectWithClient(client, apiClient) // add engine to cluster c.engines[engine.ID] = engine // load success readCloser := nopCloser{bytes.NewBufferString("")} apiClient.On("ImageLoad", mock.Anything, mock.AnythingOfType("*io.PipeReader"), false).Return(types.ImageLoadResponse{Body: readCloser}, nil).Once() callback := func(what, status string, err error) { //if load OK, err will be nil assert.Nil(t, err) } c.Load(bytes.NewReader(nil), callback) // load error err := fmt.Errorf("Load error") apiClient.On("ImageLoad", mock.Anything, mock.AnythingOfType("*io.PipeReader"), false).Return(types.ImageLoadResponse{}, err).Once() callback = func(what, status string, err error) { // load error, err is not nil assert.NotNil(t, err) } c.Load(bytes.NewReader(nil), callback) }
func TestEngineState(t *testing.T) { engine := NewEngine("test", 0, engOpts) engine.setState(stateUnhealthy) assert.False(t, engine.isConnected()) client := mockclient.NewMockClient() apiClient := engineapimock.NewMockClient() apiClient.On("Info", mock.Anything).Return(mockInfo, nil) apiClient.On("ServerVersion", mock.Anything).Return(mockVersion, nil) apiClient.On("NetworkList", mock.Anything, mock.AnythingOfType("NetworkListOptions"), ).Return([]types.NetworkResource{}, nil) apiClient.On("VolumeList", mock.Anything, mock.AnythingOfType("Args"), ).Return(types.VolumesListResponse{}, nil) client.On("StartMonitorEvents", mock.Anything, mock.Anything, mock.Anything).Return() // The client will return one container at first, then a second one will appear. client.On("ListContainers", true, false, "").Return([]dockerclient.Container{{Id: "one"}}, nil).Once() apiClient.On("ImageList", mock.Anything, mock.AnythingOfType("ImageListOptions")).Return([]types.Image{}, nil).Once() client.On("InspectContainer", "one").Return(&dockerclient.ContainerInfo{Config: &dockerclient.ContainerConfig{CpuShares: 100}}, nil).Once() client.On("ListContainers", true, false, fmt.Sprintf("{%q:[%q]}", "id", "two")).Return([]dockerclient.Container{{Id: "two"}}, nil).Once() client.On("InspectContainer", "two").Return(&dockerclient.ContainerInfo{Config: &dockerclient.ContainerConfig{CpuShares: 100}}, nil).Once() assert.NoError(t, engine.ConnectWithClient(client, apiClient)) assert.True(t, engine.isConnected()) // The engine should only have a single container at this point. containers := engine.Containers() assert.Len(t, containers, 1) if containers[0].Id != "one" { t.Fatalf("Missing container: one") } // Fake an event which will trigger a refresh. The second container will appear. engine.handler(&dockerclient.Event{ID: "two", Status: "created"}, nil) containers = engine.Containers() assert.Len(t, containers, 2) if containers[0].Id != "one" && containers[1].Id != "one" { t.Fatalf("Missing container: one") } if containers[0].Id != "two" && containers[1].Id != "two" { t.Fatalf("Missing container: two") } client.Mock.AssertExpectations(t) apiClient.Mock.AssertExpectations(t) }
func TestOutdatedEngine(t *testing.T) { engine := NewEngine("test", 0, engOpts) client := mockclient.NewMockClient() apiClient := engineapimock.NewMockClient() apiClient.On("Info", mock.Anything).Return(types.Info{}, nil) assert.Error(t, engine.ConnectWithClient(client, apiClient)) nop := nopclient.NewNopClient() nopAPIClient := engineapinop.NewNopClient() assert.Error(t, engine.ConnectWithClient(nop, nopAPIClient)) assert.False(t, engine.isConnected()) client.Mock.AssertExpectations(t) apiClient.Mock.AssertExpectations(t) }
func TestTagImage(t *testing.T) { // create cluster c := &Cluster{ engines: make(map[string]*cluster.Engine), } images := []types.Image{} image1 := types.Image{ ID: "1234567890", RepoTags: []string{"busybox:latest"}, } images = append(images, image1) // create engine id := "test-engine" engine := cluster.NewEngine(id, 0, engOpts) engine.Name = id engine.ID = id // create mock client client := mockclient.NewMockClient() apiClient := engineapimock.NewMockClient() apiClient.On("Info", mock.Anything).Return(mockInfo, nil) apiClient.On("ServerVersion", mock.Anything).Return(mockVersion, nil) apiClient.On("NetworkList", mock.Anything, mock.AnythingOfType("NetworkListOptions"), ).Return([]types.NetworkResource{}, nil) apiClient.On("VolumeList", mock.Anything, mock.Anything).Return(types.VolumesListResponse{}, nil) apiClient.On("Events", mock.Anything, mock.AnythingOfType("EventsOptions")).Return(&nopCloser{bytes.NewBufferString("")}, nil) apiClient.On("ImageList", mock.Anything, mock.AnythingOfType("ImageListOptions")).Return(images, nil) apiClient.On("ContainerList", mock.Anything, types.ContainerListOptions{All: true, Size: false}).Return([]types.Container{}, nil).Once() // connect client engine.ConnectWithClient(client, apiClient) // add engine to cluster c.engines[engine.ID] = engine // tag image apiClient.On("ImageTag", mock.Anything, mock.Anything, mock.Anything).Return(nil).Once() assert.Nil(t, c.TagImage("busybox", "test_busybox:latest", false)) assert.NotNil(t, c.TagImage("busybox_not_exists", "test_busybox:latest", false)) }
func TestContainerRemovedDuringRefresh(t *testing.T) { var ( container1 = dockerclient.Container{Id: "c1"} container2 = dockerclient.Container{Id: "c2"} info1 *dockerclient.ContainerInfo info2 = &dockerclient.ContainerInfo{Id: "c2", Config: &dockerclient.ContainerConfig{}} ) engine := NewEngine("test", 0, engOpts) engine.setState(stateUnhealthy) assert.False(t, engine.isConnected()) // A container is removed before it can be inspected. client := mockclient.NewMockClient() apiClient := engineapimock.NewMockClient() apiClient.On("Info", mock.Anything).Return(mockInfo, nil) apiClient.On("ServerVersion", mock.Anything).Return(mockVersion, nil) apiClient.On("NetworkList", mock.Anything, mock.AnythingOfType("NetworkListOptions"), ).Return([]types.NetworkResource{}, nil) apiClient.On("VolumeList", mock.Anything, mock.AnythingOfType("Args"), ).Return(types.VolumesListResponse{}, nil) apiClient.On("ImageList", mock.Anything, mock.AnythingOfType("ImageListOptions")).Return([]types.Image{}, nil) client.On("StartMonitorEvents", mock.Anything, mock.Anything, mock.Anything).Return() client.On("ListContainers", true, false, "").Return([]dockerclient.Container{container1, container2}, nil) client.On("InspectContainer", "c1").Return(info1, errors.New("Not found")) client.On("InspectContainer", "c2").Return(info2, nil) assert.NoError(t, engine.ConnectWithClient(client, apiClient)) assert.Nil(t, engine.RefreshContainers(true)) // List of containers is still valid containers := engine.Containers() assert.Len(t, containers, 1) assert.Equal(t, containers[0].Id, "c2") client.Mock.AssertExpectations(t) apiClient.Mock.AssertExpectations(t) }
func TestContainerRemovedDuringRefresh(t *testing.T) { var ( container1 = types.Container{ID: "c1"} container2 = types.Container{ID: "c2"} info1 types.ContainerJSON info2 = types.ContainerJSON{ContainerJSONBase: &types.ContainerJSONBase{HostConfig: &containertypes.HostConfig{Resources: containertypes.Resources{CPUShares: 100}}}, Config: &containertypes.Config{}, NetworkSettings: &types.NetworkSettings{Networks: nil}} ) engine := NewEngine("test", 0, engOpts) engine.setState(stateUnhealthy) assert.False(t, engine.isConnected()) // A container is removed before it can be inspected. client := mockclient.NewMockClient() apiClient := engineapimock.NewMockClient() apiClient.On("Info", mock.Anything).Return(mockInfo, nil) apiClient.On("ServerVersion", mock.Anything).Return(mockVersion, nil) apiClient.On("NetworkList", mock.Anything, mock.AnythingOfType("NetworkListOptions"), ).Return([]types.NetworkResource{}, nil) apiClient.On("VolumeList", mock.Anything, mock.AnythingOfType("Args"), ).Return(types.VolumesListResponse{}, nil) apiClient.On("ImageList", mock.Anything, mock.AnythingOfType("ImageListOptions")).Return([]types.Image{}, nil) apiClient.On("Events", mock.Anything, mock.AnythingOfType("EventsOptions")).Return(&nopCloser{infiniteRead{}}, nil) apiClient.On("ContainerList", mock.Anything, types.ContainerListOptions{All: true, Size: false}).Return([]types.Container{container1, container2}, nil) apiClient.On("ContainerInspect", mock.Anything, "c1").Return(info1, errors.New("Not found")) apiClient.On("ContainerInspect", mock.Anything, "c2").Return(info2, nil) assert.NoError(t, engine.ConnectWithClient(client, apiClient)) assert.Nil(t, engine.RefreshContainers(true)) // List of containers is still valid containers := engine.Containers() assert.Len(t, containers, 1) assert.Equal(t, containers[0].ID, "c2") client.Mock.AssertExpectations(t) apiClient.Mock.AssertExpectations(t) }
func TestRemoveImage(t *testing.T) { engine := NewEngine("test", 0, engOpts) imageName := "test-image" dIs := []types.ImageDelete{{Deleted: imageName}} apiClient := engineapimock.NewMockClient() apiClient.On("ImageList", mock.Anything, mock.AnythingOfType("ImageListOptions")).Return([]types.Image{}, nil) apiClient.On("ImageRemove", mock.Anything, mock.Anything, mock.AnythingOfType("ImageRemoveOptions")).Return(dIs, nil) engine.apiClient = apiClient deletedImages, err := engine.RemoveImage("test-image", true) if err != nil { t.Errorf("encountered an unexpected error") } if deletedImages[0].Deleted != imageName { t.Errorf("didn't get the image we removed") } apiClient.Mock.AssertExpectations(t) }
func TestEngineConnectionFailure(t *testing.T) { engine := NewEngine("test", 0, engOpts) assert.False(t, engine.isConnected()) // Always fail. client := mockclient.NewMockClient() apiClient := engineapimock.NewMockClient() apiClient.On("Info", mock.Anything).Return(types.Info{}, errors.New("fail")) // Connect() should fail assert.Error(t, engine.ConnectWithClient(client, apiClient)) // isConnected() should return false nop := nopclient.NewNopClient() nopAPIClient := engineapinop.NewNopClient() assert.Error(t, engine.ConnectWithClient(nop, nopAPIClient)) assert.False(t, engine.isConnected()) client.Mock.AssertExpectations(t) apiClient.Mock.AssertExpectations(t) }
func TestDisconnect(t *testing.T) { engine := NewEngine("test", 0, engOpts) client := mockclient.NewMockClient() apiClient := engineapimock.NewMockClient() apiClient.On("Info", mock.Anything).Return(mockInfo, nil) apiClient.On("ServerVersion", mock.Anything).Return(mockVersion, nil) apiClient.On("NetworkList", mock.Anything, mock.AnythingOfType("NetworkListOptions"), ).Return([]types.NetworkResource{}, nil) apiClient.On("VolumeList", mock.Anything, mock.AnythingOfType("Args"), ).Return(types.VolumesListResponse{}, nil) apiClient.On("Events", mock.Anything, mock.AnythingOfType("EventsOptions")).Return(&nopCloser{infiniteRead{}}, nil) // The client will return one container at first, then a second one will appear. apiClient.On("ImageList", mock.Anything, mock.AnythingOfType("ImageListOptions")).Return([]types.Image{}, nil) apiClient.On("ContainerList", mock.Anything, types.ContainerListOptions{All: true, Size: false}).Return([]types.Container{{ID: "one"}}, nil).Once() apiClient.On("ContainerInspect", mock.Anything, "one").Return(types.ContainerJSON{ContainerJSONBase: &types.ContainerJSONBase{HostConfig: &containertypes.HostConfig{Resources: containertypes.Resources{CPUShares: 100}}}, Config: &containertypes.Config{}, NetworkSettings: &types.NetworkSettings{Networks: nil}}, nil).Once() filterArgs := filters.NewArgs() filterArgs.Add("id", "two") apiClient.On("ContainerList", mock.Anything, types.ContainerListOptions{All: true, Size: false, Filter: filterArgs}).Return([]types.Container{{ID: "two"}}, nil).Once() apiClient.On("ContainerInspect", mock.Anything, "two").Return(types.ContainerJSON{ContainerJSONBase: &types.ContainerJSONBase{HostConfig: &containertypes.HostConfig{Resources: containertypes.Resources{CPUShares: 100}}}, Config: &containertypes.Config{}, NetworkSettings: &types.NetworkSettings{Networks: nil}}, nil).Once() assert.NoError(t, engine.ConnectWithClient(client, apiClient)) assert.True(t, engine.isConnected()) defer func() { if r := recover(); r != nil { t.Errorf("TestDisconnect causes panic") } }() engine.Disconnect() assert.False(t, engine.isConnected()) assert.True(t, engine.state == stateDisconnected) // Double disconnect shouldn't cause panic engine.Disconnect() }
func TestDisconnect(t *testing.T) { engine := NewEngine("test", 0, engOpts) client := mockclient.NewMockClient() apiClient := engineapimock.NewMockClient() apiClient.On("Info", mock.Anything).Return(mockInfo, nil) apiClient.On("ServerVersion", mock.Anything).Return(mockVersion, nil) apiClient.On("NetworkList", mock.Anything, mock.AnythingOfType("NetworkListOptions"), ).Return([]types.NetworkResource{}, nil) apiClient.On("VolumeList", mock.Anything, mock.AnythingOfType("Args"), ).Return(types.VolumesListResponse{}, nil) client.On("StartMonitorEvents", mock.Anything, mock.Anything, mock.Anything).Return() client.On("StopAllMonitorEvents", mock.Anything, mock.Anything, mock.Anything).Return() // The client will return one container at first, then a second one will appear. client.On("ListContainers", true, false, "").Return([]dockerclient.Container{{Id: "one"}}, nil).Once() apiClient.On("ImageList", mock.Anything, mock.AnythingOfType("ImageListOptions")).Return([]types.Image{}, nil) client.On("InspectContainer", "one").Return(&dockerclient.ContainerInfo{Config: &dockerclient.ContainerConfig{CpuShares: 100}}, nil).Once() client.On("ListContainers", true, false, fmt.Sprintf("{%q:[%q]}", "id", "two")).Return([]dockerclient.Container{{Id: "two"}}, nil).Once() client.On("InspectContainer", "two").Return(&dockerclient.ContainerInfo{Config: &dockerclient.ContainerConfig{CpuShares: 100}}, nil).Once() assert.NoError(t, engine.ConnectWithClient(client, apiClient)) assert.True(t, engine.isConnected()) defer func() { if r := recover(); r != nil { t.Errorf("TestDisconnect causes panic") } }() engine.Disconnect() assert.False(t, engine.isConnected()) assert.True(t, engine.state == stateDisconnected) // Double disconnect shouldn't cause panic engine.Disconnect() }
func TestUsedCpus(t *testing.T) { var ( containerNcpu = []int64{1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47} hostNcpu = []int{1, 2, 4, 8, 10, 12, 16, 20, 32, 36, 40, 48} ) engine := NewEngine("test", 0, engOpts) engine.setState(stateHealthy) client := mockclient.NewMockClient() apiClient := engineapimock.NewMockClient() for _, hn := range hostNcpu { for _, cn := range containerNcpu { if int(cn) <= hn { mockInfo.NCPU = hn cpuShares := int64(math.Ceil(float64(cn*1024) / float64(mockInfo.NCPU))) apiClient.On("Info", mock.Anything).Return(mockInfo, nil).Once() apiClient.On("ServerVersion", mock.Anything).Return(mockVersion, nil) apiClient.On("NetworkList", mock.Anything, mock.AnythingOfType("NetworkListOptions"), ).Return([]types.NetworkResource{}, nil) apiClient.On("VolumeList", mock.Anything, mock.AnythingOfType("Args"), ).Return(types.VolumesListResponse{}, nil) client.On("StartMonitorEvents", mock.Anything, mock.Anything, mock.Anything).Return() apiClient.On("ImageList", mock.Anything, mock.AnythingOfType("ImageListOptions")).Return([]types.Image{}, nil).Once() client.On("ListContainers", true, false, "").Return([]dockerclient.Container{{Id: "test"}}, nil).Once() client.On("InspectContainer", "test").Return(&dockerclient.ContainerInfo{Config: &dockerclient.ContainerConfig{CpuShares: cpuShares}}, nil).Once() engine.ConnectWithClient(client, apiClient) assert.Equal(t, engine.Cpus, mockInfo.NCPU) assert.Equal(t, engine.UsedCpus(), cn) } } } }
func TestUsedCpus(t *testing.T) { var ( containerNcpu = []int64{1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47} hostNcpu = []int64{1, 2, 4, 8, 10, 12, 16, 20, 32, 36, 40, 48} ) engine := NewEngine("test", 0, engOpts) engine.setState(stateHealthy) client := mockclient.NewMockClient() apiClient := engineapimock.NewMockClient() for _, hn := range hostNcpu { for _, cn := range containerNcpu { if cn <= hn { mockInfo.NCPU = int(hn) cpuShares := int64(math.Ceil(float64(cn*1024) / float64(mockInfo.NCPU))) apiClient.On("Info", mock.Anything).Return(mockInfo, nil).Once() apiClient.On("ServerVersion", mock.Anything).Return(mockVersion, nil) apiClient.On("NetworkList", mock.Anything, mock.AnythingOfType("NetworkListOptions"), ).Return([]types.NetworkResource{}, nil) apiClient.On("VolumeList", mock.Anything, mock.AnythingOfType("Args"), ).Return(types.VolumesListResponse{}, nil) apiClient.On("Events", mock.Anything, mock.AnythingOfType("EventsOptions")).Return(&nopCloser{infiniteRead{}}, nil) apiClient.On("ImageList", mock.Anything, mock.AnythingOfType("ImageListOptions")).Return([]types.Image{}, nil).Once() apiClient.On("ContainerList", mock.Anything, types.ContainerListOptions{All: true, Size: false}).Return([]types.Container{{ID: "test"}}, nil).Once() apiClient.On("ContainerInspect", mock.Anything, "test").Return(types.ContainerJSON{ContainerJSONBase: &types.ContainerJSONBase{HostConfig: &containertypes.HostConfig{Resources: containertypes.Resources{CPUShares: cpuShares}}}, Config: &containertypes.Config{}, NetworkSettings: &types.NetworkSettings{Networks: nil}}, nil).Once() engine.ConnectWithClient(client, apiClient) assert.Equal(t, engine.Cpus, int64(mockInfo.NCPU)) assert.Equal(t, engine.UsedCpus(), cn) } } } }
func TestCreateContainer(t *testing.T) { var ( config = &ContainerConfig{containertypes.Config{ Image: "busybox", Cmd: []string{"date"}, Tty: false, }, containertypes.HostConfig{ Resources: containertypes.Resources{ CPUShares: 1, }, }, networktypes.NetworkingConfig{}} engine = NewEngine("test", 0, engOpts) client = mockclient.NewMockClient() apiClient = engineapimock.NewMockClient() readCloser = nopCloser{bytes.NewBufferString("")} ) engine.setState(stateUnhealthy) apiClient.On("Info", mock.Anything).Return(mockInfo, nil) apiClient.On("ServerVersion", mock.Anything).Return(mockVersion, nil) apiClient.On("NetworkList", mock.Anything, mock.AnythingOfType("NetworkListOptions"), ).Return([]types.NetworkResource{}, nil) apiClient.On("VolumeList", mock.Anything, mock.AnythingOfType("Args"), ).Return(types.VolumesListResponse{}, nil) apiClient.On("Events", mock.Anything, mock.AnythingOfType("EventsOptions")).Return(&nopCloser{infiniteRead{}}, nil) client.On("ListContainers", true, false, "").Return([]dockerclient.Container{}, nil).Once() apiClient.On("ImageList", mock.Anything, mock.AnythingOfType("ImageListOptions")).Return([]types.Image{}, nil).Once() // filterArgs1 := filters.NewArgs() // filterArgs1.Add("id", id) apiClient.On("ContainerList", mock.Anything, types.ContainerListOptions{All: true, Size: false}).Return([]types.Container{}, nil).Once() assert.NoError(t, engine.ConnectWithClient(client, apiClient)) assert.True(t, engine.isConnected()) mockConfig := *config mockConfig.HostConfig.CPUShares = int64(math.Ceil(float64(config.HostConfig.CPUShares*1024) / float64(mockInfo.NCPU))) // Everything is ok name := "test1" id := "id1" apiClient.On("ImageList", mock.Anything, mock.AnythingOfType("ImageListOptions")).Return([]types.Image{}, nil).Once() var auth *types.AuthConfig apiClient.On("ContainerCreate", mock.Anything, &mockConfig.Config, &mockConfig.HostConfig, &mockConfig.NetworkingConfig, name).Return(types.ContainerCreateResponse{ID: id}, nil).Once() filterArgs := filters.NewArgs() filterArgs.Add("id", id) apiClient.On("ContainerList", mock.Anything, types.ContainerListOptions{All: true, Size: false, Filter: filterArgs}).Return([]types.Container{{ID: id}}, nil).Once() apiClient.On("ContainerInspect", mock.Anything, id).Return(types.ContainerJSON{Config: &config.Config, ContainerJSONBase: &types.ContainerJSONBase{HostConfig: &config.HostConfig}, NetworkSettings: &types.NetworkSettings{Networks: nil}}, nil).Once() container, err := engine.CreateContainer(config, name, false, auth) assert.Nil(t, err) assert.Equal(t, container.ID, id) assert.Len(t, engine.Containers(), 1) // Image not found, pullImage == false name = "test2" mockConfig.HostConfig.CPUShares = int64(math.Ceil(float64(config.HostConfig.CPUShares*1024) / float64(mockInfo.NCPU))) // FIXMEENGINEAPI : below should return an engine-api error, or something custom apiClient.On("ContainerCreate", mock.Anything, &mockConfig.Config, &mockConfig.HostConfig, &mockConfig.NetworkingConfig, name).Return(types.ContainerCreateResponse{}, dockerclient.ErrImageNotFound).Once() container, err = engine.CreateContainer(config, name, false, auth) assert.Equal(t, err, dockerclient.ErrImageNotFound) assert.Nil(t, container) // Image not found, pullImage == true, and the image can be pulled successfully name = "test3" id = "id3" apiClient.On("ImageList", mock.Anything, mock.AnythingOfType("ImageListOptions")).Return([]types.Image{}, nil).Once() mockConfig.HostConfig.CPUShares = int64(math.Ceil(float64(config.HostConfig.CPUShares*1024) / float64(mockInfo.NCPU))) apiClient.On("ImagePull", mock.Anything, config.Image, mock.AnythingOfType("types.ImagePullOptions")).Return(readCloser, nil).Once() // TODO(nishanttotla): below should return an engine-api error, or something custom, so that we can get rid of dockerclient apiClient.On("ContainerCreate", mock.Anything, &mockConfig.Config, &mockConfig.HostConfig, &mockConfig.NetworkingConfig, name).Return(types.ContainerCreateResponse{}, dockerclient.ErrImageNotFound).Once() // FIXMEENGINEAPI : below should return an engine-api error, or something custom apiClient.On("ContainerCreate", mock.Anything, &mockConfig.Config, &mockConfig.HostConfig, &mockConfig.NetworkingConfig, name).Return(types.ContainerCreateResponse{ID: id}, nil).Once() filterArgs = filters.NewArgs() filterArgs.Add("id", id) apiClient.On("ContainerList", mock.Anything, types.ContainerListOptions{All: true, Size: false, Filter: filterArgs}).Return([]types.Container{{ID: id}}, nil).Once() apiClient.On("ContainerInspect", mock.Anything, id).Return(types.ContainerJSON{Config: &config.Config, ContainerJSONBase: &types.ContainerJSONBase{HostConfig: &config.HostConfig}, NetworkSettings: &types.NetworkSettings{Networks: nil}}, nil).Once() container, err = engine.CreateContainer(config, name, true, auth) assert.Nil(t, err) assert.Equal(t, container.ID, id) assert.Len(t, engine.Containers(), 2) }
func TestCreateContainer(t *testing.T) { var ( config = &ContainerConfig{dockerclient.ContainerConfig{ Image: "busybox", CpuShares: 1, Cmd: []string{"date"}, Tty: false, }} engine = NewEngine("test", 0, engOpts) client = mockclient.NewMockClient() apiClient = engineapimock.NewMockClient() ) engine.setState(stateUnhealthy) apiClient.On("Info", mock.Anything).Return(mockInfo, nil) apiClient.On("ServerVersion", mock.Anything).Return(mockVersion, nil) apiClient.On("NetworkList", mock.Anything, mock.AnythingOfType("NetworkListOptions"), ).Return([]types.NetworkResource{}, nil) apiClient.On("VolumeList", mock.Anything, mock.AnythingOfType("Args"), ).Return(types.VolumesListResponse{}, nil) client.On("StartMonitorEvents", mock.Anything, mock.Anything, mock.Anything).Return() client.On("ListContainers", true, false, "").Return([]dockerclient.Container{}, nil).Once() apiClient.On("ImageList", mock.Anything, mock.AnythingOfType("ImageListOptions")).Return([]types.Image{}, nil).Once() assert.NoError(t, engine.ConnectWithClient(client, apiClient)) assert.True(t, engine.isConnected()) mockConfig := config.ContainerConfig mockConfig.CpuShares = int64(math.Ceil(float64(config.CpuShares*1024) / float64(mockInfo.NCPU))) mockConfig.HostConfig.CpuShares = mockConfig.CpuShares // Everything is ok name := "test1" id := "id1" var auth *dockerclient.AuthConfig client.On("CreateContainer", &mockConfig, name, auth).Return(id, nil).Once() client.On("ListContainers", true, false, fmt.Sprintf(`{"id":[%q]}`, id)).Return([]dockerclient.Container{{Id: id}}, nil).Once() apiClient.On("ImageList", mock.Anything, mock.AnythingOfType("ImageListOptions")).Return([]types.Image{}, nil).Once() client.On("InspectContainer", id).Return(&dockerclient.ContainerInfo{Config: &config.ContainerConfig}, nil).Once() container, err := engine.Create(config, name, false, auth) assert.Nil(t, err) assert.Equal(t, container.Id, id) assert.Len(t, engine.Containers(), 1) // Image not found, pullImage == false name = "test2" mockConfig.CpuShares = int64(math.Ceil(float64(config.CpuShares*1024) / float64(mockInfo.NCPU))) client.On("CreateContainer", &mockConfig, name, auth).Return("", dockerclient.ErrImageNotFound).Once() container, err = engine.Create(config, name, false, auth) assert.Equal(t, err, dockerclient.ErrImageNotFound) assert.Nil(t, container) // Image not found, pullImage == true, and the image can be pulled successfully name = "test3" id = "id3" mockConfig.CpuShares = int64(math.Ceil(float64(config.CpuShares*1024) / float64(mockInfo.NCPU))) client.On("PullImage", config.Image+":latest", mock.Anything).Return(nil).Once() client.On("CreateContainer", &mockConfig, name, auth).Return("", dockerclient.ErrImageNotFound).Once() client.On("CreateContainer", &mockConfig, name, auth).Return(id, nil).Once() client.On("ListContainers", true, false, fmt.Sprintf(`{"id":[%q]}`, id)).Return([]dockerclient.Container{{Id: id}}, nil).Once() apiClient.On("ImageList", mock.Anything, mock.AnythingOfType("ImageListOptions")).Return([]types.Image{}, nil).Once() client.On("InspectContainer", id).Return(&dockerclient.ContainerInfo{Config: &config.ContainerConfig}, nil).Once() container, err = engine.Create(config, name, true, auth) assert.Nil(t, err) assert.Equal(t, container.Id, id) assert.Len(t, engine.Containers(), 2) }