github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/command/volume_register_test.go (about) 1 package command 2 3 import ( 4 "testing" 5 6 "github.com/hashicorp/hcl" 7 "github.com/hashicorp/nomad/api" 8 "github.com/hashicorp/nomad/ci" 9 "github.com/stretchr/testify/require" 10 ) 11 12 func TestVolumeDispatchParse(t *testing.T) { 13 ci.Parallel(t) 14 15 cases := []struct { 16 hcl string 17 t string 18 err string 19 }{{ 20 hcl: ` 21 type = "foo" 22 rando = "bar" 23 `, 24 t: "foo", 25 err: "", 26 }, { 27 hcl: `{"id": "foo", "type": "foo", "other": "bar"}`, 28 t: "foo", 29 err: "", 30 }} 31 32 for _, c := range cases { 33 t.Run(c.hcl, func(t *testing.T) { 34 _, s, err := parseVolumeType(c.hcl) 35 require.Equal(t, c.t, s) 36 if c.err == "" { 37 require.NoError(t, err) 38 } else { 39 require.Contains(t, err.Error(), c.err) 40 } 41 42 }) 43 } 44 } 45 46 func TestCSIVolumeDecode(t *testing.T) { 47 ci.Parallel(t) 48 49 cases := []struct { 50 name string 51 hcl string 52 expected *api.CSIVolume 53 err string 54 }{{ 55 name: "volume creation", 56 hcl: ` 57 id = "testvolume" 58 namespace = "prod" 59 name = "test" 60 type = "csi" 61 plugin_id = "myplugin" 62 63 capacity_min = "10 MiB" 64 capacity_max = "1G" 65 snapshot_id = "snap-12345" 66 67 mount_options { 68 fs_type = "ext4" 69 mount_flags = ["ro"] 70 } 71 72 secrets { 73 password = "xyzzy" 74 } 75 76 parameters { 77 skuname = "Premium_LRS" 78 } 79 80 capability { 81 access_mode = "single-node-writer" 82 attachment_mode = "file-system" 83 } 84 85 capability { 86 access_mode = "single-node-reader-only" 87 attachment_mode = "block-device" 88 } 89 90 topology_request { 91 preferred { 92 topology { segments {rack = "R1"} } 93 } 94 95 required { 96 topology { segments {rack = "R1"} } 97 topology { segments {rack = "R2", zone = "us-east-1a"} } 98 } 99 } 100 `, 101 expected: &api.CSIVolume{ 102 ID: "testvolume", 103 Namespace: "prod", 104 Name: "test", 105 PluginID: "myplugin", 106 SnapshotID: "snap-12345", 107 RequestedCapacityMin: 10485760, 108 RequestedCapacityMax: 1000000000, 109 RequestedCapabilities: []*api.CSIVolumeCapability{ 110 { 111 AccessMode: api.CSIVolumeAccessModeSingleNodeWriter, 112 AttachmentMode: api.CSIVolumeAttachmentModeFilesystem, 113 }, 114 { 115 AccessMode: api.CSIVolumeAccessModeSingleNodeReader, 116 AttachmentMode: api.CSIVolumeAttachmentModeBlockDevice, 117 }, 118 }, 119 MountOptions: &api.CSIMountOptions{ 120 FSType: "ext4", 121 MountFlags: []string{"ro"}, 122 }, 123 Parameters: map[string]string{"skuname": "Premium_LRS"}, 124 Secrets: map[string]string{"password": "xyzzy"}, 125 RequestedTopologies: &api.CSITopologyRequest{ 126 Required: []*api.CSITopology{ 127 {Segments: map[string]string{"rack": "R1"}}, 128 {Segments: map[string]string{"rack": "R2", "zone": "us-east-1a"}}, 129 }, 130 Preferred: []*api.CSITopology{ 131 {Segments: map[string]string{"rack": "R1"}}, 132 }, 133 }, 134 Topologies: nil, // this is left empty 135 }, 136 err: "", 137 }, { 138 name: "volume registration", 139 hcl: ` 140 id = "testvolume" 141 namespace = "prod" 142 external_id = "vol-12345" 143 name = "test" 144 type = "csi" 145 plugin_id = "myplugin" 146 capacity_min = "" # meaningless for registration 147 148 capability { 149 access_mode = "single-node-writer" 150 attachment_mode = "file-system" 151 } 152 153 topology_request { 154 # make sure we safely handle empty blocks even 155 # if they're invalid 156 preferred { 157 topology {} 158 topology { segments {} } 159 } 160 161 required { 162 topology { segments { rack = "R2", zone = "us-east-1a"} } 163 } 164 } 165 `, 166 expected: &api.CSIVolume{ 167 ID: "testvolume", 168 Namespace: "prod", 169 ExternalID: "vol-12345", 170 Name: "test", 171 PluginID: "myplugin", 172 RequestedCapabilities: []*api.CSIVolumeCapability{ 173 { 174 AccessMode: api.CSIVolumeAccessModeSingleNodeWriter, 175 AttachmentMode: api.CSIVolumeAttachmentModeFilesystem, 176 }, 177 }, 178 RequestedTopologies: &api.CSITopologyRequest{ 179 Required: []*api.CSITopology{ 180 {Segments: map[string]string{"rack": "R2", "zone": "us-east-1a"}}, 181 }, 182 Preferred: nil, 183 }, 184 Topologies: nil, 185 }, 186 err: "", 187 }, 188 } 189 190 for _, c := range cases { 191 t.Run(c.name, func(t *testing.T) { 192 ast, err := hcl.ParseString(c.hcl) 193 require.NoError(t, err) 194 vol, err := csiDecodeVolume(ast) 195 if c.err == "" { 196 require.NoError(t, err) 197 } else { 198 require.Contains(t, err.Error(), c.err) 199 } 200 require.Equal(t, c.expected, vol) 201 202 }) 203 204 } 205 }