Skip to content

tests: virtual HID device test harness (Linux/Windows/macOS/libusb) #3

tests: virtual HID device test harness (Linux/Windows/macOS/libusb)

tests: virtual HID device test harness (Linux/Windows/macOS/libusb) #3

name: Linux libusb Virtual HID Device Test (manual)
# Brings up a virtual USB HID device with USB Raw Gadget (/dev/raw-gadget) on
# top of dummy_hcd, then runs the backend-agnostic device-I/O test against it
# through the HIDAPI libusb backend. dummy_hcd is not packaged by Ubuntu, so it
# is built out-of-tree against the runner kernel headers; everything is
# best-effort and the test self-skips (CTest code 77) if the modules can't be
# provided. Run on demand (the push trigger is for developing this branch).
on:
workflow_dispatch:
# Also runs automatically on a pull request that carries the
# 'ci-virtual-device' label (the job below is gated on that label).
pull_request:
types: [opened, reopened, labeled, synchronize]
jobs:
libusb-rawgadget:
# workflow_dispatch always runs; on a PR, only when the label is present.
if: github.event_name == 'workflow_dispatch' || contains(github.event.pull_request.labels.*.name, 'ci-virtual-device')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
path: hidapisrc
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y libudev-dev libusb-1.0-0-dev build-essential cmake
sudo apt-get install -y "linux-modules-extra-$(uname -r)" "linux-headers-$(uname -r)" || true
- name: Set up raw_gadget + dummy_hcd
run: |
set -x
echo "kernel: $(uname -r)"
# raw_gadget and dummy_hcd ship in linux-modules-extra on many kernel
# flavours; show what is actually available for this runner's kernel.
find "/lib/modules/$(uname -r)" \( -name 'raw_gadget*' -o -name 'dummy_hcd*' \) 2>/dev/null || true
sudo modprobe raw_gadget || true
sudo modprobe dummy_hcd || true
# dummy_hcd is not packaged by Ubuntu; build it out-of-tree if needed.
if ! lsmod | grep -q dummy_hcd; then
echo "Building dummy_hcd out-of-tree against $(uname -r) headers..."
git clone --depth 1 https://github.com/xairy/raw-gadget.git rg || true
if [ -d rg/dummy_hcd ]; then
make -C rg/dummy_hcd 2>&1 | tail -25 || true
sudo insmod rg/dummy_hcd/dummy_hcd.ko 2>&1 || true
fi
fi
sudo modprobe raw_gadget || true
echo "--- loaded ---"; lsmod | grep -E 'raw_gadget|dummy_hcd' || echo "(none loaded)"
ls -l /dev/raw-gadget 2>/dev/null || echo "/dev/raw-gadget absent -> DeviceIO_libusb will self-skip"
- name: Configure + build (libusb backend + tests)
run: |
cmake -B build -S hidapisrc -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DHIDAPI_WITH_LIBUSB=ON -DHIDAPI_WITH_HIDRAW=OFF -DHIDAPI_WITH_TESTS=ON
cmake --build build
- name: Run device-I/O test against the raw-gadget virtual device
working-directory: build
run: |
# Root is needed to open /dev/raw-gadget and for the libusb backend to
# detach the kernel driver and claim the interface.
sudo ctest -R DeviceIO_libusb --output-on-failure