github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/kbfs/test/multi_blocks_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 "testing"
    10  
    11  // alice writes a multi-block file, and bob reads it
    12  func TestWriteMultiblockFile(t *testing.T) {
    13  	test(t,
    14  		blockSize(20), users("alice", "bob"),
    15  		as(alice,
    16  			write("a/b", ntimesString(15, "0123456789")),
    17  		),
    18  		as(bob,
    19  			read("a/b", ntimesString(15, "0123456789")),
    20  		),
    21  	)
    22  }
    23  
    24  func TestSwitchToMultiblockFile(t *testing.T) {
    25  	test(t,
    26  		blockSize(20), users("alice", "bob"),
    27  		as(alice,
    28  			// Fill up the first block (a desired encrypted block size
    29  			// of 20 ends up with a plaintext size of 12).
    30  			write("a/b", ntimesString(3, "0123")),
    31  			// Then append to the end of the file to force a split.
    32  			pwriteBS("a/b", []byte(ntimesString(3, "0123")), 12),
    33  		),
    34  		as(bob,
    35  			read("a/b", ntimesString(6, "0123")),
    36  		),
    37  	)
    38  }
    39  
    40  // alice writes a file, and bob overwrites it with a multi-block file
    41  func TestOverwriteMultiblockFile(t *testing.T) {
    42  	test(t,
    43  		blockSize(20), users("alice", "bob"),
    44  		as(alice,
    45  			write("a/b", "hello"),
    46  		),
    47  		as(bob,
    48  			write("a/b", ntimesString(15, "0123456789")),
    49  		),
    50  		as(alice,
    51  			read("a/b", ntimesString(15, "0123456789")),
    52  		),
    53  		as(bob,
    54  			read("a/b", ntimesString(15, "0123456789")),
    55  		),
    56  	)
    57  }
    58  
    59  // bob removes a multiblock file written by alice (checks that state
    60  // is cleaned up)
    61  func TestRmMultiblockFile(t *testing.T) {
    62  	test(t,
    63  		blockSize(20), users("alice", "bob"),
    64  		as(alice,
    65  			write("a/b", ntimesString(15, "0123456789")),
    66  		),
    67  		as(bob,
    68  			read("a/b", ntimesString(15, "0123456789")),
    69  			rm("a/b"),
    70  		),
    71  		as(alice,
    72  			lsdir("a/", m{}),
    73  		),
    74  	)
    75  }
    76  
    77  // bob renames something over a multiblock file written by alice
    78  // (checks that state is cleaned up)
    79  func TestRenameOverMultiblockFile(t *testing.T) {
    80  	test(t,
    81  		blockSize(20), users("alice", "bob"),
    82  		as(alice,
    83  			write("a/b", ntimesString(15, "0123456789")),
    84  			write("a/c", "hello"),
    85  		),
    86  		as(bob,
    87  			read("a/b", ntimesString(15, "0123456789")),
    88  			read("a/c", "hello"),
    89  			rename("a/c", "a/b"),
    90  		),
    91  		as(alice,
    92  			read("a/b", "hello"),
    93  			lsdir("a/", m{"b": "FILE"}),
    94  		),
    95  	)
    96  }
    97  
    98  // bob writes a second copy of a multiblock file written by alice
    99  // (tests dedupping, but hard to verify that precisely here).
   100  func TestCopyMultiblockFile(t *testing.T) {
   101  	test(t,
   102  		blockSize(20), users("alice", "bob"),
   103  		as(alice,
   104  			write("a/b", ntimesString(15, "0123456789")),
   105  		),
   106  		as(bob,
   107  			read("a/b", ntimesString(15, "0123456789")),
   108  			write("a/c", ntimesString(15, "0123456789")),
   109  		),
   110  		as(alice,
   111  			read("a/b", ntimesString(15, "0123456789")),
   112  			read("a/c", ntimesString(15, "0123456789")),
   113  			rm("a/b"),
   114  		),
   115  		as(bob,
   116  			read("a/c", ntimesString(15, "0123456789")),
   117  		),
   118  	)
   119  }
   120  
   121  // Test that we can make a big file, delete it, then make it
   122  // again. Regression for KBFS-700.
   123  func TestMakeDeleteAndMakeMultiBlockFile(t *testing.T) {
   124  	test(t,
   125  		blockSize(20), users("alice", "bob"),
   126  		as(alice,
   127  			write("a/b", ntimesString(15, "0123456789")),
   128  		),
   129  		as(bob,
   130  			read("a/b", ntimesString(15, "0123456789")),
   131  			rm("a/b"),
   132  			write("a/b2", ntimesString(15, "0123456789")),
   133  		),
   134  		as(alice,
   135  			read("a/b2", ntimesString(15, "0123456789")),
   136  		),
   137  	)
   138  }
   139  
   140  // When block changes are unembedded, make sure other users can read
   141  // and apply them.
   142  func TestReadUnembeddedBlockChanges(t *testing.T) {
   143  	test(t,
   144  		blockChangeSize(5), users("alice", "bob"),
   145  		as(alice,
   146  			write("a/b", "hello"),
   147  		),
   148  		as(bob,
   149  			read("a/b", "hello"),
   150  			write("a/c", "hello2"),
   151  			write("a/d", "hello3"),
   152  			write("a/e", "hello4"),
   153  			write("a/f", "hello5"),
   154  		),
   155  		as(alice,
   156  			lsdir("a", m{"b": "FILE", "c": "FILE", "d": "FILE", "e": "FILE", "f": "FILE"}),
   157  			read("a/b", "hello"),
   158  			read("a/c", "hello2"),
   159  			read("a/d", "hello3"),
   160  			read("a/e", "hello4"),
   161  			read("a/f", "hello5"),
   162  		),
   163  	)
   164  }
   165  
   166  // alice writes a multi-block directory root dir, and bob reads it.
   167  func TestWriteMultiblockRootDir(t *testing.T) {
   168  	test(t,
   169  		blockSize(20), users("alice", "bob"),
   170  		as(alice,
   171  			mkfile("b", "b"),
   172  			mkfile("c", "c"),
   173  			mkfile("d", "d"),
   174  			mkfile("e", "e"),
   175  			mkfile("f", "f"),
   176  		),
   177  		as(bob,
   178  			lsdir("", m{
   179  				"b": "FILE",
   180  				"c": "FILE",
   181  				"d": "FILE",
   182  				"e": "FILE",
   183  				"f": "FILE",
   184  			}),
   185  			read("b", "b"),
   186  			read("c", "c"),
   187  			read("d", "d"),
   188  			read("e", "e"),
   189  			read("f", "f"),
   190  		),
   191  	)
   192  }
   193  
   194  // alice writes a multi-block directory in separate batches, and bob reads it.
   195  func TestWriteMultiblockDirBatches(t *testing.T) {
   196  	test(t,
   197  		blockSize(20), users("alice", "bob"),
   198  		as(alice,
   199  			mkfile("a/b", "b"),
   200  			mkfile("a/c", "c"),
   201  			mkfile("a/d", "d"),
   202  			mkfile("a/e", "e"),
   203  			mkfile("a/f", "f"),
   204  		),
   205  		as(bob,
   206  			lsdir("a/", m{
   207  				"b": "FILE",
   208  				"c": "FILE",
   209  				"d": "FILE",
   210  				"e": "FILE",
   211  				"f": "FILE",
   212  			}),
   213  			read("a/b", "b"),
   214  			read("a/c", "c"),
   215  			read("a/d", "d"),
   216  			read("a/e", "e"),
   217  			read("a/f", "f"),
   218  		),
   219  	)
   220  }
   221  
   222  // alice writes a multi-block directory in one batch, and bob reads it.
   223  func TestWriteMultiblockDirAtOnce(t *testing.T) {
   224  	test(t,
   225  		blockSize(20), users("alice", "bob"),
   226  		as(alice,
   227  			pwriteBSSync("a/b", []byte("b"), 0, false),
   228  			pwriteBSSync("a/c", []byte("c"), 0, false),
   229  			pwriteBSSync("a/d", []byte("d"), 0, false),
   230  			pwriteBSSync("a/e", []byte("e"), 0, false),
   231  			pwriteBSSync("a/f", []byte("f"), 0, false),
   232  		),
   233  		as(bob,
   234  			lsdir("a/", m{
   235  				"b": "FILE",
   236  				"c": "FILE",
   237  				"d": "FILE",
   238  				"e": "FILE",
   239  				"f": "FILE",
   240  			}),
   241  			read("a/b", "b"),
   242  			read("a/c", "c"),
   243  			read("a/d", "d"),
   244  			read("a/e", "e"),
   245  			read("a/f", "f"),
   246  		),
   247  	)
   248  }
   249  
   250  // alice writes a multi-block directory and removes one entry from it.
   251  func TestRemoveOneFromMultiblockDir(t *testing.T) {
   252  	test(t,
   253  		blockSize(20), users("alice", "bob"),
   254  		as(alice,
   255  			mkfile("a/b", "b"),
   256  			mkfile("a/c", "c"),
   257  			mkfile("a/d", "d"),
   258  			mkfile("a/e", "e"),
   259  			mkfile("a/f", "f"),
   260  		),
   261  		as(alice,
   262  			rm("a/e"),
   263  		),
   264  		as(bob,
   265  			lsdir("a/", m{
   266  				"b": "FILE",
   267  				"c": "FILE",
   268  				"d": "FILE",
   269  				"f": "FILE",
   270  			}),
   271  			read("a/b", "b"),
   272  			read("a/c", "c"),
   273  			read("a/d", "d"),
   274  			read("a/f", "f"),
   275  		),
   276  	)
   277  }
   278  
   279  // alice writes a multi-level, multi-block directory structure.
   280  func TestRemoveMultilevelMultiblockDir(t *testing.T) {
   281  	test(t,
   282  		blockSize(20), users("alice", "bob"),
   283  		as(alice,
   284  			mkfile("a/b", "b"),
   285  			mkfile("a/c", "c"),
   286  			mkdir("a/d"),
   287  			mkfile("a/d/e", "e"),
   288  			mkfile("a/d/f", "f"),
   289  			mkdir("a/g"),
   290  			mkfile("a/g/h", "h"),
   291  			mkfile("a/g/i", "i"),
   292  		),
   293  		as(bob,
   294  			lsdir("a/", m{
   295  				"b": "FILE",
   296  				"c": "FILE",
   297  				"d": "DIR",
   298  				"g": "DIR",
   299  			}),
   300  			lsdir("a/d", m{
   301  				"e": "FILE",
   302  				"f": "FILE",
   303  			}),
   304  			lsdir("a/g", m{
   305  				"h": "FILE",
   306  				"i": "FILE",
   307  			}),
   308  			read("a/b", "b"),
   309  			read("a/c", "c"),
   310  			read("a/d/e", "e"),
   311  			read("a/d/f", "f"),
   312  			read("a/g/h", "h"),
   313  			read("a/g/i", "i"),
   314  		),
   315  		as(alice,
   316  			rm("a/g/i"),
   317  			rm("a/g/h"),
   318  			rmdir("a/g"),
   319  			rm("a/d/f"),
   320  			rm("a/d/e"),
   321  			rmdir("a/d"),
   322  			rm("a/c"),
   323  			rm("a/b"),
   324  			rmdir("a"),
   325  		),
   326  		as(bob,
   327  			lsdir("", m{}),
   328  		),
   329  	)
   330  }
   331  
   332  // alice renames within a multi-block directory.
   333  func TestRenameWithinMultiblockDir(t *testing.T) {
   334  	test(t,
   335  		blockSize(20), users("alice", "bob"),
   336  		as(alice,
   337  			mkfile("a/b", "b"),
   338  			mkfile("a/c", "c"),
   339  			mkfile("a/d", "d"),
   340  			mkfile("a/e", "e"),
   341  			mkfile("a/f", "f"),
   342  		),
   343  		as(alice,
   344  			rename("a/f", "a/g"),
   345  		),
   346  		as(bob,
   347  			lsdir("a/", m{
   348  				"b": "FILE",
   349  				"c": "FILE",
   350  				"d": "FILE",
   351  				"e": "FILE",
   352  				"g": "FILE",
   353  			}),
   354  			read("a/b", "b"),
   355  			read("a/c", "c"),
   356  			read("a/d", "d"),
   357  			read("a/e", "e"),
   358  			read("a/g", "f"),
   359  		),
   360  	)
   361  }
   362  
   363  // alice renames, creating a multi-block directory.
   364  func TestRenameCreatesMultiblockDir(t *testing.T) {
   365  	test(t,
   366  		blockSize(20), users("alice", "bob"),
   367  		as(alice,
   368  			mkfile("a/b", "b"),
   369  			mkfile("a/c", "c"),
   370  			mkfile("d/e", "e"),
   371  		),
   372  		as(alice,
   373  			rename("a/c", "d/c"),
   374  		),
   375  		as(bob,
   376  			lsdir("a/", m{"b": "FILE"}),
   377  			lsdir("d/", m{"c": "FILE", "e": "FILE"}),
   378  			read("a/b", "b"),
   379  			read("d/c", "c"),
   380  			read("d/e", "e"),
   381  		),
   382  	)
   383  }