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  }