From ce4f74d275c31d066b60f0df19b4db49972d689e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Apr 2026 20:08:27 +0000 Subject: [PATCH 01/12] Fix upload-result-diff and azure-login pipeline failures - Skip Azure Login, Download, Upload, and comparison steps on pull_request events where OIDC secrets are unavailable - Separate the "Upload result diff" step from the "Fail if diff detected" step so uploads succeed independently and failures have clear error messages - Apply fixes to both test-query-health and test-codeql-latest-vs-current jobs Agent-Logs-Url: https://github.com/microsoft/Windows-Driver-Developer-Supplemental-Tools/sessions/9c85d93e-42c1-4451-81ad-2a71ece7bc2e Co-authored-by: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> --- .github/workflows/build-codeql.yaml | 36 ++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-codeql.yaml b/.github/workflows/build-codeql.yaml index e4a1fe4e..6f748053 100644 --- a/.github/workflows/build-codeql.yaml +++ b/.github/workflows/build-codeql.yaml @@ -111,6 +111,7 @@ jobs: - name: Add msbuild to PATH uses: microsoft/setup-msbuild@v2 - name: Azure Login + if: github.event_name != 'pull_request' uses: azure/login@v2 with: client-id: ${{ secrets.AZURE_CLIENT_ID }} @@ -118,6 +119,7 @@ jobs: subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} enable-AzPSSession: true - name: Download previous results + if: github.event_name != 'pull_request' uses: azure/powershell@v2 with: azPSVersion: latest @@ -127,9 +129,14 @@ jobs: Get-AzStorageFileContent -ShareName "$env:SHARE_NAME" -Path "detailedfunctiontestresults.xlsx" -Destination $destination -Context $context - name: Run test script shell: pwsh - run: python src\drivers\test\build_create_analyze_test.py --codeql_path .\codeql-cli\codeql.exe --no_build --compare_results -v + run: | + $compareFlag = "" + if ("${{ github.event_name }}" -ne "pull_request") { + $compareFlag = "--compare_results" + } + python src\drivers\test\build_create_analyze_test.py --codeql_path .\codeql-cli\codeql.exe --no_build $compareFlag -v - name: Upload result diff - if: ${{ hashFiles('diffdetailedfunctiontestresults.xlsx') != '' }} # Only upload if there are changes + if: github.event_name != 'pull_request' && hashFiles('diffdetailedfunctiontestresults.xlsx') != '' uses: azure/powershell@v2 with: azPSVersion: latest @@ -137,7 +144,12 @@ jobs: Update-AzConfig -DisplayBreakingChangeWarning $false $context = New-AzStorageContext -StorageAccountName "$env:ACCOUNT_NAME" -UseConnectedAccount -EnableFileBackupRequestIntent Set-AzStorageFileContent -ShareName "$env:SHARE_NAME" -Source "diffdetailedfunctiontestresults.xlsx" -Path "health-diffdetailedfunctiontestresults.xlsx" -Context $context -Force - exit 1 + - name: Fail if result diff detected + if: github.event_name != 'pull_request' && hashFiles('diffdetailedfunctiontestresults.xlsx') != '' + shell: pwsh + run: | + Write-Host "::error::Test results differ from the stored baseline. The diff has been uploaded to Azure Storage as 'health-diffdetailedfunctiontestresults.xlsx'. Please review." + exit 1 test-codeql-latest-vs-current: @@ -194,6 +206,7 @@ jobs: - name: Add msbuild to PATH uses: microsoft/setup-msbuild@v2 - name: Azure Login + if: github.event_name != 'pull_request' uses: azure/login@v2 with: client-id: ${{ secrets.AZURE_CLIENT_ID }} @@ -201,6 +214,7 @@ jobs: subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} enable-AzPSSession: true - name: Download previous results + if: github.event_name != 'pull_request' uses: azure/powershell@v2 with: azPSVersion: latest @@ -210,16 +224,26 @@ jobs: Get-AzStorageFileContent -ShareName "$env:SHARE_NAME" -Path "detailedfunctiontestresults.xlsx" -Destination $destination -Context $context - name: Run test script shell: pwsh - run: python src\drivers\test\build_create_analyze_test.py --codeql_path .\codeql-cli\codeql.exe --no_build --compare_results -v + run: | + $compareFlag = "" + if ("${{ github.event_name }}" -ne "pull_request") { + $compareFlag = "--compare_results" + } + python src\drivers\test\build_create_analyze_test.py --codeql_path .\codeql-cli\codeql.exe --no_build $compareFlag -v - name: Upload result diff - if: ${{ hashFiles('diffdetailedfunctiontestresults.xlsx') != '' }} # Only upload if there are changes + if: github.event_name != 'pull_request' && hashFiles('diffdetailedfunctiontestresults.xlsx') != '' uses: azure/powershell@v2 with: azPSVersion: latest inlineScript: | $context = New-AzStorageContext -StorageAccountName "$env:ACCOUNT_NAME" -UseConnectedAccount -EnableFileBackupRequestIntent Set-AzStorageFileContent -ShareName "$env:SHARE_NAME" -Source "diffdetailedfunctiontestresults.xlsx" -Path "version-diffdetailedfunctiontestresults.xlsx" -Context $context -Force - exit 1 + - name: Fail if result diff detected + if: github.event_name != 'pull_request' && hashFiles('diffdetailedfunctiontestresults.xlsx') != '' + shell: pwsh + run: | + Write-Host "::error::Test results from latest CodeQL version differ from the stored baseline. The diff has been uploaded to Azure Storage as 'version-diffdetailedfunctiontestresults.xlsx'. Please review." + exit 1 - name: Save Latest Version if: ${{ hashFiles('diffdetailedfunctiontestresults.xlsx') == '' }} # Only if there were no differences uses: actions/upload-artifact@v4 From 192346b88e661a868897e7034af7d5929e4fe3b0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Apr 2026 22:52:42 +0000 Subject: [PATCH 02/12] Fix empty-string arg passed to test script on PR runs Building the python command with an empty $compareFlag variable caused PowerShell to pass an empty string as a positional arg, producing: "unrecognized arguments: ". Switched to building an argument array and splatting it so the flag is only included when present. Applied to both test-query-health and test-codeql-latest-vs-current. Agent-Logs-Url: https://github.com/microsoft/Windows-Driver-Developer-Supplemental-Tools/sessions/a5ce6b58-e7aa-4b94-b731-d0242b47b40e Co-authored-by: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> --- .github/workflows/build-codeql.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-codeql.yaml b/.github/workflows/build-codeql.yaml index 6f748053..bf03b196 100644 --- a/.github/workflows/build-codeql.yaml +++ b/.github/workflows/build-codeql.yaml @@ -130,11 +130,11 @@ jobs: - name: Run test script shell: pwsh run: | - $compareFlag = "" + $pyArgs = @('src\drivers\test\build_create_analyze_test.py', '--codeql_path', '.\codeql-cli\codeql.exe', '--no_build', '-v') if ("${{ github.event_name }}" -ne "pull_request") { - $compareFlag = "--compare_results" + $pyArgs += '--compare_results' } - python src\drivers\test\build_create_analyze_test.py --codeql_path .\codeql-cli\codeql.exe --no_build $compareFlag -v + python @pyArgs - name: Upload result diff if: github.event_name != 'pull_request' && hashFiles('diffdetailedfunctiontestresults.xlsx') != '' uses: azure/powershell@v2 @@ -225,11 +225,11 @@ jobs: - name: Run test script shell: pwsh run: | - $compareFlag = "" + $pyArgs = @('src\drivers\test\build_create_analyze_test.py', '--codeql_path', '.\codeql-cli\codeql.exe', '--no_build', '-v') if ("${{ github.event_name }}" -ne "pull_request") { - $compareFlag = "--compare_results" + $pyArgs += '--compare_results' } - python src\drivers\test\build_create_analyze_test.py --codeql_path .\codeql-cli\codeql.exe --no_build $compareFlag -v + python @pyArgs - name: Upload result diff if: github.event_name != 'pull_request' && hashFiles('diffdetailedfunctiontestresults.xlsx') != '' uses: azure/powershell@v2 From f408ab1ee1b8a34bbb9d323950c9c58fdad48d66 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Apr 2026 23:59:53 +0000 Subject: [PATCH 03/12] Surface msbuild errors from codeql database create and fail loudly on test failures Agent-Logs-Url: https://github.com/microsoft/Windows-Driver-Developer-Supplemental-Tools/sessions/1a592ad2-4448-490f-ae16-a9c34d72bf79 Co-authored-by: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> --- .../build_create_analyze_test.cpython-312.pyc | Bin 0 -> 53218 bytes src/drivers/test/build_create_analyze_test.py | 76 +++++++++++++++--- 2 files changed, 66 insertions(+), 10 deletions(-) create mode 100644 src/drivers/test/__pycache__/build_create_analyze_test.cpython-312.pyc diff --git a/src/drivers/test/__pycache__/build_create_analyze_test.cpython-312.pyc b/src/drivers/test/__pycache__/build_create_analyze_test.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a3b0b80dafbacce3d36b1e97c7fd7daafdbb41a9 GIT binary patch literal 53218 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 Date: Tue, 21 Apr 2026 00:00:08 +0000 Subject: [PATCH 04/12] Remove stray .pyc accidentally committed in previous commit Agent-Logs-Url: https://github.com/microsoft/Windows-Driver-Developer-Supplemental-Tools/sessions/1a592ad2-4448-490f-ae16-a9c34d72bf79 Co-authored-by: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> --- .../build_create_analyze_test.cpython-312.pyc | Bin 53218 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/drivers/test/__pycache__/build_create_analyze_test.cpython-312.pyc diff --git a/src/drivers/test/__pycache__/build_create_analyze_test.cpython-312.pyc b/src/drivers/test/__pycache__/build_create_analyze_test.cpython-312.pyc deleted file mode 100644 index a3b0b80dafbacce3d36b1e97c7fd7daafdbb41a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53218 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 Date: Mon, 20 Apr 2026 17:31:57 -0700 Subject: [PATCH 05/12] Optimize pipeline for faster PR runs Removed unnecessary build steps for CA ported queries (covered by the build-all step) and adjusted dependencies in workflow to speed up PR runs (test steps will build as part of work.) Signed-off-by: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> --- .github/workflows/build-codeql.yaml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/.github/workflows/build-codeql.yaml b/.github/workflows/build-codeql.yaml index bf03b196..88da376a 100644 --- a/.github/workflows/build-codeql.yaml +++ b/.github/workflows/build-codeql.yaml @@ -58,17 +58,12 @@ jobs: shell: cmd run: .\codeql-cli\codeql.cmd query compile --check-only recommended.qls - - name: Build CA ported queries - shell: cmd - run: .\codeql-cli\codeql.cmd query compile --check-only ported_driver_ca_checks.qls - - name: Build all Windows queries shell: cmd run: .\codeql-cli\codeql.cmd query compile --check-only .\src test-query-health: runs-on: windows-latest - needs: build permissions: contents: read packages: write @@ -156,7 +151,7 @@ jobs: # Tests if the latest codeql version produces the same results as the current version. runs-on: windows-latest continue-on-error: true # Allow script to return non-zero exit code - needs: [build,test-query-health] + needs: test-query-health permissions: contents: read packages: write @@ -254,7 +249,6 @@ jobs: test-pack-version-update: runs-on: windows-latest - needs: build permissions: contents: read packages: write @@ -296,7 +290,6 @@ jobs: } test-create-dvl: runs-on: windows-latest - needs: build permissions: contents: read packages: write From 769a9177614bcccfdac6bea00d71231493d6597e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 21 Apr 2026 00:57:13 +0000 Subject: [PATCH 06/12] Add Directory.Build.props to wire WDK/SDK NuGet packages into driver test projects Agent-Logs-Url: https://github.com/microsoft/Windows-Driver-Developer-Supplemental-Tools/sessions/7795692b-bc9c-4c2e-a3d3-18f00aed9bcb Co-authored-by: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> --- src/drivers/test/Directory.Build.props | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/drivers/test/Directory.Build.props diff --git a/src/drivers/test/Directory.Build.props b/src/drivers/test/Directory.Build.props new file mode 100644 index 00000000..24be29da --- /dev/null +++ b/src/drivers/test/Directory.Build.props @@ -0,0 +1,23 @@ + + + + $(MSBuildThisFileDirectory)..\..\..\packages\ + + + + + + + From 2355673d2abceb3e85fe8fe560f22079ae554644 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 21 Apr 2026 02:32:08 +0000 Subject: [PATCH 07/12] Fix stampinf, ApiValidator, and Dvl.exe failures in CI tests - Remove items from KMDFTestTemplate.vcxproj and CppKMDFTestTemplate.vcxproj so the StampInf MSBuild task is not triggered (stampinf.exe is not available in a NuGet-only WDK environment). These templates exist solely for CodeQL analysis, not for building a production driver, so INF stamping is not needed. - Add false to Directory.Build.props. ApiValidator.exe is not included in the WDK NuGet packages and is not available in the CI environment. Disabling it allows the ApplicationForDriversTestTemplate (WindowsApplicationForDrivers10.0 toolset) to compile successfully for CodeQL. - Update dvl_tests.ps1 to locate Dvl.exe dynamically from the NuGet packages directory instead of assuming the traditional system WDK install path C:\Program Files (x86)\Windows Kits\10\Tools\dvl\Dvl.exe. Falls back to the system path for developer machines with a full WDK install, and gracefully skips the dvl command-type tests when Dvl.exe is not found in either location. - Fix typo -test_emtpy -> -test_empty in the second Test-DVL "dvl" call inside Test-Driver (the typo was previously unreachable because the test exited earlier due to the Dvl.exe failure). Agent-Logs-Url: https://github.com/microsoft/Windows-Driver-Developer-Supplemental-Tools/sessions/8484509b-2924-427f-bd9a-63e365e4b404 Co-authored-by: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> --- src/drivers/test/Directory.Build.props | 8 ++++++ .../CppKMDFTestTemplate.vcxproj | 3 --- .../KMDFTestTemplate/KMDFTestTemplate.vcxproj | 3 --- src/drivers/test/dvl_tests/dvl_tests.ps1 | 25 +++++++++++++++++-- 4 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/drivers/test/Directory.Build.props b/src/drivers/test/Directory.Build.props index 24be29da..4c4b2657 100644 --- a/src/drivers/test/Directory.Build.props +++ b/src/drivers/test/Directory.Build.props @@ -14,6 +14,14 @@ --> $(MSBuildThisFileDirectory)..\..\..\packages\ + + false diff --git a/src/drivers/test/TestTemplates/CppKMDFTestTemplate/CppKMDFTestTemplate.vcxproj b/src/drivers/test/TestTemplates/CppKMDFTestTemplate/CppKMDFTestTemplate.vcxproj index b5e8b51c..3a5309ad 100644 --- a/src/drivers/test/TestTemplates/CppKMDFTestTemplate/CppKMDFTestTemplate.vcxproj +++ b/src/drivers/test/TestTemplates/CppKMDFTestTemplate/CppKMDFTestTemplate.vcxproj @@ -33,9 +33,6 @@ - - - {0B59834A-7319-449C-822B-09B4CFAC9752} {8c0e3d8b-df43-455b-815a-4a0e72973bc6} diff --git a/src/drivers/test/TestTemplates/KMDFTestTemplate/KMDFTestTemplate.vcxproj b/src/drivers/test/TestTemplates/KMDFTestTemplate/KMDFTestTemplate.vcxproj index eee26610..7898a93e 100644 --- a/src/drivers/test/TestTemplates/KMDFTestTemplate/KMDFTestTemplate.vcxproj +++ b/src/drivers/test/TestTemplates/KMDFTestTemplate/KMDFTestTemplate.vcxproj @@ -33,9 +33,6 @@ - - - {AD97E1A9-DDBC-4BC2-B3B8-95D11062B471} {8c0e3d8b-df43-455b-815a-4a0e72973bc6} diff --git a/src/drivers/test/dvl_tests/dvl_tests.ps1 b/src/drivers/test/dvl_tests/dvl_tests.ps1 index 6982b7dd..f3094d8d 100644 --- a/src/drivers/test/dvl_tests/dvl_tests.ps1 +++ b/src/drivers/test/dvl_tests/dvl_tests.ps1 @@ -18,6 +18,23 @@ param( $starting_location = Get-Location $platforms = @("x64", "arm64") $configurations = @("Debug", "Release") + +# Locate Dvl.exe: prefer the copy shipped inside the WDK NuGet package so that +# the test works in CI environments that have the NuGet packages restored but no +# system-wide WDK installation. Fall back to the traditional WDK install path +# for developer machines that have the full WDK installed. +$dvl_exe_path = "C:\Program Files (x86)\Windows Kits\10\Tools\dvl\Dvl.exe" +$nuget_dvl = Get-ChildItem -Path "$starting_location\packages" -Filter "Dvl.exe" ` + -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1 +if ($nuget_dvl) { + $dvl_exe_path = $nuget_dvl.FullName + Write-Host "Using Dvl.exe from NuGet package: $dvl_exe_path" +} elseif (Test-Path $dvl_exe_path) { + Write-Host "Using Dvl.exe from system WDK: $dvl_exe_path" +} else { + Write-Host "WARNING: Dvl.exe not found in NuGet packages or system WDK. 'dvl' command-type tests will be skipped." + $dvl_exe_path = $null +} function Test-DVL { param ( [string]$command_type = "msbuild", @@ -85,8 +102,12 @@ function Test-DVL { $global:LASTEXITCODE = 1234567891 if ($command_type -eq "dvl") { if ($configuration -eq "Release") { + if (-not $dvl_exe_path) { + Write-Host "SKIP -- Dvl.exe not available; skipping dvl command-type test for $platform $configuration" + continue + } - $command = "& `"C:\Program Files (x86)\Windows Kits\10\Tools\dvl\Dvl.exe`" /manualCreate $vcxproj_name $platform" + $command = "& `"$dvl_exe_path`" /manualCreate $vcxproj_name $platform" $output = Invoke-Expression $command if ($LastExitCode -eq 1234567891) { Write-Host "FAIL -- Unexpected error creating DVL with $platform $configuration using $command" @@ -174,7 +195,7 @@ function Test-Driver { #Test DVL Test-DVL "msbuild" -test_empty $false - Test-DVL "dvl" -test_emtpy $false + Test-DVL "dvl" -test_empty $false Set-Location -Path $starting_location } From 8b61a8daf24a68396da0ecd5a12bfe82205bf6b4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 21 Apr 2026 03:31:52 +0000 Subject: [PATCH 08/12] plan: fix ApiValidator and parallelize test runner Agent-Logs-Url: https://github.com/microsoft/Windows-Driver-Developer-Supplemental-Tools/sessions/71e6036e-2c98-4bb7-85ab-2270cbce9c68 Co-authored-by: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> --- src/drivers/test/dvl_tests/dvl_tests.ps1 | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/drivers/test/dvl_tests/dvl_tests.ps1 b/src/drivers/test/dvl_tests/dvl_tests.ps1 index f3094d8d..f9fbbd2a 100644 --- a/src/drivers/test/dvl_tests/dvl_tests.ps1 +++ b/src/drivers/test/dvl_tests/dvl_tests.ps1 @@ -22,7 +22,9 @@ $configurations = @("Debug", "Release") # Locate Dvl.exe: prefer the copy shipped inside the WDK NuGet package so that # the test works in CI environments that have the NuGet packages restored but no # system-wide WDK installation. Fall back to the traditional WDK install path -# for developer machines that have the full WDK installed. +# for developer machines that have the full WDK installed. If Dvl.exe cannot be +# found in either location the test fails -- the dvl command-type tests are +# required and silently skipping them would let regressions slip through. $dvl_exe_path = "C:\Program Files (x86)\Windows Kits\10\Tools\dvl\Dvl.exe" $nuget_dvl = Get-ChildItem -Path "$starting_location\packages" -Filter "Dvl.exe" ` -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1 @@ -32,8 +34,8 @@ if ($nuget_dvl) { } elseif (Test-Path $dvl_exe_path) { Write-Host "Using Dvl.exe from system WDK: $dvl_exe_path" } else { - Write-Host "WARNING: Dvl.exe not found in NuGet packages or system WDK. 'dvl' command-type tests will be skipped." - $dvl_exe_path = $null + Write-Host "FAIL -- Dvl.exe not found in NuGet packages ($starting_location\packages) or system WDK ($dvl_exe_path)." + exit 1 } function Test-DVL { param ( @@ -102,11 +104,6 @@ function Test-DVL { $global:LASTEXITCODE = 1234567891 if ($command_type -eq "dvl") { if ($configuration -eq "Release") { - if (-not $dvl_exe_path) { - Write-Host "SKIP -- Dvl.exe not available; skipping dvl command-type test for $platform $configuration" - continue - } - $command = "& `"$dvl_exe_path`" /manualCreate $vcxproj_name $platform" $output = Invoke-Expression $command if ($LastExitCode -eq 1234567891) { From c5683989109d1e1a41877b423acacf96fd64d4a9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 21 Apr 2026 03:34:43 +0000 Subject: [PATCH 09/12] Fix ApiValidator failures, harden Dvl.exe check, parallelize test runner - Add src/drivers/test/Directory.Build.targets that overrides the WDK's ApiValidator MSBuild target with an empty target. The WDK NuGet packages reference ApiValidator.exe in WindowsDriver.common.targets but do not ship the binary itself, so the post-build step always failed with MSB3721 for builds using the Universal driver target platform. Replacing the target with a no-op cleanly suppresses the step; API validation is irrelevant for the CodeQL static analysis these tests perform. This is the cause of the 6 still-failing tests (UnsafeCallInGlobalInit, MultithreadedAVCondition, StaticInitializer, DeviceInitApi, FloatSafeExit, FloatUnsafeExit). - Remove the previous false workaround from Directory.Build.props -- the WDK targets do not honor that property name, so it had no effect. - dvl_tests.ps1: when Dvl.exe cannot be located in either the NuGet packages directory or the system WDK install path, exit with a clear failure instead of silently skipping the dvl command-type tests. Skipping let regressions go undetected. - build_create_analyze_test.py: parallelize the test runner. Each ql_test uses isolated working/, TestDB/, and AnalysisFiles/.sarif paths, so multiple tests are safe to execute concurrently. Use multiprocessing.pool.ThreadPool (already imported) with a worker count controlled by a new -j/--jobs flag, defaulting to os.cpu_count(). Pass --jobs 1 to fall back to the legacy sequential behaviour. Print output is already protected by print_mutex; added results_mutex around the shared health_df / detailed_health_df DataFrame writes. Refactored the body of the per-test loop into _run_single_test for use by the pool's imap_unordered. Agent-Logs-Url: https://github.com/microsoft/Windows-Driver-Developer-Supplemental-Tools/sessions/71e6036e-2c98-4bb7-85ab-2270cbce9c68 Co-authored-by: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> --- src/drivers/test/Directory.Build.props | 8 --- src/drivers/test/Directory.Build.targets | 28 ++++++++ src/drivers/test/build_create_analyze_test.py | 68 +++++++++++++++---- 3 files changed, 84 insertions(+), 20 deletions(-) create mode 100644 src/drivers/test/Directory.Build.targets diff --git a/src/drivers/test/Directory.Build.props b/src/drivers/test/Directory.Build.props index 4c4b2657..24be29da 100644 --- a/src/drivers/test/Directory.Build.props +++ b/src/drivers/test/Directory.Build.props @@ -14,14 +14,6 @@ --> $(MSBuildThisFileDirectory)..\..\..\packages\ - - false diff --git a/src/drivers/test/Directory.Build.targets b/src/drivers/test/Directory.Build.targets new file mode 100644 index 00000000..2cab4ad5 --- /dev/null +++ b/src/drivers/test/Directory.Build.targets @@ -0,0 +1,28 @@ + + + + diff --git a/src/drivers/test/build_create_analyze_test.py b/src/drivers/test/build_create_analyze_test.py index 8c53db10..f93c61b7 100644 --- a/src/drivers/test/build_create_analyze_test.py +++ b/src/drivers/test/build_create_analyze_test.py @@ -22,6 +22,7 @@ print_mutex = threading.Lock() +results_mutex = threading.Lock() health_df = pd.DataFrame() detailed_health_df = pd.DataFrame() @@ -830,6 +831,36 @@ def compare_health_results(curr_results_path): os.remove(prev_results) exit(0) +def _run_single_test(ql_test): + """ + Run a single ql_test and update the shared results DataFrames. + Returns the test name on failure, or None on success. Designed to be + safe to invoke concurrently from a thread pool: each ql_test uses its + own working/, TestDB/, and AnalysisFiles/.sarif paths, and shared + DataFrame mutations are guarded by ``results_mutex``. + """ + result_sarif = run_test(ql_test) + if args.build_database_only: + return None + if not result_sarif: + with print_mutex: + print("Error running test: " + ql_test.get_ql_name(), "Skipping...") + return ql_test.get_ql_name() + try: + analysis_results, detailed_analysis_results = sarif_results(ql_test, result_sarif) + except Exception as e: + with print_mutex: + print("Error reading sarif results for " + ql_test.get_ql_name() + ": " + str(e)) + return ql_test.get_ql_name() + with results_mutex: + health_df.at[ql_test.get_ql_name(), "Result"] = str( + int(analysis_results['error']) + + int(analysis_results['warning']) + + int(analysis_results['note'])) + detailed_health_df.at[ql_test.get_ql_name(), "Result"] = str(detailed_analysis_results) + return None + + def run_tests(ql_tests_dict): """ Run the given CodeQL tests. @@ -842,20 +873,32 @@ def run_tests(ql_tests_dict): """ ql_tests_with_attributes = parse_attributes(ql_tests_dict) - total_tests = 0 + total_tests = len(ql_tests_with_attributes) failed_tests = [] - for ql_test in ql_tests_with_attributes: - total_tests += 1 - result_sarif = run_test(ql_test) - if not args.build_database_only: - if not result_sarif: - print("Error running test: " + ql_test.get_ql_name(),"Skipping...") - failed_tests.append(ql_test.get_ql_name()) - continue - analysis_results, detailed_analysis_results = sarif_results(ql_test, result_sarif) - health_df.at[ql_test.get_ql_name(), "Result"] = str(int(analysis_results['error'])+int(analysis_results['warning'])+int(analysis_results['note'])) - detailed_health_df.at[ql_test.get_ql_name(), "Result"] = str(detailed_analysis_results) + # Each ql_test runs against its own isolated working/, TestDB/, and + # AnalysisFiles/.sarif paths, so it is safe to execute multiple + # tests concurrently. ``--jobs`` controls the worker count; the default + # of ``os.cpu_count()`` mirrors what `msbuild` and `codeql` do internally + # for their own parallelism. Use jobs=1 to fall back to the legacy + # sequential behaviour (useful when debugging a single test). + jobs = max(1, args.jobs) if args.jobs is not None else (os.cpu_count() or 1) + if jobs == 1: + for ql_test in ql_tests_with_attributes: + failed = _run_single_test(ql_test) + if failed is not None: + failed_tests.append(failed) + else: + with print_mutex: + print("Running " + str(total_tests) + " tests with " + str(jobs) + " parallel workers") + pool = ThreadPool(jobs) + try: + for failed in pool.imap_unordered(_run_single_test, ql_tests_with_attributes): + if failed is not None: + failed_tests.append(failed) + finally: + pool.close() + pool.join() # save results result_file = "functiontestresults.xlsx" @@ -950,6 +993,7 @@ def find_sln_file(path): parser.add_argument('--compare_results_no_build',help='Compare results to previous run',type=str,required=False,) parser.add_argument('--codeql_path', help='Path to the codeql executable',type=str,required=False,) parser.add_argument('--build_database_only', help='Build database only',action='store_true',required=False,) + parser.add_argument('-j', '--jobs', help='Number of tests to run in parallel (default: number of CPU cores). Use 1 to disable parallelism.', type=int, required=False) args = parser.parse_args() if args.codeql_path: From e49e5ca678efc96733dd535cbc568ea8746e5e65 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Apr 2026 22:03:35 +0000 Subject: [PATCH 10/12] Parallelize test-query-health and test-codeql-latest-vs-current jobs Agent-Logs-Url: https://github.com/microsoft/Windows-Driver-Developer-Supplemental-Tools/sessions/694e9d3d-f942-4564-8e96-8af21abeb87a Co-authored-by: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> --- .github/workflows/build-codeql.yaml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-codeql.yaml b/.github/workflows/build-codeql.yaml index 88da376a..02e34e7d 100644 --- a/.github/workflows/build-codeql.yaml +++ b/.github/workflows/build-codeql.yaml @@ -148,10 +148,13 @@ jobs: test-codeql-latest-vs-current: - # Tests if the latest codeql version produces the same results as the current version. + # Tests if the latest codeql version produces the same results as the current version. + # Runs in parallel with `test-query-health` (no `needs:` dependency) to halve the + # pipeline's wall-clock time. It is independent: it downloads its own (latest) + # CodeQL CLI and runs the same per-test build/analyze cycle. `continue-on-error` + # below means failures here never block the workflow regardless of order. runs-on: windows-latest continue-on-error: true # Allow script to return non-zero exit code - needs: test-query-health permissions: contents: read packages: write @@ -160,10 +163,6 @@ jobs: ACCOUNT_NAME: ${{ secrets.ACCOUNT_NAME }} SHARE_NAME: ${{ secrets.SHARE_NAME }} steps: - - name: Check Prev Job - if: ${{ needs.test-query-health.result == 'failure' }} - shell: pwsh - run: exit 1 - name: Enable long git paths shell: cmd run: git config --global core.longpaths true From e0230d019bda333052422576e976fde28fe27508 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Apr 2026 22:07:24 +0000 Subject: [PATCH 11/12] Fix LNK1318 mspdbsrv race; wire --jobs into workflow Agent-Logs-Url: https://github.com/microsoft/Windows-Driver-Developer-Supplemental-Tools/sessions/694e9d3d-f942-4564-8e96-8af21abeb87a Co-authored-by: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> --- .github/workflows/build-codeql.yaml | 10 ++++- src/drivers/test/build_create_analyze_test.py | 37 ++++++++++++++++++- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-codeql.yaml b/.github/workflows/build-codeql.yaml index 02e34e7d..d966f6f5 100644 --- a/.github/workflows/build-codeql.yaml +++ b/.github/workflows/build-codeql.yaml @@ -125,7 +125,10 @@ jobs: - name: Run test script shell: pwsh run: | - $pyArgs = @('src\drivers\test\build_create_analyze_test.py', '--codeql_path', '.\codeql-cli\codeql.exe', '--no_build', '-v') + # Run per-test build/analyze in parallel inside the script. Default is + # one worker per logical CPU (--jobs ); each worker is isolated to + # its own working/, TestDB/, and AnalysisFiles/.sarif paths. + $pyArgs = @('src\drivers\test\build_create_analyze_test.py', '--codeql_path', '.\codeql-cli\codeql.exe', '--no_build', '-v', '--jobs', "$env:NUMBER_OF_PROCESSORS") if ("${{ github.event_name }}" -ne "pull_request") { $pyArgs += '--compare_results' } @@ -219,7 +222,10 @@ jobs: - name: Run test script shell: pwsh run: | - $pyArgs = @('src\drivers\test\build_create_analyze_test.py', '--codeql_path', '.\codeql-cli\codeql.exe', '--no_build', '-v') + # Run per-test build/analyze in parallel inside the script. Default is + # one worker per logical CPU (--jobs ); each worker is isolated to + # its own working/, TestDB/, and AnalysisFiles/.sarif paths. + $pyArgs = @('src\drivers\test\build_create_analyze_test.py', '--codeql_path', '.\codeql-cli\codeql.exe', '--no_build', '-v', '--jobs', "$env:NUMBER_OF_PROCESSORS") if ("${{ github.event_name }}" -ne "pull_request") { $pyArgs += '--compare_results' } diff --git a/src/drivers/test/build_create_analyze_test.py b/src/drivers/test/build_create_analyze_test.py index f93c61b7..385354f2 100644 --- a/src/drivers/test/build_create_analyze_test.py +++ b/src/drivers/test/build_create_analyze_test.py @@ -33,6 +33,37 @@ db_create_failures = [] +def _build_subprocess_env(): + """ + Build an environment dict for subprocess invocations of msbuild/link.exe so + that each concurrent invocation talks to its own private ``mspdbsrv.exe`` + PDB server. + + When the parallel test runner spawns multiple `codeql database create` -> + `msbuild` -> `link.exe` chains concurrently, all link.exe processes + inherit the same per-user `_MSPDBSRV_ENDPOINT_` and contend on a single + `mspdbsrv.exe` for PDB RPC. Under load this races and the RPC server + occasionally becomes unavailable, producing: + + LINK : fatal error LNK1318: Unexpected PDB error; RPC (23) '(0x000006BA)' + + Setting a unique `_MSPDBSRV_ENDPOINT_` per invocation makes link.exe + spawn its own dedicated mspdbsrv with a unique RPC endpoint, eliminating + cross-worker contention. This is the Microsoft-recommended fix for parallel + MSVC builds. See https://learn.microsoft.com/cpp/error-messages/tool-errors/linker-tools-error-lnk1318. + """ + env = os.environ.copy() + env["_MSPDBSRV_ENDPOINT_"] = "wddst_{pid}_{tid}_{n}".format( + pid=os.getpid(), + tid=threading.get_ident(), + n=next(_endpoint_counter), + ) + return env + + +_endpoint_counter = itertools.count() + + def print_conditionally(*message): """ Prints the message if the verbose flag is set. @@ -370,7 +401,7 @@ def db_create_for_external_driver(sln_file, config, platform): out2 = subprocess.run([codeql_path, "database", "create", db_loc, "--overwrite", "-l", "cpp", "--source-root="+workdir, "--command=msbuild "+ sln_file+ " -clp:Verbosity=m -t:clean,build -property:Configuration="+config+" -property:Platform="+platform + " -p:TargetVersion=Windows10 -p:SignToolWS=/fdws -p:DriverCFlagAddOn=/wd4996 -noLogo" ], cwd=workdir, - shell=True, capture_output=True ) + shell=True, capture_output=True, env=_build_subprocess_env() ) if out2.returncode != 0: print("Error in codeql database create: " + db_loc) print("Return code: " + str(out2.returncode)) @@ -419,8 +450,10 @@ def create_codeql_test_database(ql_test): print_conditionally(" - Command to run: " + str(codeql_command)) # Always capture output so that on failure we can surface the underlying # msbuild / tracer diagnostics (which CodeQL writes mostly to stdout). + # ``env=`` injects a unique ``_MSPDBSRV_ENDPOINT_`` so concurrent workers + # do not race on a shared mspdbsrv.exe (LNK1318 RPC errors). out2 = subprocess.run(codeql_command, - shell=True, capture_output=True ) + shell=True, capture_output=True, env=_build_subprocess_env() ) if out2.returncode != 0: print("Error in codeql database create: " + ql_test.get_ql_name()) print("Command: " + str(codeql_command)) From 3a796c212a63adc3783722e6b2a2e82acb3a7382 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Apr 2026 23:14:41 +0000 Subject: [PATCH 12/12] Pipeline tweaks: progress log, parallel query compile, scoped pack-version gate, broader publish needs Agent-Logs-Url: https://github.com/microsoft/Windows-Driver-Developer-Supplemental-Tools/sessions/96f4dbad-dab0-45e8-9a14-94efd2c96d27 Co-authored-by: NateD-MSFT <34494373+NateD-MSFT@users.noreply.github.com> --- .github/workflows/build-codeql.yaml | 27 ++++++++++++++++--- src/drivers/test/build_create_analyze_test.py | 26 +++++++++++++++++- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-codeql.yaml b/.github/workflows/build-codeql.yaml index d966f6f5..79611d2b 100644 --- a/.github/workflows/build-codeql.yaml +++ b/.github/workflows/build-codeql.yaml @@ -52,15 +52,15 @@ jobs: - name: Build must-fix driver suite shell: cmd - run: .\codeql-cli\codeql.cmd query compile --check-only mustfix.qls + run: .\codeql-cli\codeql.cmd query compile --check-only --threads=0 mustfix.qls - name: Build recommended driver suite shell: cmd - run: .\codeql-cli\codeql.cmd query compile --check-only recommended.qls + run: .\codeql-cli\codeql.cmd query compile --check-only --threads=0 recommended.qls - name: Build all Windows queries shell: cmd - run: .\codeql-cli\codeql.cmd query compile --check-only .\src + run: .\codeql-cli\codeql.cmd query compile --check-only --threads=0 .\src test-query-health: runs-on: windows-latest @@ -254,6 +254,13 @@ jobs: test-pack-version-update: runs-on: windows-latest + # Only enforce qlpack version bumps when the change is actually heading to + # `main`. We routinely stage many commits in `development` and bump the + # qlpack version once when promoting to `main`, so requiring a bump on + # every `development`-targeted PR/push is noise. + if: | + (github.event_name == 'pull_request' && github.base_ref == 'main') || + (github.event_name != 'pull_request' && github.ref == 'refs/heads/main') permissions: contents: read packages: write @@ -341,7 +348,19 @@ jobs: publish: runs-on: windows-latest continue-on-error: true - needs: [build, test-pack-version-update, test-query-health] + needs: [build, test-pack-version-update, test-query-health, test-codeql-latest-vs-current, test-create-dvl] + # Run when all required gates pass. `test-pack-version-update` is skipped + # for non-`main` targets (see its `if:` above), so allow `success` *or* + # `skipped`. `test-codeql-latest-vs-current` is `continue-on-error: true`, + # which already produces a `success` result for `needs`, so we don't need + # special handling for it here -- listing it in `needs` just makes publish + # wait for it to finish before running. + if: | + always() && + needs.build.result == 'success' && + needs.test-query-health.result == 'success' && + needs.test-create-dvl.result == 'success' && + (needs.test-pack-version-update.result == 'success' || needs.test-pack-version-update.result == 'skipped') permissions: contents: read packages: write diff --git a/src/drivers/test/build_create_analyze_test.py b/src/drivers/test/build_create_analyze_test.py index 385354f2..3be48abc 100644 --- a/src/drivers/test/build_create_analyze_test.py +++ b/src/drivers/test/build_create_analyze_test.py @@ -26,6 +26,23 @@ health_df = pd.DataFrame() detailed_health_df = pd.DataFrame() +# Progress reporting for run_tests(). ``_progress_total`` is the total number +# of tests being executed in the current run; ``_progress_started`` is the +# number of tests for which a worker has begun execution. Both are guarded by +# ``_progress_mutex`` so the "[N/total]" prefix is consistent across parallel +# workers. +_progress_mutex = threading.Lock() +_progress_started = 0 +_progress_total = 0 + + +def _next_progress_label(): + """Return a "[N/total]" string and atomically advance the counter.""" + global _progress_started + with _progress_mutex: + _progress_started += 1 + return "[{}/{}]".format(_progress_started, _progress_total) + # Names of tests for which `codeql database create` failed. Tracked here # (rather than only in `run_tests`) so failures are still surfaced when the # script is invoked with --build_database_only, which legitimately returns @@ -598,7 +615,7 @@ def run_test(ql_test): # Print test attributes print_mutex.acquire() - print("\nRunning test: " + ql_test.get_ql_name()) + print("\n" + _next_progress_label() + " Running test: " + ql_test.get_ql_name()) print_conditionally(" - Template: ", ql_test.get_template(), "\n", "- Driver Framework: ", ql_test.get_ql_type(), "\n", @@ -909,6 +926,13 @@ def run_tests(ql_tests_dict): total_tests = len(ql_tests_with_attributes) failed_tests = [] + # Reset the shared "[N/total]" progress counter for this run so each + # invocation of run_tests starts at [1/total]. + global _progress_started, _progress_total + with _progress_mutex: + _progress_started = 0 + _progress_total = total_tests + # Each ql_test runs against its own isolated working/, TestDB/, and # AnalysisFiles/.sarif paths, so it is safe to execute multiple # tests concurrently. ``--jobs`` controls the worker count; the default