golang.org/x/net@v0.25.1-0.20240516223405-c87a5b62e243/http2/writesched_roundrobin_test.go (about) 1 // Copyright 2023 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 "reflect" 9 "testing" 10 ) 11 12 func TestRoundRobinScheduler(t *testing.T) { 13 const maxFrameSize = 16 14 sc := &serverConn{maxFrameSize: maxFrameSize} 15 ws := newRoundRobinWriteScheduler() 16 streams := make([]*stream, 4) 17 for i := range streams { 18 streamID := uint32(i) + 1 19 streams[i] = &stream{ 20 id: streamID, 21 sc: sc, 22 } 23 streams[i].flow.add(1 << 20) // arbitrary large value 24 ws.OpenStream(streamID, OpenStreamOptions{}) 25 wr := FrameWriteRequest{ 26 write: &writeData{ 27 streamID: streamID, 28 p: make([]byte, maxFrameSize*(i+1)), 29 endStream: false, 30 }, 31 stream: streams[i], 32 } 33 ws.Push(wr) 34 } 35 const controlFrames = 2 36 for i := 0; i < controlFrames; i++ { 37 ws.Push(makeWriteNonStreamRequest()) 38 } 39 40 // We should get the control frames first. 41 for i := 0; i < controlFrames; i++ { 42 wr, ok := ws.Pop() 43 if !ok || wr.StreamID() != 0 { 44 t.Fatalf("wr.Pop() = stream %v, %v; want 0, true", wr.StreamID(), ok) 45 } 46 } 47 48 // Each stream should write maxFrameSize bytes until it runs out of data. 49 // Stream 1 has one frame of data, 2 has two frames, etc. 50 want := []uint32{1, 2, 3, 4, 2, 3, 4, 3, 4, 4} 51 var got []uint32 52 for { 53 wr, ok := ws.Pop() 54 if !ok { 55 break 56 } 57 if wr.DataSize() != maxFrameSize { 58 t.Fatalf("wr.Pop() = %v data bytes, want %v", wr.DataSize(), maxFrameSize) 59 } 60 got = append(got, wr.StreamID()) 61 } 62 if !reflect.DeepEqual(got, want) { 63 t.Fatalf("popped streams %v, want %v", got, want) 64 } 65 }