github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/kbfs/data/bsplitter_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 package data 6 7 import ( 8 "bytes" 9 "testing" 10 11 "github.com/keybase/client/go/kbfs/kbfscodec" 12 "github.com/keybase/client/go/kbfs/kbfscrypto" 13 "github.com/stretchr/testify/require" 14 ) 15 16 func TestBsplitterEmptyCopyAll(t *testing.T) { 17 bsplit := &BlockSplitterSimple{10, 5, 10, 0} 18 fblock := NewFileBlock().(*FileBlock) 19 data := []byte{1, 2, 3, 4, 5} 20 21 if n := bsplit.CopyUntilSplit(fblock, false, data, 0); n != 5 { 22 t.Errorf("Did not copy expected number of bytes: %d", n) 23 } else if !bytes.Equal(fblock.Contents, data) { 24 t.Errorf("Wrong file contents after copy: %v", fblock.Contents) 25 } 26 } 27 28 func TestBsplitterNonemptyCopyAll(t *testing.T) { 29 bsplit := &BlockSplitterSimple{10, 5, 10, 0} 30 fblock := NewFileBlock().(*FileBlock) 31 fblock.Contents = []byte{10, 9} 32 data := []byte{1, 2, 3, 4, 5} 33 34 if n := bsplit.CopyUntilSplit(fblock, false, data, 0); n != 5 { 35 t.Errorf("Did not copy expected number of bytes: %d", n) 36 } else if !bytes.Equal(fblock.Contents, data) { 37 t.Errorf("Wrong file contents after copy: %v", fblock.Contents) 38 } 39 } 40 41 func TestBsplitterAppendAll(t *testing.T) { 42 bsplit := &BlockSplitterSimple{10, 5, 10, 0} 43 fblock := NewFileBlock().(*FileBlock) 44 fblock.Contents = []byte{10, 9} 45 data := []byte{1, 2, 3, 4, 5} 46 47 if n := bsplit.CopyUntilSplit(fblock, false, data, 2); n != 5 { 48 t.Errorf("Did not copy expected number of bytes: %d", n) 49 } else if !bytes.Equal(fblock.Contents, append([]byte{10, 9}, data...)) { 50 t.Errorf("Wrong file contents after copy: %v", fblock.Contents) 51 } 52 } 53 54 func TestBsplitterAppendExact(t *testing.T) { 55 bsplit := &BlockSplitterSimple{10, 5, 10, 0} 56 fblock := NewFileBlock().(*FileBlock) 57 fblock.Contents = []byte{10, 9, 8, 7, 6} 58 data := []byte{1, 2, 3, 4, 5} 59 60 if n := bsplit.CopyUntilSplit(fblock, false, data, 5); n != 5 { 61 t.Errorf("Did not copy expected number of bytes: %d", n) 62 } else if !bytes.Equal(fblock.Contents, 63 append([]byte{10, 9, 8, 7, 6}, data...)) { 64 t.Errorf("Wrong file contents after copy: %v", fblock.Contents) 65 } 66 } 67 68 func TestBsplitterSplitOne(t *testing.T) { 69 bsplit := &BlockSplitterSimple{10, 5, 10, 0} 70 fblock := NewFileBlock().(*FileBlock) 71 fblock.Contents = []byte{10, 9, 8, 7, 6} 72 data := []byte{1, 2, 3, 4, 5, 6} 73 74 if n := bsplit.CopyUntilSplit(fblock, false, data, 5); n != 5 { 75 t.Errorf("Did not copy expected number of bytes: %d", n) 76 } else if !bytes.Equal(fblock.Contents, 77 []byte{10, 9, 8, 7, 6, 1, 2, 3, 4, 5}) { 78 t.Errorf("Wrong file contents after copy: %v", fblock.Contents) 79 } 80 } 81 82 func TestBsplitterOverwriteMaxSizeBlock(t *testing.T) { 83 bsplit := &BlockSplitterSimple{5, 5, 10, 0} 84 fblock := NewFileBlock().(*FileBlock) 85 fblock.Contents = []byte{10, 9, 8, 7, 6} 86 data := []byte{1, 2, 3, 4, 5, 6, 7, 8} 87 88 if n := bsplit.CopyUntilSplit(fblock, false, data, 0); n != 5 { 89 t.Errorf("Did not copy expected number of bytes: %d", n) 90 } else if !bytes.Equal(fblock.Contents, []byte{1, 2, 3, 4, 5}) { 91 t.Errorf("Wrong file contents after copy: %v", fblock.Contents) 92 } 93 } 94 95 func TestBsplitterBlockTooBig(t *testing.T) { 96 bsplit := &BlockSplitterSimple{3, 5, 10, 0} 97 fblock := NewFileBlock().(*FileBlock) 98 fblock.Contents = []byte{10, 9, 8, 7, 6} 99 data := []byte{1, 2, 3, 4, 5, 6} 100 101 if n := bsplit.CopyUntilSplit(fblock, false, data, 5); n != 0 { 102 t.Errorf("Did not copy expected number of bytes: %d", n) 103 } else if !bytes.Equal(fblock.Contents, []byte{10, 9, 8, 7, 6}) { 104 t.Errorf("Wrong file contents after copy: %v", fblock.Contents) 105 } 106 } 107 108 func TestBsplitterOffTooBig(t *testing.T) { 109 bsplit := &BlockSplitterSimple{10, 5, 10, 0} 110 fblock := NewFileBlock().(*FileBlock) 111 fblock.Contents = []byte{10, 9, 8, 7, 6} 112 data := []byte{1, 2, 3, 4, 5, 6} 113 114 if n := bsplit.CopyUntilSplit(fblock, false, data, 15); n != 0 { 115 t.Errorf("Did not copy expected number of bytes: %d", n) 116 } else if !bytes.Equal(fblock.Contents, 117 []byte{10, 9, 8, 7, 6, 0, 0, 0, 0, 0}) { 118 t.Errorf("Wrong file contents after copy: %v", fblock.Contents) 119 } 120 } 121 122 func TestBsplitterShouldEmbed(t *testing.T) { 123 bsplit := &BlockSplitterSimple{10, 5, 10, 0} 124 if !bsplit.ShouldEmbedData(1) { 125 t.Errorf("Not embedding a 1-byte block change") 126 } 127 if !bsplit.ShouldEmbedData(10) { 128 t.Errorf("Not embedding a 10-byte block change") 129 } 130 } 131 132 func TestBsplitterShouldNotEmbed(t *testing.T) { 133 bsplit := &BlockSplitterSimple{10, 5, 10, 0} 134 if bsplit.ShouldEmbedData(11) { 135 t.Errorf("Not embedding a 1-byte block change") 136 } 137 } 138 139 func TestBsplitterOverhead(t *testing.T) { 140 codec := kbfscodec.NewMsgpack() 141 desiredBlockSize := int64(64 * 1024) 142 bsplit, err := NewBlockSplitterSimple(desiredBlockSize, 8*1024, codec) 143 if err != nil { 144 t.Fatalf("Got error making block splitter with overhead: %v", err) 145 } 146 147 // Test that an encoded, padded block matches this desired block size 148 block := NewFileBlock().(*FileBlock) 149 block.Contents = make([]byte, bsplit.maxSize) 150 for i := range block.Contents { 151 block.Contents[i] = byte(i) 152 } 153 encodedBlock, err := codec.Encode(block) 154 if err != nil { 155 t.Fatalf("Encoding block failed: %v", err) 156 } 157 paddedBlock, err := kbfscrypto.PadBlock(encodedBlock) 158 if err != nil { 159 t.Fatalf("Padding block failed: %v", err) 160 } 161 // first 4 bytes of the padded block encodes the block size 162 if g, e := int64(len(paddedBlock)), desiredBlockSize+4; g != e { 163 t.Fatalf("Padded block size %d doesn't match desired block size %d", 164 g, e) 165 } 166 } 167 168 func TestBsplitterSplitDir(t *testing.T) { 169 bsplit := &BlockSplitterSimple{10, 5, 10, 2} 170 dblock := NewDirBlock().(*DirBlock) 171 dblock.Children["a"] = DirEntry{} 172 dblock.Children["b"] = DirEntry{} 173 dblock.Children["c"] = DirEntry{} 174 dblock.Children["d"] = DirEntry{} 175 dblock.Children["e"] = DirEntry{} 176 dblock.Children["f"] = DirEntry{} 177 178 t.Log("Split an even block") 179 blocks, newOffset := bsplit.SplitDirIfNeeded(dblock) 180 require.Len(t, blocks, 2) 181 require.Equal(t, StringOffset("d"), *newOffset) 182 require.Len(t, blocks[0].Children, 3) 183 require.Contains(t, blocks[0].Children, "a") 184 require.Contains(t, blocks[0].Children, "b") 185 require.Contains(t, blocks[0].Children, "c") 186 require.Len(t, blocks[1].Children, 3) 187 require.Contains(t, blocks[1].Children, "d") 188 require.Contains(t, blocks[1].Children, "e") 189 require.Contains(t, blocks[1].Children, "f") 190 191 t.Log("Split odd blocks") 192 smallerBlocks, newOffset := bsplit.SplitDirIfNeeded(blocks[0]) 193 require.Len(t, smallerBlocks, 2) 194 require.Equal(t, StringOffset("b"), *newOffset) 195 require.Len(t, smallerBlocks[0].Children, 1) 196 require.Contains(t, smallerBlocks[0].Children, "a") 197 require.Len(t, smallerBlocks[1].Children, 2) 198 require.Contains(t, smallerBlocks[1].Children, "b") 199 require.Contains(t, smallerBlocks[1].Children, "c") 200 smallerBlocks, newOffset = bsplit.SplitDirIfNeeded(blocks[1]) 201 require.Len(t, smallerBlocks, 2) 202 require.Equal(t, StringOffset("e"), *newOffset) 203 require.Len(t, smallerBlocks[0].Children, 1) 204 require.Contains(t, smallerBlocks[0].Children, "d") 205 require.Len(t, smallerBlocks[1].Children, 2) 206 require.Contains(t, smallerBlocks[1].Children, "e") 207 require.Contains(t, smallerBlocks[1].Children, "f") 208 209 t.Log("Don't split small blocks") 210 noSplits, newOffset := bsplit.SplitDirIfNeeded(smallerBlocks[0]) 211 require.Len(t, noSplits, 1) 212 require.Nil(t, newOffset) 213 require.Equal(t, smallerBlocks[0], noSplits[0]) 214 noSplits, newOffset = bsplit.SplitDirIfNeeded(smallerBlocks[1]) 215 require.Len(t, noSplits, 1) 216 require.Nil(t, newOffset) 217 require.Equal(t, smallerBlocks[1], noSplits[0]) 218 }