github.com/ali-iotechsys/cli@v20.10.0+incompatible/cli/compose/convert/volume_test.go (about) 1 package convert 2 3 import ( 4 "testing" 5 6 composetypes "github.com/docker/cli/cli/compose/types" 7 "github.com/docker/docker/api/types/mount" 8 "gotest.tools/v3/assert" 9 is "gotest.tools/v3/assert/cmp" 10 ) 11 12 func TestConvertVolumeToMountAnonymousVolume(t *testing.T) { 13 config := composetypes.ServiceVolumeConfig{ 14 Type: "volume", 15 Target: "/foo/bar", 16 } 17 expected := mount.Mount{ 18 Type: mount.TypeVolume, 19 Target: "/foo/bar", 20 } 21 mount, err := convertVolumeToMount(config, volumes{}, NewNamespace("foo")) 22 assert.NilError(t, err) 23 assert.Check(t, is.DeepEqual(expected, mount)) 24 } 25 26 func TestConvertVolumeToMountAnonymousBind(t *testing.T) { 27 config := composetypes.ServiceVolumeConfig{ 28 Type: "bind", 29 Target: "/foo/bar", 30 Bind: &composetypes.ServiceVolumeBind{ 31 Propagation: "slave", 32 }, 33 } 34 _, err := convertVolumeToMount(config, volumes{}, NewNamespace("foo")) 35 assert.Error(t, err, "invalid bind source, source cannot be empty") 36 } 37 38 func TestConvertVolumeToMountUnapprovedType(t *testing.T) { 39 config := composetypes.ServiceVolumeConfig{ 40 Type: "foo", 41 Target: "/foo/bar", 42 } 43 _, err := convertVolumeToMount(config, volumes{}, NewNamespace("foo")) 44 assert.Error(t, err, "volume type must be volume, bind, tmpfs or npipe") 45 } 46 47 func TestConvertVolumeToMountConflictingOptionsBindInVolume(t *testing.T) { 48 namespace := NewNamespace("foo") 49 50 config := composetypes.ServiceVolumeConfig{ 51 Type: "volume", 52 Source: "foo", 53 Target: "/target", 54 Bind: &composetypes.ServiceVolumeBind{ 55 Propagation: "slave", 56 }, 57 } 58 _, err := convertVolumeToMount(config, volumes{}, namespace) 59 assert.Error(t, err, "bind options are incompatible with type volume") 60 } 61 62 func TestConvertVolumeToMountConflictingOptionsTmpfsInVolume(t *testing.T) { 63 namespace := NewNamespace("foo") 64 65 config := composetypes.ServiceVolumeConfig{ 66 Type: "volume", 67 Source: "foo", 68 Target: "/target", 69 Tmpfs: &composetypes.ServiceVolumeTmpfs{ 70 Size: 1000, 71 }, 72 } 73 _, err := convertVolumeToMount(config, volumes{}, namespace) 74 assert.Error(t, err, "tmpfs options are incompatible with type volume") 75 } 76 77 func TestConvertVolumeToMountConflictingOptionsVolumeInBind(t *testing.T) { 78 namespace := NewNamespace("foo") 79 80 config := composetypes.ServiceVolumeConfig{ 81 Type: "bind", 82 Source: "/foo", 83 Target: "/target", 84 Volume: &composetypes.ServiceVolumeVolume{ 85 NoCopy: true, 86 }, 87 } 88 _, err := convertVolumeToMount(config, volumes{}, namespace) 89 assert.Error(t, err, "volume options are incompatible with type bind") 90 } 91 92 func TestConvertVolumeToMountConflictingOptionsTmpfsInBind(t *testing.T) { 93 namespace := NewNamespace("foo") 94 95 config := composetypes.ServiceVolumeConfig{ 96 Type: "bind", 97 Source: "/foo", 98 Target: "/target", 99 Tmpfs: &composetypes.ServiceVolumeTmpfs{ 100 Size: 1000, 101 }, 102 } 103 _, err := convertVolumeToMount(config, volumes{}, namespace) 104 assert.Error(t, err, "tmpfs options are incompatible with type bind") 105 } 106 107 func TestConvertVolumeToMountConflictingOptionsBindInTmpfs(t *testing.T) { 108 namespace := NewNamespace("foo") 109 110 config := composetypes.ServiceVolumeConfig{ 111 Type: "tmpfs", 112 Target: "/target", 113 Bind: &composetypes.ServiceVolumeBind{ 114 Propagation: "slave", 115 }, 116 } 117 _, err := convertVolumeToMount(config, volumes{}, namespace) 118 assert.Error(t, err, "bind options are incompatible with type tmpfs") 119 } 120 121 func TestConvertVolumeToMountConflictingOptionsVolumeInTmpfs(t *testing.T) { 122 namespace := NewNamespace("foo") 123 124 config := composetypes.ServiceVolumeConfig{ 125 Type: "tmpfs", 126 Target: "/target", 127 Volume: &composetypes.ServiceVolumeVolume{ 128 NoCopy: true, 129 }, 130 } 131 _, err := convertVolumeToMount(config, volumes{}, namespace) 132 assert.Error(t, err, "volume options are incompatible with type tmpfs") 133 } 134 135 func TestConvertVolumeToMountNamedVolume(t *testing.T) { 136 stackVolumes := volumes{ 137 "normal": composetypes.VolumeConfig{ 138 Driver: "glusterfs", 139 DriverOpts: map[string]string{ 140 "opt": "value", 141 }, 142 Labels: map[string]string{ 143 "something": "labeled", 144 }, 145 }, 146 } 147 namespace := NewNamespace("foo") 148 expected := mount.Mount{ 149 Type: mount.TypeVolume, 150 Source: "foo_normal", 151 Target: "/foo", 152 ReadOnly: true, 153 VolumeOptions: &mount.VolumeOptions{ 154 Labels: map[string]string{ 155 LabelNamespace: "foo", 156 "something": "labeled", 157 }, 158 DriverConfig: &mount.Driver{ 159 Name: "glusterfs", 160 Options: map[string]string{ 161 "opt": "value", 162 }, 163 }, 164 NoCopy: true, 165 }, 166 } 167 config := composetypes.ServiceVolumeConfig{ 168 Type: "volume", 169 Source: "normal", 170 Target: "/foo", 171 ReadOnly: true, 172 Volume: &composetypes.ServiceVolumeVolume{ 173 NoCopy: true, 174 }, 175 } 176 mount, err := convertVolumeToMount(config, stackVolumes, namespace) 177 assert.NilError(t, err) 178 assert.Check(t, is.DeepEqual(expected, mount)) 179 } 180 181 func TestConvertVolumeToMountNamedVolumeWithNameCustomizd(t *testing.T) { 182 stackVolumes := volumes{ 183 "normal": composetypes.VolumeConfig{ 184 Name: "user_specified_name", 185 Driver: "vsphere", 186 DriverOpts: map[string]string{ 187 "opt": "value", 188 }, 189 Labels: map[string]string{ 190 "something": "labeled", 191 }, 192 }, 193 } 194 namespace := NewNamespace("foo") 195 expected := mount.Mount{ 196 Type: mount.TypeVolume, 197 Source: "user_specified_name", 198 Target: "/foo", 199 ReadOnly: true, 200 VolumeOptions: &mount.VolumeOptions{ 201 Labels: map[string]string{ 202 LabelNamespace: "foo", 203 "something": "labeled", 204 }, 205 DriverConfig: &mount.Driver{ 206 Name: "vsphere", 207 Options: map[string]string{ 208 "opt": "value", 209 }, 210 }, 211 NoCopy: true, 212 }, 213 } 214 config := composetypes.ServiceVolumeConfig{ 215 Type: "volume", 216 Source: "normal", 217 Target: "/foo", 218 ReadOnly: true, 219 Volume: &composetypes.ServiceVolumeVolume{ 220 NoCopy: true, 221 }, 222 } 223 mount, err := convertVolumeToMount(config, stackVolumes, namespace) 224 assert.NilError(t, err) 225 assert.Check(t, is.DeepEqual(expected, mount)) 226 } 227 228 func TestConvertVolumeToMountNamedVolumeExternal(t *testing.T) { 229 stackVolumes := volumes{ 230 "outside": composetypes.VolumeConfig{ 231 Name: "special", 232 External: composetypes.External{External: true}, 233 }, 234 } 235 namespace := NewNamespace("foo") 236 expected := mount.Mount{ 237 Type: mount.TypeVolume, 238 Source: "special", 239 Target: "/foo", 240 VolumeOptions: &mount.VolumeOptions{NoCopy: false}, 241 } 242 config := composetypes.ServiceVolumeConfig{ 243 Type: "volume", 244 Source: "outside", 245 Target: "/foo", 246 } 247 mount, err := convertVolumeToMount(config, stackVolumes, namespace) 248 assert.NilError(t, err) 249 assert.Check(t, is.DeepEqual(expected, mount)) 250 } 251 252 func TestConvertVolumeToMountNamedVolumeExternalNoCopy(t *testing.T) { 253 stackVolumes := volumes{ 254 "outside": composetypes.VolumeConfig{ 255 Name: "special", 256 External: composetypes.External{External: true}, 257 }, 258 } 259 namespace := NewNamespace("foo") 260 expected := mount.Mount{ 261 Type: mount.TypeVolume, 262 Source: "special", 263 Target: "/foo", 264 VolumeOptions: &mount.VolumeOptions{ 265 NoCopy: true, 266 }, 267 } 268 config := composetypes.ServiceVolumeConfig{ 269 Type: "volume", 270 Source: "outside", 271 Target: "/foo", 272 Volume: &composetypes.ServiceVolumeVolume{ 273 NoCopy: true, 274 }, 275 } 276 mount, err := convertVolumeToMount(config, stackVolumes, namespace) 277 assert.NilError(t, err) 278 assert.Check(t, is.DeepEqual(expected, mount)) 279 } 280 281 func TestConvertVolumeToMountBind(t *testing.T) { 282 stackVolumes := volumes{} 283 namespace := NewNamespace("foo") 284 expected := mount.Mount{ 285 Type: mount.TypeBind, 286 Source: "/bar", 287 Target: "/foo", 288 ReadOnly: true, 289 BindOptions: &mount.BindOptions{Propagation: mount.PropagationShared}, 290 } 291 config := composetypes.ServiceVolumeConfig{ 292 Type: "bind", 293 Source: "/bar", 294 Target: "/foo", 295 ReadOnly: true, 296 Bind: &composetypes.ServiceVolumeBind{Propagation: "shared"}, 297 } 298 mount, err := convertVolumeToMount(config, stackVolumes, namespace) 299 assert.NilError(t, err) 300 assert.Check(t, is.DeepEqual(expected, mount)) 301 } 302 303 func TestConvertVolumeToMountVolumeDoesNotExist(t *testing.T) { 304 namespace := NewNamespace("foo") 305 config := composetypes.ServiceVolumeConfig{ 306 Type: "volume", 307 Source: "unknown", 308 Target: "/foo", 309 ReadOnly: true, 310 } 311 _, err := convertVolumeToMount(config, volumes{}, namespace) 312 assert.Error(t, err, "undefined volume \"unknown\"") 313 } 314 315 func TestConvertTmpfsToMountVolume(t *testing.T) { 316 config := composetypes.ServiceVolumeConfig{ 317 Type: "tmpfs", 318 Target: "/foo/bar", 319 Tmpfs: &composetypes.ServiceVolumeTmpfs{ 320 Size: 1000, 321 }, 322 } 323 expected := mount.Mount{ 324 Type: mount.TypeTmpfs, 325 Target: "/foo/bar", 326 TmpfsOptions: &mount.TmpfsOptions{SizeBytes: 1000}, 327 } 328 mount, err := convertVolumeToMount(config, volumes{}, NewNamespace("foo")) 329 assert.NilError(t, err) 330 assert.Check(t, is.DeepEqual(expected, mount)) 331 } 332 333 func TestConvertTmpfsToMountVolumeWithSource(t *testing.T) { 334 config := composetypes.ServiceVolumeConfig{ 335 Type: "tmpfs", 336 Source: "/bar", 337 Target: "/foo/bar", 338 Tmpfs: &composetypes.ServiceVolumeTmpfs{ 339 Size: 1000, 340 }, 341 } 342 343 _, err := convertVolumeToMount(config, volumes{}, NewNamespace("foo")) 344 assert.Error(t, err, "invalid tmpfs source, source must be empty") 345 } 346 347 func TestConvertVolumeToMountAnonymousNpipe(t *testing.T) { 348 config := composetypes.ServiceVolumeConfig{ 349 Type: "npipe", 350 Source: `\\.\pipe\foo`, 351 Target: `\\.\pipe\foo`, 352 } 353 expected := mount.Mount{ 354 Type: mount.TypeNamedPipe, 355 Source: `\\.\pipe\foo`, 356 Target: `\\.\pipe\foo`, 357 } 358 mount, err := convertVolumeToMount(config, volumes{}, NewNamespace("foo")) 359 assert.NilError(t, err) 360 assert.Check(t, is.DeepEqual(expected, mount)) 361 }