github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/kbfs/test/simple_test.go (about) 1 // Copyright 2016 Keybase Inc. All rights reserved. 2 // Use of this source code is governed by a BSD 3 // license that can be found in the LICENSE file. 4 5 // These tests all do one conflict-free operation while a user is unstaged. 6 7 package test 8 9 import ( 10 "testing" 11 "time" 12 ) 13 14 func TestFavoritesBasic(t *testing.T) { 15 test(t, 16 users("alice", "bob"), 17 18 inPrivateTlf("alice,bob"), 19 as(alice, 20 lspublicfavorites([]string{"alice"}), 21 lsprivatefavorites([]string{"alice", "alice,bob"}), 22 ), 23 24 inPublicTlf("alice,bob"), 25 as(alice, 26 lspublicfavorites([]string{"alice", "alice,bob"}), 27 lsprivatefavorites([]string{"alice", "alice,bob"}), 28 ), 29 ) 30 } 31 32 func TestCreateDirInRoot(t *testing.T) { 33 test(t, 34 users("alice", "bob"), 35 as(alice, 36 addTime(1*time.Minute), 37 mkdir("a"), 38 // Initial check before SyncAll is called. 39 lsdir("", m{"a$": "DIR"}), 40 lsdir("a", m{}), 41 ), 42 as(alice, 43 lsdir("", m{"a$": "DIR"}), 44 lsdir("a", m{}), 45 mtime("a", time.Time{}), 46 // Make sure root directory's mtime was updated. 47 mtime("", time.Time{}), 48 ), 49 as(bob, 50 lsdir("", m{"a$": "DIR"}), 51 lsdir("a", m{}), 52 mtime("a", time.Time{}), 53 mtime("", time.Time{}), 54 ), 55 ) 56 } 57 58 func TestCreateDirInSubdir(t *testing.T) { 59 test(t, 60 users("alice", "bob"), 61 as(alice, 62 mkdir("a"), 63 ), 64 as(alice, 65 addTime(1*time.Minute), 66 mkdir("a/b"), 67 // Initial check before SyncAll is called. 68 lsdir("a", m{"b$": "DIR"}), 69 ), 70 as(alice, 71 lsdir("a", m{"b$": "DIR"}), 72 mtime("a/b", time.Time{}), 73 // Make sure parent directory's mtime was updated. 74 mtime("a", time.Time{}), 75 ), 76 as(bob, 77 lsdir("a", m{"b$": "DIR"}), 78 mtime("a/b", time.Time{}), 79 mtime("a", time.Time{}), 80 ), 81 ) 82 } 83 84 func TestCreateFileInRoot(t *testing.T) { 85 test(t, 86 users("alice", "bob"), 87 as(alice, 88 mkfile("a", "hello"), 89 // Initial check before SyncAll is called. 90 lsdir("", m{"a$": "FILE"}), 91 read("a", "hello"), 92 ), 93 as(alice, 94 lsdir("", m{"a$": "FILE"}), 95 read("a", "hello"), 96 checkPrevRevisions("a", []uint8{1}), 97 ), 98 as(bob, 99 lsdir("", m{"a$": "FILE"}), 100 read("a", "hello"), 101 checkPrevRevisions("a", []uint8{1}), 102 ), 103 ) 104 } 105 106 func TestCreateExecInRoot(t *testing.T) { 107 test(t, 108 users("alice", "bob"), 109 as(alice, 110 mkfile("a", "hello"), 111 setex("a", true), 112 // Initial check before SyncAll is called. 113 lsdir("", m{"a$": "EXEC"}), 114 read("a", "hello"), 115 ), 116 as(alice, 117 lsdir("", m{"a$": "EXEC"}), 118 read("a", "hello"), 119 ), 120 as(bob, 121 lsdir("", m{"a$": "EXEC"}), 122 read("a", "hello"), 123 ), 124 ) 125 } 126 127 func TestCreateLinkInRoot(t *testing.T) { 128 test(t, 129 skip("dokan", "Does not work with Dokan."), 130 users("alice", "bob"), 131 as(alice, 132 mkfile("a", "hello"), 133 link("b", "a"), 134 // Initial check before SyncAll is called. 135 lsdir("", m{"a$": "FILE", "b$": "SYM"}), 136 read("b", "hello"), 137 ), 138 as(alice, 139 lsdir("", m{"a$": "FILE", "b$": "SYM"}), 140 read("b", "hello"), 141 ), 142 as(bob, 143 lsdir("", m{"a$": "FILE", "b$": "SYM"}), 144 read("b", "hello"), 145 ), 146 ) 147 } 148 149 func TestRemoveFileFromRoot(t *testing.T) { 150 test(t, 151 users("alice", "bob"), 152 as(alice, 153 mkfile("a", "hello"), 154 ), 155 as(alice, 156 addTime(1*time.Minute), 157 rm("a"), 158 // Initial check before SyncAll is called. 159 lsdir("", m{}), 160 ), 161 as(alice, 162 lsdir("", m{}), 163 // Make sure root directory's mtime was updated. 164 mtime("", time.Time{}), 165 ), 166 as(bob, 167 lsdir("", m{}), 168 mtime("", time.Time{}), 169 ), 170 ) 171 } 172 173 func TestRemoveFileFromSubdir(t *testing.T) { 174 test(t, 175 users("alice", "bob"), 176 as(alice, 177 mkfile("a/b", "hello"), 178 ), 179 as(alice, 180 addTime(1*time.Minute), 181 rm("a/b"), 182 // Initial check before SyncAll is called. 183 lsdir("a", m{}), 184 ), 185 as(alice, 186 lsdir("a", m{}), 187 // Make sure root directory's mtime was updated. 188 mtime("a", time.Time{}), 189 ), 190 as(bob, 191 lsdir("a", m{}), 192 mtime("a", time.Time{}), 193 ), 194 ) 195 } 196 197 func TestRemoveExecFromRoot(t *testing.T) { 198 test(t, 199 users("alice", "bob"), 200 as(alice, 201 mkfile("a", "hello"), 202 setex("a", true), 203 ), 204 as(alice, 205 rm("a"), 206 // Initial check before SyncAll is called. 207 lsdir("", m{}), 208 ), 209 as(alice, 210 lsdir("", m{}), 211 ), 212 as(bob, 213 lsdir("", m{}), 214 ), 215 ) 216 } 217 218 func TestRemoveDirFromRoot(t *testing.T) { 219 test(t, 220 users("alice", "bob"), 221 as(alice, 222 mkdir("a"), 223 ), 224 as(alice, 225 rmdir("a"), 226 // Initial check before SyncAll is called. 227 lsdir("", m{}), 228 ), 229 as(alice, 230 lsdir("", m{}), 231 ), 232 as(bob, 233 lsdir("", m{}), 234 ), 235 ) 236 } 237 238 func TestRemoveLinkFromRoot(t *testing.T) { 239 test(t, 240 skip("dokan", "Does not work with Dokan."), 241 users("alice", "bob"), 242 as(alice, 243 mkfile("a", "hello"), 244 link("b", "a"), 245 ), 246 as(alice, 247 rm("b"), 248 // Initial check before SyncAll is called. 249 lsdir("", m{"a$": "FILE"}), 250 ), 251 as(alice, 252 lsdir("", m{"a$": "FILE"}), 253 ), 254 as(bob, 255 lsdir("", m{"a$": "FILE"}), 256 ), 257 ) 258 } 259 260 func TestRenameInDir(t *testing.T) { 261 test(t, 262 users("alice", "bob"), 263 as(alice, 264 mkfile("a/b", "hello"), 265 ), 266 as(alice, 267 rename("a/b", "a/c"), 268 // Initial check before SyncAll is called. 269 lsdir("a", m{"c$": "FILE"}), 270 read("a/c", "hello"), 271 ), 272 as(alice, 273 lsdir("a", m{"c$": "FILE"}), 274 read("a/c", "hello"), 275 // The directory underwent two revisions. 276 checkPrevRevisions("a", []uint8{1, 2}), 277 ), 278 as(bob, 279 lsdir("a", m{"c$": "FILE"}), 280 read("a/c", "hello"), 281 checkPrevRevisions("a", []uint8{1, 2}), 282 ), 283 ) 284 } 285 286 func TestRenameInDirOverFile(t *testing.T) { 287 test(t, 288 users("alice", "bob"), 289 as(alice, 290 mkfile("a/b", "hello"), 291 mkfile("a/c", "goodbye"), 292 ), 293 as(alice, 294 rename("a/b", "a/c"), 295 // Initial check before SyncAll is called. 296 lsdir("a", m{"c$": "FILE"}), 297 read("a/c", "hello"), 298 ), 299 as(alice, 300 lsdir("a", m{"c$": "FILE"}), 301 read("a/c", "hello"), 302 ), 303 as(bob, 304 lsdir("a", m{"c$": "FILE"}), 305 read("a/c", "hello"), 306 ), 307 ) 308 } 309 310 func TestRenameInRoot(t *testing.T) { 311 test(t, 312 users("alice", "bob"), 313 as(alice, 314 mkfile("a", "hello"), 315 ), 316 as(alice, 317 rename("a", "b"), 318 // Initial check before SyncAll is called. 319 lsdir("", m{"b$": "FILE"}), 320 read("b", "hello"), 321 ), 322 as(alice, 323 lsdir("", m{"b$": "FILE"}), 324 read("b", "hello"), 325 ), 326 as(bob, 327 lsdir("", m{"b$": "FILE"}), 328 read("b", "hello"), 329 ), 330 ) 331 } 332 333 func TestRenameAcrossDirs(t *testing.T) { 334 test(t, 335 users("alice", "bob"), 336 as(alice, 337 mkfile("a/b", "hello"), 338 mkdir("c"), 339 ), 340 as(alice, 341 rename("a/b", "c/d"), 342 // Initial check before SyncAll is called. 343 lsdir("a", m{}), 344 lsdir("c", m{"d$": "FILE"}), 345 read("c/d", "hello"), 346 ), 347 as(alice, 348 lsdir("a", m{}), 349 lsdir("c", m{"d$": "FILE"}), 350 read("c/d", "hello"), 351 ), 352 as(bob, 353 lsdir("a", m{}), 354 lsdir("c", m{"d$": "FILE"}), 355 read("c/d", "hello"), 356 ), 357 ) 358 } 359 360 func TestRenameAcrossPrefix(t *testing.T) { 361 test(t, 362 users("alice", "bob"), 363 as(alice, 364 mkfile("a/b", "hello"), 365 mkdir("a/c/d/e"), 366 ), 367 as(alice, 368 rename("a/b", "a/c/d/e/f"), 369 // Initial check before SyncAll is called. 370 lsdir("a", m{"c$": "DIR"}), 371 lsdir("a/c/d/e", m{"f$": "FILE"}), 372 read("a/c/d/e/f", "hello"), 373 ), 374 as(alice, 375 lsdir("a", m{"c$": "DIR"}), 376 lsdir("a/c/d/e", m{"f$": "FILE"}), 377 read("a/c/d/e/f", "hello"), 378 ), 379 as(bob, 380 lsdir("a", m{"c$": "DIR"}), 381 lsdir("a/c/d/e", m{"f$": "FILE"}), 382 read("a/c/d/e/f", "hello"), 383 ), 384 ) 385 } 386 387 func TestRenameAcrossOtherPrefix(t *testing.T) { 388 test(t, 389 users("alice", "bob"), 390 as(alice, 391 mkfile("a/b/c/d/e", "hello"), 392 ), 393 as(alice, 394 rename("a/b/c/d/e", "a/f"), 395 // Initial check before SyncAll is called. 396 lsdir("a", m{"b$": "DIR", "f": "FILE"}), 397 lsdir("a/b/c/d", m{}), 398 read("a/f", "hello"), 399 ), 400 as(alice, 401 lsdir("a", m{"b$": "DIR", "f": "FILE"}), 402 lsdir("a/b/c/d", m{}), 403 read("a/f", "hello"), 404 ), 405 as(bob, 406 lsdir("a", m{"b$": "DIR", "f": "FILE"}), 407 lsdir("a/b/c/d", m{}), 408 read("a/f", "hello"), 409 ), 410 ) 411 } 412 413 func TestUnsetExecInRoot(t *testing.T) { 414 test(t, 415 users("alice", "bob"), 416 as(alice, 417 mkfile("a", "hello"), 418 setex("a", true), 419 ), 420 as(alice, 421 setex("a", false), 422 // Initial check before SyncAll is called. 423 lsdir("", m{"a$": "FILE"}), 424 read("a", "hello"), 425 ), 426 as(alice, 427 lsdir("", m{"a$": "FILE"}), 428 read("a", "hello"), 429 ), 430 as(bob, 431 lsdir("", m{"a$": "FILE"}), 432 read("a", "hello"), 433 ), 434 ) 435 } 436 437 func TestExtraSetExecInRoot(t *testing.T) { 438 test(t, 439 users("alice", "bob"), 440 as(alice, 441 mkfile("a", "hello"), 442 setex("a", true), 443 ), 444 as(alice, 445 setex("a", true), 446 // Initial check before SyncAll is called. 447 lsdir("", m{"a$": "EXEC"}), 448 read("a", "hello"), 449 ), 450 as(alice, 451 lsdir("", m{"a$": "EXEC"}), 452 read("a", "hello"), 453 ), 454 as(bob, 455 lsdir("", m{"a$": "EXEC"}), 456 read("a", "hello"), 457 ), 458 ) 459 } 460 461 func TestExtraUnsetExecInRoot(t *testing.T) { 462 test(t, 463 users("alice", "bob"), 464 as(alice, 465 mkfile("a", "hello"), 466 ), 467 as(alice, 468 setex("a", false), 469 // Initial check before SyncAll is called. 470 lsdir("", m{"a$": "FILE"}), 471 read("a", "hello"), 472 ), 473 as(alice, 474 lsdir("", m{"a$": "FILE"}), 475 read("a", "hello"), 476 ), 477 as(bob, 478 lsdir("", m{"a$": "FILE"}), 479 read("a", "hello"), 480 ), 481 ) 482 } 483 484 func TestSetExecOnDir(t *testing.T) { 485 test(t, 486 users("alice", "bob"), 487 as(alice, 488 mkdir("a"), 489 ), 490 as(alice, 491 setex("a", true), 492 // Initial check before SyncAll is called. 493 lsdir("", m{"a$": "DIR"}), 494 ), 495 as(alice, 496 lsdir("", m{"a$": "DIR"}), 497 ), 498 as(bob, 499 lsdir("", m{"a$": "DIR"}), 500 ), 501 ) 502 } 503 504 func TestSetMtime(t *testing.T) { 505 targetMtime := time.Now().Add(1 * time.Minute) 506 test(t, 507 users("alice", "bob"), 508 as(alice, 509 mkfile("a/b", "hello"), 510 ), 511 as(alice, 512 setmtime("a/b", targetMtime), 513 // Initial check before SyncAll is called. 514 mtime("a/b", targetMtime), 515 ), 516 as(alice, 517 mtime("a/b", targetMtime), 518 ), 519 as(bob, 520 mtime("a/b", targetMtime), 521 ), 522 ) 523 } 524 525 func TestSyncTwoFilesInRoot(t *testing.T) { 526 test(t, 527 users("alice", "bob"), 528 as(alice, 529 mkfile("a", "hello"), 530 mkfile("b", "hello2"), 531 // Initial check before SyncAll is called. 532 lsdir("", m{"a$": "FILE", "b$": "FILE"}), 533 read("a", "hello"), 534 read("b", "hello2"), 535 ), 536 as(alice, 537 lsdir("", m{"a$": "FILE", "b$": "FILE"}), 538 read("a", "hello"), 539 read("b", "hello2"), 540 ), 541 as(bob, 542 lsdir("", m{"a$": "FILE", "b$": "FILE"}), 543 read("a", "hello"), 544 read("b", "hello2"), 545 ), 546 ) 547 } 548 549 // Regression for KBFS-2243. 550 func TestCreateAndRemoveDirTreeWithinBatch(t *testing.T) { 551 test(t, 552 users("alice", "bob"), 553 as(alice, 554 mkdir("a"), 555 mkdir("a/b"), 556 pwriteBSSync("a/b/c", []byte("hello"), 0, false), 557 rm("a/b/c"), 558 mkdir("b"), 559 rmdir("a/b"), 560 rmdir("a"), 561 // Initial check before SyncAll is called. 562 lsdir("", m{"b$": "DIR"}), 563 lsdir("b", m{}), 564 checkDirtyPaths([]string{ 565 "alice,bob", 566 "alice,bob/a/b/c", 567 }), 568 ), 569 as(alice, 570 checkDirtyPaths(nil), 571 lsdir("", m{"b$": "DIR"}), 572 lsdir("b", m{}), 573 ), 574 as(bob, 575 lsdir("", m{"b$": "DIR"}), 576 lsdir("b", m{}), 577 ), 578 ) 579 } 580 581 func TestRenameFromRemovedDirWithinBatch(t *testing.T) { 582 test(t, 583 users("alice", "bob"), 584 as(alice, 585 mkdir("a"), 586 mkdir("a/b"), 587 rename("a/b", "b"), 588 rmdir("a"), 589 // Initial check before SyncAll is called. 590 lsdir("", m{"b$": "DIR"}), 591 lsdir("b", m{}), 592 ), 593 as(alice, 594 lsdir("", m{"b$": "DIR"}), 595 lsdir("b", m{}), 596 ), 597 as(bob, 598 lsdir("", m{"b$": "DIR"}), 599 lsdir("b", m{}), 600 ), 601 ) 602 } 603 604 // Regression test for KBFS-2286. 605 func TestSetattrThenRenameWithinBatch(t *testing.T) { 606 targetMtime := time.Now().Add(1 * time.Minute) 607 test(t, 608 users("alice", "bob"), 609 as(alice, 610 mkdir("a"), 611 mkfile("a/b", "hello"), 612 ), 613 as(bob, 614 lsdir("", m{"a$": "DIR"}), 615 lsdir("a", m{"b$": "FILE"}), 616 read("a/b", "hello"), 617 ), 618 as(alice, 619 setmtime("a/b", targetMtime), 620 rename("a/b", "a/c"), 621 // Initial check before SyncAll is called. 622 lsdir("", m{"a$": "DIR"}), 623 lsdir("a", m{"c$": "FILE"}), 624 read("a/c", "hello"), 625 mtime("a/c", targetMtime), 626 ), 627 as(alice, 628 lsdir("", m{"a$": "DIR"}), 629 lsdir("a", m{"c$": "FILE"}), 630 read("a/c", "hello"), 631 mtime("a/c", targetMtime), 632 ), 633 as(bob, 634 lsdir("", m{"a$": "DIR"}), 635 lsdir("a", m{"c$": "FILE"}), 636 read("a/c", "hello"), 637 mtime("a/c", targetMtime), 638 ), 639 ) 640 } 641 642 // Regression test for KBFS-3351. 643 func TestRenameRenameRm(t *testing.T) { 644 test(t, 645 users("alice", "bob"), 646 as(alice, 647 mkdir("a"), 648 mkdir("b"), 649 mkfile("a/c", "hello"), 650 mkfile("b/d", "hello2"), 651 mkdir("e"), 652 ), 653 as(bob, 654 lsdir("", m{"a$": "DIR", "b$": "DIR", "e$": "DIR"}), 655 lsdir("a", m{"c$": "FILE"}), 656 lsdir("b", m{"d$": "FILE"}), 657 read("a/c", "hello"), 658 read("b/d", "hello2"), 659 lsdir("e", m{}), 660 ), 661 as(alice, 662 rename("a/c", "e/f"), 663 rename("b/d", "a/c"), 664 rm("a/c"), 665 ), 666 as(alice, 667 lsdir("", m{"a$": "DIR", "b$": "DIR", "e$": "DIR"}), 668 lsdir("a", m{}), 669 lsdir("b", m{}), 670 lsdir("e", m{"f$": "FILE"}), 671 read("e/f", "hello"), 672 ), 673 as(bob, 674 lsdir("", m{"a$": "DIR", "b$": "DIR", "e$": "DIR"}), 675 lsdir("a", m{}), 676 lsdir("b", m{}), 677 lsdir("e", m{"f$": "FILE"}), 678 read("e/f", "hello"), 679 ), 680 ) 681 }