mirror of
https://github.com/psviderski/uncloud.git
synced 2026-08-26 11:03:34 +00:00
refactor: 'service run' create missing volumes satisfying all placement constraints
This commit is contained in:
+3
-2
@@ -19,10 +19,11 @@ import (
|
||||
)
|
||||
|
||||
func assertServiceMatchesSpec(t *testing.T, svc api.Service, spec api.ServiceSpec) {
|
||||
spec = spec.SetDefaults()
|
||||
assert.Equal(t, spec.Name, svc.Name)
|
||||
|
||||
if svc.Mode == api.ServiceModeReplicated {
|
||||
assert.Contains(t, []string{"", api.ServiceModeReplicated}, spec.Mode)
|
||||
assert.Equal(t, api.ServiceModeReplicated, spec.Mode)
|
||||
assert.Len(t, svc.Containers, int(spec.Replicas), "Expected %d replicas", spec.Replicas)
|
||||
} else {
|
||||
assert.Equal(t, spec.Mode, svc.Mode)
|
||||
@@ -34,10 +35,10 @@ func assertServiceMatchesSpec(t *testing.T, svc api.Service, spec api.ServiceSpe
|
||||
}
|
||||
|
||||
func assertContainerMatchesSpec(t *testing.T, ctr api.ServiceContainer, spec api.ServiceSpec) {
|
||||
spec = spec.SetDefaults()
|
||||
status := deploy.EvalContainerSpecChange(ctr.ServiceSpec, spec)
|
||||
assert.Equal(t, deploy.ContainerUpToDate, status)
|
||||
|
||||
spec = spec.SetDefaults()
|
||||
// Verify labels.
|
||||
assert.True(t, api.ValidateServiceID(ctr.Config.Labels[api.LabelServiceID]))
|
||||
assert.Equal(t, spec.Name, ctr.Config.Labels[api.LabelServiceName])
|
||||
|
||||
@@ -1388,6 +1388,65 @@ func TestServiceLifecycle(t *testing.T) {
|
||||
assert.Equal(t, spec.Ports, ports)
|
||||
})
|
||||
|
||||
t.Run("3 replicas with volume auto-created", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
name := "test-3-replicas-volume-auto-created"
|
||||
volumeName := name
|
||||
t.Cleanup(func() {
|
||||
err := cli.RemoveService(ctx, name)
|
||||
if !errors.Is(err, api.ErrNotFound) {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
volumes, err := cli.ListVolumes(ctx, &api.VolumeFilter{Names: []string{volumeName}})
|
||||
require.NoError(t, err)
|
||||
for _, v := range volumes {
|
||||
err = cli.RemoveVolume(ctx, v.MachineID, v.Volume.Name, false)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
})
|
||||
|
||||
volumes, err := cli.ListVolumes(ctx, &api.VolumeFilter{Names: []string{volumeName}})
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, volumes, 0, "Volume should not exist before service creation")
|
||||
|
||||
spec := api.ServiceSpec{
|
||||
Name: name,
|
||||
Container: api.ContainerSpec{
|
||||
Image: "portainer/pause:latest",
|
||||
VolumeMounts: []api.VolumeMount{
|
||||
{
|
||||
VolumeName: volumeName,
|
||||
ContainerPath: "/data",
|
||||
},
|
||||
},
|
||||
},
|
||||
Volumes: []api.VolumeSpec{
|
||||
{
|
||||
Name: volumeName,
|
||||
Type: api.VolumeTypeVolume,
|
||||
},
|
||||
},
|
||||
Replicas: 3,
|
||||
}
|
||||
resp, err := cli.RunService(ctx, spec)
|
||||
require.NoError(t, err)
|
||||
|
||||
svc, err := cli.InspectService(ctx, resp.ID)
|
||||
require.NoError(t, err)
|
||||
assertServiceMatchesSpec(t, svc, spec)
|
||||
|
||||
volumes, err = cli.ListVolumes(ctx, &api.VolumeFilter{Names: []string{volumeName}})
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, volumes, 1, "Volume should be created automatically")
|
||||
assert.Equal(t, volumeName, volumes[0].Volume.Name)
|
||||
|
||||
machines := serviceMachines(svc)
|
||||
assert.Equal(t, []string{volumes[0].MachineID}, machines.ToSlice(),
|
||||
"Replicas should be on the same machine as the volume")
|
||||
})
|
||||
|
||||
t.Run("global mode", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user