viosock: tests: Add vsock_test / vsock_perf Windows ports and interop harness [SKIP-HCK-CI] - #1609
Open
irudakov77 wants to merge 16 commits into
Open
viosock: tests: Add vsock_test / vsock_perf Windows ports and interop harness [SKIP-HCK-CI]#1609irudakov77 wants to merge 16 commits into
irudakov77 wants to merge 16 commits into
Conversation
added 15 commits
July 21, 2026 19:16
Port of the Linux tools/testing/vsock/vsock_test utility to Windows, targeting the viosock Winsock2 transport provider. Key differences from the Linux version: - compat.h: POSIX shim over Winsock2 (socket wrappers, errno mapping, mmap/VirtualAlloc, signal stubs, timeout via GetTickCount64) - util.c: vsock_wait_remote_close uses WSAPoll instead of epoll/POLLRDHUP; setsockopt_timeval_check passes DWORD (ms) for SO_RCVTIMEO - Skipped tests: SO_ZEROCOPY, SOCK_NONBLOCK, transport change, kmemleak - Build: vsock_test.vcxproj + build.bat (EWDK via EWDK_PATH env var) - vsock_test added to viosock.sln Signed-off-by: Ilya Rudakov <irudakov@virtuozzo.com> (cherry picked from commit 7f6eec2010d1d9d0ca6478141933259cb3e93cbc)
Signed-off-by: Ilya Rudakov <irudakov@virtuozzo.com> (cherry picked from commit 9025a9d2ef248ecdfdaccac3f61aaa73e9e20199)
Add vsock_test to the top-level solution with Win10/Win11 Release config mappings, and add Win10/Win11 Release|Win32 entries to vsock_test.vcxproj. Without this, building virtio-win.sln fails with MSB8013 because the ProjectReference from ViosockPackage to vsock_test cannot resolve the default Debug|Win32 fallback. Signed-off-by: Ilya Rudakov <irudakov@virtuozzo.com> (cherry picked from commit 6371ba426ce2b78ce9ca8af61b35bf8d7497f013)
Relocate the 4 test projects (viosock-test, viosock-wsk-test, viosocklib-test, vsock_test) and the 2 interop helper scripts (vioconnect.py, violisten.py) into viosock/tests/. Adjust internal relative paths (#include, ProjectReference, AdditionalIncludeDirectories, AdditionalLibraryDirectories) and update viosock.sln, virtio-win.sln, ViosockPackage.vcxproj, buildAll.bat, cleanAll.bat and .hck-ci/triggers.yml accordingly. Add viosock/tests/buildAll.bat to build all tests. Signed-off-by: Ilya Rudakov <irudakov@virtuozzo.com> (cherry picked from commit 9fa6406395221c1810074ec409957873e4929357)
…O toggle
`compat_recv` / `compat_send` emulate `MSG_DONTWAIT` by toggling the socket
into non-blocking mode via `ioctlsocket(FIONBIO, 1)` before the syscall and
back to blocking via `ioctlsocket(FIONBIO, 0)` after. A successful
`ioctlsocket` clears the per-thread `WSAGetLastError()` value, so by the
time the wrapper checks the syscall return and calls `wsa_set_errno()`,
the original error code has been overwritten with 0. The translation
table treats 0 as "no error" and leaves `errno` untouched, so the caller
sees `ret = -1, errno = 0` — `perror("recv")` then prints `recv: No error`.
Capture `WSAGetLastError()` immediately after the syscall and restore it
via `WSASetLastError()` before `wsa_set_errno()`. Now `recv(MSG_DONTWAIT)`
on an empty stream correctly returns `-1` with `errno = EAGAIN` as Linux
test code expects.
Signed-off-by: Ilya Rudakov <irudakov@virtuozzo.com>
(cherry picked from commit 649fa73ebfe60303812c695b26d158cfaf57748c)
…remote_close Per MSDN, only POLLIN/POLLOUT (and their POLLRD*/POLLWR* sub-flags) are valid input events to WSAPoll; POLLHUP/POLLERR/POLLNVAL are output-only and are always reported in revents regardless of what we requested. The redundant POLLHUP in the input mask had no effect, but it implied the caller could wait specifically for peer close — there is no such input flag on Windows. Drop it and note the WSAPoll rule in a comment. Signed-off-by: Ilya Rudakov <irudakov@virtuozzo.com> (cherry picked from commit ebac517e8f3051097e0234640060d45da9c69035)
Captures the longer story behind the default skip list (test-ignore.list):
which tests fail and why, what driver path each one exercises, and
links to the relevant tickets. Two sections so far:
- Reverse-direction sweep (Windows = vsock acceptor): the 11-test
"acceptor sends RST" family, SO_LINGER on test 32, bind-only
ETIMEDOUT on test 1, and the SKIP-frame mismatch breaking 13
SEQPACKET/SHUT_*/MSG_ZEROCOPY tests.
- Loopback sweep (Windows on both sides, peer-cid = guest_cid):
21 pass / 12 fail / 6 hang of 39. The six hangs share a single
root cause — loopback Tx transfers WDFREQUEST ownership to the
peer's Rx list so the sender's send() blocks until the peer
calls recv(). Tracked as VSTOR-133703.
Includes a template at the bottom for adding per-test entries.
Signed-off-by: Ilya Rudakov <irudakov@virtuozzo.com>
(cherry picked from commit 8495bcc5790e4156dc056b5bbcabcbb34ee689bb)
Test 10 (SOCK_STREAM poll() + SO_RCVLOWAT) required revents to equal POLLIN | POLLRDNORM. On Windows, WSAPoll reports POLLRDNORM for readable normal data; POLLRDBAND (the other half of POLLIN) is only raised for OOB/priority data, which vsock streams never carry, so revents is POLLRDNORM. The Linux original set both EPOLLIN and EPOLLRDNORM as separate bits. Expect POLLRDNORM to match Windows WSAPoll semantics. Signed-off-by: Ilya Rudakov <irudakov@virtuozzo.com> (cherry picked from commit 742fc6930a86e15b39916b27b126691a0adfdd94)
Every test in test_cases[] that cannot be implemented on Windows now
carries run_client/run_server = NULL, and run_tests() treats a NULL as
"nothing to do" — the case still occupies its --pick ID and prints
"ok", but its body is gone from the binary:
* SOCK_SEQPACKET (all cases) — SEQPACKET is not implemented in the
viosock driver.
* MSG_ZEROCOPY family + accept()ed SO_ZEROCOPY regression — Winsock
has no MSG_ERRQUEUE / sock_extended_err notification path.
* SHUT_WR/SHUT_RD (SIGPIPE regressions), transport UAF, transport
change, leak accept-queue (kmemleak) — Linux kernel-debug only,
no Windows analogue.
Exclusion becomes an external runner-list policy — never a stub
inside the binary.
Signed-off-by: Ilya Rudakov <irudakov@virtuozzo.com>
* vsock_test.vcxproj: switch TargetName to per-platform (x64 →
vsock_test, ARM64 → vsock_test_arm64) — so a future ARM64 build
won't clobber the x64 exe by name.
* buildAll.bat / cleanAll.bat: thin wrappers over the repo-level
master build/clean scripts, matching the pattern used by the other
tests under viosock/tests/.
Signed-off-by: Ilya Rudakov <irudakov@virtuozzo.com>
Bash-scripted harness that drives the vsock_test binary between a
Linux host (running the upstream tools/testing/vsock/vsock_test) and
a Windows guest (running our Windows port). Two shapes:
* CI drop: prepare-ci.sh chains resolve-guest → prepare-host (build
the pinned Linux vsock_test) → prepare-guest (publisher cert,
testsigning, firewall) → install-driver → install-tests.
* Dev bench: run-all.sh (setup-env → forward → reverse → loopback)
against an already-deployed driver, config auto-discovered from
$VSOCK_CI_CONFIG / /tmp/vsock-ci/*.config / *.config.
Per-direction sweep scripts (run-forward.sh / run-reverse.sh /
run-loopback.sh) read a *.list file mapping <numeric --pick ID> ×
<variant> to a description; disabled rows carry a
"disabled: <reason>" note grep-able against a fix landing. Config
knobs (server-grace, per-test timeout, control port, bits, JUnit
output path) are env- or CLI-overridable.
_lib.sh centralises SSH/SCP/PowerShell wrappers, JUnit XML builders,
and the (variant × bits × bin_dir) → guest-command mapping so the
same list runs today's posix port and tomorrow's native-Winsock port
(wsa / overlapped) from one grammar.
Signed-off-by: Ilya Rudakov <irudakov@virtuozzo.com>
Port of Linux tools/testing/vsock/vsock_perf.c to Windows:
* Own compat.h — Winsock2 shim (poll/WSAPoll, errno mapping, memparse,
signal stubs). Standalone; does not share the vsock_test compat.h.
* Standalone link (ws2_32.lib only, ViosockGetAF() is inlined); the
driver import library isn't pulled in.
* MSG_ZEROCOPY sender path is dropped — Winsock has neither
SO_ZEROCOPY nor the MSG_ERRQUEUE completion protocol.
* Byte counts (memparse result, to_send_bytes, buf_size_bytes) use
64-bit types — Windows LLP64 makes 'unsigned long' 32-bit, so
--bytes/--buf-size of 4G+ would otherwise wrap to 0.
* --no-poll receiver flag falls back to a plain blocking read() loop
when the underlying driver doesn't implement WSAPoll on accept()ed
vsock sockets (upstream today). Reporting switches from
'POLLIN wakeups' to 'read() calls' but throughput semantics are
preserved.
Signed-off-by: Ilya Rudakov <irudakov@virtuozzo.com>
* vsock_perf.vcxproj — x64 + ARM64 configs (no Win32/x86; the perf
micro-bench doesn't need a 32-bit build), per-platform TargetName.
* buildAll.bat / cleanAll.bat — thin wrappers over the master
build/clean scripts, matching the shape used by vsock_test and the
other tests under viosock/tests/. Hardcodes x64 so master build.bat
doesn't also try the missing Win32 config (harmless MSB8013).
* viosock/tests/buildAll.bat — umbrella tests build now includes
vsock_perf (forcing x64).
* viosock/viosock.sln — register vsock_perf as a solution project so
`msbuild viosock.sln /t:vsock_perf` and IDE routing work.
Signed-off-by: Ilya Rudakov <irudakov@virtuozzo.com>
Five bash scripts + README section that pair with the freshly ported
vsock_perf.exe:
* prepare-perf-host.sh — Linux side; dev path 'make vsock_perf' in
the kernel tree prepare-host.sh already extracted, CI path
--linux-bin <file> stages a pre-built artifact.
* install-perf.sh — Windows side; scp vsock_perf.exe (and its x86
sibling if present) into guest_bin_dir. Cheap; re-run after every
Windows-side rebuild.
* prepare-perf.sh — thin orchestrator over the two above (first-time
setup / CI single-command shape).
* run-perf.sh — automated sweep: forward + reverse × two buffer
sizes (PERF_BUF_DEFAULT=64K, PERF_BUF_LARGE=1M by default).
Env-tunable (PERF_BYTES, PERF_VSK_SIZE, PERF_RCVLOWAT, PERF_PORT,
SERVER_GRACE_SECS, PERF_NO_POLL). Prints per-run RX/TX Gbps + a
final table.
* perf-one.sh — one-shot manual run for interactive tuning; pick
direction and any perf knob on the CLI.
vsock_perf has no TCP control channel, so a small SERVER_GRACE_SECS
sleep replaces the wait_guest_port poll used by vsock_test. Loopback
is not covered — hairpin traffic on the guest doesn't represent real
workload. --variant reserved as posix|wsa|overlapped for a future
native-Winsock port; only posix works today.
Signed-off-by: Ilya Rudakov <irudakov@virtuozzo.com>
Enable only the rows that pass against upstream/master viosock (the
target of this PR); everything else carries a `disabled: fails on
upstream master: <symptom>` fingerprint. The previous baseline was
an internal fork with a set of driver-side fixes already applied —
that would have produced spurious failures for an upstream reviewer.
* forward: 9 enabled (0, 1, 2, 4, 5, 14, 21, 30, 31)
* reverse: 7 enabled (0, 3, 4, 10, 12, 14, 24)
* loopback: 3 enabled (0, 1, 4)
Newly disabled (vs the previous baseline) fingerprints — these will
flip green when the corresponding driver-side fix lands upstream:
* forward 3 — "WSAPoll: No error" (WSAPoll on accept()ed vsock
not implemented in the driver).
* forward 10 — "getsockopt err: protocol not supported (135)"
(SO_RCVLOWAT not implemented).
* forward 12 — "recv: Unknown error".
* reverse 1 — "unexpected connect(2) errno 110" (ETIMEDOUT
during acceptor's accept-refuse timing).
* reverse 2, 5, 31 — Linux client prints "...ok" then exits rc=1
(COMPLETED-handshake race).
* reverse 21 — "recv: Connection reset by peer".
* reverse 22 — "unexpected EOF while receiving bytes"
(acceptor credit-update path).
* loopback 5 — "send: Unknown error" (loopback send path).
* loopback 21, 22, 23, 30, 31 — various loopback failures previously
masked under 'HUNG-timeout' on the fork baseline.
Signed-off-by: Ilya Rudakov <irudakov@virtuozzo.com>
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
Member
|
@irudakov77 Do you want to format /viosock/tests/vsock_test/vsock_test.c with all rules, or file copied from some other place? |
Ran the repo's clang-format style over `test_cases[]` in vsock_test.c
and `longopts[]` in vsock_perf.c — the two tables carried
degenerate-indent artifacts from earlier hand-edits that the local
pre-commit hook would have caught, had it been present in the branch's
clone at the time of the cherry-picks.
Whitespace only. No semantic changes; `git diff -w` is empty except
for one struct-init reflow (`{ .name = "no-poll", ... }` → the same
fields on separate lines to match its neighbours).
Signed-off-by: Ilya Rudakov <irudakov@virtuozzo.com>
Author
This needs to be formatted, but the precommit hook is missing. Fixed. |
Member
|
ok to test |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR ports two Linux tools from
linux/tools/testing/vsock/to Windows, groups them together with the existingviosock-test/viosock-wsk-test/viosocklib-testunder a commonviosock/tests/directory, and adds a Bash-scripted harness that drives them between a Linux host and a Windows guest running the viosock driver.Guest prerequisites
Windows 10/11 guest with an SSH server (Administrator login). Administrator login passwordless-authorised by the SSH key you will point the harness at (installed into
%USERPROFILE%\.ssh\authorized_keys; the matching private-key path lands in the config'sssh_keyfield, or is passed as--ssh-key <path>toprepare-ci.sh/resolve-guest.sh).prepare-guest.shdoes theVirtIOTestCertcert import + testsigning + firewall rule in one shot;install-driver.shthen does thepnputil /add-driver /install.Running the tests
The runner scripts live in the repo under
viosock/tests/run/; the host runs them directly from a checkout - they aren't packaged or deployed anywhere. Only the signed artifact drop (--package <dir>) is copied to the guest, and that drop expects, in one flat directory:viosock.inf,viosock.sys,viosock.cat,viosocklib_x64.dll,viosocklib_x86.dll,viosockwspsvc.exe- signed driver and WSP LSP.vsock_test.exe- test binary (vsock_test_x86.exenext to it is optional; used with--bits x86).VirtIOTestCert.cer- publisher cert to import intoRoot+TrustedPublisheron the guest, unless--whqlis passed (which assumes the driver is WHQL-signed and already trusted).vsock_perf.exe- the throughput benchmark. Only needed if you plan to run the perf sweep;prepare-cidoesn't install it -prepare-perf.sh --from <pkg>will pick it up in the same directory.From the Linux host:
Everything else - dev-bench flow, per-direction runners, --pick, --variant, .list grammar, etc - is documented in viosock/tests/run/README.md.
Currently disabled tests
Every disabled row in viosock/tests/run/*.list carries a grep-able disabled: note. High-level breakdown:
Notes