github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/kbfs/test/truncate_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 test truncation 6 7 package test 8 9 import ( 10 "runtime" 11 "testing" 12 ) 13 14 // Test out various truncate scenarios. 15 func TestSimpleTruncate(t *testing.T) { 16 t.Skip("This flakes more than 50% of the time. Skipping for now.") 17 const mb = 1024 * 1024 18 mzero := make([]byte, mb) 19 mdata := make([]byte, mb) 20 copy(mdata, []byte(`world`)) 21 mdat2 := make([]byte, mb) 22 const wlen = 200 * 1024 23 for i := 0; i*100 < wlen; i++ { 24 mdat2[i*100] = byte(i) 25 } 26 mdat3 := make([]byte, mb) 27 for i := 0; i*100 < len(mdat3); i++ { 28 mdat3[i*100] = byte(i) 29 } 30 test(t, 31 bandwidth(1<<31-1), // hack to turn on background syncing 32 users("alice", "bob"), 33 as(alice, 34 mkfile("file", ""), 35 truncate("file", 0), 36 read("file", ""), 37 truncate("file", 10), 38 read("file", ntimesString(10, "\000")), 39 truncate("file", 0), 40 read("file", ""), 41 truncate("file", mb), 42 preadBS("file", mzero, 0), 43 truncate("file", 0), 44 read("file", ""), 45 write("file", "world"), 46 read("file", "world"), 47 truncate("file", mb), 48 preadBS("file", mdata, 0), 49 writeBS("file", mdat2[:wlen]), 50 preadBS("file", mdat2, 0), 51 truncate("file", 0), 52 read("file", ""), 53 // Write past an unaligned hole 54 truncate("file", 777777), 55 writeBS("file", mdat3), 56 preadBS("file", mdat3, 0), 57 ), 58 as(bob, 59 preadBS("file", mdat3, 0), 60 ), 61 ) 62 } 63 64 func testTruncateLargeThenWriteToSmallerOffset(t *testing.T, dataLen int) { 65 data := make([]byte, dataLen) 66 for i := 0; i < len(data); i++ { 67 if i < 12 || (i >= 64 && i < 68) || (i >= dataLen-12) { 68 data[i] = byte(i) 69 } 70 } 71 test(t, 72 blockSize(20), blockChangeSize(100*1024), users("alice", "bob"), 73 as(alice, 74 mkfile("file", ""), 75 truncate("file", uint64(dataLen)), 76 // Write first block and sync. 77 writeBS("file", data[:12]), 78 // Write last block, don't sync yet. 79 pwriteBSSync("file", data[dataLen-12:], int64(dataLen-12), false), 80 // Then write a block in the middle somewhere, and do the sync. 81 pwriteBSSync("file", data[64:68], 64, true), 82 ), 83 as(bob, 84 read("file", string(data)), 85 ), 86 ) 87 } 88 89 func TestTruncateLargeThenWriteToSmallerOffset(t *testing.T) { 90 testTruncateLargeThenWriteToSmallerOffset( 91 t, 10*12 /* 10 min-sized blocks */) 92 } 93 94 // Regression for KBFS-2091. 95 func TestTruncateLargeThenWriteToSmallerOffsetWithHoles(t *testing.T) { 96 if runtime.GOOS == "darwin" { 97 engine := createEngine(t) 98 // Use explicit engine check, rather than `skip()`, since we 99 // only care about skipping this on darwin. 100 if engine.Name() == "fuse" { 101 // On macOS, when we write 12 bytes through fuse to a file 102 // that's truncated, the OS ends up writing 4096 bytes 103 // (presumably zero-filled) instead, which creates too 104 // many blocks for the test to handle in a reasonable 105 // amount of time. So skip it on that platform. 106 t.Skip("macOS writes blocks that are too large for the min " + 107 "block size") 108 } 109 } 110 111 testTruncateLargeThenWriteToSmallerOffset( 112 t, 1024*1024 /* above the holes threshold */) 113 }