tests: hotplug API and virtual-device hotplug scenarios #94
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
| name: Windows Virtual HID Device Test (manual) | |
| # Builds and self-signs a modified vhidmini2 UMDF2 driver, installs it on a | |
| # hosted runner, then runs the backend-agnostic device-I/O test against that | |
| # real virtual HID device (winapi backend). It installs a driver, so it is not | |
| # part of the per-push CI matrix; run it on demand from the Actions tab, or by | |
| # adding the 'ci-virtual-device' label to a pull request. | |
| # | |
| # The work is split across two runners because no single hosted image can do | |
| # both today: | |
| # - build-driver runs on windows-2022: the cached WDK (10.0.26100.6584) | |
| # ships DriverKit build tasks only up to MSBuild 17 (VS2022), which the | |
| # windows-2025* images no longer carry (VS2026 / MSBuild 18 -> MSB4062). | |
| # - win-vhid runs on windows-latest (Server 2025): the driver package's INF | |
| # depends on MsHidUmdf.inf semantics introduced in build 22000, so it does | |
| # not install on Server 2022 (build 20348). | |
| # Revisit once a WDK with 18.0 build tasks is cached here - then both jobs can | |
| # run on windows-latest again (and could be merged back into one). | |
| on: | |
| workflow_dispatch: | |
| # Also runs automatically on a pull request that carries the | |
| # 'ci-virtual-device' label (the build-driver job is gated on that label; | |
| # win-vhid follows via needs:). | |
| pull_request: | |
| types: [opened, reopened, labeled, synchronize] | |
| jobs: | |
| build-driver: | |
| # 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: windows-2022 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| # Sets up the MSVC developer environment (cl/msbuild on PATH) by locating | |
| # the installed Visual Studio (no hard-coded path or edition). | |
| - name: Set up MSVC developer environment | |
| uses: TheMrMilchmann/setup-msvc-dev@v4 | |
| with: | |
| arch: x64 | |
| # The hosted runner ships the Windows SDK but not the WDK (no UMDF headers), | |
| # so the WDK must be obtained. Cache a self-contained offline installer | |
| # layout (the components, not just the bootstrapper) so it is downloaded only | |
| # once; later runs restore it from the cache and install offline. | |
| - name: Cache the WDK installer layout | |
| id: wdk-cache | |
| uses: actions/cache@v4 | |
| with: | |
| path: wdk-layout | |
| key: wdk-layout-26100.6584 | |
| - name: Download WDK installer layout (cache miss only) | |
| if: steps.wdk-cache.outputs.cache-hit != 'true' | |
| shell: pwsh | |
| run: | | |
| Invoke-WebRequest -Uri "https://go.microsoft.com/fwlink/?linkid=2335869" -OutFile "$env:RUNNER_TEMP\wdksetup.exe" | |
| # /layout downloads a complete offline copy into wdk-layout (cached). | |
| Start-Process -FilePath "$env:RUNNER_TEMP\wdksetup.exe" -ArgumentList '/layout', "$PWD\wdk-layout", '/quiet', '/ceip', 'off' -Wait | |
| - name: Build vhidmini2 (UMDF2) | |
| shell: pwsh | |
| run: | | |
| $proj = "src\tests\windows\driver\VhidminiUm.vcxproj" | |
| $inc = "C:\Program Files (x86)\Windows Kits\10\Include" | |
| # Use a preinstalled WDK if a future image ships one (kit with UMDF | |
| # headers); otherwise install from the cached offline layout. | |
| $ver = Get-ChildItem $inc -Directory -ErrorAction SilentlyContinue | | |
| Where-Object { Test-Path (Join-Path $_.FullName 'wdf\umdf') } | | |
| Sort-Object Name -Descending | Select-Object -First 1 -ExpandProperty Name | |
| if ($ver) { | |
| Write-Host "Using preinstalled WDK ($ver)." | |
| } else { | |
| Write-Host "Installing WDK from the cached offline layout ..." | |
| Start-Process -FilePath "wdk-layout\wdksetup.exe" -ArgumentList '/quiet', '/norestart', '/ceip', 'off' -Wait | |
| $ver = "10.0.26100.0" | |
| } | |
| # msbuild comes from the MSVC developer environment set up above. | |
| msbuild $proj /p:Configuration=Release /p:Platform=x64 /p:WindowsTargetPlatformVersion=$ver /v:minimal | |
| if ($LASTEXITCODE -ne 0) { throw "vhidmini2 build failed (exit $LASTEXITCODE)." } | |
| - name: Stage driver package (+ devcon) for the test job | |
| shell: pwsh | |
| run: | | |
| $out = "src/tests/windows/driver/x64/Release" | |
| # devcon.exe ships with the WDK just installed; the test runner has no | |
| # WDK, so carry the tool along with the driver package. | |
| $devcon = Get-ChildItem "C:\Program Files (x86)\Windows Kits\10" -Recurse -Filter devcon.exe -ErrorAction SilentlyContinue | | |
| Where-Object { $_.FullName -match '\\x64\\' } | Select-Object -First 1 -ExpandProperty FullName | |
| if (-not $devcon) { throw "devcon.exe not found in the installed WDK." } | |
| Copy-Item $devcon $out\ | |
| Get-ChildItem -Recurse $out | Select-Object FullName | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: vhidmini-driver | |
| path: src/tests/windows/driver/x64/Release/ | |
| if-no-files-found: error | |
| win-vhid: | |
| needs: build-driver | |
| runs-on: windows-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: vhidmini-driver | |
| path: driver-pkg | |
| - name: Trust the driver's test certificate | |
| shell: pwsh | |
| run: | | |
| $cer = "driver-pkg/VhidminiUm.cer" | |
| Import-Certificate -FilePath $cer -CertStoreLocation Cert:\LocalMachine\Root | Out-Null | |
| Import-Certificate -FilePath $cer -CertStoreLocation Cert:\LocalMachine\TrustedPublisher | Out-Null | |
| Write-Host "Imported test cert into Root and TrustedPublisher." | |
| - name: Install virtual HID device (devcon, root-enumerated) | |
| shell: pwsh | |
| run: | | |
| $devcon = (Resolve-Path "driver-pkg/devcon.exe").Path | |
| $inf = (Resolve-Path "driver-pkg/VhidminiUm/VhidminiUm.inf").Path | |
| Write-Host "devcon: $devcon" | |
| Write-Host "inf: $inf" | |
| & $devcon install $inf "root\VhidminiUm" | |
| Write-Host "devcon exit: $LASTEXITCODE" | |
| if ($LASTEXITCODE -ne 0) { throw "devcon install failed (exit $LASTEXITCODE)." } | |
| - name: HID devices present (diagnostic) | |
| shell: pwsh | |
| run: | | |
| Start-Sleep -Seconds 3 | |
| Get-PnpDevice -Class HIDClass -ErrorAction SilentlyContinue | | |
| Select-Object Status, FriendlyName, InstanceId | Format-Table -AutoSize | |
| - name: Build HIDAPI + tests | |
| shell: pwsh | |
| run: | | |
| cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DHIDAPI_WITH_TESTS=ON | |
| cmake --build build --config Release | |
| - name: Run device-I/O test against the virtual device | |
| shell: pwsh | |
| working-directory: build | |
| run: | | |
| ctest -C Release -R "_winapi" --output-on-failure | |
| - name: Cleanup virtual device | |
| if: always() | |
| shell: pwsh | |
| run: | | |
| $devcon = "driver-pkg/devcon.exe" | |
| if (Test-Path $devcon) { & $devcon remove "root\VhidminiUm" 2>$null } | |
| Write-Host "cleanup done" |