108 lines
2.7 KiB
Go
108 lines
2.7 KiB
Go
|
|
package notify
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"errors"
|
||
|
|
"testing"
|
||
|
|
)
|
||
|
|
|
||
|
|
func TestRetryFileTransferSendHonorsRetryCount(t *testing.T) {
|
||
|
|
var attempts int
|
||
|
|
|
||
|
|
err := retryFileTransferSend(context.Background(), fileTransferConfig{
|
||
|
|
SendRetry: 3,
|
||
|
|
}, func(cfg fileTransferConfig) error {
|
||
|
|
attempts++
|
||
|
|
return errors.New("send failed")
|
||
|
|
})
|
||
|
|
if err == nil {
|
||
|
|
t.Fatal("retryFileTransferSend should return the last error")
|
||
|
|
}
|
||
|
|
if got, want := attempts, 3; got != want {
|
||
|
|
t.Fatalf("attempt count mismatch: got %d want %d", got, want)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestRetryFileTransferSendStopsAfterSuccess(t *testing.T) {
|
||
|
|
var attempts int
|
||
|
|
|
||
|
|
err := retryFileTransferSend(context.Background(), fileTransferConfig{
|
||
|
|
SendRetry: 5,
|
||
|
|
}, func(cfg fileTransferConfig) error {
|
||
|
|
attempts++
|
||
|
|
if attempts == 3 {
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
return errors.New("send failed")
|
||
|
|
})
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("retryFileTransferSend should stop after success: %v", err)
|
||
|
|
}
|
||
|
|
if got, want := attempts, 3; got != want {
|
||
|
|
t.Fatalf("attempt count mismatch: got %d want %d", got, want)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestRetryFileTransferSendHonorsContextCancel(t *testing.T) {
|
||
|
|
ctx, cancel := context.WithCancel(context.Background())
|
||
|
|
cancel()
|
||
|
|
|
||
|
|
var attempts int
|
||
|
|
err := retryFileTransferSend(ctx, fileTransferConfig{
|
||
|
|
SendRetry: 3,
|
||
|
|
}, func(cfg fileTransferConfig) error {
|
||
|
|
attempts++
|
||
|
|
return nil
|
||
|
|
})
|
||
|
|
if !errors.Is(err, context.Canceled) {
|
||
|
|
t.Fatalf("expected context canceled, got %v", err)
|
||
|
|
}
|
||
|
|
if got, want := attempts, 0; got != want {
|
||
|
|
t.Fatalf("attempt count mismatch: got %d want %d", got, want)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestRetryFileTransferSendReportsRetryAndTimeoutHooks(t *testing.T) {
|
||
|
|
var attempts int
|
||
|
|
var retries int
|
||
|
|
var timeouts int
|
||
|
|
|
||
|
|
err := retryFileTransferSend(context.Background(), fileTransferConfig{
|
||
|
|
SendRetry: 3,
|
||
|
|
}, func(cfg fileTransferConfig) error {
|
||
|
|
attempts++
|
||
|
|
if attempts < 3 {
|
||
|
|
return errFileAckTimeout
|
||
|
|
}
|
||
|
|
return nil
|
||
|
|
}, fileTransferRetryHooks{
|
||
|
|
onRetry: func(err error, attempt int) {
|
||
|
|
retries++
|
||
|
|
if !errors.Is(err, errFileAckTimeout) {
|
||
|
|
t.Fatalf("retry err = %v, want %v", err, errFileAckTimeout)
|
||
|
|
}
|
||
|
|
if attempt != retries {
|
||
|
|
t.Fatalf("retry attempt = %d, want %d", attempt, retries)
|
||
|
|
}
|
||
|
|
},
|
||
|
|
onTimeout: func(err error, attempt int) {
|
||
|
|
timeouts++
|
||
|
|
if !errors.Is(err, errFileAckTimeout) {
|
||
|
|
t.Fatalf("timeout err = %v, want %v", err, errFileAckTimeout)
|
||
|
|
}
|
||
|
|
if attempt != timeouts {
|
||
|
|
t.Fatalf("timeout attempt = %d, want %d", attempt, timeouts)
|
||
|
|
}
|
||
|
|
},
|
||
|
|
})
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("retryFileTransferSend should succeed after timeout retries: %v", err)
|
||
|
|
}
|
||
|
|
if got, want := retries, 2; got != want {
|
||
|
|
t.Fatalf("retry hook count mismatch: got %d want %d", got, want)
|
||
|
|
}
|
||
|
|
if got, want := timeouts, 2; got != want {
|
||
|
|
t.Fatalf("timeout hook count mismatch: got %d want %d", got, want)
|
||
|
|
}
|
||
|
|
}
|