tests: virtual HID device test harness for all four backends (hidraw, libusb, winapi, darwin) #815
No reviewers
Labels
No labels
3rdparty
Android
API
Author does not respond
bsd
bug
build system/CI
ci-virtual-device
CMake
Contributions Welcome
Core
dependencies
device-specific
documentation
don't_merge
duplicate
enhancement
Example
Haiku
hidraw
hotplug
info required
invalid
libusb
macOS
Misc
Not an issue
question
Release
Test
Test GUI
Windows
wontfix
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-libusb/hidapi!815
Loading…
Reference in a new issue
No description provided.
Delete branch "virtual-device-tests"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
A reusable virtual HID device test harness: HIDAPI tests run against a virtual device, so they need no physical hardware. Tests are written purely against the public HIDAPI API plus a small backend-agnostic
test_virtual_deviceinterface, so the same test runs on every backend that ships a provider.Each virtual device carries a few pre-recorded scenarios: the test sends a Feature report whose first payload byte is a
TEST_VDEV_CMD_*command, and the device replays the matching canned input report. All device behaviour lives in the per-backend provider; the test code is 100% platform-neutral. Further tests can build on this harness (e.g. thehid_read_interrupttest in #799).What's here
src/tests/test_device_io.c— a device-I/O smoke test: open → write an output report → trigger + read back two canned input reports → close. Exits with CTest's skip code (77) when no virtual device can be created, so ordinary builds on any host stay green.src/tests/test_virtual_device.h— the shared contract (report size, commands, canned payloads);test_platform.h— portable thread/timing helpers for tests.test_virtual_device_uhid.c/dev/uhidtest_virtual_device_rawgadget.c/dev/raw-gadget+dummy_hcd, inside a VMlibusb-vhid-testtest_virtual_device_win.c+src/tests/windows/driver/win-vhid-testtest_virtual_device_mac.cIOHIDUserDevice(IOKit)-DHIDAPI_WITH_TESTS=ON(offered on Linux/Windows/macOS, default OFF) buildssrc/testsfor whichever backends are present. Requires CMake ≥ 3.16 for correct skip reporting (older CMake gets a warning and no tests).CI
builds.yml): the test is built on all platforms and run where possible.ubuntu-cmakeloadsuhidand runsDeviceIO_hidrawfor real;DeviceIO_libusb, Windows and macOS build the test and self-skip — the matrix stays green everywhere.win-vhid-test.yml: builds and self-signs the vhidmini2 driver onwindows-2022(whose MSBuild matches the cached WDK's driver build tasks), then installs it viadevcononwindows-latestand runsDeviceIO_winapiagainst the real device. ✅ passing.libusb-vhid-test.yml: the hosted kernel has no USB gadget subsystem, soDeviceIO_libusbruns inside a lightweightvirtme-ng+ QEMU VM booting a generic Ubuntu kernel (withraw_gadgetloaded anddummy_hcdbuilt out-of-tree), against a real virtual USB device. ✅ passing. The same approach works locally and on WSL2.The two privileged jobs run via
workflow_dispatchor automatically on a pull request carrying theci-virtual-devicelabel, keeping them out of the per-push matrix.Licensing
src/tests/windows/driver/vendors a modified Microsoft vhidmini2 UMDF2 sample under its original MS-PL license — a completeLICENSE.txtplus aREADME.mddocumenting provenance and modifications live in that directory. It is a standalone test fixture (built, installed and removed out-of-band by CI; never linked into or shipped with the library), separate from HIDAPI's own licensing. Downstream projects consuming HIDAPI as a subproject can simply not enable the tests.Platforms without a provider
FreeBSD/NetBSD/OpenBSD have no userspace facility to create a virtual HID/USB device, so there is deliberately no provider for them —
src/tests/README.mddocuments the details. Running the macOS provider on a real Mac (Apple Developer account,com.apple.developer.hid.virtual.deviceentitlement, Accessibility consent) is documented there as well.Assisted-by: claude-code:claude-opus-4-8
Assisted-by: claude-code:claude-fable-5
Great. We need this kind of virtual test device for hidapi (and also libusb).
@Youw
FYI on WDK, the Windows runners have WDK installed already.
Nuget WDK -- smaller but lacking some tools, which may be okay for this purpose
Built-in WDK -- good enough
EWDK -- great for local build of libusb-win32/libusbK but not good for CI.
Reference:
Thanks @mcuee, that's useful. The
win-vhid-testjob currently downloads WDK 26100.6584 explicitly because the first preinstalled option I tried (the Chocolateywindowsdriverkit11VSIX) was VS2019-only, somsbuildunder the VS2022 toolset couldn't findwdf.h. Good to know the built-in (or NuGet) WDK should be enough — I'll try pointing the job at the preinstalled/NuGet WDK to drop that ~2–3 min download and the external fetch, and confirm the WDF headers resolve against the VS2022 toolset. Will report back.This reply was generated by Claude Code at my request.
https://www.instagram.com/p/DXcOy5riYPS/
(I home community don't mind a little humor here)
Followed up on the WDK tip — thanks again. On the current
windows-latestimage the runner ships the Windows SDK (10.0.26100) but not the WDK: there are no UMDF (wdf) headers underWindows Kits\10\Include, so the vhidmini2 UMDF2 build still needs the WDK installed.So rather than dropping the download, I cached it. The
win-vhid-testjob now caches a self-contained offline WDK installer layout (actions/cache@v4, keyed by WDK version) and installs from it — the WDK is downloaded only once and restored from cache on later runs. Verified: on a cache hit the download step is skipped, the driver builds, andDeviceIO_winapipasses. I also kept a preinstalled-WDK fast-path, so if a future image ships the WDK with UMDF headers it's used automatically with no download.(The NuGet WDK would be a cleaner long-term route, but it needs reworking the legacy
.vcxproj, so I left that for later.)Posted by Claude Code at my request.
I see two general issues with this PR:
CC: @JoergAtGithub - not sure if your'e watching this issue, you might be interested in this in general.
I do not see this as an issue. Just need to mention it clearly. They can just skip the test codes.
Again I think this is okay for this testing codes. I agree this should not be the case for the core library codes.
First issue -- macOS compiler error -- maybe my version is newer than the runner (just upgraded to macOS 26.5.1)
@Youw
Just wondering if you can make the documentation to carry out the tests using a physical Mac. Never did such stuff on a Mac.
BTW, is it possible to use sudo to replace the entitlement and consent?
Unfortunately now. CI runner already has sude - we would have done so already.
You actually need an Apple Developer account (cost $100 a year) with your own certificate/provision generated. I'll update the docs to have a clear mention of this. I actuall haven't tested this myself either. Don't really have time to do so.
Hi @mcuee — this is Claude Code, posting on @Youw's behalf. A few updates on the points you raised, plus one request for your help at the end.
macOS build error (
mac/hid.c:548,-Wgnu-folding-constant). This is a pre-existing issue in the core library, not in this PR's test code:create_device_info_with_usage()sizes a local buffer with aconst int, which in C isn't a constant expression, so newer Apple clang (21) folds it from a VLA — and the project's-pedantic -Werrormakes that fatal. The CI macOS runner's older clang doesn't flag it, which is why this branch built green. A small fix (use anenumconstant) is in its own PR: #816. Per the plan, once #816 is reviewed/merged this branch will be rebased on top so the virtual-device tests build on up-to-date Macs.Running on a real Mac. Added a "Running the macOS (
darwin) provider on a real Mac" section tosrc/tests/README.mdwith the known requirements — a paid Apple Developer account, a signing cert/provisioning profile carrying thecom.apple.developer.hid.virtual.deviceentitlement, and granting Accessibility (TCC) consent — and a note thatsudocan't substitute for the entitlement or the prompt. It's flagged as the known requirements rather than a verified recipe, since this path hasn't been exercised by the maintainers.MS-licensed driver. The vendored vhidmini2 driver now ships its upstream MS-PL
LICENSE.txtand aREADME.mdinsrc/tests/windows/driver/stating it's MS-PL (separate from HIDAPI's own license) and a standalone test fixture downstream projects can simply skip — matching your "just need to mention it clearly."My request — this is Claude asking for your help, on @Youw's behalf: could you confirm #816 builds cleanly for you on macOS 26.5.1 / Apple clang 21? I can't reproduce the warning on the CI runner's older clang and don't have a current Mac to test on myself, so a confirmation from your setup would be a big help in verifying the fix actually resolves the error you hit.
Posted by Claude Code at @Youw's request.
Great. #816 fixed the macOS build issue.