171 lines
4.3 KiB
Go
171 lines
4.3 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
package structs
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/hashicorp/nomad/ci"
|
|
"github.com/shoenig/test/must"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestVolumeRequest_Validate(t *testing.T) {
|
|
ci.Parallel(t)
|
|
|
|
testCases := []struct {
|
|
name string
|
|
expected []string
|
|
canariesCount int
|
|
taskGroupCount int
|
|
req *VolumeRequest
|
|
}{
|
|
{
|
|
name: "host volume with empty source",
|
|
expected: []string{"volume has an empty source"},
|
|
req: &VolumeRequest{
|
|
Type: VolumeTypeHost,
|
|
},
|
|
},
|
|
{
|
|
name: "host volume with CSI volume config",
|
|
expected: []string{
|
|
"host volumes cannot have an access mode",
|
|
"host volumes cannot have an attachment mode",
|
|
"host volumes cannot have mount options",
|
|
"volume cannot be per_alloc for system or sysbatch jobs",
|
|
"volume cannot be per_alloc when canaries are in use",
|
|
},
|
|
canariesCount: 1,
|
|
req: &VolumeRequest{
|
|
Type: VolumeTypeHost,
|
|
ReadOnly: false,
|
|
AccessMode: CSIVolumeAccessModeSingleNodeReader,
|
|
AttachmentMode: CSIVolumeAttachmentModeBlockDevice,
|
|
MountOptions: &CSIMountOptions{
|
|
FSType: "ext4",
|
|
MountFlags: []string{"ro"},
|
|
},
|
|
PerAlloc: true,
|
|
},
|
|
},
|
|
{
|
|
name: "CSI volume multi-reader-single-writer access mode",
|
|
expected: []string{
|
|
"volume with multi-node-single-writer access mode allows only one writer",
|
|
},
|
|
taskGroupCount: 2,
|
|
req: &VolumeRequest{
|
|
Type: VolumeTypeCSI,
|
|
AccessMode: CSIVolumeAccessModeMultiNodeSingleWriter,
|
|
},
|
|
},
|
|
{
|
|
name: "CSI volume single reader access mode",
|
|
expected: []string{
|
|
"volume with single-node-reader-only access mode allows only one reader",
|
|
},
|
|
taskGroupCount: 2,
|
|
req: &VolumeRequest{
|
|
Type: VolumeTypeCSI,
|
|
AccessMode: CSIVolumeAccessModeSingleNodeReader,
|
|
ReadOnly: true,
|
|
},
|
|
},
|
|
{
|
|
name: "CSI volume per-alloc with canaries",
|
|
expected: []string{
|
|
"volume cannot be per_alloc for system or sysbatch jobs",
|
|
"volume cannot be per_alloc when canaries are in use",
|
|
},
|
|
canariesCount: 1,
|
|
req: &VolumeRequest{
|
|
Type: VolumeTypeCSI,
|
|
PerAlloc: true,
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
err := tc.req.Validate(JobTypeSystem, tc.taskGroupCount, tc.canariesCount)
|
|
for _, expected := range tc.expected {
|
|
require.Contains(t, err.Error(), expected)
|
|
}
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
func TestVolumeRequest_Equal(t *testing.T) {
|
|
ci.Parallel(t)
|
|
|
|
must.Equal[*VolumeRequest](t, nil, nil)
|
|
must.NotEqual[*VolumeRequest](t, nil, new(VolumeRequest))
|
|
|
|
must.StructEqual(t, &VolumeRequest{
|
|
Name: "name",
|
|
Type: "type",
|
|
Source: "source",
|
|
ReadOnly: true,
|
|
AccessMode: "access",
|
|
AttachmentMode: "attachment",
|
|
MountOptions: &CSIMountOptions{
|
|
FSType: "fs1",
|
|
MountFlags: []string{"flag1"},
|
|
},
|
|
PerAlloc: true,
|
|
}, []must.Tweak[*VolumeRequest]{{
|
|
Field: "Name",
|
|
Apply: func(vr *VolumeRequest) { vr.Name = "name2" },
|
|
}, {
|
|
Field: "Type",
|
|
Apply: func(vr *VolumeRequest) { vr.Type = "type2" },
|
|
}, {
|
|
Field: "Source",
|
|
Apply: func(vr *VolumeRequest) { vr.Source = "source2" },
|
|
}, {
|
|
Field: "ReadOnly",
|
|
Apply: func(vr *VolumeRequest) { vr.ReadOnly = false },
|
|
}, {
|
|
Field: "AccessMode",
|
|
Apply: func(vr *VolumeRequest) { vr.AccessMode = "access2" },
|
|
}, {
|
|
Field: "AttachmentMode",
|
|
Apply: func(vr *VolumeRequest) { vr.AttachmentMode = "attachment2" },
|
|
}, {
|
|
Field: "MountOptions",
|
|
Apply: func(vr *VolumeRequest) { vr.MountOptions = nil },
|
|
}, {
|
|
Field: "PerAlloc",
|
|
Apply: func(vr *VolumeRequest) { vr.PerAlloc = false },
|
|
}})
|
|
}
|
|
|
|
func TestVolumeMount_Equal(t *testing.T) {
|
|
ci.Parallel(t)
|
|
|
|
must.Equal[*VolumeMount](t, nil, nil)
|
|
must.NotEqual[*VolumeMount](t, nil, new(VolumeMount))
|
|
|
|
must.StructEqual(t, &VolumeMount{
|
|
Volume: "volume",
|
|
Destination: "destination",
|
|
ReadOnly: true,
|
|
PropagationMode: "mode",
|
|
}, []must.Tweak[*VolumeMount]{{
|
|
Field: "Volume",
|
|
Apply: func(vm *VolumeMount) { vm.Volume = "vol2" },
|
|
}, {
|
|
Field: "Destination",
|
|
Apply: func(vm *VolumeMount) { vm.Destination = "dest2" },
|
|
}, {
|
|
Field: "ReadOnly",
|
|
Apply: func(vm *VolumeMount) { vm.ReadOnly = false },
|
|
}, {
|
|
Field: "PropogationMode",
|
|
Apply: func(vm *VolumeMount) { vm.PropagationMode = "mode2" },
|
|
}})
|
|
}
|