Files
go-astikit/io_test.go
2024-10-15 16:22:55 +02:00

180 lines
4.5 KiB
Go

package astikit
import (
"bytes"
"context"
"errors"
"io"
"reflect"
"testing"
"time"
)
func TestCopy(t *testing.T) {
// Context canceled
ctx, cancel := context.WithCancel(context.Background())
cancel()
r, w := bytes.NewBuffer([]byte("bla bla bla")), &bytes.Buffer{}
n, err := Copy(ctx, w, r)
if e := int64(0); n != e {
t.Fatalf("expected %v, got %v", e, n)
}
if e := context.Canceled; !errors.Is(err, e) {
t.Fatalf("error should be %+v, got %+v", e, err)
}
// Default
n, err = Copy(context.Background(), w, r)
if e := int64(11); n != e {
t.Fatalf("expected %v, got %v", e, n)
}
if err != nil {
t.Fatalf("expected no error, got %+v", err)
}
}
func TestWriterAdapter(t *testing.T) {
// Init
var o []string
var w = NewWriterAdapter(WriterAdapterOptions{
Callback: func(i []byte) {
o = append(o, string(i))
},
Split: []byte("\n"),
})
// No Split
w.Write([]byte("bla bla ")) //nolint:errcheck
if len(o) != 0 {
t.Fatalf("expected %v, got %v", 0, len(o))
}
// Multi Split
w.Write([]byte("bla \nbla bla\nbla")) //nolint:errcheck
if e := []string{"bla bla bla ", "bla bla"}; !reflect.DeepEqual(o, e) {
t.Fatalf("expected %+v, got %+v", e, o)
}
// Close
w.Close()
if e := []string{"bla bla bla ", "bla bla", "bla"}; !reflect.DeepEqual(o, e) {
t.Fatalf("expected %+v, got %+v", e, o)
}
}
func TestPiper(t *testing.T) {
p1 := NewPiper(PiperOptions{})
defer p1.Close()
// Piper shouldn't block on write
w := []byte("test")
ctx1, cancel1 := context.WithTimeout(context.Background(), time.Second)
defer cancel1()
var n int
var err error
go func() {
defer cancel1()
n, err = p1.Write(w)
}()
<-ctx1.Done()
if errCtx := ctx1.Err(); errors.Is(errCtx, context.DeadlineExceeded) {
t.Fatalf("expected no deadline exceeded error, got %+v", errCtx)
}
if err != nil {
t.Fatalf("expected no error, got %+v", err)
}
if e, g := 4, n; e != g {
t.Fatalf("expected %d, got %d", e, g)
}
r := make([]byte, 10)
n, err = p1.Read(r)
if err != nil {
t.Fatalf("expected no error, got %+v", err)
}
if e, g := 4, n; e != g {
t.Fatalf("expected %d, got %d", e, g)
}
if e, g := w, r[:n]; !bytes.Equal(e, g) {
t.Fatalf("expected %s, got %s", e, g)
}
// Piper should block on read unless write or piper is closed
ctx2, cancel2 := context.WithTimeout(context.Background(), 100*time.Millisecond)
defer cancel2()
ctx3, cancel3 := context.WithTimeout(context.Background(), time.Second)
defer cancel3()
r = make([]byte, 10)
go func() {
defer cancel2()
defer cancel3()
n, err = p1.Read(r)
}()
<-ctx2.Done()
if errCtx := ctx2.Err(); !errors.Is(errCtx, context.DeadlineExceeded) {
t.Fatalf("expected deadline exceeded error, got %+v", errCtx)
}
_, errWrite := p1.Write(w)
if errWrite != nil {
t.Fatalf("expected no error, got %+v", errWrite)
}
<-ctx3.Done()
if errCtx := ctx3.Err(); errors.Is(errCtx, context.DeadlineExceeded) {
t.Fatalf("expected no deadline exceeded error, got %+v", errCtx)
}
if err != nil {
t.Fatalf("expected no error, got %+v", err)
}
if e, g := 4, n; e != g {
t.Fatalf("expected %d, got %d", e, g)
}
if e, g := w, r[:n]; !bytes.Equal(e, g) {
t.Fatalf("expected %s, got %s", e, g)
}
ctx4, cancel4 := context.WithTimeout(context.Background(), 100*time.Millisecond)
defer cancel4()
ctx5, cancel5 := context.WithTimeout(context.Background(), time.Second)
defer cancel5()
go func() {
defer cancel4()
defer cancel5()
_, err = p1.Read(r)
}()
<-ctx4.Done()
if errCtx := ctx4.Err(); !errors.Is(errCtx, context.DeadlineExceeded) {
t.Fatalf("expected deadline exceeded error, got %+v", errCtx)
}
p1.Close()
<-ctx5.Done()
if errCtx := ctx5.Err(); errors.Is(errCtx, context.DeadlineExceeded) {
t.Fatalf("expected no deadline exceeded error, got %+v", errCtx)
}
if !errors.Is(err, io.EOF) {
t.Fatalf("expected io.EOF error, got %+v", err)
}
_, err = p1.Write(w)
if !errors.Is(err, io.EOF) {
t.Fatalf("expected io.EOF error, got %+v", err)
}
// Piper should timeout on read if a read timeout is provided
e1 := errors.New("1")
p2 := NewPiper(PiperOptions{
ReadTimeout: time.Millisecond,
ReadTimeoutError: e1,
})
defer p2.Close()
ctx6, cancel6 := context.WithTimeout(context.Background(), time.Second)
defer cancel6()
go func() {
defer cancel6()
_, err = p2.Read(r)
}()
<-ctx6.Done()
if errCtx := ctx6.Err(); errors.Is(errCtx, context.DeadlineExceeded) {
t.Fatalf("expected no deadline exceeded error, got %+v", errCtx)
}
if !errors.Is(err, e1) {
t.Fatalf("expected %s, got %s", e1, err)
}
}