golang.org/x/net@v0.25.1-0.20240516223405-c87a5b62e243/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  }