notify/file_transfer_monitor_test.go

330 lines
11 KiB
Go
Raw Normal View History

package notify
import (
"testing"
"time"
)
func TestClientTransferMonitorTracksSendLifecycle(t *testing.T) {
client := NewClient().(*ClientCommon)
monitor := client.getFileTransferState().monitorView()
now := time.Unix(100, 0)
client.publishSendFileEvent(FileEvent{
NetType: NET_CLIENT,
Kind: EnvelopeFileMeta,
Packet: FilePacket{FileID: "send-1", Size: 100},
Path: "/tmp/send-1.bin",
Total: 100,
Time: now,
})
client.publishSendFileEvent(FileEvent{
NetType: NET_CLIENT,
Kind: EnvelopeFileChunk,
Packet: FilePacket{FileID: "send-1", Size: 100},
Path: "/tmp/send-1.bin",
Received: 40,
Total: 100,
Percent: 40,
StartedAt: now,
UpdatedAt: now.Add(2 * time.Second),
Duration: 2 * time.Second,
RateBPS: 20,
Time: now.Add(2 * time.Second),
StepDuration: 2 * time.Second,
})
active := monitor.activeSnapshots()
if got, want := len(active), 1; got != want {
t.Fatalf("active count mismatch: got %d want %d", got, want)
}
if got, want := active[0].Direction, fileTransferDirectionSend; got != want {
t.Fatalf("direction mismatch: got %v want %v", got, want)
}
if got, want := active[0].Scope, clientFileScope(); got != want {
t.Fatalf("scope mismatch: got %q want %q", got, want)
}
if got, want := active[0].Received, int64(40); got != want {
t.Fatalf("received mismatch: got %d want %d", got, want)
}
snapshot, ok := monitor.latestSnapshot(fileTransferDirectionSend, clientFileScope(), "send-1")
if !ok {
t.Fatal("latest snapshot should exist while active")
}
if got, want := snapshot.Kind, EnvelopeFileChunk; got != want {
t.Fatalf("latest active kind mismatch: got %v want %v", got, want)
}
if got, want := snapshot.Received, int64(40); got != want {
t.Fatalf("latest active received mismatch: got %d want %d", got, want)
}
client.publishSendFileEvent(FileEvent{
NetType: NET_CLIENT,
Kind: EnvelopeFileEnd,
Packet: FilePacket{FileID: "send-1", Size: 100},
Path: "/tmp/send-1.bin",
Received: 100,
Total: 100,
Percent: 100,
Done: true,
StartedAt: now,
UpdatedAt: now.Add(4 * time.Second),
Duration: 4 * time.Second,
RateBPS: 25,
Time: now.Add(4 * time.Second),
})
active = monitor.activeSnapshots()
if got, want := len(active), 0; got != want {
t.Fatalf("active count after end mismatch: got %d want %d", got, want)
}
completed := monitor.completedSnapshots()
if got, want := len(completed), 1; got != want {
t.Fatalf("completed count mismatch: got %d want %d", got, want)
}
if got, want := completed[0].Done, true; got != want {
t.Fatalf("done mismatch: got %v want %v", got, want)
}
if got, want := completed[0].Received, int64(100); got != want {
t.Fatalf("completed received mismatch: got %d want %d", got, want)
}
snapshot, ok = monitor.latestSnapshot(fileTransferDirectionSend, clientFileScope(), "send-1")
if !ok {
t.Fatal("latest snapshot should exist after completion")
}
if got, want := snapshot.Kind, EnvelopeFileEnd; got != want {
t.Fatalf("latest completed kind mismatch: got %v want %v", got, want)
}
if got, want := snapshot.Done, true; got != want {
t.Fatalf("latest completed done mismatch: got %v want %v", got, want)
}
}
func TestServerTransferMonitorUsesClientScope(t *testing.T) {
server := NewServer().(*ServerCommon)
monitor := server.getFileTransferState().monitorView()
client := &ClientConn{ClientID: "client-1"}
now := time.Unix(200, 0)
server.publishReceivedFileEvent(FileEvent{
NetType: NET_SERVER,
ClientConn: client,
Kind: EnvelopeFileChunk,
Packet: FilePacket{FileID: "recv-1", Size: 50},
Path: "/tmp/recv-1.part",
Received: 20,
Total: 50,
Percent: 40,
StartedAt: now,
UpdatedAt: now.Add(time.Second),
Duration: time.Second,
RateBPS: 20,
Time: now.Add(time.Second),
})
active := monitor.activeSnapshots()
if got, want := len(active), 1; got != want {
t.Fatalf("active count mismatch: got %d want %d", got, want)
}
if got, want := active[0].Direction, fileTransferDirectionReceive; got != want {
t.Fatalf("direction mismatch: got %v want %v", got, want)
}
if got, want := active[0].Scope, serverFileScope(client); got != want {
t.Fatalf("scope mismatch: got %q want %q", got, want)
}
if got, want := active[0].FileID, "recv-1"; got != want {
t.Fatalf("fileID mismatch: got %q want %q", got, want)
}
}
func TestTransferMonitorDirectionQueries(t *testing.T) {
monitor := newFileTransferMonitor()
now := time.Unix(300, 0)
monitor.observe(fileTransferDirectionSend, FileEvent{
Kind: EnvelopeFileChunk,
Packet: FilePacket{FileID: "shared", Size: 10},
Received: 4,
Total: 10,
Time: now,
})
monitor.observe(fileTransferDirectionReceive, FileEvent{
Kind: EnvelopeFileChunk,
Packet: FilePacket{FileID: "shared", Size: 10},
Received: 7,
Total: 10,
Time: now.Add(time.Second),
})
sendSnapshots := monitor.activeSnapshotsByDirection(fileTransferDirectionSend)
if got, want := len(sendSnapshots), 1; got != want {
t.Fatalf("send snapshots count mismatch: got %d want %d", got, want)
}
if got, want := sendSnapshots[0].Received, int64(4); got != want {
t.Fatalf("send snapshot received mismatch: got %d want %d", got, want)
}
recvSnapshots := monitor.activeSnapshotsByDirection(fileTransferDirectionReceive)
if got, want := len(recvSnapshots), 1; got != want {
t.Fatalf("recv snapshots count mismatch: got %d want %d", got, want)
}
if got, want := recvSnapshots[0].Received, int64(7); got != want {
t.Fatalf("recv snapshot received mismatch: got %d want %d", got, want)
}
sendSnapshot, ok := monitor.latestSnapshot(fileTransferDirectionSend, clientFileScope(), "shared")
if !ok {
t.Fatal("send latest snapshot should exist")
}
if got, want := sendSnapshot.Received, int64(4); got != want {
t.Fatalf("send latest received mismatch: got %d want %d", got, want)
}
recvSnapshot, ok := monitor.latestSnapshot(fileTransferDirectionReceive, clientFileScope(), "shared")
if !ok {
t.Fatal("recv latest snapshot should exist")
}
if got, want := recvSnapshot.Received, int64(7); got != want {
t.Fatalf("recv latest received mismatch: got %d want %d", got, want)
}
}
func TestTransferMonitorSnapshotsByFileID(t *testing.T) {
monitor := newFileTransferMonitor()
now := time.Unix(400, 0)
serverClientA := &ClientConn{ClientID: "client-a"}
serverClientB := &ClientConn{ClientID: "client-b"}
monitor.observe(fileTransferDirectionSend, FileEvent{
Kind: EnvelopeFileChunk,
Packet: FilePacket{FileID: "shared", Size: 20},
Received: 8,
Total: 20,
Time: now,
})
monitor.observe(fileTransferDirectionReceive, FileEvent{
ClientConn: serverClientA,
Kind: EnvelopeFileChunk,
Packet: FilePacket{FileID: "shared", Size: 20},
Received: 12,
Total: 20,
Time: now.Add(time.Second),
})
monitor.observe(fileTransferDirectionReceive, FileEvent{
ClientConn: serverClientB,
Kind: EnvelopeFileEnd,
Packet: FilePacket{FileID: "shared", Size: 20},
Received: 20,
Total: 20,
Done: true,
Time: now.Add(2 * time.Second),
})
allSnapshots := monitor.snapshotsByFileID("shared")
if got, want := len(allSnapshots), 3; got != want {
t.Fatalf("all snapshots count mismatch: got %d want %d", got, want)
}
if got, want := allSnapshots[0].Direction, fileTransferDirectionReceive; got != want {
t.Fatalf("first snapshot direction mismatch: got %v want %v", got, want)
}
if got, want := allSnapshots[0].Scope, serverFileScope(serverClientA); got != want {
t.Fatalf("first snapshot scope mismatch: got %q want %q", got, want)
}
if got, want := allSnapshots[1].Scope, serverFileScope(serverClientB); got != want {
t.Fatalf("second snapshot scope mismatch: got %q want %q", got, want)
}
if got, want := allSnapshots[2].Direction, fileTransferDirectionSend; got != want {
t.Fatalf("third snapshot direction mismatch: got %v want %v", got, want)
}
recvSnapshots := monitor.snapshotsByDirectionAndFileID(fileTransferDirectionReceive, "shared")
if got, want := len(recvSnapshots), 2; got != want {
t.Fatalf("recv snapshots count mismatch: got %d want %d", got, want)
}
if got, want := recvSnapshots[0].Scope, serverFileScope(serverClientA); got != want {
t.Fatalf("recv first scope mismatch: got %q want %q", got, want)
}
if got, want := recvSnapshots[1].Scope, serverFileScope(serverClientB); got != want {
t.Fatalf("recv second scope mismatch: got %q want %q", got, want)
}
if got, want := recvSnapshots[1].Done, true; got != want {
t.Fatalf("recv completed snapshot mismatch: got %v want %v", got, want)
}
sendSnapshots := monitor.snapshotsByDirectionAndFileID(fileTransferDirectionSend, "shared")
if got, want := len(sendSnapshots), 1; got != want {
t.Fatalf("send snapshots count mismatch: got %d want %d", got, want)
}
if got, want := sendSnapshots[0].Received, int64(8); got != want {
t.Fatalf("send snapshot received mismatch: got %d want %d", got, want)
}
}
func TestTransferMonitorCompletedRetentionEvictsOldest(t *testing.T) {
monitor := newFileTransferMonitorWithCompletedLimit(2)
now := time.Unix(500, 0)
monitor.observe(fileTransferDirectionSend, FileEvent{
Kind: EnvelopeFileChunk,
Packet: FilePacket{FileID: "active-1", Size: 10},
Received: 3,
Total: 10,
Time: now,
})
monitor.observe(fileTransferDirectionSend, FileEvent{
Kind: EnvelopeFileEnd,
Packet: FilePacket{FileID: "done-1", Size: 10},
Received: 10,
Total: 10,
Done: true,
Time: now.Add(time.Second),
})
monitor.observe(fileTransferDirectionSend, FileEvent{
Kind: EnvelopeFileEnd,
Packet: FilePacket{FileID: "done-2", Size: 10},
Received: 10,
Total: 10,
Done: true,
Time: now.Add(2 * time.Second),
})
monitor.observe(fileTransferDirectionSend, FileEvent{
Kind: EnvelopeFileEnd,
Packet: FilePacket{FileID: "done-3", Size: 10},
Received: 10,
Total: 10,
Done: true,
Time: now.Add(3 * time.Second),
})
active := monitor.activeSnapshots()
if got, want := len(active), 1; got != want {
t.Fatalf("active count mismatch: got %d want %d", got, want)
}
if got, want := active[0].FileID, "active-1"; got != want {
t.Fatalf("active fileID mismatch: got %q want %q", got, want)
}
completed := monitor.completedSnapshots()
if got, want := len(completed), 2; got != want {
t.Fatalf("completed count mismatch: got %d want %d", got, want)
}
if got, want := completed[0].FileID, "done-2"; got != want {
t.Fatalf("first completed fileID mismatch: got %q want %q", got, want)
}
if got, want := completed[1].FileID, "done-3"; got != want {
t.Fatalf("second completed fileID mismatch: got %q want %q", got, want)
}
if _, ok := monitor.latestSnapshot(fileTransferDirectionSend, clientFileScope(), "done-1"); ok {
t.Fatal("oldest completed snapshot should be evicted")
}
if _, ok := monitor.latestSnapshot(fileTransferDirectionSend, clientFileScope(), "done-3"); !ok {
t.Fatal("latest completed snapshot should be retained")
}
if snapshot, ok := monitor.latestSnapshot(fileTransferDirectionSend, clientFileScope(), "active-1"); !ok {
t.Fatal("active snapshot should remain available")
} else if got, want := snapshot.Kind, EnvelopeFileChunk; got != want {
t.Fatalf("active latest kind mismatch: got %v want %v", got, want)
}
}