mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
240a9fcb83
Adds code to support Cluster Volumes in Swarm using CSI drivers. Signed-off-by: Drew Erny <derny@mirantis.com>
210 lines
5.6 KiB
Go
210 lines
5.6 KiB
Go
package convert
|
|
|
|
import (
|
|
"testing"
|
|
|
|
volumetypes "github.com/docker/docker/api/types/volume"
|
|
swarmapi "github.com/moby/swarmkit/v2/api"
|
|
|
|
"gotest.tools/v3/assert"
|
|
)
|
|
|
|
func TestTopologyFromGRPC(t *testing.T) {
|
|
nilTopology := topologyFromGRPC(nil)
|
|
assert.DeepEqual(t, nilTopology, volumetypes.Topology{})
|
|
|
|
swarmTop := &swarmapi.Topology{
|
|
Segments: map[string]string{"foo": "bar"},
|
|
}
|
|
|
|
top := topologyFromGRPC(swarmTop)
|
|
assert.DeepEqual(t, top.Segments, swarmTop.Segments)
|
|
}
|
|
|
|
func TestCapacityRangeFromGRPC(t *testing.T) {
|
|
nilCapacity := capacityRangeFromGRPC(nil)
|
|
assert.Assert(t, nilCapacity == nil)
|
|
|
|
swarmZeroCapacity := &swarmapi.CapacityRange{}
|
|
zeroCapacity := capacityRangeFromGRPC(swarmZeroCapacity)
|
|
assert.Assert(t, zeroCapacity != nil)
|
|
assert.Equal(t, zeroCapacity.RequiredBytes, int64(0))
|
|
assert.Equal(t, zeroCapacity.LimitBytes, int64(0))
|
|
|
|
swarmNonZeroCapacity := &swarmapi.CapacityRange{
|
|
RequiredBytes: 1024,
|
|
LimitBytes: 2048,
|
|
}
|
|
nonZeroCapacity := capacityRangeFromGRPC(swarmNonZeroCapacity)
|
|
assert.Assert(t, nonZeroCapacity != nil)
|
|
assert.Equal(t, nonZeroCapacity.RequiredBytes, int64(1024))
|
|
assert.Equal(t, nonZeroCapacity.LimitBytes, int64(2048))
|
|
}
|
|
|
|
func TestVolumeAvailabilityFromGRPC(t *testing.T) {
|
|
for _, tc := range []struct {
|
|
name string
|
|
in swarmapi.VolumeSpec_VolumeAvailability
|
|
expected volumetypes.Availability
|
|
}{
|
|
{
|
|
name: "Active",
|
|
in: swarmapi.VolumeAvailabilityActive,
|
|
expected: volumetypes.AvailabilityActive,
|
|
}, {
|
|
name: "Pause",
|
|
in: swarmapi.VolumeAvailabilityPause,
|
|
expected: volumetypes.AvailabilityPause,
|
|
}, {
|
|
name: "Drain",
|
|
in: swarmapi.VolumeAvailabilityDrain,
|
|
expected: volumetypes.AvailabilityDrain,
|
|
},
|
|
} {
|
|
tc := tc
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
actual := volumeAvailabilityFromGRPC(tc.in)
|
|
assert.Equal(t, actual, tc.expected)
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestAccessModeFromGRPC tests that the AccessMode type is correctly converted
|
|
func TestAccessModeFromGRPC(t *testing.T) {
|
|
for _, tc := range []struct {
|
|
name string
|
|
in *swarmapi.VolumeAccessMode
|
|
expected *volumetypes.AccessMode
|
|
}{
|
|
{
|
|
name: "MountVolume",
|
|
in: &swarmapi.VolumeAccessMode{
|
|
Scope: swarmapi.VolumeScopeSingleNode,
|
|
Sharing: swarmapi.VolumeSharingNone,
|
|
AccessType: &swarmapi.VolumeAccessMode_Mount{
|
|
Mount: &swarmapi.VolumeAccessMode_MountVolume{
|
|
FsType: "foo",
|
|
// TODO(dperny): maybe don't convert this?
|
|
MountFlags: []string{"one", "two"},
|
|
},
|
|
},
|
|
},
|
|
expected: &volumetypes.AccessMode{
|
|
Scope: volumetypes.ScopeSingleNode,
|
|
Sharing: volumetypes.SharingNone,
|
|
MountVolume: &volumetypes.TypeMount{
|
|
FsType: "foo",
|
|
MountFlags: []string{"one", "two"},
|
|
},
|
|
},
|
|
}, {
|
|
name: "BlockVolume",
|
|
in: &swarmapi.VolumeAccessMode{
|
|
Scope: swarmapi.VolumeScopeSingleNode,
|
|
Sharing: swarmapi.VolumeSharingNone,
|
|
AccessType: &swarmapi.VolumeAccessMode_Block{
|
|
Block: &swarmapi.VolumeAccessMode_BlockVolume{},
|
|
},
|
|
},
|
|
expected: &volumetypes.AccessMode{
|
|
Scope: volumetypes.ScopeSingleNode,
|
|
Sharing: volumetypes.SharingNone,
|
|
BlockVolume: &volumetypes.TypeBlock{},
|
|
},
|
|
},
|
|
} {
|
|
tc := tc
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
out := accessModeFromGRPC(tc.in)
|
|
assert.DeepEqual(t, tc.expected, out)
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestVolumeCreateToGRPC tests that a docker-typed VolumeCreateBody is
|
|
// correctly converted to a swarm-typed VolumeSpec.
|
|
func TestVolumeCreateToGRPC(t *testing.T) {
|
|
volume := &volumetypes.CreateOptions{
|
|
Driver: "plug1",
|
|
DriverOpts: map[string]string{"options": "yeah"},
|
|
Labels: map[string]string{"labeled": "yeah"},
|
|
Name: "volume1",
|
|
}
|
|
|
|
spec := &volumetypes.ClusterVolumeSpec{
|
|
Group: "gronp",
|
|
AccessMode: &volumetypes.AccessMode{
|
|
Scope: volumetypes.ScopeMultiNode,
|
|
Sharing: volumetypes.SharingAll,
|
|
MountVolume: &volumetypes.TypeMount{
|
|
FsType: "foo",
|
|
MountFlags: []string{"one", "two"},
|
|
},
|
|
},
|
|
Secrets: []volumetypes.Secret{
|
|
{Key: "key1", Secret: "secret1"},
|
|
{Key: "key2", Secret: "secret2"},
|
|
},
|
|
AccessibilityRequirements: &volumetypes.TopologyRequirement{
|
|
Requisite: []volumetypes.Topology{
|
|
{Segments: map[string]string{"top1": "yup"}},
|
|
{Segments: map[string]string{"top2": "def"}},
|
|
{Segments: map[string]string{"top3": "nah"}},
|
|
},
|
|
Preferred: []volumetypes.Topology{},
|
|
},
|
|
CapacityRange: &volumetypes.CapacityRange{
|
|
RequiredBytes: 1,
|
|
LimitBytes: 0,
|
|
},
|
|
}
|
|
|
|
volume.ClusterVolumeSpec = spec
|
|
|
|
swarmSpec := VolumeCreateToGRPC(volume)
|
|
|
|
assert.Assert(t, swarmSpec != nil)
|
|
expectedSwarmSpec := &swarmapi.VolumeSpec{
|
|
Annotations: swarmapi.Annotations{
|
|
Name: "volume1",
|
|
Labels: map[string]string{
|
|
"labeled": "yeah",
|
|
},
|
|
},
|
|
Group: "gronp",
|
|
Driver: &swarmapi.Driver{
|
|
Name: "plug1",
|
|
Options: map[string]string{
|
|
"options": "yeah",
|
|
},
|
|
},
|
|
AccessMode: &swarmapi.VolumeAccessMode{
|
|
Scope: swarmapi.VolumeScopeMultiNode,
|
|
Sharing: swarmapi.VolumeSharingAll,
|
|
AccessType: &swarmapi.VolumeAccessMode_Mount{
|
|
Mount: &swarmapi.VolumeAccessMode_MountVolume{
|
|
FsType: "foo",
|
|
MountFlags: []string{"one", "two"},
|
|
},
|
|
},
|
|
},
|
|
Secrets: []*swarmapi.VolumeSecret{
|
|
{Key: "key1", Secret: "secret1"},
|
|
{Key: "key2", Secret: "secret2"},
|
|
},
|
|
AccessibilityRequirements: &swarmapi.TopologyRequirement{
|
|
Requisite: []*swarmapi.Topology{
|
|
{Segments: map[string]string{"top1": "yup"}},
|
|
{Segments: map[string]string{"top2": "def"}},
|
|
{Segments: map[string]string{"top3": "nah"}},
|
|
},
|
|
Preferred: nil,
|
|
},
|
|
CapacityRange: &swarmapi.CapacityRange{
|
|
RequiredBytes: 1,
|
|
LimitBytes: 0,
|
|
},
|
|
}
|
|
|
|
assert.DeepEqual(t, swarmSpec, expectedSwarmSpec)
|
|
}
|