100 lines
3.3 KiB
Go
100 lines
3.3 KiB
Go
package updater_test
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
|
|
"github.com/docker/docker/api/types/swarm"
|
|
"github.com/shcizo/package-updater/internal/discovery"
|
|
"github.com/shcizo/package-updater/internal/updater"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
type fakeSwarmDockerClient struct {
|
|
inspectService swarm.Service
|
|
inspectErr error
|
|
updateErr error
|
|
|
|
inspectCalled bool
|
|
updateCalled bool
|
|
updateCalledServiceID string
|
|
updateCalledVersion swarm.Version
|
|
updateCalledSpec swarm.ServiceSpec
|
|
updateCalledOpts swarm.ServiceUpdateOptions
|
|
}
|
|
|
|
func (f *fakeSwarmDockerClient) ServiceInspectWithRaw(_ context.Context, _ string, _ swarm.ServiceInspectOptions) (swarm.Service, []byte, error) {
|
|
f.inspectCalled = true
|
|
return f.inspectService, nil, f.inspectErr
|
|
}
|
|
|
|
func (f *fakeSwarmDockerClient) ServiceUpdate(_ context.Context, serviceID string, version swarm.Version, spec swarm.ServiceSpec, opts swarm.ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error) {
|
|
f.updateCalled = true
|
|
f.updateCalledServiceID = serviceID
|
|
f.updateCalledVersion = version
|
|
f.updateCalledSpec = spec
|
|
f.updateCalledOpts = opts
|
|
return swarm.ServiceUpdateResponse{}, f.updateErr
|
|
}
|
|
|
|
func mkInspectService(version uint64, image string) swarm.Service {
|
|
return swarm.Service{
|
|
ID: "svc-myapp",
|
|
Meta: swarm.Meta{Version: swarm.Version{Index: version}},
|
|
Spec: swarm.ServiceSpec{
|
|
Annotations: swarm.Annotations{Name: "myapp_web"},
|
|
TaskTemplate: swarm.TaskSpec{ContainerSpec: &swarm.ContainerSpec{Image: image}},
|
|
},
|
|
}
|
|
}
|
|
|
|
func TestSwarmExecutor_UpdatesImageAndVersion(t *testing.T) {
|
|
fake := &fakeSwarmDockerClient{inspectService: mkInspectService(7, "registry.example.com/myapp:v1")}
|
|
e := updater.NewSwarmExecutor(fake)
|
|
|
|
job := discovery.Job{Service: "myapp_web", ServiceID: "svc-myapp", Image: "registry.example.com/myapp:v2"}
|
|
err := e.Execute(context.Background(), job)
|
|
|
|
require.NoError(t, err)
|
|
require.True(t, fake.updateCalled)
|
|
require.Equal(t, "svc-myapp", fake.updateCalledServiceID)
|
|
require.Equal(t, uint64(7), fake.updateCalledVersion.Index)
|
|
require.Equal(t, "registry.example.com/myapp:v2", fake.updateCalledSpec.TaskTemplate.ContainerSpec.Image)
|
|
require.True(t, fake.updateCalledOpts.QueryRegistry)
|
|
}
|
|
|
|
func TestSwarmExecutor_InspectError(t *testing.T) {
|
|
fake := &fakeSwarmDockerClient{inspectErr: errors.New("service not found")}
|
|
e := updater.NewSwarmExecutor(fake)
|
|
|
|
err := e.Execute(context.Background(), discovery.Job{ServiceID: "svc-missing", Image: "x:v2"})
|
|
|
|
require.Error(t, err)
|
|
require.False(t, fake.updateCalled)
|
|
}
|
|
|
|
func TestSwarmExecutor_UpdateError(t *testing.T) {
|
|
fake := &fakeSwarmDockerClient{
|
|
inspectService: mkInspectService(1, "registry.example.com/myapp:v1"),
|
|
updateErr: errors.New("update rejected"),
|
|
}
|
|
e := updater.NewSwarmExecutor(fake)
|
|
|
|
err := e.Execute(context.Background(), discovery.Job{ServiceID: "svc-myapp", Image: "registry.example.com/myapp:v2"})
|
|
|
|
require.Error(t, err)
|
|
}
|
|
|
|
func TestSwarmExecutor_RefusedJobIsNotExecuted(t *testing.T) {
|
|
fake := &fakeSwarmDockerClient{}
|
|
e := updater.NewSwarmExecutor(fake)
|
|
job := discovery.Job{ServiceID: "svc-myapp", Image: "x:v2", Refused: true, RefusedReason: "not opted in"}
|
|
|
|
err := e.Execute(context.Background(), job)
|
|
|
|
require.Error(t, err)
|
|
require.False(t, fake.inspectCalled)
|
|
require.False(t, fake.updateCalled)
|
|
}
|