199 lines
4.1 KiB
Go
199 lines
4.1 KiB
Go
|
|
package buffer_test
|
||
|
|
|
||
|
|
import (
|
||
|
|
"bytes"
|
||
|
|
"code.squareroundforest.org/arpio/buffer"
|
||
|
|
"testing"
|
||
|
|
"time"
|
||
|
|
)
|
||
|
|
|
||
|
|
func TestBlock(t *testing.T) {
|
||
|
|
t.Run("read", func(t *testing.T) {
|
||
|
|
segmentSize := 1 << 12
|
||
|
|
blockAfter := segmentSize
|
||
|
|
bc := make(chan struct{})
|
||
|
|
g := &gen{
|
||
|
|
max: 1 << 15,
|
||
|
|
blockAfter: []int{blockAfter},
|
||
|
|
unblock: map[int]<-chan struct{}{blockAfter: bc},
|
||
|
|
}
|
||
|
|
|
||
|
|
r := buffer.BufferedReader(g, buffer.Options{BufferPool: buffer.NoPool(segmentSize)})
|
||
|
|
b := make([]byte, 2*segmentSize)
|
||
|
|
if n, err := r.Read(b); n != segmentSize || err != nil {
|
||
|
|
t.Fatal(n, err)
|
||
|
|
}
|
||
|
|
|
||
|
|
if string(b[:segmentSize]) != string(generate(segmentSize)) {
|
||
|
|
t.Log(string(b))
|
||
|
|
t.Log(string(generate(segmentSize)))
|
||
|
|
t.Fatal("invalid content 1")
|
||
|
|
}
|
||
|
|
|
||
|
|
ubc := make(chan struct{})
|
||
|
|
go func() {
|
||
|
|
if n, err := r.Read(b); n != segmentSize || err != nil {
|
||
|
|
t.Fatal(n, err)
|
||
|
|
}
|
||
|
|
|
||
|
|
if string(b[:segmentSize]) != string(generate(2 * segmentSize)[segmentSize:]) {
|
||
|
|
t.Fatal("invalid content 2")
|
||
|
|
}
|
||
|
|
|
||
|
|
close(ubc)
|
||
|
|
}()
|
||
|
|
|
||
|
|
select {
|
||
|
|
case <-time.After(10 * time.Millisecond):
|
||
|
|
case <-ubc:
|
||
|
|
t.Fatal("unexpected read return")
|
||
|
|
}
|
||
|
|
|
||
|
|
close(bc)
|
||
|
|
select {
|
||
|
|
case <-time.After(10 * time.Millisecond):
|
||
|
|
t.Fatal("timeout")
|
||
|
|
case <-ubc:
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("read bytes", func(t *testing.T) {
|
||
|
|
segmentSize := 1 << 12
|
||
|
|
blockAfter := segmentSize
|
||
|
|
bc := make(chan struct{})
|
||
|
|
g := &gen{
|
||
|
|
max: 1 << 15,
|
||
|
|
blockAfter: []int{blockAfter},
|
||
|
|
unblock: map[int]<-chan struct{}{blockAfter: bc},
|
||
|
|
}
|
||
|
|
|
||
|
|
r := buffer.BufferedReader(g, buffer.Options{BufferPool: buffer.NoPool(segmentSize)})
|
||
|
|
ubc := make(chan struct{})
|
||
|
|
go func() {
|
||
|
|
if b, err := r.ReadBytes([]byte("123"), 2*segmentSize); len(b) != 0 || err != nil {
|
||
|
|
t.Fatal(len(b), err)
|
||
|
|
}
|
||
|
|
|
||
|
|
close(ubc)
|
||
|
|
}()
|
||
|
|
|
||
|
|
select {
|
||
|
|
case <-time.After(10 * time.Millisecond):
|
||
|
|
case <-ubc:
|
||
|
|
t.Fatal("unexpected read return")
|
||
|
|
}
|
||
|
|
|
||
|
|
close(bc)
|
||
|
|
select {
|
||
|
|
case <-time.After(10 * time.Millisecond):
|
||
|
|
t.Fatal("timeout")
|
||
|
|
case <-ubc:
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("read utf8", func(t *testing.T) {
|
||
|
|
segmentSize := 1 << 12
|
||
|
|
blockAfter := segmentSize
|
||
|
|
bc := make(chan struct{})
|
||
|
|
g := &gen{
|
||
|
|
max: 1 << 15,
|
||
|
|
blockAfter: []int{blockAfter},
|
||
|
|
unblock: map[int]<-chan struct{}{blockAfter: bc},
|
||
|
|
}
|
||
|
|
|
||
|
|
r := buffer.BufferedReader(g, buffer.Options{BufferPool: buffer.NoPool(segmentSize)})
|
||
|
|
ubc := make(chan struct{})
|
||
|
|
go func() {
|
||
|
|
if r, n, err := r.ReadUTF8(2 * segmentSize); len(r) != 2*segmentSize ||
|
||
|
|
n != 2*segmentSize ||
|
||
|
|
err != nil {
|
||
|
|
t.Fatal(len(r), err)
|
||
|
|
}
|
||
|
|
|
||
|
|
close(ubc)
|
||
|
|
}()
|
||
|
|
|
||
|
|
select {
|
||
|
|
case <-time.After(10 * time.Millisecond):
|
||
|
|
case <-ubc:
|
||
|
|
t.Fatal("unexpected read return")
|
||
|
|
}
|
||
|
|
|
||
|
|
close(bc)
|
||
|
|
select {
|
||
|
|
case <-time.After(10 * time.Millisecond):
|
||
|
|
t.Fatal("timeout")
|
||
|
|
case <-ubc:
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("peek", func(t *testing.T) {
|
||
|
|
segmentSize := 1 << 12
|
||
|
|
blockAfter := segmentSize
|
||
|
|
bc := make(chan struct{})
|
||
|
|
g := &gen{
|
||
|
|
max: 1 << 15,
|
||
|
|
blockAfter: []int{blockAfter},
|
||
|
|
unblock: map[int]<-chan struct{}{blockAfter: bc},
|
||
|
|
}
|
||
|
|
|
||
|
|
r := buffer.BufferedReader(g, buffer.Options{BufferPool: buffer.NoPool(segmentSize)})
|
||
|
|
ubc := make(chan struct{})
|
||
|
|
go func() {
|
||
|
|
if b, err := r.Peek(2 * segmentSize); len(b) != 2*segmentSize || err != nil {
|
||
|
|
t.Fatal(len(b), err)
|
||
|
|
}
|
||
|
|
|
||
|
|
close(ubc)
|
||
|
|
}()
|
||
|
|
|
||
|
|
select {
|
||
|
|
case <-time.After(10 * time.Millisecond):
|
||
|
|
case <-ubc:
|
||
|
|
t.Fatal("unexpected read return")
|
||
|
|
}
|
||
|
|
|
||
|
|
close(bc)
|
||
|
|
select {
|
||
|
|
case <-time.After(10 * time.Millisecond):
|
||
|
|
t.Fatal("timeout")
|
||
|
|
case <-ubc:
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("write to", func(t *testing.T) {
|
||
|
|
segmentSize := 1 << 12
|
||
|
|
blockAfter := segmentSize
|
||
|
|
bc := make(chan struct{})
|
||
|
|
g := &gen{
|
||
|
|
max: 1 << 15,
|
||
|
|
blockAfter: []int{blockAfter},
|
||
|
|
unblock: map[int]<-chan struct{}{blockAfter: bc},
|
||
|
|
}
|
||
|
|
|
||
|
|
r := buffer.BufferedReader(g, buffer.Options{BufferPool: buffer.NoPool(segmentSize)})
|
||
|
|
ubc := make(chan struct{})
|
||
|
|
go func() {
|
||
|
|
var b bytes.Buffer
|
||
|
|
if n, err := r.WriteTo(&b); n != 1<<15 || err != nil {
|
||
|
|
t.Fatal(b, err)
|
||
|
|
}
|
||
|
|
|
||
|
|
close(ubc)
|
||
|
|
}()
|
||
|
|
|
||
|
|
select {
|
||
|
|
case <-time.After(10 * time.Millisecond):
|
||
|
|
case <-ubc:
|
||
|
|
t.Fatal("unexpected read return")
|
||
|
|
}
|
||
|
|
|
||
|
|
close(bc)
|
||
|
|
select {
|
||
|
|
case <-time.After(10 * time.Millisecond):
|
||
|
|
t.Fatal("timeout")
|
||
|
|
case <-ubc:
|
||
|
|
}
|
||
|
|
})
|
||
|
|
}
|