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