stario/fn_test.go

175 lines
4.5 KiB
Go
Raw Normal View History

package stario
import (
"context"
"errors"
"testing"
"time"
)
func TestWaitUntilContextReturnsWorkerError(t *testing.T) {
want := errors.New("worker failed")
err := WaitUntilContext(context.Background(), func(ctx context.Context) error {
return want
})
if !errors.Is(err, want) {
t.Fatalf("unexpected error: got %v want %v", err, want)
}
}
func TestWaitUntilContextReturnsDeadlineExceeded(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Millisecond)
defer cancel()
workerReturned := make(chan struct{})
err := WaitUntilContext(ctx, func(ctx context.Context) error {
<-ctx.Done()
close(workerReturned)
return nil
})
if !errors.Is(err, context.DeadlineExceeded) {
t.Fatalf("unexpected context error: %v", err)
}
select {
case <-workerReturned:
case <-time.After(200 * time.Millisecond):
t.Fatal("worker did not return after context deadline")
}
}
func TestWaitUntilContextFinishedReturnsCanceled(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
cancel()
result := WaitUntilContextFinished(ctx, func(ctx context.Context) error {
<-ctx.Done()
return nil
})
err, ok := <-result
if !ok {
t.Fatal("result channel closed without value")
}
if !errors.Is(err, context.Canceled) {
t.Fatalf("unexpected context error: %v", err)
}
if _, ok := <-result; ok {
t.Fatal("result channel should be closed after delivering the outcome")
}
}
func TestWaitUntilContextDoneBridgesDoneChannel(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
doneClosed := make(chan struct{})
go func() {
time.Sleep(20 * time.Millisecond)
cancel()
}()
err := WaitUntilContextDone(ctx, func(done <-chan struct{}) error {
<-done
close(doneClosed)
return nil
})
if !errors.Is(err, context.Canceled) {
t.Fatalf("unexpected context error: %v", err)
}
select {
case <-doneClosed:
case <-time.After(200 * time.Millisecond):
t.Fatal("done channel was not closed when context canceled")
}
}
func TestWaitUntilContextDoneFinishedReturnsCanceled(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
doneClosed := make(chan struct{})
go func() {
time.Sleep(20 * time.Millisecond)
cancel()
}()
result := WaitUntilContextDoneFinished(ctx, func(done <-chan struct{}) error {
<-done
close(doneClosed)
return nil
})
err, ok := <-result
if !ok {
t.Fatal("result channel closed without value")
}
if !errors.Is(err, context.Canceled) {
t.Fatalf("unexpected context error: %v", err)
}
select {
case <-doneClosed:
case <-time.After(200 * time.Millisecond):
t.Fatal("done channel was not closed when context canceled")
}
if _, ok := <-result; ok {
t.Fatal("result channel should be closed after delivering the outcome")
}
}
func TestWaitUntilTimeoutReturnsWorkerError(t *testing.T) {
want := errors.New("worker failed")
err := WaitUntilTimeout(time.Second, func(stop chan struct{}) error {
return want
})
if !errors.Is(err, want) {
t.Fatalf("unexpected error: got %v want %v", err, want)
}
}
func TestWaitUntilTimeoutTimesOutWithoutBlockingWorkerReturn(t *testing.T) {
workerReturned := make(chan struct{})
err := WaitUntilTimeout(20*time.Millisecond, func(stop chan struct{}) error {
<-stop
close(workerReturned)
return nil
})
if !errors.Is(err, ERR_TIMEOUT) {
t.Fatalf("unexpected timeout error: %v", err)
}
select {
case <-workerReturned:
case <-time.After(200 * time.Millisecond):
t.Fatal("worker did not return after timeout signal")
}
}
func TestWaitUntilFinishedReturnsWorkerError(t *testing.T) {
want := errors.New("worker failed")
err := <-WaitUntilFinished(func() error {
return want
})
if !errors.Is(err, want) {
t.Fatalf("unexpected error: got %v want %v", err, want)
}
}
func TestWaitUntilTimeoutFinishedReturnsTimeout(t *testing.T) {
result := WaitUntilTimeoutFinished(20*time.Millisecond, func(stop chan struct{}) error {
<-stop
return nil
})
err, ok := <-result
if !ok {
t.Fatal("result channel closed without value")
}
if !errors.Is(err, ERR_TIMEOUT) {
t.Fatalf("unexpected timeout error: %v", err)
}
if _, ok := <-result; ok {
t.Fatal("result channel should be closed after delivering the outcome")
}
}
func TestWaitUntilTimeoutFinishedReturnsWorkerError(t *testing.T) {
want := errors.New("worker failed")
err, ok := <-WaitUntilTimeoutFinished(time.Second, func(stop chan struct{}) error {
return want
})
if !ok {
t.Fatal("result channel closed without value")
}
if !errors.Is(err, want) {
t.Fatalf("unexpected error: got %v want %v", err, want)
}
}