blob: bcb3a8bc05c16e1a2536a5b166aa26153ffd0d33 [file] [log] [blame]
// 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)
}
}
}
}
}