- 将 RecordStream 出站路径收敛为单 writer loop - 支持在 batch header 中 piggyback AckSeq,保留独立 ack 作为兼容回退 - 增加 record stream 打开阶段能力协商,支持 mixed-version peer 自动降级 - 补充 RecordSnapshot 与 diagnostics summary 的 record-plane 观测项 - 增加 batch/ack/error frame、piggyback ack、barrier 等待拆分与 apply backlog 指标 - 收紧 TransportConn detach 后的 runtime snapshot 语义 - 补充 README 中的 RecordStream 语义、兼容行为与诊断快照说明 - 补充相关单测与 race 回归验证
79 lines
2.3 KiB
Go
79 lines
2.3 KiB
Go
package notify
|
|
|
|
import (
|
|
"context"
|
|
"net"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestNegotiateRecordStreamOpenMetadataEnablesBatchAck(t *testing.T) {
|
|
reqMetadata, respMetadata := negotiateRecordStreamOpenMetadata(StreamRecordChannel, StreamMetadata{
|
|
recordStreamMetadataCapBatchAckKey: recordStreamMetadataEnabledValue,
|
|
})
|
|
if !recordStreamUseBatchAck(reqMetadata) {
|
|
t.Fatal("request metadata should enable batch ack")
|
|
}
|
|
if !recordStreamUseBatchAck(respMetadata) {
|
|
t.Fatal("response metadata should enable batch ack")
|
|
}
|
|
}
|
|
|
|
func TestNegotiateRecordStreamOpenMetadataKeepsFallbackWithoutCapability(t *testing.T) {
|
|
reqMetadata, respMetadata := negotiateRecordStreamOpenMetadata(StreamRecordChannel, nil)
|
|
if recordStreamUseBatchAck(reqMetadata) {
|
|
t.Fatalf("request metadata should keep fallback mode: %+v", reqMetadata)
|
|
}
|
|
if recordStreamUseBatchAck(respMetadata) {
|
|
t.Fatalf("response metadata should keep fallback mode: %+v", respMetadata)
|
|
}
|
|
}
|
|
|
|
func TestOpenRecordStreamNegotiatesBatchAck(t *testing.T) {
|
|
server := NewServer().(*ServerCommon)
|
|
secret := []byte("0123456789abcdef0123456789abcdef")
|
|
server = newRunningPeerAttachServerForTest(t, func(server *ServerCommon) {
|
|
server.SetSecretKey(secret)
|
|
})
|
|
|
|
acceptedCh := make(chan RecordAcceptInfo, 1)
|
|
server.SetRecordStreamHandler(func(info RecordAcceptInfo) error {
|
|
acceptedCh <- info
|
|
return nil
|
|
})
|
|
|
|
client := NewClient().(*ClientCommon)
|
|
client.SetSecretKey(secret)
|
|
left, right := net.Pipe()
|
|
defer right.Close()
|
|
bootstrapPeerAttachConnForTest(t, server, right)
|
|
if err := client.ConnectByConn(left); err != nil {
|
|
t.Fatalf("client ConnectByConn failed: %v", err)
|
|
}
|
|
defer func() {
|
|
client.setByeFromServer(true)
|
|
_ = client.Stop()
|
|
}()
|
|
|
|
record, err := client.OpenRecordStream(context.Background(), RecordOpenOptions{})
|
|
if err != nil {
|
|
t.Fatalf("OpenRecordStream failed: %v", err)
|
|
}
|
|
defer func() {
|
|
_ = record.Close()
|
|
}()
|
|
|
|
if !recordStreamUseBatchAck(record.Metadata()) {
|
|
t.Fatalf("client record stream metadata should negotiate batch ack: %+v", record.Metadata())
|
|
}
|
|
|
|
select {
|
|
case accepted := <-acceptedCh:
|
|
if !recordStreamUseBatchAck(accepted.Metadata) {
|
|
t.Fatalf("accepted record metadata should negotiate batch ack: %+v", accepted.Metadata)
|
|
}
|
|
case <-time.After(2 * time.Second):
|
|
t.Fatal("timed out waiting accepted record stream")
|
|
}
|
|
}
|