github.com/NVIDIA/aistore@v1.3.23-0.20240517131212-7df6609be51d/fs/mountfs_test.go (about) 1 // Package fs provides mountpath and FQN abstractions and methods to resolve/map stored content 2 /* 3 * Copyright (c) 2018-2024, NVIDIA CORPORATION. All rights reserved. 4 */ 5 package fs_test 6 7 import ( 8 "testing" 9 10 "github.com/NVIDIA/aistore/api/apc" 11 "github.com/NVIDIA/aistore/cmn" 12 "github.com/NVIDIA/aistore/cmn/cos" 13 "github.com/NVIDIA/aistore/cmn/fname" 14 "github.com/NVIDIA/aistore/core/mock" 15 "github.com/NVIDIA/aistore/fs" 16 "github.com/NVIDIA/aistore/tools" 17 "github.com/NVIDIA/aistore/tools/tassert" 18 "github.com/NVIDIA/aistore/tools/trand" 19 ) 20 21 func TestMountpathAddNonExisting(t *testing.T) { 22 initFS() 23 24 _, err := fs.Add("/nonexistingpath", "") 25 tassert.Errorf(t, err != nil, "adding non-existing mountpath succeeded") 26 27 tools.AssertMountpathCount(t, 0, 0) 28 } 29 30 func TestMountpathAddExisting(t *testing.T) { 31 initFS() 32 33 tools.AddMpath(t, "/tmp/abc") 34 tools.AssertMountpathCount(t, 1, 0) 35 } 36 37 func TestMountpathAddValid(t *testing.T) { 38 initFS() 39 40 mpaths := []string{"/tmp/clouder", "/tmp/locals/abc", "/tmp/locals/err"} 41 for _, mpath := range mpaths { 42 tools.AddMpath(t, mpath) 43 } 44 tools.AssertMountpathCount(t, 3, 0) 45 46 for _, mpath := range mpaths { 47 removedMP, err := fs.Remove(mpath) 48 tassert.Errorf(t, err == nil, "removing valid mountpath %q failed, err: %v", mpath, err) 49 tassert.Errorf(t, removedMP != nil, "expected remove to return removed mountpath") 50 } 51 tools.AssertMountpathCount(t, 0, 0) 52 } 53 54 func TestMountpathAddIncorrect(t *testing.T) { 55 initFS() 56 57 _, err := fs.Add("tmp/not/absolute/path", "") 58 tassert.Errorf(t, err != nil, "expected adding incorrect mountpath to fail") 59 60 tools.AssertMountpathCount(t, 0, 0) 61 } 62 63 func TestMountpathAddAlreadyAdded(t *testing.T) { 64 initFS() 65 66 mpath := "/tmp/abc" 67 tools.AddMpath(t, mpath) 68 tools.AssertMountpathCount(t, 1, 0) 69 70 _, err := fs.Add(mpath, "daeID") 71 tassert.Errorf(t, err != nil, "adding already added mountpath succeeded") 72 73 tools.AssertMountpathCount(t, 1, 0) 74 } 75 76 func TestMountpathRemoveNonExisting(t *testing.T) { 77 initFS() 78 79 removedMP, err := fs.Remove("/nonexistingpath") 80 tassert.Errorf(t, err != nil, "removing non-existing mountpath succeeded") 81 tassert.Errorf(t, removedMP == nil, "expected no mountpath removed") 82 83 tools.AssertMountpathCount(t, 0, 0) 84 } 85 86 func TestMountpathRemoveExisting(t *testing.T) { 87 initFS() 88 89 mpath := "/tmp/abc" 90 tools.AddMpath(t, mpath) 91 92 removedMP, err := fs.Remove(mpath) 93 tassert.CheckError(t, err) 94 tassert.Errorf(t, removedMP != nil, "expected remove to return removed mountpath") 95 96 tools.AssertMountpathCount(t, 0, 0) 97 } 98 99 func TestMountpathRemoveDisabled(t *testing.T) { 100 initFS() 101 102 mpath := "/tmp/abc" 103 tools.AddMpath(t, mpath) 104 105 _, err := fs.Disable(mpath) 106 tassert.CheckFatal(t, err) 107 tools.AssertMountpathCount(t, 0, 1) 108 109 removedMP, err := fs.Remove(mpath) 110 tassert.CheckError(t, err) 111 tassert.Errorf(t, removedMP != nil, "expected remove to return removed mountpath") 112 113 tools.AssertMountpathCount(t, 0, 0) 114 } 115 116 func TestMountpathDisableNonExisting(t *testing.T) { 117 initFS() 118 119 _, err := fs.Disable("/tmp") 120 tassert.Errorf(t, err != nil, "disabling non existing mountpath should not be successful") 121 122 tools.AssertMountpathCount(t, 0, 0) 123 } 124 125 func TestMountpathDisableExisting(t *testing.T) { 126 initFS() 127 128 mpath := "/tmp/abc" 129 tools.AddMpath(t, mpath) 130 131 disabledMP, err := fs.Disable(mpath) 132 tassert.CheckFatal(t, err) 133 tassert.Errorf(t, disabledMP != nil, "disabling was not successful") 134 135 tools.AssertMountpathCount(t, 0, 1) 136 } 137 138 func TestMountpathDisableAlreadyDisabled(t *testing.T) { 139 initFS() 140 141 mpath := "/tmp/abc" 142 tools.AddMpath(t, mpath) 143 144 disabledMP, err := fs.Disable(mpath) 145 tassert.CheckFatal(t, err) 146 tassert.Errorf(t, disabledMP != nil, "disabling was not successful") 147 148 disabledMP, err = fs.Disable(mpath) 149 tassert.CheckFatal(t, err) 150 tassert.Errorf(t, disabledMP == nil, "already disabled mountpath should not be disabled again") 151 152 tools.AssertMountpathCount(t, 0, 1) 153 } 154 155 func TestMountpathEnableNonExisting(t *testing.T) { 156 fs.TestNew(nil) 157 _, err := fs.Enable("/tmp") 158 tassert.Errorf(t, err != nil, "enabling nonexisting mountpath should end with error") 159 160 tools.AssertMountpathCount(t, 0, 0) 161 } 162 163 func TestMountpathEnableExistingButNotDisabled(t *testing.T) { 164 initFS() 165 166 mpath := "/tmp/abc" 167 tools.AddMpath(t, mpath) 168 enabledMP, err := fs.Enable(mpath) 169 tassert.CheckFatal(t, err) 170 tassert.Errorf(t, enabledMP == nil, "already enabled mountpath should not be enabled again") 171 172 tools.AssertMountpathCount(t, 1, 0) 173 } 174 175 func TestMountpathEnableExistingAndDisabled(t *testing.T) { 176 initFS() 177 178 mpath := "/tmp/abc" 179 tools.AddMpath(t, mpath) 180 181 disabledMP, err := fs.Disable(mpath) 182 tassert.CheckFatal(t, err) 183 tassert.Errorf(t, disabledMP != nil, "disabling was not successful") 184 185 enabled, err := fs.Enable(mpath) 186 tassert.CheckFatal(t, err) 187 tassert.Errorf(t, enabled != nil, "enabling was not successful") 188 189 tools.AssertMountpathCount(t, 1, 0) 190 } 191 192 func TestMountpathEnableAlreadyEnabled(t *testing.T) { 193 initFS() 194 195 mpath := "/tmp/abc" 196 tools.AddMpath(t, mpath) 197 198 disabledMP, err := fs.Disable(mpath) 199 tassert.CheckFatal(t, err) 200 tassert.Errorf(t, disabledMP != nil, "disabling was not successful") 201 202 tools.AssertMountpathCount(t, 0, 1) 203 204 enabledMP, err := fs.Enable(mpath) 205 tassert.CheckFatal(t, err) 206 tassert.Errorf(t, enabledMP != nil, "enabling was not successful") 207 208 enabledMP, err = fs.Enable(mpath) 209 tassert.CheckFatal(t, err) 210 tassert.Errorf(t, enabledMP == nil, "enabling already enabled mountpath should not be successful") 211 212 tools.AssertMountpathCount(t, 1, 0) 213 } 214 215 func TestMountpathsAddMultipleWithSameFSID(t *testing.T) { 216 fs.TestNew(mock.NewIOS()) 217 218 mpath := "/tmp/abc" 219 tools.AddMpath(t, mpath) 220 221 _, err := fs.Add("/", "") 222 tassert.Errorf(t, err != nil, "expected adding path with same FSID to be unsuccessful") 223 224 tools.AssertMountpathCount(t, 1, 0) 225 } 226 227 func TestMountpathAddAndDisableMultiple(t *testing.T) { 228 initFS() 229 230 mp1, mp2 := "/tmp/mp1", "/tmp/mp2" 231 tools.AddMpath(t, mp1) 232 tools.AddMpath(t, mp2) 233 234 tools.AssertMountpathCount(t, 2, 0) 235 236 disabledMP, err := fs.Disable(mp1) 237 tassert.CheckFatal(t, err) 238 tassert.Errorf(t, disabledMP != nil, "disabling was not successful") 239 tools.AssertMountpathCount(t, 1, 1) 240 } 241 242 func TestMoveToDeleted(t *testing.T) { 243 initFS() 244 245 mpath := t.TempDir() 246 tools.AddMpath(t, mpath) 247 248 mpaths := fs.GetAvail() 249 mi := mpaths[mpath] 250 251 // Initially .$deleted directory should not exist. 252 tools.CheckPathNotExists(t, mi.DeletedRoot()) 253 254 // Removing path that don't exist is still good. 255 err := mi.MoveToDeleted("/path/to/wonderland") 256 tassert.CheckFatal(t, err) 257 258 for range 5 { 259 topDir, _ := tools.PrepareDirTree(t, tools.DirTreeDesc{ 260 Dirs: 10, 261 Files: 10, 262 Depth: 2, 263 Empty: false, 264 }) 265 266 tools.CheckPathExists(t, topDir, true /*dir*/) 267 268 err = mi.MoveToDeleted(topDir) 269 tassert.CheckFatal(t, err) 270 271 tools.CheckPathNotExists(t, topDir) 272 tools.CheckPathExists(t, mi.DeletedRoot(), true /*dir*/) 273 } 274 } 275 276 func TestMoveMarkers(t *testing.T) { 277 tests := []struct { 278 name string 279 f func(string, ...func()) (*fs.Mountpath, error) 280 }{ 281 {name: "remove", f: fs.Remove}, 282 {name: "disable", f: fs.Disable}, 283 } 284 for _, test := range tests { 285 t.Run(test.name, func(t *testing.T) { 286 initFS() 287 288 mpath := createMountpath(t) 289 290 fatalErr, writeErr := fs.PersistMarker(fname.RebalanceMarker) 291 tassert.CheckFatal(t, fatalErr) 292 tassert.CheckFatal(t, writeErr) 293 294 createMountpath(t) 295 296 exists := fs.MarkerExists(fname.RebalanceMarker) 297 tassert.Fatalf(t, exists, "marker does not exist") 298 299 _, err := test.f(mpath.Path) 300 tassert.CheckFatal(t, err) 301 302 exists = fs.MarkerExists(fname.RebalanceMarker) 303 tassert.Fatalf(t, exists, "marker does not exist") 304 }) 305 } 306 } 307 308 func initFS() { 309 fs.TestNew(mock.NewIOS()) 310 } 311 312 func createMountpath(t *testing.T) *fs.Mountpath { 313 mpathDir := t.TempDir() 314 tools.AddMpath(t, mpathDir) 315 mpaths := fs.GetAvail() 316 return mpaths[mpathDir] 317 } 318 319 func BenchmarkMakePathFQN(b *testing.B) { 320 var ( 321 bck = cmn.Bck{ 322 Name: "bck", 323 Provider: apc.Azure, 324 Ns: cmn.Ns{Name: "name", UUID: "uuid"}, 325 } 326 mi = fs.Mountpath{Path: trand.String(200)} 327 objName = trand.String(15) 328 ) 329 330 b.ReportAllocs() 331 b.ResetTimer() 332 for range b.N { 333 s := mi.MakePathFQN(&bck, fs.ObjectType, objName) 334 cos.Assert(s != "") 335 } 336 }