github.com/stuarqi/moby@v1.13.1/opts/mount_test.go (about) 1 package opts 2 3 import ( 4 "os" 5 "testing" 6 7 mounttypes "github.com/docker/docker/api/types/mount" 8 "github.com/docker/docker/pkg/testutil/assert" 9 ) 10 11 func TestMountOptString(t *testing.T) { 12 mount := MountOpt{ 13 values: []mounttypes.Mount{ 14 { 15 Type: mounttypes.TypeBind, 16 Source: "/home/path", 17 Target: "/target", 18 }, 19 { 20 Type: mounttypes.TypeVolume, 21 Source: "foo", 22 Target: "/target/foo", 23 }, 24 }, 25 } 26 expected := "bind /home/path /target, volume foo /target/foo" 27 assert.Equal(t, mount.String(), expected) 28 } 29 30 func TestMountOptSetBindNoErrorBind(t *testing.T) { 31 for _, testcase := range []string{ 32 // tests several aliases that should have same result. 33 "type=bind,target=/target,source=/source", 34 "type=bind,src=/source,dst=/target", 35 "type=bind,source=/source,dst=/target", 36 "type=bind,src=/source,target=/target", 37 } { 38 var mount MountOpt 39 40 assert.NilError(t, mount.Set(testcase)) 41 42 mounts := mount.Value() 43 assert.Equal(t, len(mounts), 1) 44 assert.Equal(t, mounts[0], mounttypes.Mount{ 45 Type: mounttypes.TypeBind, 46 Source: "/source", 47 Target: "/target", 48 }) 49 } 50 } 51 52 func TestMountOptSetVolumeNoError(t *testing.T) { 53 for _, testcase := range []string{ 54 // tests several aliases that should have same result. 55 "type=volume,target=/target,source=/source", 56 "type=volume,src=/source,dst=/target", 57 "type=volume,source=/source,dst=/target", 58 "type=volume,src=/source,target=/target", 59 } { 60 var mount MountOpt 61 62 assert.NilError(t, mount.Set(testcase)) 63 64 mounts := mount.Value() 65 assert.Equal(t, len(mounts), 1) 66 assert.Equal(t, mounts[0], mounttypes.Mount{ 67 Type: mounttypes.TypeVolume, 68 Source: "/source", 69 Target: "/target", 70 }) 71 } 72 } 73 74 // TestMountOptDefaultType ensures that a mount without the type defaults to a 75 // volume mount. 76 func TestMountOptDefaultType(t *testing.T) { 77 var mount MountOpt 78 assert.NilError(t, mount.Set("target=/target,source=/foo")) 79 assert.Equal(t, mount.values[0].Type, mounttypes.TypeVolume) 80 } 81 82 func TestMountOptSetErrorNoTarget(t *testing.T) { 83 var mount MountOpt 84 assert.Error(t, mount.Set("type=volume,source=/foo"), "target is required") 85 } 86 87 func TestMountOptSetErrorInvalidKey(t *testing.T) { 88 var mount MountOpt 89 assert.Error(t, mount.Set("type=volume,bogus=foo"), "unexpected key 'bogus'") 90 } 91 92 func TestMountOptSetErrorInvalidField(t *testing.T) { 93 var mount MountOpt 94 assert.Error(t, mount.Set("type=volume,bogus"), "invalid field 'bogus'") 95 } 96 97 func TestMountOptSetErrorInvalidReadOnly(t *testing.T) { 98 var mount MountOpt 99 assert.Error(t, mount.Set("type=volume,readonly=no"), "invalid value for readonly: no") 100 assert.Error(t, mount.Set("type=volume,readonly=invalid"), "invalid value for readonly: invalid") 101 } 102 103 func TestMountOptDefaultEnableReadOnly(t *testing.T) { 104 var m MountOpt 105 assert.NilError(t, m.Set("type=bind,target=/foo,source=/foo")) 106 assert.Equal(t, m.values[0].ReadOnly, false) 107 108 m = MountOpt{} 109 assert.NilError(t, m.Set("type=bind,target=/foo,source=/foo,readonly")) 110 assert.Equal(t, m.values[0].ReadOnly, true) 111 112 m = MountOpt{} 113 assert.NilError(t, m.Set("type=bind,target=/foo,source=/foo,readonly=1")) 114 assert.Equal(t, m.values[0].ReadOnly, true) 115 116 m = MountOpt{} 117 assert.NilError(t, m.Set("type=bind,target=/foo,source=/foo,readonly=true")) 118 assert.Equal(t, m.values[0].ReadOnly, true) 119 120 m = MountOpt{} 121 assert.NilError(t, m.Set("type=bind,target=/foo,source=/foo,readonly=0")) 122 assert.Equal(t, m.values[0].ReadOnly, false) 123 } 124 125 func TestMountOptVolumeNoCopy(t *testing.T) { 126 var m MountOpt 127 assert.NilError(t, m.Set("type=volume,target=/foo,volume-nocopy")) 128 assert.Equal(t, m.values[0].Source, "") 129 130 m = MountOpt{} 131 assert.NilError(t, m.Set("type=volume,target=/foo,source=foo")) 132 assert.Equal(t, m.values[0].VolumeOptions == nil, true) 133 134 m = MountOpt{} 135 assert.NilError(t, m.Set("type=volume,target=/foo,source=foo,volume-nocopy=true")) 136 assert.Equal(t, m.values[0].VolumeOptions != nil, true) 137 assert.Equal(t, m.values[0].VolumeOptions.NoCopy, true) 138 139 m = MountOpt{} 140 assert.NilError(t, m.Set("type=volume,target=/foo,source=foo,volume-nocopy")) 141 assert.Equal(t, m.values[0].VolumeOptions != nil, true) 142 assert.Equal(t, m.values[0].VolumeOptions.NoCopy, true) 143 144 m = MountOpt{} 145 assert.NilError(t, m.Set("type=volume,target=/foo,source=foo,volume-nocopy=1")) 146 assert.Equal(t, m.values[0].VolumeOptions != nil, true) 147 assert.Equal(t, m.values[0].VolumeOptions.NoCopy, true) 148 } 149 150 func TestMountOptTypeConflict(t *testing.T) { 151 var m MountOpt 152 assert.Error(t, m.Set("type=bind,target=/foo,source=/foo,volume-nocopy=true"), "cannot mix") 153 assert.Error(t, m.Set("type=volume,target=/foo,source=/foo,bind-propagation=rprivate"), "cannot mix") 154 } 155 156 func TestMountOptSetTmpfsNoError(t *testing.T) { 157 for _, testcase := range []string{ 158 // tests several aliases that should have same result. 159 "type=tmpfs,target=/target,tmpfs-size=1m,tmpfs-mode=0700", 160 "type=tmpfs,target=/target,tmpfs-size=1MB,tmpfs-mode=700", 161 } { 162 var mount MountOpt 163 164 assert.NilError(t, mount.Set(testcase)) 165 166 mounts := mount.Value() 167 assert.Equal(t, len(mounts), 1) 168 assert.DeepEqual(t, mounts[0], mounttypes.Mount{ 169 Type: mounttypes.TypeTmpfs, 170 Target: "/target", 171 TmpfsOptions: &mounttypes.TmpfsOptions{ 172 SizeBytes: 1024 * 1024, // not 1000 * 1000 173 Mode: os.FileMode(0700), 174 }, 175 }) 176 } 177 } 178 179 func TestMountOptSetTmpfsError(t *testing.T) { 180 var m MountOpt 181 assert.Error(t, m.Set("type=tmpfs,target=/foo,tmpfs-size=foo"), "invalid value for tmpfs-size") 182 assert.Error(t, m.Set("type=tmpfs,target=/foo,tmpfs-mode=foo"), "invalid value for tmpfs-mode") 183 assert.Error(t, m.Set("type=tmpfs"), "target is required") 184 }