// 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) } } } } }