package notify import ( "testing" "time" ) func TestFileTransferQueryActiveCompletedAndFailed(t *testing.T) { monitor := newFileTransferMonitor() query := newFileTransferQuery(monitor) now := time.Unix(800, 0) serverClient := &ClientConn{ClientID: "client-a"} monitor.observe(fileTransferDirectionSend, FileEvent{ Kind: EnvelopeFileChunk, Packet: FilePacket{FileID: "active-send", Size: 10}, Received: 4, Total: 10, Time: now, }) monitor.observe(fileTransferDirectionReceive, FileEvent{ ClientConn: serverClient, Kind: EnvelopeFileEnd, Packet: FilePacket{FileID: "done-recv", Size: 12}, Received: 12, Total: 12, Done: true, Time: now.Add(time.Second), }) monitor.observe(fileTransferDirectionSend, FileEvent{ Kind: EnvelopeFileAbort, Packet: FilePacket{FileID: "failed-send", Size: 8, Stage: "chunk"}, Received: 3, Total: 8, Time: now.Add(2 * time.Second), Err: errString("send failed"), }) active := query.active() 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].FileID, "active-send"; got != want { t.Fatalf("active send fileID mismatch: got %q want %q", got, want) } if got, want := len(active.Receive), 0; got != want { t.Fatalf("active receive count mismatch: got %d want %d", got, want) } completed := query.completed() if got, want := len(completed.Send), 0; got != want { t.Fatalf("completed send count mismatch: got %d want %d", got, want) } if got, want := len(completed.Receive), 1; got != want { t.Fatalf("completed receive count mismatch: got %d want %d", got, want) } if got, want := completed.Receive[0].FileID, "done-recv"; got != want { t.Fatalf("completed receive fileID mismatch: got %q want %q", got, want) } if got, want := completed.Receive[0].Done, true; got != want { t.Fatalf("completed receive done mismatch: got %v want %v", got, want) } failed := query.failed() if got, want := len(failed.Send), 1; got != want { t.Fatalf("failed send count mismatch: got %d want %d", got, want) } if got, want := failed.Send[0].FileID, "failed-send"; got != want { t.Fatalf("failed send fileID mismatch: got %q want %q", got, want) } if got, want := failed.Send[0].Failed, true; got != want { t.Fatalf("failed send flag mismatch: got %v want %v", got, want) } if got, want := len(failed.Receive), 0; got != want { t.Fatalf("failed receive count mismatch: got %d want %d", got, want) } } func TestFileTransferQueryLatestByFileID(t *testing.T) { monitor := newFileTransferMonitor() query := newFileTransferQuery(monitor) now := time.Unix(900, 0) serverClientA := &ClientConn{ClientID: "client-a"} serverClientB := &ClientConn{ClientID: "client-b"} monitor.observe(fileTransferDirectionSend, FileEvent{ Kind: EnvelopeFileChunk, Packet: FilePacket{FileID: "shared", Size: 20}, Received: 6, Total: 20, Time: now, }) monitor.observe(fileTransferDirectionReceive, FileEvent{ ClientConn: serverClientA, Kind: EnvelopeFileChunk, Packet: FilePacket{FileID: "shared", Size: 20}, Received: 9, 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), }) group := query.latestByFileID("shared") if got, want := len(group.Send), 1; got != want { t.Fatalf("group send count mismatch: got %d want %d", got, want) } if got, want := group.Send[0].FileID, "shared"; got != want { t.Fatalf("group send fileID mismatch: got %q want %q", got, want) } if got, want := len(group.Receive), 2; got != want { t.Fatalf("group receive count mismatch: got %d want %d", got, want) } if got, want := group.Receive[0].Scope, serverFileScope(serverClientA); got != want { t.Fatalf("first receive scope mismatch: got %q want %q", got, want) } if got, want := group.Receive[1].Scope, serverFileScope(serverClientB); got != want { t.Fatalf("second receive scope mismatch: got %q want %q", got, want) } send := query.latestSendByFileID("shared") if got, want := len(send), 1; got != want { t.Fatalf("send count mismatch: got %d want %d", got, want) } if got, want := send[0].Received, int64(6); got != want { t.Fatalf("send received mismatch: got %d want %d", got, want) } receive := query.latestReceiveByFileID("shared") if got, want := len(receive), 2; got != want { t.Fatalf("receive count mismatch: got %d want %d", got, want) } if got, want := receive[0].Scope, serverFileScope(serverClientA); got != want { t.Fatalf("receive first scope mismatch: got %q want %q", got, want) } if got, want := receive[1].Done, true; got != want { t.Fatalf("receive second done mismatch: got %v want %v", got, want) } } func TestClientTransferQueryFollowsPublishedEvents(t *testing.T) { client := NewClient().(*ClientCommon) now := time.Unix(1000, 0) client.publishSendFileEvent(FileEvent{ NetType: NET_CLIENT, Kind: EnvelopeFileEnd, Packet: FilePacket{FileID: "client-done", Size: 16}, Received: 16, Total: 16, Done: true, StartedAt: now, UpdatedAt: now.Add(time.Second), Duration: time.Second, Time: now.Add(time.Second), }) completed := client.getFileTransferState().completed() if got, want := len(completed.Send), 1; got != want { t.Fatalf("client completed send count mismatch: got %d want %d", got, want) } if got, want := completed.Send[0].FileID, "client-done"; got != want { t.Fatalf("client completed send fileID mismatch: got %q want %q", got, want) } } func TestFileTransferQueryLatestByFileIDQueryResolvesTransportGeneration(t *testing.T) { monitor := newFileTransferMonitor() query := newFileTransferQuery(monitor) now := time.Unix(960, 0) serverClient := &ClientConn{ClientID: "client-gen"} serverClient.markClientConnIdentityBound() serverClient.markClientConnStreamTransport() serverClient.markClientConnTransportAttached() monitor.observe(fileTransferDirectionReceive, FileEvent{ ClientConn: serverClient, Kind: EnvelopeFileChunk, Packet: FilePacket{FileID: "shared", Size: 20}, Received: 5, Total: 20, Time: now, }) firstRuntimeScope := serverTransportScope(serverClient) logicalScope := serverFileScope(serverClient) serverClient.markClientConnTransportDetached("read error", nil) serverClient.markClientConnTransportAttached() monitor.observe(fileTransferDirectionReceive, FileEvent{ ClientConn: serverClient, Kind: EnvelopeFileChunk, Packet: FilePacket{FileID: "shared", Size: 20}, Received: 9, Total: 20, Time: now.Add(time.Second), }) secondRuntimeScope := serverTransportScope(serverClient) if secondRuntimeScope == firstRuntimeScope { t.Fatalf("runtime scope should change across transport generations: got %q", secondRuntimeScope) } legacy := query.latestReceiveByFileID("shared") if got, want := len(legacy), 1; got != want { t.Fatalf("legacy receive count mismatch: got %d want %d", got, want) } if got, want := legacy[0].TransportGeneration, uint64(2); got != want { t.Fatalf("legacy receive generation mismatch: got %d want %d", got, want) } runtimeAll := query.latestReceiveByFileIDQuery("shared", fileTransferSummaryQuery{ Scope: logicalScope, }) if got, want := len(runtimeAll), 2; got != want { t.Fatalf("runtime receive count mismatch: got %d want %d", got, want) } gen1 := query.latestReceiveByFileIDQuery("shared", fileTransferSummaryQuery{ Scope: logicalScope, TransportGeneration: 1, MatchTransportGeneration: true, }) if got, want := len(gen1), 1; got != want { t.Fatalf("generation-1 receive count mismatch: got %d want %d", got, want) } if got, want := gen1[0].RuntimeScope, firstRuntimeScope; got != want { t.Fatalf("generation-1 runtime scope mismatch: got %q want %q", got, want) } gen2 := query.latestReceiveByFileIDQuery("shared", fileTransferSummaryQuery{ Scope: logicalScope, TransportGeneration: 2, MatchTransportGeneration: true, }) if got, want := len(gen2), 1; got != want { t.Fatalf("generation-2 receive count mismatch: got %d want %d", got, want) } if got, want := gen2[0].RuntimeScope, secondRuntimeScope; got != want { t.Fatalf("generation-2 runtime scope mismatch: got %q want %q", got, want) } }