feat(notify): 重构通信内核并补齐 stream/bulk/record/transfer 能力
- 引入 LogicalConn/TransportConn 分层,ClientConn 保留兼容适配层 - 新增 Stream、Bulk、RecordStream 三条数据面能力及对应控制路径 - 完成 transfer/file 传输内核与状态快照、诊断能力 - 补齐 reconnect、inbound dispatcher、modern psk 等基础模块 - 增加大规模回归、并发与基准测试覆盖 - 更新依赖库
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user