golang.org/x/net@v0.25.1-0.20240516223405-c87a5b62e243/quic/pipe_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  //go:build go1.21
     6  
     7  package quic
     8  
     9  import (
    10  	"bytes"
    11  	"math/rand"
    12  	"testing"
    13  )
    14  
    15  func TestPipeWrites(t *testing.T) {
    16  	type writeOp struct {
    17  		start, end int64
    18  	}
    19  	type discardBeforeOp struct {
    20  		off int64
    21  	}
    22  	type op any
    23  	src := make([]byte, 65536)
    24  	rand.New(rand.NewSource(0)).Read(src)
    25  	for _, test := range []struct {
    26  		desc string
    27  		ops  []op
    28  	}{{
    29  		desc: "sequential writes",
    30  		ops: []op{
    31  			writeOp{0, 1024},
    32  			writeOp{1024, 4096},
    33  			writeOp{4096, 65536},
    34  		},
    35  	}, {
    36  		desc: "disordered overlapping writes",
    37  		ops: []op{
    38  			writeOp{2000, 8000},
    39  			writeOp{0, 3000},
    40  			writeOp{7000, 12000},
    41  		},
    42  	}, {
    43  		desc: "write to discarded region",
    44  		ops: []op{
    45  			writeOp{0, 65536},
    46  			discardBeforeOp{32768},
    47  			writeOp{0, 1000},
    48  			writeOp{3000, 5000},
    49  			writeOp{0, 32768},
    50  		},
    51  	}, {
    52  		desc: "write overlaps discarded region",
    53  		ops: []op{
    54  			discardBeforeOp{10000},
    55  			writeOp{0, 20000},
    56  		},
    57  	}, {
    58  		desc: "discard everything",
    59  		ops: []op{
    60  			writeOp{0, 10000},
    61  			discardBeforeOp{10000},
    62  			writeOp{10000, 20000},
    63  		},
    64  	}, {
    65  		desc: "discard before writing",
    66  		ops: []op{
    67  			discardBeforeOp{1000},
    68  			writeOp{0, 1},
    69  		},
    70  	}} {
    71  		var p pipe
    72  		var wantset rangeset[int64]
    73  		var wantStart, wantEnd int64
    74  		for i, o := range test.ops {
    75  			switch o := o.(type) {
    76  			case writeOp:
    77  				p.writeAt(src[o.start:o.end], o.start)
    78  				wantset.add(o.start, o.end)
    79  				wantset.sub(0, wantStart)
    80  				if o.end > wantEnd {
    81  					wantEnd = o.end
    82  				}
    83  			case discardBeforeOp:
    84  				p.discardBefore(o.off)
    85  				wantset.sub(0, o.off)
    86  				wantStart = o.off
    87  				if o.off > wantEnd {
    88  					wantEnd = o.off
    89  				}
    90  			}
    91  			if p.start != wantStart || p.end != wantEnd {
    92  				t.Errorf("%v: after %#v p contains [%v,%v), want [%v,%v)", test.desc, test.ops[:i+1], p.start, p.end, wantStart, wantEnd)
    93  			}
    94  			for _, r := range wantset {
    95  				want := src[r.start:][:r.size()]
    96  				got := make([]byte, r.size())
    97  				p.copy(r.start, got)
    98  				if !bytes.Equal(got, want) {
    99  					t.Errorf("%v after %#v, mismatch in data in %v", test.desc, test.ops[:i+1], r)
   100  				}
   101  			}
   102  		}
   103  	}
   104  }