notify/file_transfer_public_test.go
starainrt 09d972c7b7
feat(notify): 重构通信内核并补齐 stream/bulk/record/transfer 能力
- 引入 LogicalConn/TransportConn 分层,ClientConn 保留兼容适配层
  - 新增 Stream、Bulk、RecordStream 三条数据面能力及对应控制路径
  - 完成 transfer/file 传输内核与状态快照、诊断能力
  - 补齐 reconnect、inbound dispatcher、modern psk 等基础模块
  - 增加大规模回归、并发与基准测试覆盖
  - 更新依赖库
2026-04-15 15:24:36 +08:00

203 lines
8.1 KiB
Go

package notify
import (
"errors"
"testing"
"time"
)
func TestGetClientFileTransferSummariesRejectNil(t *testing.T) {
if _, err := GetClientFileTransferActiveSummaries(nil); !errors.Is(err, errClientFileTransferSummaryNil) {
t.Fatalf("GetClientFileTransferActiveSummaries nil error = %v, want %v", err, errClientFileTransferSummaryNil)
}
if _, err := GetClientFileTransferCompletedSummaries(nil); !errors.Is(err, errClientFileTransferSummaryNil) {
t.Fatalf("GetClientFileTransferCompletedSummaries nil error = %v, want %v", err, errClientFileTransferSummaryNil)
}
if _, err := GetClientFileTransferFailedSummaries(nil); !errors.Is(err, errClientFileTransferSummaryNil) {
t.Fatalf("GetClientFileTransferFailedSummaries nil error = %v, want %v", err, errClientFileTransferSummaryNil)
}
if _, err := GetClientFileTransferLatestByFileID(nil, "x"); !errors.Is(err, errClientFileTransferSummaryNil) {
t.Fatalf("GetClientFileTransferLatestByFileID nil error = %v, want %v", err, errClientFileTransferSummaryNil)
}
if _, err := GetClientFileTransferLatestByFileIDQuery(nil, "x", FileTransferSummaryQuery{}); !errors.Is(err, errClientFileTransferSummaryNil) {
t.Fatalf("GetClientFileTransferLatestByFileIDQuery nil error = %v, want %v", err, errClientFileTransferSummaryNil)
}
if _, err := GetServerFileTransferActiveSummaries(nil); !errors.Is(err, errServerFileTransferSummaryNil) {
t.Fatalf("GetServerFileTransferActiveSummaries nil error = %v, want %v", err, errServerFileTransferSummaryNil)
}
if _, err := GetServerFileTransferCompletedSummaries(nil); !errors.Is(err, errServerFileTransferSummaryNil) {
t.Fatalf("GetServerFileTransferCompletedSummaries nil error = %v, want %v", err, errServerFileTransferSummaryNil)
}
if _, err := GetServerFileTransferFailedSummaries(nil); !errors.Is(err, errServerFileTransferSummaryNil) {
t.Fatalf("GetServerFileTransferFailedSummaries nil error = %v, want %v", err, errServerFileTransferSummaryNil)
}
if _, err := GetServerFileTransferLatestByFileID(nil, "x"); !errors.Is(err, errServerFileTransferSummaryNil) {
t.Fatalf("GetServerFileTransferLatestByFileID nil error = %v, want %v", err, errServerFileTransferSummaryNil)
}
if _, err := GetServerFileTransferLatestByFileIDQuery(nil, "x", FileTransferSummaryQuery{}); !errors.Is(err, errServerFileTransferSummaryNil) {
t.Fatalf("GetServerFileTransferLatestByFileIDQuery nil error = %v, want %v", err, errServerFileTransferSummaryNil)
}
}
func TestGetClientFileTransferSummariesPublicAPI(t *testing.T) {
client := NewClient().(*ClientCommon)
now := time.Unix(2000, 0)
client.publishSendFileEvent(FileEvent{
NetType: NET_CLIENT,
Kind: EnvelopeFileChunk,
Packet: FilePacket{FileID: "client-public", Size: 16},
Received: 6,
Total: 16,
Percent: 37.5,
StartedAt: now,
UpdatedAt: now.Add(time.Second),
Duration: time.Second,
Time: now.Add(time.Second),
})
active, err := GetClientFileTransferActiveSummaries(client)
if err != nil {
t.Fatalf("GetClientFileTransferActiveSummaries failed: %v", err)
}
if got, want := len(active.Send), 1; got != want {
t.Fatalf("active send count mismatch: got %d want %d", got, want)
}
if got, want := active.Send[0].RuntimeScope, clientFileScope(); got != want {
t.Fatalf("active runtime scope mismatch: got %q want %q", got, want)
}
if got := active.Send[0].TransportGeneration; got != 0 {
t.Fatalf("active transport generation mismatch: got %d want 0", got)
}
latest, err := GetClientFileTransferLatestByFileID(client, "client-public")
if err != nil {
t.Fatalf("GetClientFileTransferLatestByFileID failed: %v", err)
}
if got, want := len(latest.Send), 1; got != want {
t.Fatalf("latest send count mismatch: got %d want %d", got, want)
}
if got, want := latest.Send[0].Direction, TransferDirectionSend; got != want {
t.Fatalf("latest direction mismatch: got %v want %v", got, want)
}
query, err := GetClientFileTransferLatestByFileIDQuery(client, "client-public", FileTransferSummaryQuery{
RuntimeScope: clientFileScope(),
})
if err != nil {
t.Fatalf("GetClientFileTransferLatestByFileIDQuery failed: %v", err)
}
if got, want := len(query.Send), 1; got != want {
t.Fatalf("query send count mismatch: got %d want %d", got, want)
}
client.publishSendFileEvent(FileEvent{
NetType: NET_CLIENT,
Kind: EnvelopeFileEnd,
Packet: FilePacket{FileID: "client-public", Size: 16},
Received: 16,
Total: 16,
Percent: 100,
Done: true,
StartedAt: now,
UpdatedAt: now.Add(2 * time.Second),
Duration: 2 * time.Second,
Time: now.Add(2 * time.Second),
})
completed, err := GetClientFileTransferCompletedSummaries(client)
if err != nil {
t.Fatalf("GetClientFileTransferCompletedSummaries failed: %v", err)
}
if got, want := len(completed.Send), 1; got != want {
t.Fatalf("completed send count mismatch: got %d want %d", got, want)
}
if got, want := completed.Send[0].Done, true; got != want {
t.Fatalf("completed done mismatch: got %v want %v", got, want)
}
}
func TestGetServerFileTransferLatestByFileIDQueryResolvesTransportGenerationPublicAPI(t *testing.T) {
server := NewServer().(*ServerCommon)
now := time.Unix(2100, 0)
serverClient := &ClientConn{ClientID: "public-gen"}
serverClient.markClientConnIdentityBound()
serverClient.markClientConnStreamTransport()
serverClient.markClientConnTransportAttached()
server.getFileTransferState().observe(fileTransferDirectionReceive, FileEvent{
ClientConn: serverClient,
Kind: EnvelopeFileChunk,
Packet: FilePacket{FileID: "shared-public", Size: 20},
Received: 5,
Total: 20,
Time: now,
})
firstRuntimeScope := serverTransportScope(serverClient)
logicalScope := serverFileScope(serverClient)
serverClient.markClientConnTransportDetached("read error", nil)
serverClient.markClientConnTransportAttached()
server.getFileTransferState().observe(fileTransferDirectionReceive, FileEvent{
ClientConn: serverClient,
Kind: EnvelopeFileChunk,
Packet: FilePacket{FileID: "shared-public", Size: 20},
Received: 9,
Total: 20,
Time: now.Add(time.Second),
})
secondRuntimeScope := serverTransportScope(serverClient)
legacy, err := GetServerFileTransferLatestByFileID(server, "shared-public")
if err != nil {
t.Fatalf("GetServerFileTransferLatestByFileID failed: %v", err)
}
if got, want := len(legacy.Receive), 1; got != want {
t.Fatalf("legacy receive count mismatch: got %d want %d", got, want)
}
if got, want := legacy.Receive[0].TransportGeneration, uint64(2); got != want {
t.Fatalf("legacy receive generation mismatch: got %d want %d", got, want)
}
allRuntime, err := GetServerFileTransferLatestByFileIDQuery(server, "shared-public", FileTransferSummaryQuery{
Scope: logicalScope,
})
if err != nil {
t.Fatalf("GetServerFileTransferLatestByFileIDQuery scope failed: %v", err)
}
if got, want := len(allRuntime.Receive), 2; got != want {
t.Fatalf("runtime receive count mismatch: got %d want %d", got, want)
}
gen1, err := GetServerFileTransferLatestByFileIDQuery(server, "shared-public", FileTransferSummaryQuery{
Scope: logicalScope,
TransportGeneration: 1,
MatchTransportGeneration: true,
})
if err != nil {
t.Fatalf("GetServerFileTransferLatestByFileIDQuery generation-1 failed: %v", err)
}
if got, want := len(gen1.Receive), 1; got != want {
t.Fatalf("generation-1 receive count mismatch: got %d want %d", got, want)
}
if got, want := gen1.Receive[0].RuntimeScope, firstRuntimeScope; got != want {
t.Fatalf("generation-1 runtime scope mismatch: got %q want %q", got, want)
}
gen2, err := GetServerFileTransferLatestByFileIDQuery(server, "shared-public", FileTransferSummaryQuery{
Scope: logicalScope,
TransportGeneration: 2,
MatchTransportGeneration: true,
})
if err != nil {
t.Fatalf("GetServerFileTransferLatestByFileIDQuery generation-2 failed: %v", err)
}
if got, want := len(gen2.Receive), 1; got != want {
t.Fatalf("generation-2 receive count mismatch: got %d want %d", got, want)
}
if got, want := gen2.Receive[0].RuntimeScope, secondRuntimeScope; got != want {
t.Fatalf("generation-2 runtime scope mismatch: got %q want %q", got, want)
}
}