github.com/Andyfoo/golang/x/net@v0.0.0-20190901054642-57c1bf301704/http2/databuffer_test.go (about) 1 // Copyright 2017 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package http2 6 7 import ( 8 "bytes" 9 "fmt" 10 "reflect" 11 "testing" 12 ) 13 14 func fmtDataChunk(chunk []byte) string { 15 out := "" 16 var last byte 17 var count int 18 for _, c := range chunk { 19 if c != last { 20 if count > 0 { 21 out += fmt.Sprintf(" x %d ", count) 22 count = 0 23 } 24 out += string([]byte{c}) 25 last = c 26 } 27 count++ 28 } 29 if count > 0 { 30 out += fmt.Sprintf(" x %d", count) 31 } 32 return out 33 } 34 35 func fmtDataChunks(chunks [][]byte) string { 36 var out string 37 for _, chunk := range chunks { 38 out += fmt.Sprintf("{%q}", fmtDataChunk(chunk)) 39 } 40 return out 41 } 42 43 func testDataBuffer(t *testing.T, wantBytes []byte, setup func(t *testing.T) *dataBuffer) { 44 // Run setup, then read the remaining bytes from the dataBuffer and check 45 // that they match wantBytes. We use different read sizes to check corner 46 // cases in Read. 47 for _, readSize := range []int{1, 2, 1 * 1024, 32 * 1024} { 48 t.Run(fmt.Sprintf("ReadSize=%d", readSize), func(t *testing.T) { 49 b := setup(t) 50 buf := make([]byte, readSize) 51 var gotRead bytes.Buffer 52 for { 53 n, err := b.Read(buf) 54 gotRead.Write(buf[:n]) 55 if err == errReadEmpty { 56 break 57 } 58 if err != nil { 59 t.Fatalf("error after %v bytes: %v", gotRead.Len(), err) 60 } 61 } 62 if got, want := gotRead.Bytes(), wantBytes; !bytes.Equal(got, want) { 63 t.Errorf("FinalRead=%q, want %q", fmtDataChunk(got), fmtDataChunk(want)) 64 } 65 }) 66 } 67 } 68 69 func TestDataBufferAllocation(t *testing.T) { 70 writes := [][]byte{ 71 bytes.Repeat([]byte("a"), 1*1024-1), 72 []byte("a"), 73 bytes.Repeat([]byte("b"), 4*1024-1), 74 []byte("b"), 75 bytes.Repeat([]byte("c"), 8*1024-1), 76 []byte("c"), 77 bytes.Repeat([]byte("d"), 16*1024-1), 78 []byte("d"), 79 bytes.Repeat([]byte("e"), 32*1024), 80 } 81 var wantRead bytes.Buffer 82 for _, p := range writes { 83 wantRead.Write(p) 84 } 85 86 testDataBuffer(t, wantRead.Bytes(), func(t *testing.T) *dataBuffer { 87 b := &dataBuffer{} 88 for _, p := range writes { 89 if n, err := b.Write(p); n != len(p) || err != nil { 90 t.Fatalf("Write(%q x %d)=%v,%v want %v,nil", p[:1], len(p), n, err, len(p)) 91 } 92 } 93 want := [][]byte{ 94 bytes.Repeat([]byte("a"), 1*1024), 95 bytes.Repeat([]byte("b"), 4*1024), 96 bytes.Repeat([]byte("c"), 8*1024), 97 bytes.Repeat([]byte("d"), 16*1024), 98 bytes.Repeat([]byte("e"), 16*1024), 99 bytes.Repeat([]byte("e"), 16*1024), 100 } 101 if !reflect.DeepEqual(b.chunks, want) { 102 t.Errorf("dataBuffer.chunks\ngot: %s\nwant: %s", fmtDataChunks(b.chunks), fmtDataChunks(want)) 103 } 104 return b 105 }) 106 } 107 108 func TestDataBufferAllocationWithExpected(t *testing.T) { 109 writes := [][]byte{ 110 bytes.Repeat([]byte("a"), 1*1024), // allocates 16KB 111 bytes.Repeat([]byte("b"), 14*1024), 112 bytes.Repeat([]byte("c"), 15*1024), // allocates 16KB more 113 bytes.Repeat([]byte("d"), 2*1024), 114 bytes.Repeat([]byte("e"), 1*1024), // overflows 32KB expectation, allocates just 1KB 115 } 116 var wantRead bytes.Buffer 117 for _, p := range writes { 118 wantRead.Write(p) 119 } 120 121 testDataBuffer(t, wantRead.Bytes(), func(t *testing.T) *dataBuffer { 122 b := &dataBuffer{expected: 32 * 1024} 123 for _, p := range writes { 124 if n, err := b.Write(p); n != len(p) || err != nil { 125 t.Fatalf("Write(%q x %d)=%v,%v want %v,nil", p[:1], len(p), n, err, len(p)) 126 } 127 } 128 want := [][]byte{ 129 append(bytes.Repeat([]byte("a"), 1*1024), append(bytes.Repeat([]byte("b"), 14*1024), bytes.Repeat([]byte("c"), 1*1024)...)...), 130 append(bytes.Repeat([]byte("c"), 14*1024), bytes.Repeat([]byte("d"), 2*1024)...), 131 bytes.Repeat([]byte("e"), 1*1024), 132 } 133 if !reflect.DeepEqual(b.chunks, want) { 134 t.Errorf("dataBuffer.chunks\ngot: %s\nwant: %s", fmtDataChunks(b.chunks), fmtDataChunks(want)) 135 } 136 return b 137 }) 138 } 139 140 func TestDataBufferWriteAfterPartialRead(t *testing.T) { 141 testDataBuffer(t, []byte("cdxyz"), func(t *testing.T) *dataBuffer { 142 b := &dataBuffer{} 143 if n, err := b.Write([]byte("abcd")); n != 4 || err != nil { 144 t.Fatalf("Write(\"abcd\")=%v,%v want 4,nil", n, err) 145 } 146 p := make([]byte, 2) 147 if n, err := b.Read(p); n != 2 || err != nil || !bytes.Equal(p, []byte("ab")) { 148 t.Fatalf("Read()=%q,%v,%v want \"ab\",2,nil", p, n, err) 149 } 150 if n, err := b.Write([]byte("xyz")); n != 3 || err != nil { 151 t.Fatalf("Write(\"xyz\")=%v,%v want 3,nil", n, err) 152 } 153 return b 154 }) 155 }