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