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