diff --git a/pkg/scaler/docker_swarm.go b/pkg/scaler/docker_swarm.go index 72ffd02..7162016 100644 --- a/pkg/scaler/docker_swarm.go +++ b/pkg/scaler/docker_swarm.go @@ -21,7 +21,6 @@ func NewDockerSwarmScaler() *DockerSwarmScaler { } func (scaler *DockerSwarmScaler) ScaleUp(name string) error { - log.Infof("scaling up %s to %d", name, onereplicas) ctx := context.Background() service, err := scaler.GetServiceByName(name, ctx) @@ -30,6 +29,12 @@ func (scaler *DockerSwarmScaler) ScaleUp(name string) error { return err } + if *service.Spec.Mode.Replicated.Replicas == onereplicas { + log.Infof("%s already scaled up to %d", name, onereplicas) + return nil + } + log.Infof("scaling up %s to %d", name, onereplicas) + service.Spec.Mode.Replicated = &swarm.ReplicatedService{ Replicas: &onereplicas, } @@ -48,7 +53,6 @@ func (scaler *DockerSwarmScaler) ScaleUp(name string) error { } func (scaler *DockerSwarmScaler) ScaleDown(name string) error { - log.Infof("scaling down %s to 0", name) ctx := context.Background() service, err := scaler.GetServiceByName(name, ctx) @@ -59,6 +63,12 @@ func (scaler *DockerSwarmScaler) ScaleDown(name string) error { replicas := uint64(0) + if *service.Spec.Mode.Replicated.Replicas == replicas { + log.Infof("%s already scaled down to %d", name, replicas) + return nil + } + log.Infof("scaling down %s to %d", name, replicas) + service.Spec.Mode.Replicated = &swarm.ReplicatedService{ Replicas: &replicas, } diff --git a/pkg/scaler/docker_swarm_test.go b/pkg/scaler/docker_swarm_test.go index 2afd9eb..399ef5f 100644 --- a/pkg/scaler/docker_swarm_test.go +++ b/pkg/scaler/docker_swarm_test.go @@ -80,6 +80,38 @@ func TestDockerSwarmScaler_ScaleUp(t *testing.T) { tt.fields.Client.AssertExpectations(t) }) } + + t.Run("scale nginx service to 1 replica twice", func(t *testing.T) { + swarmMock := mocks.NewServiceAPIClientMock() + + serviceList := []swarm.Service{ + { + ID: "nginx_service", + Meta: swarm.Meta{Version: swarm.Version{}}, + Spec: swarm.ServiceSpec{ + Mode: swarm.ServiceMode{ + Replicated: &swarm.ReplicatedService{ + Replicas: &zeroreplicas, + }, + }, + }, + }, + } + + swarmMock.On("ServiceList", mock.Anything, mock.Anything).Return(serviceList, nil) + swarmMock.On("ServiceUpdate", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(types.ServiceUpdateResponse{ + Warnings: []string{}, + }, nil) + + scaler := &DockerSwarmScaler{ + Client: swarmMock, + } + + scaler.ScaleUp("nginx") + scaler.ScaleUp("nginx") + + swarmMock.AssertNumberOfCalls(t, "ServiceUpdate", 1) + }) } func TestDockerSwarmScaler_ScaleDown(t *testing.T) { @@ -148,6 +180,37 @@ func TestDockerSwarmScaler_ScaleDown(t *testing.T) { tt.fields.Client.AssertExpectations(t) }) } + t.Run("scale nginx service to 0 replica twice", func(t *testing.T) { + swarmMock := mocks.NewServiceAPIClientMock() + + serviceList := []swarm.Service{ + { + ID: "nginx_service", + Meta: swarm.Meta{Version: swarm.Version{}}, + Spec: swarm.ServiceSpec{ + Mode: swarm.ServiceMode{ + Replicated: &swarm.ReplicatedService{ + Replicas: &onereplicas, + }, + }, + }, + }, + } + + swarmMock.On("ServiceList", mock.Anything, mock.Anything).Return(serviceList, nil) + swarmMock.On("ServiceUpdate", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(types.ServiceUpdateResponse{ + Warnings: []string{}, + }, nil) + + scaler := &DockerSwarmScaler{ + Client: swarmMock, + } + + scaler.ScaleDown("nginx") + scaler.ScaleDown("nginx") + + swarmMock.AssertNumberOfCalls(t, "ServiceUpdate", 1) + }) } func TestDockerSwarmScaler_IsUp(t *testing.T) {