github.com/swiftstack/ProxyFS@v0.0.0-20210203235616-4017c267d62f/inode/api_test.go (about) 1 // Copyright (c) 2015-2021, NVIDIA CORPORATION. 2 // SPDX-License-Identifier: Apache-2.0 3 4 package inode 5 6 import ( 7 "bytes" 8 "fmt" 9 "strings" 10 "testing" 11 "time" 12 13 "github.com/stretchr/testify/assert" 14 "github.com/swiftstack/ProxyFS/swiftclient" 15 "github.com/swiftstack/ProxyFS/utils" 16 ) 17 18 const durationToDelayOrSkew = "100ms" 19 20 var AllMetadataFields = map[string]bool{ 21 "InodeType": true, 22 "LinkCount": true, 23 "Size": true, 24 "CreationTime": true, 25 "ModificationTime": true, 26 "AccessTime": true, 27 "AttrChangeTime": true, 28 "NumWrites": true, 29 "InodeStreamNameSlice": true, 30 "Mode": true, 31 "UserID": true, 32 "GroupID": true, 33 } 34 35 var MetadataPermFields = map[string]bool{ 36 "Mode": true, 37 "UserID": true, 38 "GroupID": true, 39 } 40 41 var MetadataLinkCountField = map[string]bool{ 42 "LinkCount": true, 43 } 44 45 var MetadataCrTimeField = map[string]bool{ 46 "CreationTime": true, 47 } 48 49 var MetadataModTimeField = map[string]bool{ 50 "ModificationTime": true, 51 } 52 53 var MetadataSizeField = map[string]bool{ 54 "Size": true, 55 } 56 57 var MetadataTimeFields = map[string]bool{ 58 "CreationTime": true, 59 "AttrChangeTime": true, 60 "ModificationTime": true, 61 "AccessTime": true, 62 } 63 64 var MetadataNotAttrTimeFields = map[string]bool{ 65 "CreationTime": true, 66 "ModificationTime": true, 67 "AccessTime": true, 68 } 69 70 var MetadataNumWritesField = map[string]bool{ 71 "NumWrites": true, 72 } 73 74 func checkMetadata(t *testing.T, md *MetadataStruct, expMd *MetadataStruct, fieldsToCheck map[string]bool, errorPrefix string) { 75 for field := range fieldsToCheck { 76 switch field { 77 78 case "InodeType": 79 value := md.InodeType 80 expValue := expMd.InodeType 81 if value != expValue { 82 t.Fatalf("%s returned %s %v, expected %v", errorPrefix, field, value, expValue) 83 } 84 85 case "LinkCount": 86 value := md.LinkCount 87 expValue := expMd.LinkCount 88 if value != expValue { 89 t.Fatalf("%s returned %s %v, expected %v", errorPrefix, field, value, expValue) 90 } 91 92 case "Size": 93 value := md.Size 94 expValue := expMd.Size 95 if value != expValue { 96 t.Fatalf("%s returned %s %v, expected %v", errorPrefix, field, value, expValue) 97 } 98 99 case "CreationTime": 100 value := md.CreationTime 101 expValue := expMd.CreationTime 102 if !value.Equal(expValue) { 103 t.Fatalf("%s returned %s %v, expected %v", errorPrefix, field, value, expValue) 104 } 105 106 case "ModificationTime": 107 value := md.ModificationTime 108 expValue := expMd.ModificationTime 109 if !value.Equal(expValue) { 110 t.Fatalf("%s returned %s %v, expected %v", errorPrefix, field, value, expValue) 111 } 112 113 case "AccessTime": 114 value := md.AccessTime 115 expValue := expMd.AccessTime 116 if !value.Equal(expValue) { 117 t.Fatalf("%s returned %s %v, expected %v", errorPrefix, field, value, expValue) 118 } 119 120 case "AttrChangeTime": 121 value := md.AttrChangeTime 122 expValue := expMd.AttrChangeTime 123 if !value.Equal(expValue) { 124 t.Fatalf("%s returned %s %v, expected %v", errorPrefix, field, value, expValue) 125 } 126 127 case "NumWrites": 128 value := md.NumWrites 129 expValue := expMd.NumWrites 130 if value != expValue { 131 t.Fatalf("%s returned %s %v, expected %v", errorPrefix, field, value, expValue) 132 } 133 134 case "InodeStreamNameSlice": 135 value := len(md.InodeStreamNameSlice) 136 expValue := len(expMd.InodeStreamNameSlice) 137 if value != expValue { 138 t.Fatalf("%s returned %s %v, expected %v", errorPrefix, field, value, expValue) 139 } 140 for i, streamName := range md.InodeStreamNameSlice { 141 value := streamName 142 expValue := expMd.InodeStreamNameSlice[i] 143 if value != expValue { 144 t.Fatalf("%s returned %s[%d] %v, expected %v", errorPrefix, 145 field, i, value, expValue) 146 } 147 } 148 149 case "Mode": 150 value := md.Mode 151 expValue := expMd.Mode 152 153 // Add the file type to the expected mode 154 if md.InodeType == DirType { 155 expValue |= PosixModeDir 156 } else if md.InodeType == SymlinkType { 157 expValue |= PosixModeSymlink 158 } else if md.InodeType == FileType { 159 expValue |= PosixModeFile 160 } 161 if value != expValue { 162 t.Fatalf("%s returned %s %v, expected %v", errorPrefix, field, value, expValue) 163 } 164 165 case "UserID": 166 value := md.UserID 167 expValue := expMd.UserID 168 if value != expValue { 169 t.Fatalf("%s returned %s %v, expected %v", errorPrefix, field, value, expValue) 170 } 171 172 case "GroupID": 173 value := md.GroupID 174 expValue := expMd.GroupID 175 if value != expValue { 176 t.Fatalf("%s returned %s %v, expected %v", errorPrefix, field, value, expValue) 177 } 178 179 default: 180 // catch field name typos 181 t.Fatalf("%s specified unknown field '%v'", errorPrefix, field) 182 } 183 } 184 } 185 186 func checkMetadataTimeChanges(t *testing.T, oldMd *MetadataStruct, newMd *MetadataStruct, creationTimeShouldChange bool, modificationTimeShouldChange bool, accessTimeShouldChange bool, attrChangeTimeShouldChange bool, errorPrefix string) { 187 if creationTimeShouldChange { 188 if oldMd.CreationTime == newMd.CreationTime { 189 t.Fatalf("%s should have changed CreationTime", errorPrefix) 190 } 191 } else { 192 if oldMd.CreationTime != newMd.CreationTime { 193 t.Fatalf("%s should not have changed CreationTime", errorPrefix) 194 } 195 } 196 197 if modificationTimeShouldChange { 198 if oldMd.ModificationTime == newMd.ModificationTime { 199 t.Fatalf("%s should have changed ModificationTime", errorPrefix) 200 } 201 } else { 202 if oldMd.ModificationTime != newMd.ModificationTime { 203 t.Fatalf("%s should not have changed ModificationTime", errorPrefix) 204 } 205 } 206 207 if accessTimeShouldChange { 208 if oldMd.AccessTime == newMd.AccessTime { 209 t.Fatalf("%s should have changed AccessTime", errorPrefix) 210 } 211 } else { 212 if oldMd.AccessTime != newMd.AccessTime { 213 t.Fatalf("%s should not have changed AccessTime", errorPrefix) 214 } 215 } 216 217 if attrChangeTimeShouldChange { 218 if oldMd.AttrChangeTime == newMd.AttrChangeTime { 219 t.Fatalf("%s should have changed AttrChangeTime", errorPrefix) 220 } 221 } else { 222 if oldMd.AttrChangeTime != newMd.AttrChangeTime { 223 t.Fatalf("%s should not have changed AttrChangeTime", errorPrefix) 224 } 225 } 226 } 227 228 func TestAPI(t *testing.T) { 229 var ( 230 timeBeforeOp time.Time 231 timeAfterOp time.Time 232 toDestroyInodeNumber InodeNumber 233 ) 234 235 testSetup(t, false) 236 237 _, ok := AccountNameToVolumeName("BadAccountName") 238 if ok { 239 t.Fatalf("AccountNameToVolumeName(\"BadAccountName\") should have failed") 240 } 241 242 goodVolumeName, ok := AccountNameToVolumeName("AUTH_test") 243 if !ok { 244 t.Fatalf("AccountNameToVolumeName(\"AUTH_test\") should have succeeded") 245 } 246 if "TestVolume" != goodVolumeName { 247 t.Fatalf("AccountNameToVolumeName(\"AUTH_test\") should have returned \"TestVolume\"") 248 } 249 250 _, ok = VolumeNameToActivePeerPrivateIPAddr("BadVolumeName") 251 if ok { 252 t.Fatalf("VolumeNameToActivePeerPrivateIPAddr(\"BadVolumeName\") should have failed") 253 } 254 255 goodActivePeerPrivateIPAddr, ok := VolumeNameToActivePeerPrivateIPAddr("TestVolume") 256 if !ok { 257 t.Fatalf("VolumeNameToActivePeerPrivateIPAddr(\"TestVolume\") should have succeeded") 258 } 259 if "127.0.0.1" != goodActivePeerPrivateIPAddr { 260 t.Fatalf("VolumeNameToActivePeerPrivateIPAddr(\"TestVolume\") should have returned \"127.0.0.1\"") 261 } 262 263 _, err := FetchVolumeHandle("BadVolumeName") 264 if nil == err { 265 t.Fatalf("FetchVolumeHandle(\"BadVolumeName\") should have failed") 266 } 267 268 testVolumeHandle, err := FetchVolumeHandle("TestVolume") 269 if nil != err { 270 t.Fatalf("FetchVolumeHandle(\"TestVolume\") should have worked - got error: %v", err) 271 } 272 273 fsid := testVolumeHandle.GetFSID() 274 if 1 != fsid { 275 t.Fatalf("GetFSID() returned unexpected FSID") 276 } 277 278 fileInodeNumber, err := testVolumeHandle.CreateFile(InodeMode(0000), InodeRootUserID, InodeGroupID(0)) 279 if nil != err { 280 t.Fatalf("CreateFile() failed: %v", err) 281 } 282 283 if !testVolumeHandle.Access(fileInodeNumber, InodeRootUserID, InodeGroupID(0), nil, F_OK, NoOverride) { 284 t.Fatalf("Access(fileInodeNumber,,,,F_OK) after CreateFile() should not have failed") 285 } 286 287 if !testVolumeHandle.Access(fileInodeNumber, InodeRootUserID, InodeGroupID(456), nil, 288 R_OK|W_OK, NoOverride) { 289 t.Fatalf("Access(fileInodeNumber,InodeUserID(123),,,R_OK|W_OK) should have returned true") 290 } 291 292 // not even root can execute a file without any execute bits set 293 if testVolumeHandle.Access(fileInodeNumber, InodeRootUserID, InodeGroupID(456), nil, 294 X_OK, NoOverride) { 295 t.Fatalf("Access(fileInodeNumber,InodeUserID(123),,,R_OK|W_OK|X_OK) should have returned false") 296 } 297 298 if testVolumeHandle.Access(fileInodeNumber, InodeUserID(123), InodeGroupID(0), nil, 299 R_OK|W_OK|X_OK, NoOverride) { 300 t.Fatalf("Access(fileInodeNumber,InodeUserID(123),InodeGroupID(0),,R_OK|W_OK|X_OK) should have returned false") 301 } 302 303 if testVolumeHandle.Access(fileInodeNumber, InodeRootUserID, InodeGroupID(0), nil, 304 R_OK|P_OK, NoOverride) { 305 t.Fatalf("Access(fileInodeNumber,,,,R_OK|X_OK) should have returned false") 306 } 307 308 err = testVolumeHandle.SetOwnerUserID(fileInodeNumber, InodeUserID(123)) 309 if nil != err { 310 t.Fatalf("SetOwnerUserID(,InodeUserID(123)) failed: %v", err) 311 } 312 313 if !testVolumeHandle.Access(fileInodeNumber, InodeRootUserID, InodeGroupID(0), nil, P_OK, NoOverride) { 314 t.Fatalf("Access(fileInodeNumber,InodeRootUserID,,,P_OK should have returned true") 315 } 316 317 if !testVolumeHandle.Access(fileInodeNumber, InodeUserID(123), InodeGroupID(0), nil, P_OK, NoOverride) { 318 t.Fatalf("Access(fileInodeNumber,InodeUserID(123),,,P_OK should have returned true") 319 } 320 321 if !testVolumeHandle.Access(fileInodeNumber, InodeUserID(123), InodeGroupID(0), nil, P_OK, OwnerOverride) { 322 t.Fatalf("Access(fileInodeNumber,InodeUserID(123),,,P_OK,UserOveride should have returned true") 323 } 324 325 if testVolumeHandle.Access(fileInodeNumber, InodeUserID(789), InodeGroupID(0), nil, P_OK, NoOverride) { 326 t.Fatalf("Access(fileInodeNumber,InodeUserID(789),,,P_OK should have returned false") 327 } 328 329 err = testVolumeHandle.SetPermMode(fileInodeNumber, InodeMode(0600)) 330 if nil != err { 331 t.Fatalf("SetPermMode(,InodeMode(0600)) failed: %v", err) 332 } 333 334 if !testVolumeHandle.Access(fileInodeNumber, InodeUserID(123), InodeGroupID(456), nil, R_OK, NoOverride) { 335 t.Fatalf("Access(fileInodeNumber,InodeUserID(123),,,R_OK) should have returned true") 336 } 337 338 if !testVolumeHandle.Access(fileInodeNumber, InodeUserID(123), InodeGroupID(456), nil, W_OK, NoOverride) { 339 t.Fatalf("Access(fileInodeNumber,InodeUserID(123),,,W_OK) should have returned true") 340 } 341 342 if testVolumeHandle.Access(fileInodeNumber, InodeUserID(123), InodeGroupID(456), nil, X_OK, NoOverride) { 343 t.Fatalf("Access(fileInodeNumber,InodeUserID(123),,,X_OK) should have returned false") 344 } 345 346 if !testVolumeHandle.Access(fileInodeNumber, InodeUserID(123), InodeGroupID(456), nil, R_OK|W_OK, NoOverride) { 347 t.Fatalf("Access(fileInodeNumber,InodeUserID(123),,,R_OK|W_OK) should have returned true") 348 } 349 350 if testVolumeHandle.Access(fileInodeNumber, InodeUserID(123), InodeGroupID(456), nil, 351 R_OK|W_OK|X_OK, NoOverride) { 352 t.Fatalf("Access(fileInodeNumber,InodeUserID(123),,,R_OK|W_OK|X_OK) should have returned false") 353 } 354 355 if testVolumeHandle.Access(fileInodeNumber, InodeUserID(123), InodeGroupID(456), nil, 356 R_OK|W_OK|X_OK, OwnerOverride) { 357 t.Fatalf("Access(fileInodeNumber,InodeUserID(123),OwnerOverride,,R_OK|W_OK|X_OK) should have returned false") 358 } 359 360 err = testVolumeHandle.SetOwnerUserIDGroupID(fileInodeNumber, InodeRootUserID, InodeGroupID(456)) 361 if nil != err { 362 t.Fatalf("SetOwnerUserIDGroupID(,InodeRootUserID,InodeGroupID(456)) failed: %v", err) 363 } 364 365 err = testVolumeHandle.SetPermMode(fileInodeNumber, InodeMode(0060)) 366 if nil != err { 367 t.Fatalf("SetPermMode(,InodeMode(0060)) failed: %v", err) 368 } 369 370 if !testVolumeHandle.Access(fileInodeNumber, InodeUserID(123), InodeGroupID(456), nil, R_OK, NoOverride) { 371 t.Fatalf("Access(fileInodeNumber,,InodeGroupID(456),,R_OK) should have returned true") 372 } 373 374 if !testVolumeHandle.Access(fileInodeNumber, InodeUserID(123), InodeGroupID(456), nil, W_OK, NoOverride) { 375 t.Fatalf("Access(fileInodeNumber,,InodeGroupID(456),,W_OK) should have returned true") 376 } 377 378 if testVolumeHandle.Access(fileInodeNumber, InodeUserID(123), InodeGroupID(456), nil, X_OK, NoOverride) { 379 t.Fatalf("Access(fileInodeNumber,,InodeGroupID(456),,X_OK) should have returned false") 380 } 381 382 if testVolumeHandle.Access(fileInodeNumber, InodeUserID(123), InodeGroupID(456), nil, X_OK, OwnerOverride) { 383 t.Fatalf("Access(fileInodeNumber,,InodeGroupID(456),,X_OK,OwnerOverride) should have returned false") 384 } 385 386 if !testVolumeHandle.Access(fileInodeNumber, InodeUserID(123), InodeGroupID(456), nil, 387 R_OK|W_OK, NoOverride) { 388 t.Fatalf("Access(fileInodeNumber,,InodeGroupID(456),,R_OK|W_OK) should have returned true") 389 } 390 391 if testVolumeHandle.Access(fileInodeNumber, InodeUserID(123), InodeGroupID(456), nil, 392 R_OK|W_OK|X_OK, NoOverride) { 393 t.Fatalf("Access(fileInodeNumber,,InodeGroupID(456),,R_OK|W_OK|X_OK) should have returned false") 394 } 395 396 if !testVolumeHandle.Access(fileInodeNumber, InodeUserID(123), InodeGroupID(789), 397 []InodeGroupID{InodeGroupID(456)}, R_OK, NoOverride) { 398 t.Fatalf("Access(fileInodeNumber,,,[]InodeGroupID{InodeGroupID(456)},R_OK) should have returned true") 399 } 400 401 if !testVolumeHandle.Access(fileInodeNumber, InodeUserID(123), InodeGroupID(789), 402 []InodeGroupID{InodeGroupID(456)}, W_OK, NoOverride) { 403 t.Fatalf("Access(fileInodeNumber,,,[]InodeGroupID{InodeGroupID(456)},W_OK) should have returned true") 404 } 405 406 if testVolumeHandle.Access(fileInodeNumber, InodeUserID(123), InodeGroupID(789), 407 []InodeGroupID{InodeGroupID(456)}, X_OK, NoOverride) { 408 t.Fatalf("Access(fileInodeNumber,,,[]InodeGroupID{InodeGroupID(456)},X_OK) should have returned false") 409 } 410 411 if !testVolumeHandle.Access(fileInodeNumber, InodeUserID(123), InodeGroupID(789), 412 []InodeGroupID{InodeGroupID(456)}, R_OK|W_OK, NoOverride) { 413 t.Fatalf("Access(fileInodeNumber,,,[]InodeGroupID{InodeGroupID(456)},R_OK|W_OK) should have returned true") 414 } 415 416 if testVolumeHandle.Access(fileInodeNumber, InodeUserID(123), InodeGroupID(789), 417 []InodeGroupID{InodeGroupID(456)}, R_OK|W_OK|X_OK, NoOverride) { 418 t.Fatalf("Access(fileInodeNumber,,,[]InodeGroupID{InodeGroupID(456)},R_OK|W_OK|X_OK) should have returned false") 419 } 420 421 err = testVolumeHandle.SetPermMode(fileInodeNumber, InodeMode(0006)) 422 if nil != err { 423 t.Fatalf("SetPermMode(,InodeMode(0006)) failed: %v", err) 424 } 425 err = testVolumeHandle.SetOwnerUserIDGroupID(fileInodeNumber, InodeUserID(456), InodeGroupID(0)) 426 if nil != err { 427 t.Fatalf("SetOwnerUserIDGroupID(,InodeRootUserID,InodeGroupID(0)) failed: %v", err) 428 } 429 430 if !testVolumeHandle.Access(fileInodeNumber, InodeUserID(123), InodeGroupID(456), nil, R_OK, NoOverride) { 431 t.Fatalf("Access(fileInodeNumber,,,,R_OK) should have returned true") 432 } 433 434 if !testVolumeHandle.Access(fileInodeNumber, InodeUserID(123), InodeGroupID(456), nil, W_OK, NoOverride) { 435 t.Fatalf("Access(fileInodeNumber,,,,W_OK) should have returned true") 436 } 437 438 if testVolumeHandle.Access(fileInodeNumber, InodeUserID(123), InodeGroupID(456), nil, X_OK, NoOverride) { 439 t.Fatalf("Access(fileInodeNumber,,,,X_OK) should have returned false") 440 } 441 442 if !testVolumeHandle.Access(fileInodeNumber, InodeUserID(123), InodeGroupID(456), nil, 443 R_OK|W_OK, NoOverride) { 444 t.Fatalf("Access(fileInodeNumber,,,,R_OK|W_OK) should have returned true") 445 } 446 447 if testVolumeHandle.Access(fileInodeNumber, InodeUserID(123), InodeGroupID(456), nil, 448 R_OK|W_OK|X_OK, NoOverride) { 449 t.Fatalf("Access(fileInodeNumber,,,,R_OK|W_OK|X_OK) should have returned false") 450 } 451 452 // Test the ability of OwnerOverride to override permissions checks for owner (except for exec) 453 if testVolumeHandle.Access(fileInodeNumber, InodeUserID(456), InodeGroupID(456), nil, R_OK, NoOverride) { 454 t.Fatalf("Access(fileInodeNumber,,,,R_OK) should have returned false") 455 } 456 if !testVolumeHandle.Access(fileInodeNumber, InodeUserID(456), InodeGroupID(456), nil, R_OK, OwnerOverride) { 457 t.Fatalf("Access(fileInodeNumber,,,,R_OK) should have returned true") 458 } 459 460 if testVolumeHandle.Access(fileInodeNumber, InodeUserID(456), InodeGroupID(456), nil, W_OK, NoOverride) { 461 t.Fatalf("Access(fileInodeNumber,,,,W_OK) should have returned false") 462 } 463 if !testVolumeHandle.Access(fileInodeNumber, InodeUserID(456), InodeGroupID(456), nil, W_OK, OwnerOverride) { 464 t.Fatalf("Access(fileInodeNumber,,,,W_OK) should have returned true") 465 } 466 467 if testVolumeHandle.Access(fileInodeNumber, InodeUserID(456), InodeGroupID(456), nil, X_OK, NoOverride) { 468 t.Fatalf("Access(fileInodeNumber,,,,X_OK) should have returned false") 469 } 470 if testVolumeHandle.Access(fileInodeNumber, InodeUserID(456), InodeGroupID(456), nil, X_OK, OwnerOverride) { 471 t.Fatalf("Access(fileInodeNumber,,,,X_OK) should have returned false") 472 } 473 474 err = testVolumeHandle.Destroy(fileInodeNumber) 475 if nil != err { 476 t.Fatalf("Destroy(fileInodeNumber) failed: %v", err) 477 } 478 479 if testVolumeHandle.Access(fileInodeNumber, InodeRootUserID, InodeGroupID(0), nil, F_OK, NoOverride) { 480 t.Fatalf("Access(fileInodeNumber,,,,F_OK) after Destroy() should have failed") 481 } 482 483 rootDirInodeType, err := testVolumeHandle.GetType(RootDirInodeNumber) 484 if nil != err { 485 t.Fatalf("GetType(RootDirInodeNumber) failed: %v", err) 486 } 487 if DirType != rootDirInodeType { 488 t.Fatalf("GetType(RootDirInodeNumber) returned unexpected type: %v", rootDirInodeType) 489 } 490 491 rootDirLinkCount, err := testVolumeHandle.GetLinkCount(RootDirInodeNumber) 492 if nil != err { 493 t.Fatalf("GetLinkCount(RootDirInodeNumber) failed: %v", err) 494 } 495 if 2 != rootDirLinkCount { 496 t.Fatalf("GetLinkCount(RootDirInodeNumber) returned unexpected linkCount: %v", rootDirLinkCount) 497 } 498 499 numEntries, err := testVolumeHandle.NumDirEntries(RootDirInodeNumber) 500 501 if nil != err { 502 t.Fatalf("NumDirEntries(RootDirInodeNumber) failed: %v", err) 503 } 504 if 2 != numEntries { 505 t.Fatalf("NumDirEntries(RootDirInodeNumber) should have returned numEntries == 2") 506 } 507 508 dirEntrySlice, moreEntries, err := testVolumeHandle.ReadDir(RootDirInodeNumber, 0, 0) 509 510 if nil != err { 511 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) failed: %v", err) 512 } 513 if moreEntries { 514 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) should have returned moreEntries == false") 515 } 516 if 2 != len(dirEntrySlice) { 517 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) should have returned dirEntrySlice with 2 elements") 518 } 519 if (dirEntrySlice[0].InodeNumber != RootDirInodeNumber) || (dirEntrySlice[0].Basename != ".") || (dirEntrySlice[0].NextDirLocation != 1) { 520 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) returned unexpected dirEntrySlice[0]") 521 } 522 if (dirEntrySlice[1].InodeNumber != RootDirInodeNumber) || (dirEntrySlice[1].Basename != "..") || (dirEntrySlice[1].NextDirLocation != 2) { 523 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) returned unexpected dirEntrySlice[1]") 524 } 525 526 dirEntrySlice, moreEntries, err = testVolumeHandle.ReadDir(RootDirInodeNumber, 0, 0, InodeDirLocation(-1)) 527 528 if nil != err { 529 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0, InodeDirLocation(-1)) failed: %v", err) 530 } 531 if moreEntries { 532 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0, InodeDirLocation(-1)) should have returned moreEntries == false") 533 } 534 if 2 != len(dirEntrySlice) { 535 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0, InodeDirLocation(-1)) should have returned dirEntrySlice with 2 elements") 536 } 537 if (dirEntrySlice[0].InodeNumber != RootDirInodeNumber) || (dirEntrySlice[0].Basename != ".") || (dirEntrySlice[0].NextDirLocation != 1) { 538 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0, InodeDirLocation(-1)) returned unexpected dirEntrySlice[0]") 539 } 540 if (dirEntrySlice[1].InodeNumber != RootDirInodeNumber) || (dirEntrySlice[1].Basename != "..") || (dirEntrySlice[1].NextDirLocation != 2) { 541 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0, InodeDirLocation(-1)) returned unexpected dirEntrySlice[1]") 542 } 543 544 dirEntrySlice, moreEntries, err = testVolumeHandle.ReadDir(RootDirInodeNumber, 0, 0, "") 545 546 if nil != err { 547 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0, \"\") failed: %v", err) 548 } 549 if moreEntries { 550 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0, \"\") should have returned moreEntries == false") 551 } 552 if 2 != len(dirEntrySlice) { 553 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0, \"\") should have returned dirEntrySlice with 2 elements") 554 } 555 if (dirEntrySlice[0].InodeNumber != RootDirInodeNumber) || (dirEntrySlice[0].Basename != ".") || (dirEntrySlice[0].NextDirLocation != 1) { 556 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0, \"\") returned unexpected dirEntrySlice[0]") 557 } 558 if (dirEntrySlice[1].InodeNumber != RootDirInodeNumber) || (dirEntrySlice[1].Basename != "..") || (dirEntrySlice[1].NextDirLocation != 2) { 559 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0, \"\") returned unexpected dirEntrySlice[1]") 560 } 561 562 testMetadata := &MetadataStruct{ 563 InodeType: FileType, 564 NumWrites: 0, 565 LinkCount: 0, 566 Mode: PosixModePerm, 567 UserID: InodeUserID(123), 568 GroupID: InodeGroupID(456), 569 } 570 571 fileInodeNumber, err = testVolumeHandle.CreateFile(testMetadata.Mode, testMetadata.UserID, testMetadata.GroupID) 572 if nil != err { 573 t.Fatalf("CreateFile() failed: %v", err) 574 } 575 576 fileInodeType, err := testVolumeHandle.GetType(fileInodeNumber) 577 if nil != err { 578 t.Fatalf("GetType(fileInodeNumber) failed: %v", err) 579 } 580 if FileType != fileInodeType { 581 t.Fatalf("GetType(fileInodeNumber) returned unexpected type: %v", fileInodeType) 582 } 583 584 fileLinkCount, err := testVolumeHandle.GetLinkCount(fileInodeNumber) 585 if nil != err { 586 t.Fatalf("GetLinkCount(fileInodeNumber) failed: %v", err) 587 } 588 if 0 != fileLinkCount { 589 t.Fatalf("GetLinkCount(fileInodeNumber) returned unexpected linkCount: %v", fileLinkCount) 590 } 591 592 postMetadata, err := testVolumeHandle.GetMetadata(fileInodeNumber) 593 if nil != err { 594 t.Fatalf("GetMetadata(fileInodeNumber) failed: %v", err) 595 } 596 if FileType != postMetadata.InodeType { 597 t.Fatalf("GetMetadata(fileInodeNumber) returned unexpected InodeType") 598 } 599 checkMetadata(t, postMetadata, testMetadata, MetadataLinkCountField, "GetMetadata() after CreateFile()") 600 601 // TODO: Add more tests related to CreateFile(): mode > 0777, etc. 602 603 preMetadata, err := testVolumeHandle.GetMetadata(fileInodeNumber) 604 if nil != err { 605 t.Fatalf("GetMetadata(fileInodeNumber) failed: %v", err) 606 } 607 time.Sleep(time.Millisecond) 608 609 testMetadata.Mode = PosixModePerm - 1 610 611 err = testVolumeHandle.SetPermMode(fileInodeNumber, testMetadata.Mode) 612 if nil != err { 613 t.Fatalf("SetPermMode(fileInodeNumber, %v) failed: %v", testMetadata.Mode, err) 614 } 615 616 postMetadata, err = testVolumeHandle.GetMetadata(fileInodeNumber) 617 if nil != err { 618 t.Fatalf("GetMetadata(fileInodeNumber) failed: %v", err) 619 } 620 checkMetadata(t, postMetadata, testMetadata, MetadataPermFields, "GetMetadata() after SetPermMode()") 621 checkMetadataTimeChanges(t, preMetadata, postMetadata, false, false, false, true, "SetPermMode()") 622 623 preMetadata, err = testVolumeHandle.GetMetadata(fileInodeNumber) 624 if nil != err { 625 t.Fatalf("GetMetadata(fileInodeNumber) failed: %v", err) 626 } 627 time.Sleep(time.Millisecond) 628 629 testMetadata.UserID = 9753 630 631 err = testVolumeHandle.SetOwnerUserID(fileInodeNumber, testMetadata.UserID) 632 if nil != err { 633 t.Fatalf("SetOwnerUserID(fileInodeNumber, %v) failed: %v", testMetadata.UserID, err) 634 } 635 636 postMetadata, err = testVolumeHandle.GetMetadata(fileInodeNumber) 637 if nil != err { 638 t.Fatalf("GetMetadata(fileInodeNumber) failed: %v", err) 639 } 640 checkMetadata(t, postMetadata, testMetadata, MetadataPermFields, "GetMetadata() after SetOwnerUserID()") 641 checkMetadataTimeChanges(t, preMetadata, postMetadata, false, false, false, true, "SetOwnerUserID()") 642 643 preMetadata, err = testVolumeHandle.GetMetadata(fileInodeNumber) 644 if nil != err { 645 t.Fatalf("GetMetadata(fileInodeNumber) failed: %v", err) 646 } 647 time.Sleep(time.Millisecond) 648 649 testMetadata.GroupID = 12345678 650 651 err = testVolumeHandle.SetOwnerGroupID(fileInodeNumber, testMetadata.GroupID) 652 if nil != err { 653 t.Fatalf("SetOwnerGroupID(fileInodeNumber, %v) failed: %v", testMetadata.GroupID, err) 654 } 655 656 postMetadata, err = testVolumeHandle.GetMetadata(fileInodeNumber) 657 if nil != err { 658 t.Fatalf("GetMetadata(fileInodeNumber) failed: %v", err) 659 } 660 checkMetadata(t, postMetadata, testMetadata, MetadataPermFields, "GetMetadata() after SetOwnerGroupID()") 661 checkMetadataTimeChanges(t, preMetadata, postMetadata, false, false, false, true, "SetOwnerGroupID()") 662 663 preMetadata, err = testVolumeHandle.GetMetadata(fileInodeNumber) 664 if nil != err { 665 t.Fatalf("GetMetadata(fileInodeNumber) failed: %v", err) 666 } 667 time.Sleep(time.Millisecond) 668 669 testMetadata.UserID = 3579 670 testMetadata.GroupID = 87654321 671 672 err = testVolumeHandle.SetOwnerUserIDGroupID(fileInodeNumber, testMetadata.UserID, testMetadata.GroupID) 673 if nil != err { 674 t.Fatalf("SetOwnerUserIDGroupID(fileInodeNumber, %v, %v) failed: %v", testMetadata.UserID, testMetadata.GroupID, err) 675 } 676 677 postMetadata, err = testVolumeHandle.GetMetadata(fileInodeNumber) 678 if nil != err { 679 t.Fatalf("GetMetadata(fileInodeNumber) failed: %v", err) 680 } 681 checkMetadata(t, postMetadata, testMetadata, MetadataPermFields, "GetMetadata() after SetOwnerUserIDGroupID()") 682 checkMetadataTimeChanges(t, preMetadata, postMetadata, false, false, false, true, "SetOwnerUserIDGroupID()") 683 684 err = testVolumeHandle.Link(RootDirInodeNumber, "link_1_to_file_inode", fileInodeNumber, false) 685 if nil != err { 686 t.Fatalf("Link(RootDirInodeNumber, \"link_1_to_file_inode\", fileInodeNumber, false) failed: %v", err) 687 } 688 689 numEntries, err = testVolumeHandle.NumDirEntries(RootDirInodeNumber) 690 691 if nil != err { 692 t.Fatalf("NumDirEntries(RootDirInodeNumber) failed: %v", err) 693 } 694 if 3 != numEntries { 695 t.Fatalf("NumDirEntries(RootDirInodeNumber) should have returned numEntries == 3") 696 } 697 698 fileLinkCount, err = testVolumeHandle.GetLinkCount(fileInodeNumber) 699 if nil != err { 700 t.Fatalf("GetLinkCount(fileInodeNumber) failed: %v", err) 701 } 702 if 1 != fileLinkCount { 703 t.Fatalf("GetLinkCount(fileInodeNumber) returned unexpected linkCount: %v", fileLinkCount) 704 } 705 706 postMetadata, err = testVolumeHandle.GetMetadata(fileInodeNumber) 707 if nil != err { 708 t.Fatalf("GetMetadata(fileInodeNumber) failed: %v", err) 709 } 710 testMetadata.LinkCount = 1 711 checkMetadata(t, postMetadata, testMetadata, MetadataLinkCountField, "GetMetadata() after Link()") 712 713 err = testVolumeHandle.Link(RootDirInodeNumber, "link_2_to_file_inode", fileInodeNumber, false) 714 if nil != err { 715 t.Fatalf("Link(RootDirInodeNumber, \"link_2_to_file_inode\", fileInodeNumber, false) failed: %v", err) 716 } 717 718 numEntries, err = testVolumeHandle.NumDirEntries(RootDirInodeNumber) 719 720 if nil != err { 721 t.Fatalf("NumDirEntries(RootDirInodeNumber) failed: %v", err) 722 } 723 if 4 != numEntries { 724 t.Fatalf("NumDirEntries(RootDirInodeNumber) should have returned numEntries == 4") 725 } 726 727 fileLinkCount, err = testVolumeHandle.GetLinkCount(fileInodeNumber) 728 if nil != err { 729 t.Fatalf("GetLinkCount(fileInodeNumber) failed: %v", err) 730 } 731 if 2 != fileLinkCount { 732 t.Fatalf("GetLinkCount(fileInodeNumber) returned unexpected linkCount: %v", fileLinkCount) 733 } 734 735 postMetadata, err = testVolumeHandle.GetMetadata(fileInodeNumber) 736 if nil != err { 737 t.Fatalf("GetMetadata(fileInodeNumber) failed: %v", err) 738 } 739 testMetadata.LinkCount = 2 740 checkMetadata(t, postMetadata, testMetadata, MetadataLinkCountField, "GetMetadata() after Link()") 741 742 symlinkInodeToLink1ToFileInode, err := testVolumeHandle.CreateSymlink("link_1_to_file_inode", PosixModePerm, 0, 0) 743 if nil != err { 744 t.Fatalf("CreateSymlink(\"link_1_to_file_inode\") failed: %v", err) 745 } 746 747 symlinkInodeToLink1ToFileInodeType, err := testVolumeHandle.GetType(symlinkInodeToLink1ToFileInode) 748 if nil != err { 749 t.Fatalf("GetType(symlinkInodeToLink1ToFileInode) failed: %v", err) 750 } 751 if SymlinkType != symlinkInodeToLink1ToFileInodeType { 752 t.Fatalf("GetType(symlinkInodeToLink1ToFileInode) returned unexpected type: %v", symlinkInodeToLink1ToFileInodeType) 753 } 754 755 symlinkToLink1ToFileInodeLinkCount, err := testVolumeHandle.GetLinkCount(symlinkInodeToLink1ToFileInode) 756 if nil != err { 757 t.Fatalf("GetLinkCount(symlinkInodeToLink1ToFileInode) failed: %v", err) 758 } 759 if 0 != symlinkToLink1ToFileInodeLinkCount { 760 t.Fatalf("GetLinkCount(symlinkInodeToLink1ToFileInode) returned unexpected linkCount: %v", symlinkToLink1ToFileInodeLinkCount) 761 } 762 763 symlinkInodeToLink1ToFileInodeTarget, err := testVolumeHandle.GetSymlink(symlinkInodeToLink1ToFileInode) 764 if nil != err { 765 t.Fatalf("GetSymlink(symlinkInodeToLink1ToFileInode) failed: %v", err) 766 } 767 if "link_1_to_file_inode" != symlinkInodeToLink1ToFileInodeTarget { 768 t.Fatalf("GetSymlink(symlinkInodeToLink1ToFileInode) should have returned target == \"%v\"... instead got \"%v\"", "link_1_to_file_inode", symlinkInodeToLink1ToFileInodeTarget) 769 } 770 771 err = testVolumeHandle.Link(RootDirInodeNumber, "symlink_to_link_1_to_file_inode", symlinkInodeToLink1ToFileInode, false) 772 if nil != err { 773 t.Fatalf("Link(RootDirInodeNumber, \"symlink_to_link_1_to_file_inode\", symlinkInodeToLink1ToFileInode, false) failed: %v", err) 774 } 775 776 numEntries, err = testVolumeHandle.NumDirEntries(RootDirInodeNumber) 777 778 if nil != err { 779 t.Fatalf("NumDirEntries(RootDirInodeNumber) failed: %v", err) 780 } 781 if 5 != numEntries { 782 t.Fatalf("NumDirEntries(RootDirInodeNumber) should have returned numEntries == 5") 783 } 784 785 symlinkToLink1ToFileInodeLinkCount, err = testVolumeHandle.GetLinkCount(symlinkInodeToLink1ToFileInode) 786 if nil != err { 787 t.Fatalf("GetLinkCount(symlinkInodeToLink1ToFileInode) failed: %v", err) 788 } 789 if 1 != symlinkToLink1ToFileInodeLinkCount { 790 t.Fatalf("GetLinkCount(symlinkInodeToLink1ToFileInode) returned unexpected linkCount: %v", symlinkToLink1ToFileInodeLinkCount) 791 } 792 793 symlinkInodeToLink1ToFileInodeLookupResult, err := testVolumeHandle.Lookup(RootDirInodeNumber, "symlink_to_link_1_to_file_inode") 794 if nil != err { 795 t.Fatalf("Lookup(RootDirInodeNumber, \"symlink_to_link_1_to_file_inode\") failed: %v", err) 796 } 797 if symlinkInodeToLink1ToFileInodeLookupResult != symlinkInodeToLink1ToFileInode { 798 t.Fatalf("Lookup(RootDirInodeNumber, \"symlink_to_link_1_to_file_inode\") returned unexpected InodeNumber") 799 } 800 801 dirEntrySlice, moreEntries, err = testVolumeHandle.ReadDir(RootDirInodeNumber, 1, 0) 802 if nil != err { 803 t.Fatalf("ReadDir(RootDirInodeNumber, 1, 0) failed: %v", err) 804 } 805 if !moreEntries { 806 t.Fatalf("ReadDir(RootDirInodeNumber, 1, 0) should have returned moreEntries == true") 807 } 808 if 1 != len(dirEntrySlice) { 809 t.Fatalf("ReadDir(RootDirInodeNumber, 1, 0) should have returned dirEntrySlice with 1 element, got %v elements", len(dirEntrySlice)) 810 } 811 if (dirEntrySlice[0].InodeNumber != RootDirInodeNumber) || (dirEntrySlice[0].Basename != ".") || (dirEntrySlice[0].NextDirLocation != 1) { 812 t.Fatalf("ReadDir(RootDirInodeNumber, 1, 0) returned unexpected dirEntrySlice[0]") 813 } 814 815 // 60 = ".." entry length (8 + (2 + 1) + 2 + 8) + "link_1_to_file_inode" entry length (8 + (20 + 1) + 2 + 8) 816 dirEntrySlice, moreEntries, err = testVolumeHandle.ReadDir(RootDirInodeNumber, 0, 60, InodeDirLocation(0)) 817 if nil != err { 818 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 60, InodeDirLocation(0)) failed: %v", err) 819 } 820 if !moreEntries { 821 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 60, InodeDirLocation(0)) should have returned moreEntries == true") 822 } 823 if 2 != len(dirEntrySlice) { 824 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 60, InodeDirLocation(0)) should have returned dirEntrySlice with 2 elements, got %v elements", len(dirEntrySlice)) 825 } 826 if (dirEntrySlice[0].InodeNumber != RootDirInodeNumber) || (dirEntrySlice[0].Basename != "..") || (dirEntrySlice[0].NextDirLocation != 2) { 827 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 60, InodeDirLocation(0)) returned unexpected dirEntrySlice[0]") 828 } 829 if (dirEntrySlice[1].InodeNumber != fileInodeNumber) || (dirEntrySlice[1].Basename != "link_1_to_file_inode") || (dirEntrySlice[1].NextDirLocation != 3) { 830 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 60, InodeDirLocation(0)) returned unexpected dirEntrySlice[1]") 831 } 832 833 dirEntrySlice, moreEntries, err = testVolumeHandle.ReadDir(RootDirInodeNumber, 0, 60, ".") 834 if nil != err { 835 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 60, \".\") failed: %v", err) 836 } 837 if !moreEntries { 838 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 60, \".\") should have returned moreEntries == true") 839 } 840 if 2 != len(dirEntrySlice) { 841 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 60, \".\") should have returned dirEntrySlice with 2 elements, got %v elements", len(dirEntrySlice)) 842 } 843 if (dirEntrySlice[0].InodeNumber != RootDirInodeNumber) || (dirEntrySlice[0].Basename != "..") || (dirEntrySlice[0].NextDirLocation != 2) { 844 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 60, \".\") returned unexpected dirEntrySlice[0]") 845 } 846 if (dirEntrySlice[1].InodeNumber != fileInodeNumber) || (dirEntrySlice[1].Basename != "link_1_to_file_inode") || (dirEntrySlice[1].NextDirLocation != 3) { 847 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 60, \".\") returned unexpected dirEntrySlice[1]") 848 } 849 850 dirEntrySlice, moreEntries, err = testVolumeHandle.ReadDir(RootDirInodeNumber, 0, 0, InodeDirLocation(2)) 851 if nil != err { 852 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0, InodeDirLocation(2)) failed: %v", err) 853 } 854 if moreEntries { 855 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0, InodeDirLocation(2)) should have returned moreEntries == false") 856 } 857 if 2 != len(dirEntrySlice) { 858 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0, InodeDirLocation(2)) should have returned dirEntrySlice with 2 elements") 859 } 860 if (dirEntrySlice[0].InodeNumber != fileInodeNumber) || (dirEntrySlice[0].Basename != "link_2_to_file_inode") || (dirEntrySlice[0].NextDirLocation != 4) { 861 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0, InodeDirLocation(2)) returned unexpected dirEntrySlice[0]") 862 } 863 if (dirEntrySlice[1].InodeNumber != symlinkInodeToLink1ToFileInode) || (dirEntrySlice[1].Basename != "symlink_to_link_1_to_file_inode") || (dirEntrySlice[1].NextDirLocation != 5) { 864 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0, InodeDirLocation(2)) returned unexpected dirEntrySlice[1]") 865 } 866 867 dirEntrySlice, moreEntries, err = testVolumeHandle.ReadDir(RootDirInodeNumber, 0, 0, "link_1_to_file_inode") 868 if nil != err { 869 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0, \"link_1_to_file_inode\") failed: %v", err) 870 } 871 if moreEntries { 872 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0, \"link_1_to_file_inode\") should have returned moreEntries == false") 873 } 874 if 2 != len(dirEntrySlice) { 875 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0, \"link_1_to_file_inode\") should have returned dirEntrySlice with 2 elements") 876 } 877 if (dirEntrySlice[0].InodeNumber != fileInodeNumber) || (dirEntrySlice[0].Basename != "link_2_to_file_inode") || (dirEntrySlice[0].NextDirLocation != 4) { 878 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0, \"link_1_to_file_inode\") returned unexpected dirEntrySlice[0]") 879 } 880 if (dirEntrySlice[1].InodeNumber != symlinkInodeToLink1ToFileInode) || (dirEntrySlice[1].Basename != "symlink_to_link_1_to_file_inode") || (dirEntrySlice[1].NextDirLocation != 5) { 881 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0, \"link_1_to_file_inode\") returned unexpected dirEntrySlice[1]") 882 } 883 884 toDestroyInodeNumber, err = testVolumeHandle.Unlink(RootDirInodeNumber, "link_1_to_file_inode", false) 885 if nil != err { 886 t.Fatalf("Unlink(RootDirInodeNumber, \"link_1_to_file_inode\", false) failed: %v", err) 887 } 888 if InodeNumber(0) != toDestroyInodeNumber { 889 t.Fatalf("Unlink(RootDirInodeNumber, \"link_1_to_file_inode\", false) should have returned toDestroyInodeNumber == 0") 890 } 891 fileLinkCount, err = testVolumeHandle.GetLinkCount(fileInodeNumber) 892 if nil != err { 893 t.Fatalf("GetLinkCount(fileInodeNumber) failed: %v", err) 894 } 895 if 1 != fileLinkCount { 896 t.Fatalf("GetLinkCount(fileInodeNumber) returned unexpected linkCount: %v", fileLinkCount) 897 } 898 899 numEntries, err = testVolumeHandle.NumDirEntries(RootDirInodeNumber) 900 901 if nil != err { 902 t.Fatalf("NumDirEntries(RootDirInodeNumber) failed: %v", err) 903 } 904 if 4 != numEntries { 905 t.Fatalf("NumDirEntries(RootDirInodeNumber) should have returned numEntries == 4") 906 } 907 908 toDestroyInodeNumber, err = testVolumeHandle.Unlink(RootDirInodeNumber, "link_2_to_file_inode", false) 909 if nil != err { 910 t.Fatalf("Unlink(RootDirInodeNumber, \"link_2_to_file_inode\", false) failed: %v", err) 911 } 912 if fileInodeNumber != toDestroyInodeNumber { 913 t.Fatalf("Unlink(RootDirInodeNumber, \"link_2_to_file_inode\", false) should have returned toDestroyInodeNumber == fileInodeNumber") 914 } 915 fileLinkCount, err = testVolumeHandle.GetLinkCount(fileInodeNumber) 916 if nil != err { 917 t.Fatalf("GetLinkCount(fileInodeNumber) failed: %v", err) 918 } 919 if 0 != fileLinkCount { 920 t.Fatalf("GetLinkCount(fileInodeNumber) returned unexpected linkCount: %v", fileLinkCount) 921 } 922 923 numEntries, err = testVolumeHandle.NumDirEntries(RootDirInodeNumber) 924 925 if nil != err { 926 t.Fatalf("NumDirEntries(RootDirInodeNumber) failed: %v", err) 927 } 928 if 3 != numEntries { 929 t.Fatalf("NumDirEntries(RootDirInodeNumber) should have returned numEntries == 3") 930 } 931 932 toDestroyInodeNumber, err = testVolumeHandle.Unlink(RootDirInodeNumber, "symlink_to_link_1_to_file_inode", false) 933 if nil != err { 934 t.Fatalf("Unlink(RootDirInodeNumber, \"symlink_to_link_1_to_file_inode\", false) failed: %v", err) 935 } 936 if symlinkInodeToLink1ToFileInode != toDestroyInodeNumber { 937 t.Fatalf("Unlink(RootDirInodeNumber, \"symlink_to_link_1_to_file_inode\", false) should have returned toDestroyInodeNumber == symlinkInodeToLink1ToFileInode") 938 } 939 940 numEntries, err = testVolumeHandle.NumDirEntries(RootDirInodeNumber) 941 942 if nil != err { 943 t.Fatalf("NumDirEntries(RootDirInodeNumber) failed: %v", err) 944 } 945 if 2 != numEntries { 946 t.Fatalf("NumDirEntries(RootDirInodeNumber) should have returned numEntries == 2") 947 } 948 949 err = testVolumeHandle.Destroy(symlinkInodeToLink1ToFileInode) 950 if nil != err { 951 t.Fatalf("Destroy(symlinkInodeToLink1ToFileInode) failed: %v", err) 952 } 953 954 err = testVolumeHandle.Flush(fileInodeNumber, false) 955 if nil != err { 956 t.Fatalf("Flush(fileInodeNumber, false) failed: %v", err) 957 } 958 err = testVolumeHandle.Purge(fileInodeNumber) 959 if nil != err { 960 t.Fatalf("Purge(fileInodeNumber) failed: %v", err) 961 } 962 963 err = testVolumeHandle.PutStream(fileInodeNumber, "test_stream", []byte{0x00, 0x01, 0x02}) 964 if nil != err { 965 t.Fatalf("PutStream(fileInodeNumber, \"test_stream\", []byte{0x00, 0x01, 0x02}) failed: %v", err) 966 } 967 968 postMetadata, err = testVolumeHandle.GetMetadata(fileInodeNumber) 969 if nil != err { 970 t.Fatalf("GetMetadata(fileInodeNumber) failed: %v", err) 971 } 972 if 1 != len(postMetadata.InodeStreamNameSlice) { 973 t.Fatalf("GetMetadata(fileInodeNumber) should have returned postMetadata.InodeStreamNameSlice with 1 element") 974 } 975 if postMetadata.InodeStreamNameSlice[0] != "test_stream" { 976 t.Fatalf("GetMetadata(fileInodeNumber) returned unexpected postMetadata.InodeStreamNameSlice[0]") 977 } 978 979 testStreamData, err := testVolumeHandle.GetStream(fileInodeNumber, "test_stream") 980 if nil != err { 981 t.Fatalf("GetStream(fileInodeNumber, \"test_stream\") failed: %v", err) 982 } 983 if 0 != bytes.Compare(testStreamData, []byte{0x00, 0x01, 0x02}) { 984 t.Fatalf("GetStream(fileInodeNumber, \"test_stream\") returned unexpected testStreamData") 985 } 986 987 err = testVolumeHandle.DeleteStream(fileInodeNumber, "test_stream") 988 if nil != err { 989 t.Fatalf("DeleteStream(fileInodeNumber, \"test_stream\") failed: %v", err) 990 } 991 992 postMetadata, err = testVolumeHandle.GetMetadata(fileInodeNumber) 993 if nil != err { 994 t.Fatalf("GetMetadata(fileInodeNumber) failed: %v", err) 995 } 996 if 0 != len(postMetadata.InodeStreamNameSlice) { 997 t.Fatalf("GetMetadata(fileInodeNumber) should have returned postMetadata.InodeStreamNameSlice with 0 elements") 998 } 999 1000 testMetadata.CreationTime = time.Now().Add(time.Hour) 1001 err = testVolumeHandle.SetCreationTime(fileInodeNumber, testMetadata.CreationTime) 1002 if nil != err { 1003 t.Fatalf("SetCreationTime(fileInodeNumber, oneHourFromNow) failed: %v", err) 1004 } 1005 postMetadata, err = testVolumeHandle.GetMetadata(fileInodeNumber) 1006 if nil != err { 1007 t.Fatalf("GetMetadata(fileInodeNumber) failed: %v", err) 1008 } 1009 checkMetadata(t, postMetadata, testMetadata, MetadataCrTimeField, 1010 "GetMetadata() after SetCreationTime() test 1") 1011 1012 testMetadata.ModificationTime = time.Now().Add(2 * time.Hour) 1013 err = testVolumeHandle.SetModificationTime(fileInodeNumber, testMetadata.ModificationTime) 1014 if nil != err { 1015 t.Fatalf("SetModificationTime(fileInodeNumber, twoHoursFromNow) failed: %v", err) 1016 } 1017 postMetadata, err = testVolumeHandle.GetMetadata(fileInodeNumber) 1018 if nil != err { 1019 t.Fatalf("GetMetadata(fileInodeNumber) failed: %v", err) 1020 } 1021 checkMetadata(t, postMetadata, testMetadata, MetadataModTimeField, "GetMetadata() after SetModificationTime()") 1022 1023 checkMetadata(t, postMetadata, testMetadata, MetadataNumWritesField, "GetMetadata() before Write()") 1024 err = testVolumeHandle.Write(fileInodeNumber, 0, []byte{0x00, 0x01, 0x02, 0x03, 0x04}, nil) 1025 if nil != err { 1026 t.Fatalf("Write(fileInodeNumber, 0, []byte{0x00, 0x01, 0x02, 0x03, 0x04}) failed: %v", err) 1027 } 1028 postMetadata, err = testVolumeHandle.GetMetadata(fileInodeNumber) 1029 if nil != err { 1030 t.Fatalf("GetMetadata(fileInodeNumber) failed: %v", err) 1031 } 1032 testMetadata.NumWrites = 1 1033 checkMetadata(t, postMetadata, testMetadata, MetadataNumWritesField, "GetMetadata() after Write()") 1034 1035 err = testVolumeHandle.Flush(fileInodeNumber, false) 1036 if err != nil { 1037 t.Fatalf("Flush(fileInodeNumber) failed: %v", err) 1038 } 1039 1040 fileInodeObjectPath, err := testVolumeHandle.ProvisionObject() 1041 if nil != err { 1042 t.Fatalf("ProvisionObjectPath() failed: %v", err) 1043 } 1044 1045 accountName, containerName, objectName, err := utils.PathToAcctContObj(fileInodeObjectPath) 1046 if err != nil { 1047 t.Fatalf("couldn't parse %v as object path", fileInodeObjectPath) 1048 } 1049 1050 putContext, err := swiftclient.ObjectFetchChunkedPutContext(accountName, containerName, objectName, "") 1051 1052 if err != nil { 1053 t.Fatalf("fetching chunked put context failed") 1054 } 1055 err = putContext.SendChunk([]byte{0x11, 0x22, 0x33}) 1056 if err != nil { 1057 t.Fatalf("sending chunk failed") 1058 } 1059 err = putContext.Close() 1060 if err != nil { 1061 t.Fatalf("closing chunked PUT failed") 1062 } 1063 1064 postMetadata, err = testVolumeHandle.GetMetadata(fileInodeNumber) 1065 if nil != err { 1066 t.Fatalf("GetMetadata(fileInodeNumber) failed: %v", err) 1067 } 1068 checkMetadata(t, postMetadata, testMetadata, MetadataNumWritesField, "GetMetadata() before Wrote(,,,,,,,true)") 1069 err = testVolumeHandle.Wrote(fileInodeNumber, containerName, objectName, []uint64{1}, []uint64{0}, []uint64{3}, time.Now(), true) 1070 if nil != err { 1071 t.Fatalf("Wrote(fileInodeNumber, containerName, objectName, []uint64{1}, []uint64{0}, []uint64{3}, time.Now(), true) failed: %v", err) 1072 } 1073 postMetadata, err = testVolumeHandle.GetMetadata(fileInodeNumber) 1074 if nil != err { 1075 t.Fatalf("GetMetadata(fileInodeNumber) failed: %v", err) 1076 } 1077 testMetadata.NumWrites = 2 1078 checkMetadata(t, postMetadata, testMetadata, MetadataNumWritesField, "GetMetadata() after Wrote(,,,,,,,true)") 1079 1080 testFileInodeData, err := testVolumeHandle.Read(fileInodeNumber, 0, 5, nil) 1081 if nil != err { 1082 t.Fatalf("Read(fileInodeNumber, 0, 5) failed: %v", err) 1083 } 1084 if 0 != bytes.Compare(testFileInodeData, []byte{0x00, 0x11, 0x22, 0x33, 0x04}) { 1085 t.Fatalf("Read(fileInodeNumber, 0, 5) returned unexpected testFileInodeData") 1086 } 1087 1088 offset := uint64(0) 1089 length := uint64(5) 1090 testReadPlan, err := testVolumeHandle.GetReadPlan(fileInodeNumber, &offset, &length) 1091 if nil != err { 1092 t.Fatalf("GetReadPlan(fileInodeNumber, 0, 5) failed: %v", err) 1093 } 1094 if 3 != len(testReadPlan) { 1095 t.Fatalf("GetReadPlan(fileInodeNumber, 0, 5) should have returned testReadPlan with 3 elements") 1096 } 1097 if (1 != testReadPlan[0].Length) || (fileInodeObjectPath != testReadPlan[1].ObjectPath) || (0 != testReadPlan[1].Offset) || (3 != testReadPlan[1].Length) || (1 != testReadPlan[2].Length) { 1098 t.Fatalf("GetReadPlan(fileInodeNumber, 0, 5) returned unexpected testReadPlan") 1099 } 1100 1101 testExtentMapChunk, err := testVolumeHandle.FetchExtentMapChunk(fileInodeNumber, uint64(2), 2, 1) 1102 if nil != err { 1103 t.Fatalf("FetchExtentMap(fileInodeNumber, uint64(2), 2, 1) failed: %v", err) 1104 } 1105 if 0 != testExtentMapChunk.FileOffsetRangeStart { 1106 t.Fatalf("FetchExtentMap(fileInodeNumber, uint64(2), 2, 1) should have returned testExtentMapChunk.FileOffsetRangeStart == 0") 1107 } 1108 if 5 != testExtentMapChunk.FileOffsetRangeEnd { 1109 t.Fatalf("FetchExtentMap(fileInodeNumber, uint64(2), 2, 1) should have returned testExtentMapChunk.FileOffsetRangeEnd == 5") 1110 } 1111 if 5 != testExtentMapChunk.FileSize { 1112 t.Fatalf("FetchExtentMap(fileInodeNumber, uint64(2), 2, 1) should have returned testExtentMapChunk.FileSize == 5") 1113 } 1114 if 3 != len(testExtentMapChunk.ExtentMapEntry) { 1115 t.Fatalf("FetchExtentMap(fileInodeNumber, uint64(2), 2, 1) should have returned testExtentMapChunk.ExtentMapEntry slice with 3 elements") 1116 } 1117 fileInodeObjectPathSplit := strings.Split(fileInodeObjectPath, "/") 1118 fileInodeObjectPathContainerName := fileInodeObjectPathSplit[len(fileInodeObjectPathSplit)-2] 1119 fileInodeObjectPathObjectName := fileInodeObjectPathSplit[len(fileInodeObjectPathSplit)-1] 1120 if (0 != testExtentMapChunk.ExtentMapEntry[0].FileOffset) || 1121 (0 != testExtentMapChunk.ExtentMapEntry[0].LogSegmentOffset) || 1122 (1 != testExtentMapChunk.ExtentMapEntry[0].Length) || 1123 (1 != testExtentMapChunk.ExtentMapEntry[1].FileOffset) || 1124 (0 != testExtentMapChunk.ExtentMapEntry[1].LogSegmentOffset) || 1125 (3 != testExtentMapChunk.ExtentMapEntry[1].Length) || 1126 (fileInodeObjectPathContainerName != testExtentMapChunk.ExtentMapEntry[1].ContainerName) || 1127 (fileInodeObjectPathObjectName != testExtentMapChunk.ExtentMapEntry[1].ObjectName) || 1128 (4 != testExtentMapChunk.ExtentMapEntry[2].FileOffset) || 1129 (4 != testExtentMapChunk.ExtentMapEntry[2].LogSegmentOffset) || 1130 (1 != testExtentMapChunk.ExtentMapEntry[2].Length) { 1131 t.Fatalf("FetchExtentMap(fileInodeNumber, uint64(2), 2, 1) returned unexpected testExtentMapChunk.ExtentMapEntry slice") 1132 } 1133 1134 // Suffix byte range query, like "Range: bytes=-2" 1135 length = uint64(3) 1136 testSuffixReadPlan, err := testVolumeHandle.GetReadPlan(fileInodeNumber, nil, &length) 1137 if nil != err { 1138 t.Fatalf("GetReadPlan(fileInodeNumber, nil, 3) failed: %v", err) 1139 } 1140 bytesFromReadPlan := []byte{} 1141 for _, rps := range testSuffixReadPlan { 1142 pathParts := strings.SplitN(rps.ObjectPath, "/", 5) 1143 b, err := swiftclient.ObjectGet(pathParts[2], pathParts[3], pathParts[4], rps.Offset, rps.Length) 1144 if err != nil { 1145 t.Fatalf("ObjectGet() returned unexpected error %v", err) 1146 } 1147 bytesFromReadPlan = append(bytesFromReadPlan, b...) 1148 } 1149 if !bytes.Equal(bytesFromReadPlan, []byte{0x22, 0x33, 0x04}) { 1150 t.Fatalf("expected bytes from suffix read plan 0x22, 0x33, 0x04; got %v", bytesFromReadPlan) 1151 } 1152 1153 // Long suffix byte range query, like "Range: bytes=-200" (for a file of size < 200) 1154 length = uint64(10) // our file has only 5 bytes 1155 testSuffixReadPlan, err = testVolumeHandle.GetReadPlan(fileInodeNumber, nil, &length) 1156 if nil != err { 1157 t.Fatalf("GetReadPlan(fileInodeNumber, nil, 10) failed: %v", err) 1158 } 1159 bytesFromReadPlan = []byte{} 1160 for _, rps := range testSuffixReadPlan { 1161 pathParts := strings.SplitN(rps.ObjectPath, "/", 5) 1162 b, err := swiftclient.ObjectGet(pathParts[2], pathParts[3], pathParts[4], rps.Offset, rps.Length) 1163 if err != nil { 1164 t.Fatalf("ObjectGet() returned unexpected error %v", err) 1165 } 1166 bytesFromReadPlan = append(bytesFromReadPlan, b...) 1167 } 1168 if !bytes.Equal(bytesFromReadPlan, []byte{0x00, 0x11, 0x22, 0x33, 0x04}) { 1169 t.Fatalf("expected bytes from suffix read plan 0x00, 0x11, 0x22, 0x33, 0x04; got %v", bytesFromReadPlan) 1170 } 1171 1172 // Prefix byte range query, like "Range: bytes=4-" 1173 offset = uint64(3) 1174 testPrefixReadPlan, err := testVolumeHandle.GetReadPlan(fileInodeNumber, &offset, nil) 1175 if nil != err { 1176 t.Fatalf("GetReadPlan(fileInodeNumber, 3, nil) failed: %v", err) 1177 } 1178 bytesFromReadPlan = []byte{} 1179 for _, rps := range testPrefixReadPlan { 1180 pathParts := strings.SplitN(rps.ObjectPath, "/", 5) 1181 b, err := swiftclient.ObjectGet(pathParts[2], pathParts[3], pathParts[4], rps.Offset, rps.Length) 1182 if err != nil { 1183 t.Fatalf("ObjectGet() returned unexpected error %v", err) 1184 } 1185 bytesFromReadPlan = append(bytesFromReadPlan, b...) 1186 } 1187 if !bytes.Equal(bytesFromReadPlan, []byte{0x33, 0x04}) { 1188 t.Fatalf("expected bytes from prefix read plan 0x33, 0x04; got %v", bytesFromReadPlan) 1189 } 1190 1191 accountName, containerName, objectName, err = utils.PathToAcctContObj(testReadPlan[0].ObjectPath) 1192 if nil != err { 1193 t.Fatalf("expected %q to be a legal object path", testReadPlan[0].ObjectPath) 1194 } 1195 1196 headSlice, err := swiftclient.ObjectGet(accountName, containerName, objectName, testReadPlan[0].Offset, 1) 1197 if nil != err { 1198 t.Fatalf("ObjectGet() returned unexpected error: %v", err) 1199 } 1200 if 0 != bytes.Compare(headSlice, []byte{0x00}) { 1201 t.Fatalf("expected byte of %v to be 0x00, got %x", testReadPlan[0].ObjectPath, headSlice) 1202 } 1203 1204 accountName, containerName, objectName, err = utils.PathToAcctContObj(testReadPlan[1].ObjectPath) 1205 if nil != err { 1206 t.Fatalf("expected %q to be a legal object path", testReadPlan[1].ObjectPath) 1207 } 1208 middleSlice, err := swiftclient.ObjectGet(accountName, containerName, objectName, testReadPlan[1].Offset, 3) 1209 if nil != err { 1210 t.Fatalf("ObjectGet() returned unexpected error: %v", err) 1211 } 1212 if 0 != bytes.Compare(middleSlice, []byte{0x11, 0x22, 0x33}) { 1213 t.Fatalf("expected byte of %v to be 0x00, got %x", testReadPlan[0].ObjectPath, headSlice) 1214 } 1215 1216 accountName, containerName, objectName, err = utils.PathToAcctContObj(testReadPlan[2].ObjectPath) 1217 if nil != err { 1218 t.Fatalf("expected %q to be a legal object path", testReadPlan[2].ObjectPath) 1219 } 1220 tailSlice, err := swiftclient.ObjectGet(accountName, containerName, objectName, testReadPlan[2].Offset, 1) 1221 if nil != err { 1222 t.Fatalf("objectContext.Get() returned unexpected error: %v", err) 1223 } 1224 if 0 != bytes.Compare(tailSlice, []byte{0x04}) { 1225 t.Fatalf("expected byte of %v to be 0x04, got %x", testReadPlan[0].ObjectPath, tailSlice) 1226 } 1227 1228 fileInodeObjectPath, err = testVolumeHandle.ProvisionObject() 1229 if nil != err { 1230 t.Fatalf("ProvisionObjectPath() failed: %v", err) 1231 } 1232 1233 accountName, containerName, objectName, err = utils.PathToAcctContObj(fileInodeObjectPath) 1234 if err != nil { 1235 t.Fatalf("couldn't parse %v as object path", fileInodeObjectPath) 1236 } 1237 1238 putContext, err = swiftclient.ObjectFetchChunkedPutContext(accountName, containerName, objectName, "") 1239 if err != nil { 1240 t.Fatalf("fetching chunked put context failed") 1241 } 1242 err = putContext.SendChunk([]byte{0xFE, 0xFF}) 1243 if err != nil { 1244 t.Fatalf("sending chunk failed") 1245 } 1246 err = putContext.Close() 1247 if err != nil { 1248 t.Fatalf("closing chunked PUT failed") 1249 } 1250 1251 postMetadata, err = testVolumeHandle.GetMetadata(fileInodeNumber) 1252 if nil != err { 1253 t.Fatalf("GetMetadata(fileInodeNumber) failed: %v", err) 1254 } 1255 checkMetadata(t, postMetadata, testMetadata, MetadataNumWritesField, "GetMetadata() before Wrote(,,,,,,,false)") 1256 err = testVolumeHandle.Wrote(fileInodeNumber, containerName, objectName, []uint64{0}, []uint64{0}, []uint64{2}, time.Now(), false) 1257 if nil != err { 1258 t.Fatalf("Wrote(fileInodeNumber, containerName, objectName, []uint64{0}, []uint64{0}, []uint64{2}, time.Now(), false) failed: %v", err) 1259 } 1260 postMetadata, err = testVolumeHandle.GetMetadata(fileInodeNumber) 1261 if nil != err { 1262 t.Fatalf("GetMetadata(fileInodeNumber) failed: %v", err) 1263 } 1264 testMetadata.NumWrites = 1 1265 checkMetadata(t, postMetadata, testMetadata, MetadataNumWritesField, "GetMetadata() after Wrote(,,,,,,,false)") 1266 1267 testFileInodeData, err = testVolumeHandle.Read(fileInodeNumber, 0, 4, nil) 1268 if nil != err { 1269 t.Fatalf("Read(fileInodeNumber, 0, 4) failed: %v", err) 1270 } 1271 if 0 != bytes.Compare(testFileInodeData, []byte{0xFE, 0xFF}) { 1272 t.Fatalf("Read(fileInodeNumber, 0, 4) returned unexpected testFileInodeData") 1273 } 1274 1275 preResizeMetadata, err := testVolumeHandle.GetMetadata(fileInodeNumber) 1276 if nil != err { 1277 t.Fatalf("GetMetadata(fileInodeNumber) failed: %v", err) 1278 } 1279 1280 testMetadata.Size = 0 1281 err = testVolumeHandle.SetSize(fileInodeNumber, testMetadata.Size) 1282 if nil != err { 1283 t.Fatalf("SetSize(fileInodeNumber, 0) failed: %v", err) 1284 } 1285 1286 postMetadata, err = testVolumeHandle.GetMetadata(fileInodeNumber) 1287 if nil != err { 1288 t.Fatalf("GetMetadata(fileInodeNumber) failed: %v", err) 1289 } 1290 checkMetadata(t, postMetadata, testMetadata, MetadataSizeField, "GetMetadata() after SetSize()") 1291 checkMetadataTimeChanges(t, preResizeMetadata, postMetadata, false, true, false, true, "SetSize changed metadata times inappropriately") 1292 1293 err = testVolumeHandle.Flush(fileInodeNumber, true) 1294 if nil != err { 1295 t.Fatalf("Flush(fileInodeNumber, true) failed: %v", err) 1296 } 1297 1298 err = testVolumeHandle.Destroy(fileInodeNumber) 1299 if nil != err { 1300 t.Fatalf("Destroy(fileInodeNumber) failed: %v", err) 1301 } 1302 1303 file1Inode, err := testVolumeHandle.CreateFile(PosixModePerm, 0, 0) 1304 if nil != err { 1305 t.Fatalf("CreateFile() failed: %v", err) 1306 } 1307 1308 file2Inode, err := testVolumeHandle.CreateFile(PosixModePerm, 0, 0) 1309 if nil != err { 1310 t.Fatalf("CreateFile() failed: %v", err) 1311 } 1312 1313 err = testVolumeHandle.Link(RootDirInodeNumber, "1stLocation", file1Inode, false) 1314 if nil != err { 1315 t.Fatalf("Link(RootDirInodeNumber, \"1stLocation\", file1Inode, false) failed: %v", err) 1316 } 1317 1318 err = testVolumeHandle.Link(RootDirInodeNumber, "3rdLocation", file2Inode, false) 1319 if nil != err { 1320 t.Fatalf("Link(RootDirInodeNumber, \"3rdLocation\", file2Inode, false) failed: %v", err) 1321 } 1322 1323 dirEntrySlice, moreEntries, err = testVolumeHandle.ReadDir(RootDirInodeNumber, 0, 0) 1324 if nil != err { 1325 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) failed: %v", err) 1326 } 1327 if moreEntries { 1328 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) should have returned moreEntries == false") 1329 } 1330 if 4 != len(dirEntrySlice) { 1331 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) should have returned dirEntrySlice with 2 elements") 1332 } 1333 if (dirEntrySlice[0].InodeNumber != RootDirInodeNumber) || (dirEntrySlice[0].Basename != ".") || (dirEntrySlice[0].NextDirLocation != 1) { 1334 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) returned unexpected dirEntrySlice[0]") 1335 } 1336 if (dirEntrySlice[1].InodeNumber != RootDirInodeNumber) || (dirEntrySlice[1].Basename != "..") || (dirEntrySlice[1].NextDirLocation != 2) { 1337 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) returned unexpected dirEntrySlice[1]") 1338 } 1339 if (dirEntrySlice[2].InodeNumber != file1Inode) || (dirEntrySlice[2].Basename != "1stLocation") || (dirEntrySlice[2].NextDirLocation != 3) { 1340 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) returned unexpected dirEntrySlice[2]") 1341 } 1342 if (dirEntrySlice[3].InodeNumber != file2Inode) || (dirEntrySlice[3].Basename != "3rdLocation") || (dirEntrySlice[3].NextDirLocation != 4) { 1343 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) returned unexpected dirEntrySlice[2]") 1344 } 1345 1346 toDestroyInodeNumber, err = testVolumeHandle.Move(RootDirInodeNumber, "1stLocation", RootDirInodeNumber, "2ndLocation") 1347 if nil != err { 1348 t.Fatalf("Move(RootDirInodeNumber, \"1stLocation\", RootDirInodeNumber, \"2ndLocation\") failed: %v", err) 1349 } 1350 if InodeNumber(0) != toDestroyInodeNumber { 1351 t.Fatalf("Move(RootDirInodeNumber, \"1stLocation\", RootDirInodeNumber, \"2ndLocation\") should have returned toDestroyInodeNumber == 0") 1352 } 1353 1354 dirEntrySlice, moreEntries, err = testVolumeHandle.ReadDir(RootDirInodeNumber, 0, 0) 1355 if nil != err { 1356 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) failed: %v", err) 1357 } 1358 if moreEntries { 1359 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) should have returned moreEntries == false") 1360 } 1361 if 4 != len(dirEntrySlice) { 1362 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) should have returned dirEntrySlice with 2 elements") 1363 } 1364 if (dirEntrySlice[0].InodeNumber != RootDirInodeNumber) || (dirEntrySlice[0].Basename != ".") || (dirEntrySlice[0].NextDirLocation != 1) { 1365 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) returned unexpected dirEntrySlice[0]") 1366 } 1367 if (dirEntrySlice[1].InodeNumber != RootDirInodeNumber) || (dirEntrySlice[1].Basename != "..") || (dirEntrySlice[1].NextDirLocation != 2) { 1368 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) returned unexpected dirEntrySlice[1]") 1369 } 1370 if (dirEntrySlice[2].InodeNumber != file1Inode) || (dirEntrySlice[2].Basename != "2ndLocation") || (dirEntrySlice[2].NextDirLocation != 3) { 1371 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) returned unexpected dirEntrySlice[2]") 1372 } 1373 if (dirEntrySlice[3].InodeNumber != file2Inode) || (dirEntrySlice[3].Basename != "3rdLocation") || (dirEntrySlice[3].NextDirLocation != 4) { 1374 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) returned unexpected dirEntrySlice[2]") 1375 } 1376 1377 toDestroyInodeNumber, err = testVolumeHandle.Unlink(RootDirInodeNumber, "3rdLocation", false) 1378 if nil != err { 1379 t.Fatalf("Unlink(RootDirInodeNumber, \"3rdLocation\", false) failed: %v", err) 1380 } 1381 if file2Inode != toDestroyInodeNumber { 1382 t.Fatalf("Unlink(RootDirInodeNumber, \"3rdLocation\", false) should have returned toDestroyInodeNumber == file2Inode") 1383 } 1384 toDestroyInodeNumber, err = testVolumeHandle.Move(RootDirInodeNumber, "2ndLocation", RootDirInodeNumber, "3rdLocation") 1385 if nil != err { 1386 t.Fatalf("Move(RootDirInodeNumber, \"2ndLocation\", RootDirInodeNumber, \"3rdLocation\") failed: %v", err) 1387 } 1388 if InodeNumber(0) != toDestroyInodeNumber { 1389 t.Fatalf("Move(RootDirInodeNumber, \"2ndLocation\", RootDirInodeNumber, \"3rdLocation\") should have returned toDestroyInodeNumber == 0") 1390 } 1391 1392 dirEntrySlice, moreEntries, err = testVolumeHandle.ReadDir(RootDirInodeNumber, 0, 0) 1393 if nil != err { 1394 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) failed: %v", err) 1395 } 1396 if moreEntries { 1397 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) should have returned moreEntries == false") 1398 } 1399 if 3 != len(dirEntrySlice) { 1400 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) should have returned dirEntrySlice with 2 elements") 1401 } 1402 if (dirEntrySlice[0].InodeNumber != RootDirInodeNumber) || (dirEntrySlice[0].Basename != ".") || (dirEntrySlice[0].NextDirLocation != 1) { 1403 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) returned unexpected dirEntrySlice[0]") 1404 } 1405 if (dirEntrySlice[1].InodeNumber != RootDirInodeNumber) || (dirEntrySlice[1].Basename != "..") || (dirEntrySlice[1].NextDirLocation != 2) { 1406 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) returned unexpected dirEntrySlice[1]") 1407 } 1408 if (dirEntrySlice[2].InodeNumber != file1Inode) || (dirEntrySlice[2].Basename != "3rdLocation") || (dirEntrySlice[2].NextDirLocation != 3) { 1409 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) returned unexpected dirEntrySlice[2]") 1410 } 1411 1412 err = testVolumeHandle.Destroy(file2Inode) 1413 if nil != err { 1414 t.Fatalf("Destroy(file2Inode) failed: %v", err) 1415 } 1416 1417 postMetadata, err = testVolumeHandle.GetMetadata(RootDirInodeNumber) 1418 if nil != err { 1419 t.Fatalf("GetMetadata(RootDirInodeNumber) failed: %v", err) 1420 } 1421 testMetadata.LinkCount = 2 1422 checkMetadata(t, postMetadata, testMetadata, MetadataLinkCountField, "GetMetadata() after multiple calls to Link()") 1423 1424 subDirInode, err := testVolumeHandle.CreateDir(PosixModePerm, 0, 0) 1425 if nil != err { 1426 t.Fatalf("CreateDir() failed: %v", err) 1427 } 1428 1429 subDirInodeType, err := testVolumeHandle.GetType(subDirInode) 1430 if nil != err { 1431 t.Fatalf("GetType(subDirInode) failed: %v", err) 1432 } 1433 if DirType != subDirInodeType { 1434 t.Fatalf("GetType(subDirInode) returned unexpected type: %v", subDirInodeType) 1435 } 1436 1437 subDirLinkCount, err := testVolumeHandle.GetLinkCount(subDirInode) 1438 if nil != err { 1439 t.Fatalf("GetLinkCount(subDirInode) failed: %v", err) 1440 } 1441 if 1 != subDirLinkCount { 1442 t.Fatalf("GetLinkCount(subDirInode) returned unexpected linkCount: %v", subDirLinkCount) 1443 } 1444 1445 err = testVolumeHandle.SetLinkCount(subDirInode, uint64(2)) 1446 if nil != err { 1447 t.Fatalf("SetLinkCount(subDirInode, uint64(2)) failed: %v", err) 1448 } 1449 1450 subDirLinkCount, err = testVolumeHandle.GetLinkCount(subDirInode) 1451 if nil != err { 1452 t.Fatalf("GetLinkCount(subDirInode) failed: %v", err) 1453 } 1454 if 2 != subDirLinkCount { 1455 t.Fatalf("GetLinkCount(subDirInode) returned unexpected linkCount: %v", subDirLinkCount) 1456 } 1457 1458 err = testVolumeHandle.SetLinkCount(subDirInode, uint64(1)) 1459 if nil != err { 1460 t.Fatalf("SetLinkCount(subDirInode, uint64(1)) failed: %v", err) 1461 } 1462 1463 subDirLinkCount, err = testVolumeHandle.GetLinkCount(subDirInode) 1464 if nil != err { 1465 t.Fatalf("GetLinkCount(subDirInode) failed: %v", err) 1466 } 1467 if 1 != subDirLinkCount { 1468 t.Fatalf("GetLinkCount(subDirInode) returned unexpected linkCount: %v", subDirLinkCount) 1469 } 1470 1471 // it should be illegal to link to a directory 1472 err = testVolumeHandle.Link(RootDirInodeNumber, "subDir", subDirInode, false) 1473 if nil != err { 1474 t.Fatalf("Link(RootDirInodeNumber, \"subDir\", subDirInode, false) failed: %v", err) 1475 } 1476 1477 rootDirLinkCount, err = testVolumeHandle.GetLinkCount(RootDirInodeNumber) 1478 if nil != err { 1479 t.Fatalf("GetLinkCount(RootDirInodeNumber) failed: %v", err) 1480 } 1481 if 3 != rootDirLinkCount { 1482 t.Fatalf("GetLinkCount(RootDirInodeNumber) returned unexpected linkCount: %v", rootDirLinkCount) 1483 } 1484 1485 subDirLinkCount, err = testVolumeHandle.GetLinkCount(subDirInode) 1486 if nil != err { 1487 t.Fatalf("GetLinkCount(subDirInode) failed: %v", err) 1488 } 1489 if 2 != subDirLinkCount { 1490 t.Fatalf("GetLinkCount(subDirInode) returned unexpected linkCount: %v", subDirLinkCount) 1491 } 1492 1493 postMetadata, err = testVolumeHandle.GetMetadata(RootDirInodeNumber) 1494 if nil != err { 1495 t.Fatalf("GetMetadata(RootDirInodeNumber) failed: %v", err) 1496 } 1497 testMetadata.LinkCount = 3 1498 checkMetadata(t, postMetadata, testMetadata, MetadataLinkCountField, "GetMetadata() after Link()") 1499 1500 dirEntrySlice, moreEntries, err = testVolumeHandle.ReadDir(RootDirInodeNumber, 0, 0) 1501 if nil != err { 1502 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) failed: %v", err) 1503 } 1504 if moreEntries { 1505 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) should have returned moreEntries == false") 1506 } 1507 if 4 != len(dirEntrySlice) { 1508 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) should have returned dirEntrySlice with 2 elements, got %#v, which is of length %v", dirEntrySlice, len(dirEntrySlice)) 1509 } 1510 if (dirEntrySlice[0].InodeNumber != RootDirInodeNumber) || (dirEntrySlice[0].Basename != ".") || (dirEntrySlice[0].NextDirLocation != 1) { 1511 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) returned unexpected dirEntrySlice[0]") 1512 } 1513 if (dirEntrySlice[1].InodeNumber != RootDirInodeNumber) || (dirEntrySlice[1].Basename != "..") || (dirEntrySlice[1].NextDirLocation != 2) { 1514 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) returned unexpected dirEntrySlice[1]") 1515 } 1516 if (dirEntrySlice[2].InodeNumber != file1Inode) || (dirEntrySlice[2].Basename != "3rdLocation") || (dirEntrySlice[2].NextDirLocation != 3) { 1517 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) returned unexpected dirEntrySlice[2]") 1518 } 1519 if (dirEntrySlice[3].InodeNumber != subDirInode) || (dirEntrySlice[3].Basename != "subDir") || (dirEntrySlice[3].NextDirLocation != 4) { 1520 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) returned unexpected dirEntrySlice[3]") 1521 } 1522 1523 dirEntrySlice, moreEntries, err = testVolumeHandle.ReadDir(subDirInode, 0, 0) 1524 if nil != err { 1525 t.Fatalf("ReadDir(subDirInode, 0, 0) failed: %v", err) 1526 } 1527 if moreEntries { 1528 t.Fatalf("ReadDir(subDirInode, 0, 0) should have returned moreEntries == false") 1529 } 1530 if 2 != len(dirEntrySlice) { 1531 t.Fatalf("ReadDir(subDirInode, 0, 0) should have returned dirEntrySlice with 2 elements") 1532 } 1533 if (dirEntrySlice[0].InodeNumber != subDirInode) || (dirEntrySlice[0].Basename != ".") || (dirEntrySlice[0].NextDirLocation != 1) { 1534 t.Fatalf("ReadDir(subDirInode, 0, 0) returned unexpected dirEntrySlice[0]") 1535 } 1536 if (dirEntrySlice[1].InodeNumber != RootDirInodeNumber) || (dirEntrySlice[1].Basename != "..") || (dirEntrySlice[1].NextDirLocation != 2) { 1537 t.Fatalf("ReadDir(subDirInode, 0, 0) returned unexpected dirEntrySlice[1]") 1538 } 1539 1540 toDestroyInodeNumber, err = testVolumeHandle.Move(RootDirInodeNumber, "3rdLocation", subDirInode, "4thLocation") 1541 if nil != err { 1542 t.Fatalf("Move(RootDirInodeNumber, \"3rdLocation\", subDirInode, \"4thLocation\") failed: %v", err) 1543 } 1544 if InodeNumber(0) != toDestroyInodeNumber { 1545 t.Fatalf("Move(RootDirInodeNumber, \"3rdLocation\", subDirInode, \"4thLocation\") should have returned toDestroyInodeNumber == 0") 1546 } 1547 1548 dirEntrySlice, moreEntries, err = testVolumeHandle.ReadDir(RootDirInodeNumber, 0, 0) 1549 if nil != err { 1550 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) failed: %v", err) 1551 } 1552 if moreEntries { 1553 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) should have returned moreEntries == false") 1554 } 1555 if 3 != len(dirEntrySlice) { 1556 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) should have returned dirEntrySlice with 2 elements, got %#v", dirEntrySlice) 1557 } 1558 if (dirEntrySlice[0].InodeNumber != RootDirInodeNumber) || (dirEntrySlice[0].Basename != ".") || (dirEntrySlice[0].NextDirLocation != 1) { 1559 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) returned unexpected dirEntrySlice[0]") 1560 } 1561 if (dirEntrySlice[1].InodeNumber != RootDirInodeNumber) || (dirEntrySlice[1].Basename != "..") || (dirEntrySlice[1].NextDirLocation != 2) { 1562 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) returned unexpected dirEntrySlice[1]") 1563 } 1564 if (dirEntrySlice[2].InodeNumber != subDirInode) || (dirEntrySlice[2].Basename != "subDir") || (dirEntrySlice[2].NextDirLocation != 3) { 1565 t.Fatalf("ReadDir(RootDirInodeNumber, 0, 0) returned unexpected dirEntrySlice[2]") 1566 } 1567 1568 dirEntrySlice, moreEntries, err = testVolumeHandle.ReadDir(subDirInode, 0, 0) 1569 if nil != err { 1570 t.Fatalf("ReadDir(subDirInode, 0, 0) failed: %v", err) 1571 } 1572 if moreEntries { 1573 t.Fatalf("ReadDir(subDirInode, 0, 0) should have returned moreEntries == false") 1574 } 1575 if 3 != len(dirEntrySlice) { 1576 t.Fatalf("ReadDir(subDirInode, 0, 0) should have returned dirEntrySlice with 2 elements") 1577 } 1578 if (dirEntrySlice[0].InodeNumber != subDirInode) || (dirEntrySlice[0].Basename != ".") || (dirEntrySlice[0].NextDirLocation != 1) { 1579 t.Fatalf("ReadDir(subDirInode, 0, 0) returned unexpected dirEntrySlice[0]") 1580 } 1581 if (dirEntrySlice[1].InodeNumber != RootDirInodeNumber) || (dirEntrySlice[1].Basename != "..") || (dirEntrySlice[1].NextDirLocation != 2) { 1582 t.Fatalf("ReadDir(subDirInode, 0, 0) returned unexpected dirEntrySlice[1]") 1583 } 1584 if (dirEntrySlice[2].InodeNumber != file1Inode) || (dirEntrySlice[2].Basename != "4thLocation") || (dirEntrySlice[2].NextDirLocation != 3) { 1585 t.Fatalf("ReadDir(subDirInode, 0, 0) returned unexpected dirEntrySlice[2]") 1586 } 1587 1588 toDestroyInodeNumber, err = testVolumeHandle.Unlink(subDirInode, "4thLocation", false) 1589 if nil != err { 1590 t.Fatalf("Unlink(subDirInode, \"4thLocation\", false) failed: %v", err) 1591 } 1592 if file1Inode != toDestroyInodeNumber { 1593 t.Fatalf("Unlink(subDirInode, \"4thLocation\", false) should have returned toDestroyInodeNumber == file1Inode") 1594 } 1595 1596 err = testVolumeHandle.Destroy(file1Inode) 1597 if nil != err { 1598 t.Fatalf("Destroy(file1Inode) failed: %v", err) 1599 } 1600 1601 toDestroyInodeNumber, err = testVolumeHandle.Unlink(RootDirInodeNumber, "subDir", false) 1602 if nil != err { 1603 t.Fatalf("Unlink(RootDirInodeNumber, \"subDir\", false) failed: %v", err) 1604 } 1605 if subDirInode != toDestroyInodeNumber { 1606 t.Fatalf("Unlink(RootDirInodeNumber, \"subDir\", false) should have returned toDestroyInodeNumber == subDirInode") 1607 } 1608 1609 rootDirLinkCount, err = testVolumeHandle.GetLinkCount(RootDirInodeNumber) 1610 if nil != err { 1611 t.Fatalf("GetLinkCount(RootDirInodeNumber) failed: %v", err) 1612 } 1613 if 2 != rootDirLinkCount { 1614 t.Fatalf("GetLinkCount(RootDirInodeNumber) returned unexpected linkCount: %v", rootDirLinkCount) 1615 } 1616 1617 subDirLinkCount, err = testVolumeHandle.GetLinkCount(subDirInode) 1618 if nil != err { 1619 t.Fatalf("GetLinkCount(subDirInode) failed: %v", err) 1620 } 1621 if 1 != subDirLinkCount { 1622 t.Fatalf("GetLinkCount(subDirInode) returned unexpected linkCount: %v", subDirLinkCount) 1623 } 1624 1625 err = testVolumeHandle.Destroy(subDirInode) 1626 if nil != err { 1627 t.Fatalf("Destroy(subDirInode) failed: %v", err) 1628 } 1629 1630 positiveDurationToDelayOrSkew, err := time.ParseDuration("+" + durationToDelayOrSkew) 1631 if nil != err { 1632 t.Fatalf("time.ParseDuration(\"100ms\") failed: %v", err) 1633 } 1634 negativeDurationToDelayOrSkew, err := time.ParseDuration("-" + durationToDelayOrSkew) 1635 if nil != err { 1636 t.Fatalf("time.ParseDuration(\"-100ms\") failed: %v", err) 1637 } 1638 1639 timeBeforeCreateDir := time.Now() 1640 1641 time.Sleep(positiveDurationToDelayOrSkew) 1642 1643 testMetadata.Mode = InodeMode(0744) 1644 testMetadata.UserID = InodeUserID(987) 1645 testMetadata.GroupID = InodeGroupID(654) 1646 dirInode, err := testVolumeHandle.CreateDir(testMetadata.Mode, testMetadata.UserID, testMetadata.GroupID) 1647 if nil != err { 1648 t.Fatalf("CreateDir() failed: %v", err) 1649 } 1650 1651 time.Sleep(positiveDurationToDelayOrSkew) 1652 1653 timeAfterCreateDir := time.Now() 1654 1655 dirInodeMetadataAfterCreateDir, err := testVolumeHandle.GetMetadata(dirInode) 1656 if nil != err { 1657 t.Fatalf("GetMetadata(dirInode) failed: %v", err) 1658 } 1659 if dirInodeMetadataAfterCreateDir.CreationTime.Before(timeBeforeCreateDir) || dirInodeMetadataAfterCreateDir.CreationTime.After(timeAfterCreateDir) { 1660 t.Fatalf("dirInodeMetadataAfterCreateDir.CreationTime unexpected") 1661 } 1662 if !dirInodeMetadataAfterCreateDir.ModificationTime.Equal(dirInodeMetadataAfterCreateDir.CreationTime) { 1663 t.Fatalf("dirInodeMetadataAfterCreateDir.ModificationTime unexpected") 1664 } 1665 if !dirInodeMetadataAfterCreateDir.AccessTime.Equal(dirInodeMetadataAfterCreateDir.CreationTime) { 1666 t.Fatalf("dirInodeMetadataAfterCreateDir.AccessTime unexpected") 1667 } 1668 if !dirInodeMetadataAfterCreateDir.AttrChangeTime.Equal(dirInodeMetadataAfterCreateDir.CreationTime) { 1669 t.Fatalf("dirInodeMetadataAfterCreateDir.AttrChangeTime unexpected") 1670 } 1671 checkMetadata(t, dirInodeMetadataAfterCreateDir, testMetadata, MetadataPermFields, "GetMetadata() after CreateDir()") 1672 1673 // TODO: Add more tests related to mode/uid/gid and CreateDir(): mode > 0777, etc. 1674 1675 testMetadata.CreationTime = dirInodeMetadataAfterCreateDir.CreationTime.Add(negativeDurationToDelayOrSkew) 1676 testMetadata.ModificationTime = dirInodeMetadataAfterCreateDir.ModificationTime 1677 testMetadata.AccessTime = dirInodeMetadataAfterCreateDir.AccessTime 1678 testMetadata.AttrChangeTime = dirInodeMetadataAfterCreateDir.AttrChangeTime 1679 1680 timeBeforeOp = time.Now() 1681 time.Sleep(positiveDurationToDelayOrSkew) 1682 1683 err = testVolumeHandle.SetCreationTime(dirInode, testMetadata.CreationTime) 1684 if nil != err { 1685 t.Fatalf("SetCreationTime(dirInode,) failed: %v", err) 1686 } 1687 time.Sleep(positiveDurationToDelayOrSkew) 1688 timeAfterOp = time.Now() 1689 1690 dirInodeMetadataAfterSetCreationTime, err := testVolumeHandle.GetMetadata(dirInode) 1691 if nil != err { 1692 t.Fatalf("GetMetadata(dirInode) failed: %v", err) 1693 } 1694 checkMetadata(t, dirInodeMetadataAfterSetCreationTime, testMetadata, MetadataNotAttrTimeFields, 1695 "GetMetadata() after SetCreationTime() test 2") 1696 if dirInodeMetadataAfterSetCreationTime.AttrChangeTime.Before(timeBeforeOp) || 1697 dirInodeMetadataAfterSetCreationTime.AttrChangeTime.After(timeAfterOp) { 1698 t.Fatalf("dirInodeMetadataAfterSetCreationTime.AttrChangeTime unexpected") 1699 } 1700 1701 testMetadata.ModificationTime = dirInodeMetadataAfterSetCreationTime.ModificationTime.Add(negativeDurationToDelayOrSkew) 1702 timeBeforeOp = time.Now() 1703 time.Sleep(positiveDurationToDelayOrSkew) 1704 1705 err = testVolumeHandle.SetModificationTime(dirInode, testMetadata.ModificationTime) 1706 if nil != err { 1707 t.Fatalf("SetModificationTime(dirInode,) failed: %v", err) 1708 } 1709 time.Sleep(positiveDurationToDelayOrSkew) 1710 timeAfterOp = time.Now() 1711 1712 dirInodeMetadataAfterSetModificationTime, err := testVolumeHandle.GetMetadata(dirInode) 1713 if nil != err { 1714 t.Fatalf("GetMetadata(dirInode) failed: %v", err) 1715 } 1716 checkMetadata(t, dirInodeMetadataAfterSetModificationTime, testMetadata, MetadataNotAttrTimeFields, "GetMetadata() after SetModificationTime()") 1717 if dirInodeMetadataAfterSetModificationTime.AttrChangeTime.Before(timeBeforeOp) || 1718 dirInodeMetadataAfterSetModificationTime.AttrChangeTime.After(timeAfterOp) { 1719 t.Fatalf("dirInodeMetadataAfterSetModificationTime.AttrChangeTime unexpected") 1720 } 1721 1722 testMetadata.AccessTime = dirInodeMetadataAfterSetModificationTime.AccessTime.Add(negativeDurationToDelayOrSkew) 1723 timeBeforeOp = time.Now() 1724 time.Sleep(positiveDurationToDelayOrSkew) 1725 1726 err = testVolumeHandle.SetAccessTime(dirInode, testMetadata.AccessTime) 1727 if nil != err { 1728 t.Fatalf("SetAccessTime(dirInode,) failed: %v", err) 1729 } 1730 time.Sleep(positiveDurationToDelayOrSkew) 1731 timeAfterOp = time.Now() 1732 1733 dirInodeMetadataAfterSetAccessTime, err := testVolumeHandle.GetMetadata(dirInode) 1734 if nil != err { 1735 t.Fatalf("GetMetadata(dirInode) failed: %v", err) 1736 } 1737 checkMetadata(t, dirInodeMetadataAfterSetAccessTime, testMetadata, MetadataNotAttrTimeFields, "GetMetadata() after testVolumeHandle.SetAccessTime()") 1738 if dirInodeMetadataAfterSetAccessTime.AttrChangeTime.Before(timeBeforeOp) || 1739 dirInodeMetadataAfterSetAccessTime.AttrChangeTime.After(timeAfterOp) { 1740 t.Fatalf("dirInodeMetadataAfterSetAccessTime.AttrChangeTime unexpected") 1741 } 1742 1743 timeBeforeDirInodePutStream := time.Now() 1744 1745 time.Sleep(positiveDurationToDelayOrSkew) 1746 1747 err = testVolumeHandle.PutStream(dirInode, "stream_name", []byte{}) 1748 if nil != err { 1749 t.Fatalf("PutStream(dirInode,,) failed: %v", err) 1750 } 1751 time.Sleep(positiveDurationToDelayOrSkew) 1752 1753 timeAfterDirInodePutStream := time.Now() 1754 1755 dirInodeMetadataAfterPutStream, err := testVolumeHandle.GetMetadata(dirInode) 1756 if nil != err { 1757 t.Fatalf("GetMetadata(dirInode) failed: %v", err) 1758 } 1759 testMetadata.CreationTime = dirInodeMetadataAfterSetAccessTime.CreationTime 1760 testMetadata.ModificationTime = dirInodeMetadataAfterSetAccessTime.ModificationTime 1761 testMetadata.AccessTime = dirInodeMetadataAfterSetAccessTime.AccessTime 1762 checkMetadata(t, dirInodeMetadataAfterPutStream, testMetadata, MetadataNotAttrTimeFields, "GetMetadata() after PutStream()") 1763 if dirInodeMetadataAfterPutStream.AttrChangeTime.Before(timeBeforeDirInodePutStream) || dirInodeMetadataAfterPutStream.AttrChangeTime.After(timeAfterDirInodePutStream) { 1764 t.Fatalf("dirInodeMetadataAfterPutStream.AttrChangeTime unexpected") 1765 } 1766 1767 timeBeforeDirInodeDeleteStream := time.Now() 1768 1769 time.Sleep(positiveDurationToDelayOrSkew) 1770 1771 err = testVolumeHandle.DeleteStream(dirInode, "stream_name") 1772 if nil != err { 1773 t.Fatalf("DeleteStream(dirInode,) failed: %v", err) 1774 } 1775 1776 time.Sleep(positiveDurationToDelayOrSkew) 1777 1778 timeAfterDirInodeDeleteStream := time.Now() 1779 1780 dirInodeMetadataAfterDeleteStream, err := testVolumeHandle.GetMetadata(dirInode) 1781 if nil != err { 1782 t.Fatalf("GetMetadata(dirInode) failed: %v", err) 1783 } 1784 checkMetadata(t, dirInodeMetadataAfterPutStream, testMetadata, MetadataNotAttrTimeFields, "GetMetadata() after PutStream()") 1785 if dirInodeMetadataAfterDeleteStream.AttrChangeTime.Before(timeBeforeDirInodeDeleteStream) || dirInodeMetadataAfterDeleteStream.AttrChangeTime.After(timeAfterDirInodeDeleteStream) { 1786 t.Fatalf("dirInodeMetadataAfterDeleteStream.AttrChangeTime unexpected") 1787 } 1788 1789 timeBeforeCreateFile := time.Now() 1790 1791 time.Sleep(positiveDurationToDelayOrSkew) 1792 1793 fileInode, err := testVolumeHandle.CreateFile(PosixModePerm, 0, 0) 1794 if nil != err { 1795 t.Fatalf("CreateFile() failed: %v", err) 1796 } 1797 1798 time.Sleep(positiveDurationToDelayOrSkew) 1799 1800 timeAfterCreateFile := time.Now() 1801 1802 fileInodeMetadataAfterCreateFile, err := testVolumeHandle.GetMetadata(fileInode) 1803 if nil != err { 1804 t.Fatalf("GetMetadata(fileInode) failed: %v", err) 1805 } 1806 if fileInodeMetadataAfterCreateFile.CreationTime.Before(timeBeforeCreateFile) || fileInodeMetadataAfterCreateFile.CreationTime.After(timeAfterCreateFile) { 1807 t.Fatalf("fileInodeMetadataAfterCreateDir.CreationTime unexpected") 1808 } 1809 if !fileInodeMetadataAfterCreateFile.ModificationTime.Equal(fileInodeMetadataAfterCreateFile.CreationTime) { 1810 t.Fatalf("fileInodeMetadataAfterCreateDir.ModificationTime unexpected") 1811 } 1812 if !fileInodeMetadataAfterCreateFile.AccessTime.Equal(fileInodeMetadataAfterCreateFile.CreationTime) { 1813 t.Fatalf("fileInodeMetadataAfterCreateDir.AccessTime unexpected") 1814 } 1815 if !fileInodeMetadataAfterCreateFile.AttrChangeTime.Equal(fileInodeMetadataAfterCreateFile.CreationTime) { 1816 t.Fatalf("fileInodeMetadataAfterCreateDir.AttrChangeTime unexpected") 1817 } 1818 1819 testMetadata.CreationTime = fileInodeMetadataAfterCreateFile.CreationTime.Add(negativeDurationToDelayOrSkew) 1820 testMetadata.ModificationTime = fileInodeMetadataAfterCreateFile.ModificationTime 1821 testMetadata.AccessTime = fileInodeMetadataAfterCreateFile.AccessTime 1822 testMetadata.AttrChangeTime = fileInodeMetadataAfterCreateFile.AttrChangeTime 1823 1824 timeBeforeOp = time.Now() 1825 time.Sleep(positiveDurationToDelayOrSkew) 1826 1827 err = testVolumeHandle.SetCreationTime(fileInode, testMetadata.CreationTime) 1828 if nil != err { 1829 t.Fatalf("SetCreationTime(fileInode,) failed: %v", err) 1830 } 1831 time.Sleep(positiveDurationToDelayOrSkew) 1832 timeAfterOp = time.Now() 1833 1834 fileInodeMetadataAfterSetCreationTime, err := testVolumeHandle.GetMetadata(fileInode) 1835 if nil != err { 1836 t.Fatalf("GetMetadata(fileInode) failed: %v", err) 1837 } 1838 checkMetadata(t, fileInodeMetadataAfterSetCreationTime, testMetadata, MetadataNotAttrTimeFields, 1839 "GetMetadata() after SetCreationTime() test 3") 1840 if fileInodeMetadataAfterSetCreationTime.AttrChangeTime.Before(timeBeforeOp) || 1841 fileInodeMetadataAfterSetCreationTime.AttrChangeTime.After(timeAfterOp) { 1842 t.Fatalf("fileInodeMetadataAfterSetCreationTime.AttrChangeTime unexpected") 1843 } 1844 1845 testMetadata.ModificationTime = fileInodeMetadataAfterSetCreationTime.ModificationTime.Add(negativeDurationToDelayOrSkew) 1846 err = testVolumeHandle.SetModificationTime(fileInode, testMetadata.ModificationTime) 1847 if nil != err { 1848 t.Fatalf("SetModificationTime(fileInode,) failed: %v", err) 1849 } 1850 fileInodeMetadataAfterSetModificationTime, err := testVolumeHandle.GetMetadata(fileInode) 1851 if nil != err { 1852 t.Fatalf("GetMetadata(fileInode) failed: %v", err) 1853 } 1854 checkMetadata(t, fileInodeMetadataAfterSetModificationTime, testMetadata, MetadataNotAttrTimeFields, "GetMetadata() after SetModificationTime()") 1855 1856 testMetadata.AccessTime = fileInodeMetadataAfterSetModificationTime.AccessTime.Add(negativeDurationToDelayOrSkew) 1857 err = testVolumeHandle.SetAccessTime(fileInode, testMetadata.AccessTime) 1858 if nil != err { 1859 t.Fatalf("SetAccessTime(fileInode,) failed: %v", err) 1860 } 1861 fileInodeMetadataAfterSetAccessTime, err := testVolumeHandle.GetMetadata(fileInode) 1862 if nil != err { 1863 t.Fatalf("GetMetadata(fileInode) failed: %v", err) 1864 } 1865 checkMetadata(t, fileInodeMetadataAfterSetAccessTime, testMetadata, MetadataNotAttrTimeFields, "GetMetadata() after SetAccessTime() test 1") 1866 1867 timeBeforeFileInodePutStream := time.Now() 1868 1869 time.Sleep(positiveDurationToDelayOrSkew) 1870 1871 err = testVolumeHandle.PutStream(fileInode, "stream_name", []byte{}) 1872 if nil != err { 1873 t.Fatalf("PutStream(fileInode,,) failed: %v", err) 1874 } 1875 1876 time.Sleep(positiveDurationToDelayOrSkew) 1877 1878 timeAfterFileInodePutStream := time.Now() 1879 1880 fileInodeMetadataAfterPutStream, err := testVolumeHandle.GetMetadata(fileInode) 1881 if nil != err { 1882 t.Fatalf("GetMetadata(fileInode) failed: %v", err) 1883 } 1884 checkMetadata(t, fileInodeMetadataAfterPutStream, testMetadata, MetadataNotAttrTimeFields, "GetMetadata() after PutStream()") 1885 if fileInodeMetadataAfterPutStream.AttrChangeTime.Before(timeBeforeFileInodePutStream) || fileInodeMetadataAfterPutStream.AttrChangeTime.After(timeAfterFileInodePutStream) { 1886 t.Fatalf("fileInodeMetadataAfterPutStream.AttrChangeTime unexpected") 1887 } 1888 1889 timeBeforeFileInodeDeleteStream := time.Now() 1890 1891 time.Sleep(positiveDurationToDelayOrSkew) 1892 1893 err = testVolumeHandle.DeleteStream(fileInode, "stream_name") 1894 if nil != err { 1895 t.Fatalf("DeleteStream(fileInode,) failed: %v", err) 1896 } 1897 1898 time.Sleep(positiveDurationToDelayOrSkew) 1899 1900 timeAfterFileInodeDeleteStream := time.Now() 1901 1902 fileInodeMetadataAfterDeleteStream, err := testVolumeHandle.GetMetadata(fileInode) 1903 if nil != err { 1904 t.Fatalf("GetMetadata(fileInode) failed: %v", err) 1905 } 1906 checkMetadata(t, fileInodeMetadataAfterDeleteStream, testMetadata, MetadataNotAttrTimeFields, "GetMetadata() after DeleteStream()") 1907 if fileInodeMetadataAfterDeleteStream.AttrChangeTime.Before(timeBeforeFileInodeDeleteStream) || fileInodeMetadataAfterDeleteStream.AttrChangeTime.After(timeAfterFileInodeDeleteStream) { 1908 t.Fatalf("fileInodeMetadataAfterDeleteStream.AttrChangeTime unexpected") 1909 } 1910 1911 timeBeforeCreateSymlink := time.Now() 1912 1913 time.Sleep(positiveDurationToDelayOrSkew) 1914 1915 testMetadata.Mode = PosixModePerm 1916 testMetadata.UserID = InodeUserID(1111) 1917 testMetadata.GroupID = InodeGroupID(7777) 1918 symlinkInode, err := testVolumeHandle.CreateSymlink("nowhere", testMetadata.Mode, testMetadata.UserID, testMetadata.GroupID) 1919 if nil != err { 1920 t.Fatalf("CreateSymlink(\"nowhere\") failed: %v", err) 1921 } 1922 1923 time.Sleep(positiveDurationToDelayOrSkew) 1924 1925 timeAfterCreateSymlink := time.Now() 1926 1927 symlinkInodeMetadataAfterCreateSymlink, err := testVolumeHandle.GetMetadata(symlinkInode) 1928 if nil != err { 1929 t.Fatalf("GetMetadata(symlinkInode) failed: %v", err) 1930 } 1931 if symlinkInodeMetadataAfterCreateSymlink.CreationTime.Before(timeBeforeCreateSymlink) || symlinkInodeMetadataAfterCreateSymlink.CreationTime.After(timeAfterCreateSymlink) { 1932 t.Fatalf("symlinkInodeMetadataAfterCreateDir.CreationTime unexpected") 1933 } 1934 if !symlinkInodeMetadataAfterCreateSymlink.ModificationTime.Equal(symlinkInodeMetadataAfterCreateSymlink.CreationTime) { 1935 t.Fatalf("symlinkInodeMetadataAfterCreateDir.ModificationTime unexpected") 1936 } 1937 if !symlinkInodeMetadataAfterCreateSymlink.AccessTime.Equal(symlinkInodeMetadataAfterCreateSymlink.CreationTime) { 1938 t.Fatalf("symlinkInodeMetadataAfterCreateDir.AccessTime unexpected") 1939 } 1940 if !symlinkInodeMetadataAfterCreateSymlink.AttrChangeTime.Equal(symlinkInodeMetadataAfterCreateSymlink.CreationTime) { 1941 t.Fatalf("symlinkInodeMetadataAfterCreateDir.AttrChangeTime unexpected") 1942 } 1943 checkMetadata(t, symlinkInodeMetadataAfterCreateSymlink, testMetadata, MetadataPermFields, "GetMetadata() after CreateSymlink()") 1944 1945 // TODO: Add more tests related to mode/uid/gid and CreateFile(): mode > 0777, etc. 1946 1947 testMetadata.CreationTime = symlinkInodeMetadataAfterCreateSymlink.CreationTime.Add(negativeDurationToDelayOrSkew) 1948 testMetadata.ModificationTime = symlinkInodeMetadataAfterCreateSymlink.ModificationTime 1949 testMetadata.AccessTime = symlinkInodeMetadataAfterCreateSymlink.AccessTime 1950 testMetadata.AttrChangeTime = symlinkInodeMetadataAfterCreateSymlink.AttrChangeTime 1951 timeBeforeOp = time.Now() 1952 time.Sleep(positiveDurationToDelayOrSkew) 1953 1954 err = testVolumeHandle.SetCreationTime(symlinkInode, testMetadata.CreationTime) 1955 if nil != err { 1956 t.Fatalf("SetCreationTime(symlinkInode,) failed: %v", err) 1957 } 1958 time.Sleep(positiveDurationToDelayOrSkew) 1959 timeAfterOp = time.Now() 1960 1961 symlinkInodeMetadataAfterSetCreationTime, err := testVolumeHandle.GetMetadata(symlinkInode) 1962 if nil != err { 1963 t.Fatalf("GetMetadata(symlinkInode) failed: %v", err) 1964 } 1965 checkMetadata(t, symlinkInodeMetadataAfterSetCreationTime, testMetadata, MetadataNotAttrTimeFields, 1966 "GetMetadata() after SetCreationTime() test 4") 1967 if symlinkInodeMetadataAfterSetCreationTime.AttrChangeTime.Before(timeBeforeOp) || 1968 symlinkInodeMetadataAfterSetCreationTime.AttrChangeTime.After(timeAfterOp) { 1969 t.Fatalf("symlinkInodeMetadataAfterSetCreationTime.AttrChangeTime unexpected") 1970 } 1971 1972 testMetadata.ModificationTime = symlinkInodeMetadataAfterSetCreationTime.ModificationTime.Add(negativeDurationToDelayOrSkew) 1973 err = testVolumeHandle.SetModificationTime(symlinkInode, testMetadata.ModificationTime) 1974 if nil != err { 1975 t.Fatalf("SetModificationTime(symlinkInode,) failed: %v", err) 1976 } 1977 symlinkInodeMetadataAfterSetModificationTime, err := testVolumeHandle.GetMetadata(symlinkInode) 1978 if nil != err { 1979 t.Fatalf("GetMetadata(symlinkInode) failed: %v", err) 1980 } 1981 checkMetadata(t, symlinkInodeMetadataAfterSetModificationTime, testMetadata, MetadataNotAttrTimeFields, "GetMetadata() after SetModificationTime()") 1982 1983 testMetadata.AccessTime = symlinkInodeMetadataAfterSetModificationTime.AccessTime.Add(negativeDurationToDelayOrSkew) 1984 err = testVolumeHandle.SetAccessTime(symlinkInode, testMetadata.AccessTime) 1985 if nil != err { 1986 t.Fatalf("SetAccessTime(symlinkInode,) failed: %v", err) 1987 } 1988 symlinkInodeMetadataAfterSetAccessTime, err := testVolumeHandle.GetMetadata(symlinkInode) 1989 if nil != err { 1990 t.Fatalf("GetMetadata(symlinkInode) failed: %v", err) 1991 } 1992 checkMetadata(t, symlinkInodeMetadataAfterSetAccessTime, testMetadata, MetadataNotAttrTimeFields, "GetMetadata() after SetAccessTime() test 2") 1993 1994 timeBeforeSymlinkInodePutStream := time.Now() 1995 1996 time.Sleep(positiveDurationToDelayOrSkew) 1997 1998 err = testVolumeHandle.PutStream(symlinkInode, "stream_name", []byte{}) 1999 if nil != err { 2000 t.Fatalf("PutStream(symlinkInode,,) failed: %v", err) 2001 } 2002 2003 time.Sleep(positiveDurationToDelayOrSkew) 2004 2005 timeAfterSymlinkInodePutStream := time.Now() 2006 2007 symlinkInodeMetadataAfterPutStream, err := testVolumeHandle.GetMetadata(symlinkInode) 2008 if nil != err { 2009 t.Fatalf("GetMetadata(symlinkInode) failed: %v", err) 2010 } 2011 checkMetadata(t, symlinkInodeMetadataAfterPutStream, testMetadata, MetadataNotAttrTimeFields, "GetMetadata() after PutStream()") 2012 if symlinkInodeMetadataAfterPutStream.AttrChangeTime.Before(timeBeforeSymlinkInodePutStream) || symlinkInodeMetadataAfterPutStream.AttrChangeTime.After(timeAfterSymlinkInodePutStream) { 2013 t.Fatalf("symlinkInodeMetadataAfterPutStream.AttrChangeTime unexpected") 2014 } 2015 2016 timeBeforeSymlinkInodeDeleteStream := time.Now() 2017 2018 time.Sleep(positiveDurationToDelayOrSkew) 2019 2020 err = testVolumeHandle.DeleteStream(symlinkInode, "stream_name") 2021 if nil != err { 2022 t.Fatalf("DeleteStream(symlinkInode,) failed: %v", err) 2023 } 2024 2025 time.Sleep(positiveDurationToDelayOrSkew) 2026 2027 timeAfterSymlinkInodeDeleteStream := time.Now() 2028 2029 symlinkInodeMetadataAfterDeleteStream, err := testVolumeHandle.GetMetadata(symlinkInode) 2030 if nil != err { 2031 t.Fatalf("GetMetadata(symlinkInode) failed: %v", err) 2032 } 2033 checkMetadata(t, symlinkInodeMetadataAfterDeleteStream, testMetadata, MetadataNotAttrTimeFields, "GetMetadata() after DeleteStream()") 2034 if symlinkInodeMetadataAfterDeleteStream.AttrChangeTime.Before(timeBeforeSymlinkInodeDeleteStream) || symlinkInodeMetadataAfterDeleteStream.AttrChangeTime.After(timeAfterSymlinkInodeDeleteStream) { 2035 t.Fatalf("symlinkInodeMetadataAfterDeleteStream.AttrChangeTime unexpected") 2036 } 2037 2038 timeBeforeLink := time.Now() 2039 2040 time.Sleep(positiveDurationToDelayOrSkew) 2041 2042 err = testVolumeHandle.Link(dirInode, "loc_1", fileInode, false) 2043 if nil != err { 2044 t.Fatalf("Link(dirInode, \"loc_1\", fileInode, false) failed: %v", err) 2045 } 2046 2047 time.Sleep(positiveDurationToDelayOrSkew) 2048 2049 timeAfterLink := time.Now() 2050 2051 dirInodeMetadataAfterLink, err := testVolumeHandle.GetMetadata(dirInode) 2052 if nil != err { 2053 t.Fatalf("GetMetadata(dirInode) failed: %v", err) 2054 } 2055 fileInodeMetadataAfterLink, err := testVolumeHandle.GetMetadata(fileInode) 2056 if nil != err { 2057 t.Fatalf("GetMetadata(fileInode) failed: %v", err) 2058 } 2059 2060 if !dirInodeMetadataAfterLink.CreationTime.Equal(dirInodeMetadataAfterDeleteStream.CreationTime) { 2061 t.Fatalf("dirInodeMetadataAfterLink.CreationTime unexpected") 2062 } 2063 if dirInodeMetadataAfterLink.ModificationTime.Before(timeBeforeLink) || dirInodeMetadataAfterLink.ModificationTime.After(timeAfterLink) { 2064 t.Fatalf("dirInodeMetadataAfterLink.ModificationTime unexpected") 2065 } 2066 if !dirInodeMetadataAfterLink.AccessTime.Equal(dirInodeMetadataAfterDeleteStream.AccessTime) { 2067 t.Fatalf("dirInodeMetadataAfterLink.AccessTime unexpected changed") 2068 } 2069 if dirInodeMetadataAfterLink.AttrChangeTime.Before(timeBeforeLink) || dirInodeMetadataAfterLink.AttrChangeTime.After(timeAfterLink) { 2070 t.Fatalf("dirInodeMetadataAfterLink.AttrChangeTime unexpected") 2071 } 2072 if !dirInodeMetadataAfterLink.AttrChangeTime.Equal(dirInodeMetadataAfterLink.ModificationTime) { 2073 t.Fatalf("dirInodeMetadataAfterLink.AttrChangeTime should equal dirInodeMetadataAfterLink.ModificationTime") 2074 } 2075 if !fileInodeMetadataAfterLink.CreationTime.Equal(fileInodeMetadataAfterDeleteStream.CreationTime) { 2076 t.Fatalf("fileInodeMetadataAfterLink.CreationTime unexpected") 2077 } 2078 if !fileInodeMetadataAfterLink.ModificationTime.Equal(fileInodeMetadataAfterDeleteStream.ModificationTime) { 2079 t.Fatalf("fileInodeMetadataAfterLink.ModificationTime unexpected") 2080 } 2081 if !fileInodeMetadataAfterLink.AccessTime.Equal(fileInodeMetadataAfterDeleteStream.AccessTime) { 2082 t.Fatalf("fileInodeMetadataAfterLink.AccessTime unexpected") 2083 } 2084 if fileInodeMetadataAfterLink.AttrChangeTime.Before(timeBeforeLink) || fileInodeMetadataAfterLink.AttrChangeTime.After(timeAfterLink) { 2085 t.Fatalf("fileInodeMetadataAfterLink.AttrChangeTime unexpected") 2086 } 2087 2088 time.Sleep(positiveDurationToDelayOrSkew) 2089 2090 toDestroyInodeNumber, err = testVolumeHandle.Move(dirInode, "loc_1", dirInode, "loc_2") 2091 if nil != err { 2092 t.Fatalf("Move(dirInode, \"loc_1\", dirInode, \"loc_2\") failed: %v", err) 2093 } 2094 if InodeNumber(0) != toDestroyInodeNumber { 2095 t.Fatalf("Move(dirInode, \"loc_1\", dirInode, \"loc_2\") should have returned toDestroyInodeNumber == 0") 2096 } 2097 2098 time.Sleep(positiveDurationToDelayOrSkew) 2099 2100 timeAfterMove := time.Now() 2101 2102 dirInodeMetadataAfterMove, err := testVolumeHandle.GetMetadata(dirInode) 2103 if nil != err { 2104 t.Fatalf("GetMetadata(dirInode) failed: %v", err) 2105 } 2106 fileInodeMetadataAfterMove, err := testVolumeHandle.GetMetadata(fileInode) 2107 if nil != err { 2108 t.Fatalf("GetMetadata(fileInode) failed: %v", err) 2109 } 2110 2111 if !dirInodeMetadataAfterMove.CreationTime.Equal(dirInodeMetadataAfterLink.CreationTime) { 2112 t.Fatalf("dirInodeMetadataAfterMove.CreationTime unexpected") 2113 } 2114 if dirInodeMetadataAfterMove.ModificationTime.Before(timeAfterLink) || dirInodeMetadataAfterMove.ModificationTime.After(timeAfterMove) { 2115 t.Fatalf("dirInodeMetadataAfterMove.ModificationTime unexpected") 2116 } 2117 if !dirInodeMetadataAfterMove.AccessTime.Equal(dirInodeMetadataAfterLink.AccessTime) { 2118 t.Fatalf("dirInodeMetadataAfterMove.AccessTime unexpected change") 2119 } 2120 if dirInodeMetadataAfterMove.AttrChangeTime.Equal(dirInodeMetadataAfterLink.AttrChangeTime) { 2121 t.Fatalf("dirInodeMetadataAfterMove.AttrChangeTime unchanged") 2122 } 2123 if !fileInodeMetadataAfterMove.CreationTime.Equal(fileInodeMetadataAfterLink.CreationTime) { 2124 t.Fatalf("fileInodeMetadataAfterMove.CreationTime unexpected") 2125 } 2126 if !fileInodeMetadataAfterMove.ModificationTime.Equal(fileInodeMetadataAfterLink.ModificationTime) { 2127 t.Fatalf("fileInodeMetadataAfterMove.ModificationTime unexpected") 2128 } 2129 if !fileInodeMetadataAfterMove.AccessTime.Equal(fileInodeMetadataAfterLink.AccessTime) { 2130 t.Fatalf("fileInodeMetadataAfterMove.AccessTime unexpected") 2131 } 2132 if fileInodeMetadataAfterMove.AttrChangeTime.Equal(fileInodeMetadataAfterLink.AttrChangeTime) { 2133 t.Fatalf("fileInodeMetadataAfterMove.AttrChangeTime should change after move") 2134 } 2135 2136 time.Sleep(positiveDurationToDelayOrSkew) 2137 2138 toDestroyInodeNumber, err = testVolumeHandle.Unlink(dirInode, "loc_2", false) 2139 if nil != err { 2140 t.Fatalf("Unlink(dirInode, \"loc_2\", false) failed: %v", err) 2141 } 2142 if fileInode != toDestroyInodeNumber { 2143 t.Fatalf("Unlink(dirInode, \"loc_2\", false) should have returned toDestroyInodeNumber == fileInode") 2144 } 2145 2146 time.Sleep(positiveDurationToDelayOrSkew) 2147 2148 timeAfterUnlink := time.Now() 2149 2150 dirInodeMetadataAfterUnlink, err := testVolumeHandle.GetMetadata(dirInode) 2151 if nil != err { 2152 t.Fatalf("GetMetadata(dirInode) failed: %v", err) 2153 } 2154 fileInodeMetadataAfterUnlink, err := testVolumeHandle.GetMetadata(fileInode) 2155 if nil != err { 2156 t.Fatalf("GetMetadata(fileInode) failed: %v", err) 2157 } 2158 2159 if !dirInodeMetadataAfterUnlink.CreationTime.Equal(dirInodeMetadataAfterMove.CreationTime) { 2160 t.Fatalf("dirInodeMetadataAfterUnlink.CreationTime unexpected") 2161 } 2162 if dirInodeMetadataAfterUnlink.ModificationTime.Before(timeAfterMove) || dirInodeMetadataAfterUnlink.ModificationTime.After(timeAfterUnlink) { 2163 t.Fatalf("dirInodeMetadataAfterUnlink.ModificationTime unexpected") 2164 } 2165 if !dirInodeMetadataAfterUnlink.AccessTime.Equal(dirInodeMetadataAfterMove.AccessTime) { 2166 t.Fatalf("dirInodeMetadataAfterUnlink.AccessTime unexpected change") 2167 } 2168 if dirInodeMetadataAfterUnlink.AttrChangeTime.Before(timeAfterMove) || dirInodeMetadataAfterUnlink.AttrChangeTime.After(timeAfterUnlink) { 2169 t.Fatalf("dirInodeMetadataAfterUnlink.AttrChangeTime unexpected") 2170 } 2171 if !fileInodeMetadataAfterUnlink.CreationTime.Equal(fileInodeMetadataAfterMove.CreationTime) { 2172 t.Fatalf("fileInodeMetadataAfterUnlink.CreationTime unexpected") 2173 } 2174 if !fileInodeMetadataAfterUnlink.ModificationTime.Equal(fileInodeMetadataAfterMove.ModificationTime) { 2175 t.Fatalf("fileInodeMetadataAfterUnlink.ModificationTime unexpected") 2176 } 2177 if !fileInodeMetadataAfterUnlink.AccessTime.Equal(fileInodeMetadataAfterMove.AccessTime) { 2178 t.Fatalf("fileInodeMetadataAfterUnlink.AccessTime unexpected") 2179 } 2180 if fileInodeMetadataAfterUnlink.AttrChangeTime.Before(timeAfterMove) || fileInodeMetadataAfterUnlink.AttrChangeTime.After(timeAfterUnlink) { 2181 t.Fatalf("fileInodeMetadataAfterUnlink.AttrChangeTime unexpected") 2182 } 2183 2184 time.Sleep(positiveDurationToDelayOrSkew) 2185 2186 err = testVolumeHandle.Write(fileInode, uint64(0), []byte{0x00}, nil) 2187 if nil != err { 2188 t.Fatalf("Write(fileInode, uint64(0), []byte{0x00}) failed: %v", err) 2189 } 2190 2191 time.Sleep(positiveDurationToDelayOrSkew) 2192 2193 timeAfterWrite := time.Now() 2194 2195 fileInodeMetadataAfterWrite, err := testVolumeHandle.GetMetadata(fileInode) 2196 if nil != err { 2197 t.Fatalf("GetMetadata(fileInode) failed: %v", err) 2198 } 2199 2200 if !fileInodeMetadataAfterWrite.CreationTime.Equal(fileInodeMetadataAfterUnlink.CreationTime) { 2201 t.Fatalf("fileInodeMetadataAfterWrite.CreationTime unexpected") 2202 } 2203 if fileInodeMetadataAfterWrite.ModificationTime.Before(timeAfterUnlink) || fileInodeMetadataAfterWrite.ModificationTime.After(timeAfterWrite) { 2204 t.Fatalf("fileInodeMetadataAfterWrite.ModificationTime unexpected") 2205 } 2206 if !fileInodeMetadataAfterWrite.AttrChangeTime.Equal(fileInodeMetadataAfterWrite.ModificationTime) { 2207 t.Fatalf("fileInodeMetadataAfterWrite.AttrChangeTime unexpected") 2208 } 2209 if !fileInodeMetadataAfterWrite.AccessTime.Equal(fileInodeMetadataAfterUnlink.AccessTime) { 2210 t.Fatalf("fileInodeMetadataAfterWrite.AccessTime unexpected change") 2211 } 2212 2213 time.Sleep(positiveDurationToDelayOrSkew) 2214 2215 objectPath, err := testVolumeHandle.ProvisionObject() 2216 if nil != err { 2217 t.Fatalf("ProvisionObject() failed: %v", err) 2218 } 2219 _, containerName, objectName, err = utils.PathToAcctContObj(objectPath) 2220 if err != nil { 2221 t.Fatalf("couldn't parse %v as object path", objectPath) 2222 } 2223 err = testVolumeHandle.Wrote(fileInode, containerName, objectName, []uint64{0}, []uint64{0}, []uint64{2}, time.Now(), false) 2224 if nil != err { 2225 t.Fatalf("Wrote(fileInode, objectPath, []uint64{0}, []uint64{0}, []uint64{2}, time.Now(), false) failed: %v", err) 2226 } 2227 2228 time.Sleep(positiveDurationToDelayOrSkew) 2229 2230 timeAfterWrote := time.Now() 2231 2232 fileInodeMetadataAfterWrote, err := testVolumeHandle.GetMetadata(fileInode) 2233 if nil != err { 2234 t.Fatalf("GetMetadata(fileInode) failed: %v", err) 2235 } 2236 2237 if !fileInodeMetadataAfterWrote.CreationTime.Equal(fileInodeMetadataAfterWrite.CreationTime) { 2238 t.Fatalf("fileInodeMetadataAfterWrote.CreationTime unexpected") 2239 } 2240 if fileInodeMetadataAfterWrote.ModificationTime.Before(timeAfterWrite) || fileInodeMetadataAfterWrote.ModificationTime.After(timeAfterWrote) { 2241 t.Fatalf("fileInodeMetadataAfterWrote.ModificationTime unexpected") 2242 } 2243 if !fileInodeMetadataAfterWrote.AttrChangeTime.Equal(fileInodeMetadataAfterWrote.ModificationTime) { 2244 t.Fatalf("fileInodeMetadataAfterWrote.AttrChangeTime should equal fileInodeMetadataAfterWrote.ModificationTime") 2245 } 2246 if !fileInodeMetadataAfterWrote.AccessTime.Equal(fileInodeMetadataAfterWrite.AccessTime) { 2247 t.Fatalf("fileInodeMetadataAfterWrote.AccessTime unexpected change") 2248 } 2249 2250 time.Sleep(positiveDurationToDelayOrSkew) 2251 2252 err = testVolumeHandle.SetSize(fileInode, uint64(0)) 2253 if nil != err { 2254 t.Fatalf("SetSize(fileInode, uint64(0)) failed: %v", err) 2255 } 2256 2257 time.Sleep(positiveDurationToDelayOrSkew) 2258 2259 timeAfterSetSize := time.Now() 2260 2261 fileInodeMetadataAfterSetSize, err := testVolumeHandle.GetMetadata(fileInode) 2262 if nil != err { 2263 t.Fatalf("GetMetadata(fileInode) failed: %v", err) 2264 } 2265 2266 if !fileInodeMetadataAfterSetSize.CreationTime.Equal(fileInodeMetadataAfterWrote.CreationTime) { 2267 t.Fatalf("fileInodeMetadataAfterSetSize.CreationTime unexpected") 2268 } 2269 if fileInodeMetadataAfterSetSize.ModificationTime.Before(timeAfterWrote) || fileInodeMetadataAfterSetSize.ModificationTime.After(timeAfterSetSize) { 2270 t.Fatalf("fileInodeMetadataAfterSetSize.ModificationTime unexpected") 2271 } 2272 if !fileInodeMetadataAfterSetSize.AttrChangeTime.Equal(fileInodeMetadataAfterSetSize.ModificationTime) { 2273 t.Fatalf("fileInodeMetadataAfterSetsize.AttrChangeTime should equal fileInodeMetadataAfterSetSize.ModificationTime") 2274 } 2275 if !fileInodeMetadataAfterSetSize.AccessTime.Equal(fileInodeMetadataAfterWrote.AccessTime) { 2276 t.Fatalf("fileInodeMetadataAfterSetSize.AccessTime unexpected change") 2277 } 2278 2279 // TODO: Need to test GetFragmentationReport() 2280 2281 // TODO: Once implemented, need to test Optimize() 2282 2283 testTeardown(t) 2284 } 2285 2286 func TestInodeDiscard(t *testing.T) { 2287 testSetup(t, false) 2288 2289 assert := assert.New(t) 2290 testVolumeHandle, err := FetchVolumeHandle("TestVolume") 2291 if nil != err { 2292 t.Fatalf("FetchVolumeHandle(\"TestVolume\") should have worked - got error: %v", err) 2293 } 2294 2295 // Calculate how many inodes we must create to make sure the inode cache discard 2296 // routine will find something to discard. 2297 vS := testVolumeHandle.(*volumeStruct) 2298 maxBytes := vS.inodeCacheLRUMaxBytes 2299 iSize := globals.inodeSize 2300 entriesNeeded := maxBytes / iSize 2301 entriesNeeded = entriesNeeded * 6 2302 for i := uint64(0); i < entriesNeeded; i++ { 2303 fileInodeNumber, err := testVolumeHandle.CreateFile(InodeMode(0000), InodeRootUserID, InodeGroupID(0)) 2304 if nil != err { 2305 t.Fatalf("CreateFile() failed: %v", err) 2306 } 2307 2308 fName := fmt.Sprintf("file-%v i: %v", fileInodeNumber, i) 2309 err = testVolumeHandle.Link(RootDirInodeNumber, fName, fileInodeNumber, false) 2310 if nil != err { 2311 t.Fatalf("Link(RootDirInodeNumber, \"%v\", file1Inode, false) failed: %v", fName, err) 2312 } 2313 2314 fileInode, ok, err := vS.fetchInode(fileInodeNumber) 2315 assert.Nil(err, nil, "Unable to fetchInode due to err - even though just created") 2316 assert.True(ok, "fetchInode returned !ok - even though just created") 2317 assert.False(fileInode.dirty, "fetchInode.dirty == true - even though just linked") 2318 } 2319 2320 discarded, dirty, locked, lruItems := vS.inodeCacheDiscard() 2321 2322 assert.NotEqual(discarded, uint64(0), "Number of inodes discarded should be non-zero") 2323 assert.Equal(dirty, uint64(0), "Number of inodes dirty should zero") 2324 assert.Equal(locked, uint64(0), "Number of inodes locked should zero") 2325 assert.Equal((lruItems * iSize), (maxBytes/iSize)*iSize, "Number of inodes in cache not same as max") 2326 2327 testTeardown(t) 2328 }