github.com/useflyent/fhttp@v0.0.0-20211004035111-333f430cfbbf/http2/writesched_test.go (about)

     1  // Copyright 2016 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  	"fmt"
     9  	"math"
    10  	"reflect"
    11  	"testing"
    12  )
    13  
    14  func makeWriteNonStreamRequest() FrameWriteRequest {
    15  	return FrameWriteRequest{writeSettingsAck{}, nil, nil}
    16  }
    17  
    18  func makeWriteHeadersRequest(streamID uint32) FrameWriteRequest {
    19  	st := &stream{id: streamID}
    20  	return FrameWriteRequest{&writeResHeaders{streamID: streamID, httpResCode: 200}, st, nil}
    21  }
    22  
    23  func makeHandlerPanicRST(streamID uint32) FrameWriteRequest {
    24  	st := &stream{id: streamID}
    25  	return FrameWriteRequest{&handlerPanicRST{StreamID: streamID}, st, nil}
    26  }
    27  
    28  func checkConsume(wr FrameWriteRequest, nbytes int32, want []FrameWriteRequest) error {
    29  	consumed, rest, n := wr.Consume(nbytes)
    30  	var wantConsumed, wantRest FrameWriteRequest
    31  	switch len(want) {
    32  	case 0:
    33  	case 1:
    34  		wantConsumed = want[0]
    35  	case 2:
    36  		wantConsumed = want[0]
    37  		wantRest = want[1]
    38  	}
    39  	if !reflect.DeepEqual(consumed, wantConsumed) || !reflect.DeepEqual(rest, wantRest) || n != len(want) {
    40  		return fmt.Errorf("got %v, %v, %v\nwant %v, %v, %v", consumed, rest, n, wantConsumed, wantRest, len(want))
    41  	}
    42  	return nil
    43  }
    44  
    45  func TestFrameWriteRequestNonData(t *testing.T) {
    46  	wr := makeWriteNonStreamRequest()
    47  	if got, want := wr.DataSize(), 0; got != want {
    48  		t.Errorf("DataSize: got %v, want %v", got, want)
    49  	}
    50  
    51  	// Non-DATA frames are always consumed whole.
    52  	if err := checkConsume(wr, 0, []FrameWriteRequest{wr}); err != nil {
    53  		t.Errorf("Consume:\n%v", err)
    54  	}
    55  }
    56  
    57  func TestFrameWriteRequestData(t *testing.T) {
    58  	st := &stream{
    59  		id: 1,
    60  		sc: &serverConn{maxFrameSize: 16},
    61  	}
    62  	const size = 32
    63  	wr := FrameWriteRequest{&writeData{st.id, make([]byte, size), true}, st, make(chan error)}
    64  	if got, want := wr.DataSize(), size; got != want {
    65  		t.Errorf("DataSize: got %v, want %v", got, want)
    66  	}
    67  
    68  	// No flow-control bytes available: cannot consume anything.
    69  	if err := checkConsume(wr, math.MaxInt32, []FrameWriteRequest{}); err != nil {
    70  		t.Errorf("Consume(limited by flow control):\n%v", err)
    71  	}
    72  
    73  	// Add enough flow-control bytes to consume the entire frame,
    74  	// but we're now restricted by st.sc.maxFrameSize.
    75  	st.flow.add(size)
    76  	want := []FrameWriteRequest{
    77  		{
    78  			write:  &writeData{st.id, make([]byte, st.sc.maxFrameSize), false},
    79  			stream: st,
    80  			done:   nil,
    81  		},
    82  		{
    83  			write:  &writeData{st.id, make([]byte, size-st.sc.maxFrameSize), true},
    84  			stream: st,
    85  			done:   wr.done,
    86  		},
    87  	}
    88  	if err := checkConsume(wr, math.MaxInt32, want); err != nil {
    89  		t.Errorf("Consume(limited by maxFrameSize):\n%v", err)
    90  	}
    91  	rest := want[1]
    92  
    93  	// Consume 8 bytes from the remaining frame.
    94  	want = []FrameWriteRequest{
    95  		{
    96  			write:  &writeData{st.id, make([]byte, 8), false},
    97  			stream: st,
    98  			done:   nil,
    99  		},
   100  		{
   101  			write:  &writeData{st.id, make([]byte, size-st.sc.maxFrameSize-8), true},
   102  			stream: st,
   103  			done:   wr.done,
   104  		},
   105  	}
   106  	if err := checkConsume(rest, 8, want); err != nil {
   107  		t.Errorf("Consume(8):\n%v", err)
   108  	}
   109  	rest = want[1]
   110  
   111  	// Consume all remaining bytes.
   112  	want = []FrameWriteRequest{
   113  		{
   114  			write:  &writeData{st.id, make([]byte, size-st.sc.maxFrameSize-8), true},
   115  			stream: st,
   116  			done:   wr.done,
   117  		},
   118  	}
   119  	if err := checkConsume(rest, math.MaxInt32, want); err != nil {
   120  		t.Errorf("Consume(remainder):\n%v", err)
   121  	}
   122  }
   123  
   124  func TestFrameWriteRequest_StreamID(t *testing.T) {
   125  	const streamID = 123
   126  	wr := FrameWriteRequest{write: streamError(streamID, ErrCodeNo)}
   127  	if got := wr.StreamID(); got != streamID {
   128  		t.Errorf("FrameWriteRequest(StreamError) = %v; want %v", got, streamID)
   129  	}
   130  }