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