Commit 2395650
Add NTTTCP full duplex mode (microsoft#692)
* Add full-duplex mode to NTTTCP networking workload
Enable bidirectional network testing where both nodes run sender and receiver
simultaneously, producing separate TX/RX throughput metrics per direction.
Core changes:
- NTttcpExecutor: Add DuplexMode property, ExecuteFullDuplexWorkloadAsync with
parallel sender+receiver processes, CaptureDirectionalMetrics for per-direction
telemetry, role-aware port assignment (forward/reverse), direction-aware -m IP
mapping for correct sender→receiver targeting
- NetworkingWorkloadState: Add DuplexMode property for client-server state sync
- NetworkingWorkloadExecutor: Pass DuplexMode through orchestration instructions
Profile:
- PERF-NETWORK-NTTTCP-FULLDUPLEX.json: 6 TCP scenarios (T1/T32 x 4K/64K/256K)
with DuplexMode=Full, same dependencies as half-duplex profile
Tests (21 tests):
- NTttcpFullDuplexTests: IsFullDuplex property, ReversePort offset, command-line
flag/port/buffer verification for both platforms, execution tests for client
send+receive on Linux/Windows, results file separation, half-duplex backward
compatibility, NetworkingWorkloadState serialization with DuplexMode
Upstream fixes (pre-existing bugs in main):
- ProcessProxy.cs: Fix catch clause ordering (general catch before specific)
- CommandBase.cs: Fix NullReferenceException on isolationTargets.TargetPackages
Verified on real hardware: win-x64 (10.177.236.133) <-> win-arm64 (10.199.102.112)
TCP 4K T1: Send 3226 Mbps / Receive 1455 Mbps
TCP 64K T1: Send 6490 Mbps / Receive 6163 Mbps
* Fix NTttcp full-duplex tests failing on Linux CI
Use Path.Combine instead of mockFixture.Combine for reading actual
test example files from disk. When the mock platform is Win32NT,
mockFixture.Combine produces backslash paths that fail on Linux CI.
* Fix full-duplex race condition with cross-machine handshake
In full-duplex mode, both client and server run a receiver and a sender
simultaneously. The server starts first (triggered by START instructions),
then the client starts after polling detects the server state is Running.
Race condition: The server starts its receiver, sets state=Running via
ConfirmProcessRunningAsync, then starts its sender 2 seconds later. The
sender connects to the client's reverse port (Port+100). However, the
client only starts its receiver after detecting Running via the 10-second
polling interval. By the time the client's receiver begins listening, the
server's sender has already been attempting to connect for ~8+ seconds.
Linux ntttcp sender has an ~11-second retry budget (warmup period). When
this budget is exhausted before the client receiver is ready, the
connection fails with 'Unexpected disconnect from NTttcp.exe'. This
caused ~86% failure rate (6/7 iterations) when Windows=Client and
Linux=Server, because Linux's sender is less tolerant of connection
delays than Windows.
Fix: Add a cross-machine handshake using the existing VirtualClient
state API to ensure both receivers are listening before either sender
starts:
1. Server starts receiver, signals Running (existing behavior)
2. Client detects Running, starts its receiver on the reverse port
3. Client signals FullDuplexClientReceiverReady to server via state API
4. Server polls for this signal, then starts its sender
5. Client starts its sender (server receiver is already listening)
6. Handshake state is cleaned up in the finally block
Verified on Azure VMs: success rate improved from 14% (1/7) to 100%
(5/5) for the previously-failing Win=Client, Linux=Server configuration.
---------
Co-authored-by: Rudra Pratap SIngh <rudrasingh@microsoft.com>1 parent 75d744b commit 2395650
6 files changed
Lines changed: 1293 additions & 39 deletions
File tree
- src/VirtualClient
- VirtualClient.Actions.UnitTests/Network/NTttcp
- VirtualClient.Actions/Network/NetworkingWorkload
- NTttcp
- VirtualClient.Main/profiles
- website/docs/workloads/network-suite
0 commit comments