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 }