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  }