multiwindow/gg: add cross-platform multiwindow services and lifecycle safety #6087
Workflow file for this run
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: CI Windows TCC | |
| on: | |
| workflow_dispatch: | |
| push: | |
| branches: | |
| - master | |
| paths-ignore: | |
| - 'vlib/v3/**' | |
| - '**.md' | |
| - '**.yml' | |
| - '!**.bat' | |
| - '!**/windows_ci_tcc.yml' | |
| - 'cmd/tools/**' | |
| - '!cmd/tools/builders/**.v' | |
| pull_request: | |
| paths-ignore: | |
| - 'vlib/v3/**' | |
| - '**.md' | |
| - '**.yml' | |
| - '!**.bat' | |
| - '!**/windows_ci_tcc.yml' | |
| - '!**/windows-install-sqlite.bat' | |
| - 'cmd/tools/**' | |
| - '!cmd/tools/builders/**.v' | |
| concurrency: | |
| group: windows-${{ github.workflow }}-${{ github.ref == 'refs/heads/master' && github.sha || github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| tcc-windows: | |
| runs-on: windows-2022 | |
| timeout-minutes: 60 | |
| env: | |
| VFLAGS: -cc tcc -no-retry-compilation | |
| VTEST_SHOW_LONGEST_BY_RUNTIME: 3 | |
| VTEST_SHOW_LONGEST_BY_COMPTIME: 3 | |
| VTEST_SHOW_LONGEST_BY_TOTALTIME: 3 | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Install OpenSSL | |
| run: | | |
| choco install openssl -y --no-progress | |
| # choco's openssl package (Win64OpenSSL installer under the hood) | |
| # deploys to `C:\Program Files\OpenSSL\`, matching | |
| # ecdsa.c.v/rsa_pss.c.v's SECOND `#flag windows` fallback path -- | |
| # NOT the first one (`...OpenSSL-Win64\...`), confirmed by an | |
| # actual CI run after guessing wrong the first time. | |
| $opensslBin = 'C:\Program Files\OpenSSL\bin' | |
| if (-not (Test-Path $opensslBin)) { | |
| throw "OpenSSL bin directory not found at $opensslBin after choco install" | |
| } | |
| Add-Content -Path $env:GITHUB_PATH -Value $opensslBin | |
| Write-Host "OpenSSL install:" | |
| Get-ChildItem 'C:\Program Files\OpenSSL\lib\VC\x64\MD' | |
| Write-Host "OpenSSL bin DLLs:" | |
| Get-ChildItem $opensslBin -Filter *.dll | |
| # TCC resolves `-lcrypto`/`-lssl` by searching the -L dir for | |
| # `lib<name>.def` FIRST (confirmed against tinycc's own source, | |
| # tcc_add_library's PE search-pattern array: "%s/%s.def", | |
| # "%s/lib%s.def", "%s/%s.dll", "%s/lib%s.dll"), and when a .def | |
| # file is found, tccpe.c's pe_load_def reads the file's own | |
| # `LIBRARY <name>` directive via get_token() to get the DLL | |
| # filename to embed in the import table. Confirmed against | |
| # tinycc's own source that get_token() does NOT strip surrounding | |
| # double quotes, and the extracted name is used AS-IS with no | |
| # `.dll` extension appended. This OpenSSL 4.0.1 package's | |
| # libcrypto.def/libssl.def declare `LIBRARY "libcrypto-4-x64"` / | |
| # `LIBRARY "libssl-4-x64"` -- quoted, no extension -- so TCC | |
| # embeds the LITERAL string `"libcrypto-4-x64"` (quote characters | |
| # included, no `.dll`) as the runtime DLL name. `"` is illegal in | |
| # a Windows filename, so NO real file can ever match that name -- | |
| # guaranteeing STATUS_DLL_NOT_FOUND (exit -1073741515, empty | |
| # output) for every TCC-linked test touching | |
| # crypto.ecdsa/crypto.rsa_pss/net.quic, confirmed via an actual CI | |
| # failure, regardless of what DLLs actually exist in bin\ (MSVC | |
| # is unaffected: it reads the DLL name from the .lib's own | |
| # build-time metadata, which is already a valid, unquoted, | |
| # extensioned filename). A file-aliasing workaround (mirroring | |
| # msvc-windows' crypto.lib/libcrypto.lib alias) CANNOT fix this -- | |
| # you cannot create a file whose name contains a literal `"` on | |
| # Windows. Fix at the source instead: rewrite each .def's LIBRARY | |
| # line in place, stripping the quotes and appending `.dll` if | |
| # missing, before TCC ever reads it. The rewritten name | |
| # (`libcrypto-4-x64.dll`) already exists as a real file in bin\ | |
| # (this package ships both v3 and v4 runtime DLLs side by side), | |
| # so no aliasing is needed once the .def itself is correct. | |
| $libDir = 'C:\Program Files\OpenSSL\lib\VC\x64\MD' | |
| foreach ($name in @('libcrypto', 'libssl')) { | |
| $defPath = Join-Path $libDir "$name.def" | |
| if (-not (Test-Path $defPath)) { | |
| Write-Host "$name.def not found at $defPath, skipping LIBRARY-line fix" | |
| continue | |
| } | |
| $lines = Get-Content $defPath | |
| $fixedAny = $false | |
| $newLines = $lines | ForEach-Object { | |
| if ($_ -match '^(\s*LIBRARY\s+)"?([^"\s]+)"?\s*$') { | |
| $dllName = $Matches[2] | |
| if ($dllName -notmatch '\.dll$') { | |
| $dllName = "$dllName.dll" | |
| } | |
| Write-Host "${name}: rewriting LIBRARY line '$_' -> 'LIBRARY $dllName'" | |
| $fixedAny = $true | |
| "LIBRARY $dllName" | |
| } else { | |
| $_ | |
| } | |
| } | |
| if ($fixedAny) { | |
| Set-Content -Path $defPath -Value $newLines | |
| } else { | |
| Write-Host "${name}: no LIBRARY line found to rewrite in $defPath" | |
| } | |
| } | |
| - name: Build with makev.bat -tcc | |
| run: | | |
| .\makev.bat -tcc | |
| .\v.exe symlink | |
| - name: Pkg-config regression (TCC dynamic isolation) | |
| run: | | |
| .\v.exe -cc tcc -no-retry-compilation test vlib\v\checker\pkgconfig_static_mode_test.v | |
| if ($LASTEXITCODE -ne 0) { | |
| throw "pkg-config TCC isolation regression failed with exit code $LASTEXITCODE" | |
| } | |
| - name: All code is formatted | |
| run: v -silent test-cleancode | |
| - name: Test new v.c | |
| run: | | |
| v -o v.c cmd/v | |
| $direct_c_flags = @( | |
| '-Ithirdparty/zip' | |
| '-Ithirdparty/cJSON' | |
| '-Ithirdparty/mbedtls/library' | |
| '-Ithirdparty/mbedtls/include' | |
| '-Ithirdparty/mbedtls/3rdparty/everest/include' | |
| '-Ithirdparty/mbedtls/3rdparty/everest/include/everest' | |
| '-Ithirdparty/mbedtls/3rdparty/everest/include/everest/kremlib' | |
| '-Ithirdparty/vschannel' | |
| ) | |
| # Match makev.bat's Windows stack reserve; the direct TCC-built | |
| # compiler can otherwise crash while compiling net.http-heavy scripts. | |
| .\thirdparty\tcc\tcc.exe -Werror -w @direct_c_flags -ladvapi32 -lws2_32 -bt10 '-Wl,-stack=33554432' v.c | |
| - name: Install dependencies | |
| run: | | |
| v retry -- v setup-freetype | |
| .\.github\workflows\windows-install-sqlite.bat | |
| - name: v -g self | |
| run: v -g self | |
| - name: v doctor | |
| run: | | |
| v doctor | |
| - name: Verify `v test` works | |
| run: | | |
| v cmd/tools/test_if_v_test_system_works.v | |
| .\cmd\tools\test_if_v_test_system_works.exe | |
| - name: Legacy gg import multiwindow isolation | |
| run: v test vlib/gg/legacy_import_multiwindow_isolation_test.v | |
| - name: Verify `v vlib/v/gen/c/coutput_test.v` works | |
| run: v vlib/v/gen/c/coutput_test.v | |
| - name: Make sure running TCC64 instead of TCC32 | |
| run: v test .github\workflows\make_sure_ci_run_with_64bit_compiler_test.v | |
| - name: Test ./v doc -v clipboard *BEFORE building tools* | |
| run: v doc -v clipboard | |
| - name: Test v build-tools | |
| run: v -silent -W build-tools | |
| - name: Test pure V math module | |
| run: v -silent -exclude @vlib/math/*.c.v test vlib/math/ | |
| - name: Multiwindow render runtime contract | |
| run: .\v.exe -silent vlib\gg\multiwindow_render_runtime_contract_test.v | |
| - name: Self tests | |
| run: v -silent test-self vlib | |
| - name: Test v->js | |
| run: v -o hi.js examples/js_hello_world.v && node hi.js | |
| - name: Test v binaries | |
| run: v build-vbinaries | |
| - name: Build examples | |
| run: v build-examples | |
| - name: Compile and run the veb example (fasthttp) and check its HTML | |
| run: v run .github/workflows/veb_example_windows_smoke.v | |
| - name: v2 self compilation | |
| run: v -o v2.exe cmd/v && .\v2.exe -o v3.exe cmd/v && .\v3.exe -o v4.exe cmd/v | |
| tcc-multiwindow: | |
| runs-on: windows-2022 | |
| timeout-minutes: 60 | |
| env: | |
| VTEST_SHOW_LONGEST_BY_RUNTIME: 3 | |
| VTEST_SHOW_LONGEST_BY_COMPTIME: 3 | |
| VTEST_SHOW_LONGEST_BY_TOTALTIME: 3 | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Build with makev.bat -tcc | |
| run: | | |
| .\makev.bat -tcc | |
| .\v.exe symlink | |
| - name: Checkout pinned Windows TCC bundle | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 | |
| with: | |
| repository: vlang/tccbin | |
| ref: f48b48b2a2a027ee91cec7634395d1ec48d3e325 | |
| path: .ci/tccbin-windows-amd64 | |
| persist-credentials: false | |
| - name: Route TCC validation to pinned bundle | |
| shell: pwsh | |
| run: | | |
| $expectedSha = 'f48b48b2a2a027ee91cec7634395d1ec48d3e325' | |
| $bundle = (Resolve-Path '.\.ci\tccbin-windows-amd64').Path | |
| $actualSha = (git -C $bundle rev-parse HEAD).Trim() | |
| if ($actualSha -cne $expectedSha) { | |
| throw "expected tccbin $expectedSha, got $actualSha" | |
| } | |
| $tcc = Join-Path $bundle 'tcc.exe' | |
| if (-not (Test-Path -LiteralPath $tcc -PathType Leaf)) { | |
| throw "pinned TCC executable is missing: $tcc" | |
| } | |
| $tccLink = Join-Path $env:GITHUB_WORKSPACE 'thirdparty\tcc' | |
| if (Test-Path -LiteralPath $tccLink) { | |
| Remove-Item -LiteralPath $tccLink -Recurse -Force | |
| } | |
| New-Item -ItemType Junction -Path $tccLink -Target $bundle | Out-Null | |
| $junctionTarget = [string](Get-Item -LiteralPath $tccLink).Target | |
| if ([IO.Path]::GetFullPath($junctionTarget) -cne [IO.Path]::GetFullPath($bundle)) { | |
| throw "thirdparty/tcc does not target the pinned bundle: $junctionTarget" | |
| } | |
| Add-Content -Path $env:GITHUB_PATH -Value $bundle | |
| Add-Content -Path $env:GITHUB_ENV -Value "PINNED_TCC=$tcc" | |
| Add-Content -Path $env:GITHUB_ENV ` | |
| -Value "VFLAGS=-cc $tcc -no-retry-compilation" | |
| - name: Verify pinned TCC command resolution | |
| shell: pwsh | |
| run: | | |
| $resolvedTcc = (Get-Command tcc.exe -CommandType Application -ErrorAction Stop).Source | |
| if ([IO.Path]::GetFullPath($resolvedTcc) -cne [IO.Path]::GetFullPath($env:PINNED_TCC)) { | |
| throw "tcc.exe resolved to '$resolvedTcc', expected '$env:PINNED_TCC'" | |
| } | |
| Write-Host "Pinned TCC command: $resolvedTcc" | |
| - name: Legacy gg import multiwindow isolation | |
| run: v test vlib/gg/legacy_import_multiwindow_isolation_test.v | |
| - name: Public gg Win32 services no-flag contract | |
| run: v test vlib/gg/multiwindow_win32_public_services_contract_windows_test.v | |
| - name: Win32 W3 native/public GREEN contracts | |
| shell: pwsh | |
| run: | | |
| .\.github\workflows\run_multiwindow_win32_w3_green.ps1 -Compiler tcc ` | |
| -ExpectedCompositeSha256 '836c1d52c3042f8ec85d0c64489f1b0d1ead8ffafcfdb2a06f567a9b52e2785f' ` | |
| -ExpectedRunnerSha256 '9326948a5be280164fb5c6706295b2c35facae252b2ea1c11e26c5a9129cf955' | |
| - name: Multiwindow render runtime contract | |
| run: .\v.exe -silent vlib\gg\multiwindow_render_runtime_contract_test.v | |
| - name: Public gg Win32 proven W1 services enabled contract | |
| shell: pwsh | |
| run: | | |
| $testFile = (Resolve-Path ` | |
| '.\vlib\gg\multiwindow_win32_public_services_contract_windows_test.v').Path | |
| $discoveredTests = @( | |
| Select-String -LiteralPath $testFile -Pattern '^fn (test_[A-Za-z0-9_]+)\(\)' | | |
| ForEach-Object { $_.Matches[0].Groups[1].Value } | |
| ) | |
| if ($discoveredTests.Count -eq 0) { | |
| throw "no public Win32 service tests were discovered in $testFile" | |
| } | |
| $noFlagOnlyTest = 'test_win32_public_services_stay_disabled_without_opt_in' | |
| $diagnosticTest = 'test_win32_public_controls_publish_observed_state_red' | |
| $w3GreenTest = 'test_win32_public_monitor_projection_and_event_order_red' | |
| $w4RedTest = 'test_win32_public_clipboard_cf_unicodetext_bmp_astral_roundtrip_red' | |
| $tests = @( | |
| 'test_win32_public_hwnd_borrow_route_red' | |
| 'test_win32_public_conditional_focus_refusal_is_not_a_capability_error_red' | |
| 'test_win32_public_partial_focus_is_never_reported_as_success_red' | |
| ) | |
| $classifiedTests = @($noFlagOnlyTest) + $tests + @( | |
| $diagnosticTest | |
| $w3GreenTest | |
| $w4RedTest | |
| ) | |
| $missingTests = @( | |
| $classifiedTests | Where-Object { $discoveredTests -cnotcontains $_ } | |
| ) | |
| $unclassifiedTests = @( | |
| $discoveredTests | Where-Object { $classifiedTests -cnotcontains $_ } | |
| ) | |
| if ($missingTests.Count -ne 0 -or $unclassifiedTests.Count -ne 0) { | |
| throw "public Win32 service test classification mismatch: missing=$($missingTests -join ',') unclassified=$($unclassifiedTests -join ',')" | |
| } | |
| foreach ($test in $tests) { | |
| Write-Host "W1_TCC_CASE_BEGIN name=$test" | |
| $startInfo = [System.Diagnostics.ProcessStartInfo]::new() | |
| $startInfo.FileName = (Resolve-Path '.\v.exe').Path | |
| $startInfo.UseShellExecute = $false | |
| $startInfo.RedirectStandardOutput = $true | |
| $startInfo.RedirectStandardError = $true | |
| $startInfo.CreateNoWindow = $true | |
| foreach ($argument in @( | |
| '-d', 'gg_multiwindow', | |
| '-run-only', $test, | |
| 'test', $testFile | |
| )) { | |
| [void]$startInfo.ArgumentList.Add($argument) | |
| } | |
| $process = [System.Diagnostics.Process]::new() | |
| $process.StartInfo = $startInfo | |
| try { | |
| if (-not $process.Start()) { | |
| throw "failed to start public Win32 service test $test" | |
| } | |
| $stdoutTask = $process.StandardOutput.ReadToEndAsync() | |
| $stderrTask = $process.StandardError.ReadToEndAsync() | |
| $timedOut = -not $process.WaitForExit(45000) | |
| if ($timedOut) { | |
| $process.Kill($true) | |
| [void]$process.WaitForExit(5000) | |
| } else { | |
| $process.WaitForExit() | |
| } | |
| $stdout = $stdoutTask.GetAwaiter().GetResult() | |
| $stderr = $stderrTask.GetAwaiter().GetResult() | |
| if ($stdout) { | |
| Write-Host $stdout.TrimEnd() | |
| } | |
| if ($stderr) { | |
| [Console]::Error.WriteLine($stderr.TrimEnd()) | |
| } | |
| $exitCode = if ($timedOut) { 'timeout' } else { [string]$process.ExitCode } | |
| Write-Host "W1_TCC_CASE_END name=$test timeout=$timedOut exit=$exitCode" | |
| if ($timedOut) { | |
| throw "public Win32 service test timed out: $test" | |
| } | |
| if ($process.ExitCode -ne 0) { | |
| throw "first failing public Win32 service test: $test (exit $($process.ExitCode))" | |
| } | |
| $summaryLines = @( | |
| ([string]$stdout -split "\r?\n") | | |
| Where-Object { $_ -cmatch '^Summary for all V _test\.v files:' } | |
| ) | |
| $combinedOutput = ([string]$stdout) + "`n" + ([string]$stderr) | |
| $selectionAnomalies = @( | |
| ($combinedOutput -split "\r?\n") | | |
| Where-Object { $_ -match '(?i)\bretrying\b|\bSKIP(?:PED)?\b' } | |
| ) | |
| $summaryMatchesSelection = ( | |
| $summaryLines.Count -eq 1 -and | |
| $summaryLines[0] -cmatch '^Summary for all V _test\.v files: 1 passed, 1 total\.' -and | |
| $selectionAnomalies.Count -eq 0 | |
| ) | |
| if (-not $summaryMatchesSelection) { | |
| $foundSummary = if ($summaryLines.Count -eq 0) { | |
| '<none>' | |
| } else { | |
| $summaryLines -join ' | ' | |
| } | |
| $foundAnomalies = if ($selectionAnomalies.Count -eq 0) { | |
| '<none>' | |
| } else { | |
| $selectionAnomalies -join ' | ' | |
| } | |
| throw "selection/summary mismatch for ${test}: expected exactly one '1 passed, 1 total' summary without skip/retry; summary=$foundSummary anomalies=$foundAnomalies" | |
| } | |
| } finally { | |
| $process.Dispose() | |
| } | |
| } | |
| - name: Package 2 native Win32 RED matrix | |
| shell: pwsh | |
| run: .\.github\workflows\run_multiwindow_win32_package2_red.ps1 -Compiler tcc | |
| - name: Win32 W4 clipboard contracts | |
| shell: pwsh | |
| env: | |
| VFLAGS: '' | |
| run: | | |
| .\.github\workflows\run_multiwindow_win32_w4.ps1 ` | |
| -Compiler tcc ` | |
| -Expectation Green ` | |
| -ExpectedOracleSha256 '804e8cbc5f5f7c390e90736d54a60d65d19b649a94afa4915bd9cb4e95c4e04d' ` | |
| -ExpectedNativeTestSha256 '1796d8221d14f9bc40c74e163d797b50f4eeb09a67aee0c4703834880354ef66' ` | |
| -ExpectedPublicTestSha256 'd08eafb919ae97b185fc480c22f6d990973396152e9a0b3a01035c3e9a30275c' ` | |
| -ExpectedNoOptProbeSha256 '288f148ca15b6694481f117c03be5f80c4045baf76d3b0e90db61b5e0596741c' ` | |
| -ExpectedServiceBackendSha256 '8ad39d63360446ef7049c726544200780eff61ff39917830f7024243dfd363be' ` | |
| -ExpectedEventDeliverySha256 'd38c868f574c02fc46e047da25e770e5b9f672500d796694b5ef35bf042cdae0' ` | |
| -ExpectedWin32BackendSha256 '57b7e02241fb3624ffde0619cf99441b0ae91cc112734cffb29433adbfe7b191' ` | |
| -ExpectedWin32ServiceBackendSha256 'faaf67be3e0381ea8a0e7a753b477b7965dde6e655f83f220eca036da19c5df6' ` | |
| -ExpectedWin32ServiceNativeSha256 '2ffc93e245a43c4a557fd7cc66ebcdda8874b9783ec3050ba754657a97efd033' ` | |
| -ExpectedRedSurfaceSha256 'fe7fa76370ee25883e4da25e72b339daeba9d1b47ff70b8b56b0ada87a0027c6' ` | |
| -ExpectedGreenSurfaceSha256 '703041609ba8ed459c785d567bba74e2b90470eb73c6edf99982ab24cf68ccd9' ` | |
| -ExpectedRunnerSha256 '9a38a51e00f609a3e04dbace876028c35bff3cd1a02326c1af40798374ea137a' | |
| - name: Win32 W5 raw-input A0 preflight | |
| shell: pwsh | |
| run: | | |
| .\.github\workflows\run_multiwindow_win32_w5_a0.ps1 -Compiler tcc ` | |
| -ExpectedHeaderSha256 '9decdc2e825c91da2b9d2ce0c98cb8ccdad5c4800a690863d166135eb188e916' ` | |
| -ExpectedMainSha256 '5f30869ae97f680032e622273ea69986d612cc82cad2adf53e4c3b1415154301' ` | |
| -ExpectedTupleSha256 '99ef24bf101dc83543f26f86cb23a80c82607e0f1b35c32e9dbb431368ecc7c4' ` | |
| -ExpectedRunnerSha256 'ce4da58e24730899f970a7566dc65d82eb0c07d38f74efcaeeb02c450a011b68' | |
| - name: Win32 W5 raw-input A1 public GREEN | |
| shell: pwsh | |
| env: | |
| VFLAGS: '' | |
| run: | | |
| .\.github\workflows\run_multiwindow_win32_w5_a1.ps1 -Compiler tcc ` | |
| -Expectation Green ` | |
| -ExpectedTestSha256 '005d3f7c7668bd18d593ba5f42e94cf247058c5f61ca46ce6d6a42bac03b5000' ` | |
| -ExpectedOracleSha256 '7362f17f06ea6b0ab5a64c74abf2407a0e284cbace2c10809a5235d406d16461' ` | |
| -ExpectedTupleSha256 '16739d9b8b73d9615ba3037c9e18219d6bf1271ef1d2f7dba4b2f2e53b1efac5' ` | |
| -ExpectedA0HeaderSha256 '9decdc2e825c91da2b9d2ce0c98cb8ccdad5c4800a690863d166135eb188e916' ` | |
| -ExpectedA0MainSha256 '5f30869ae97f680032e622273ea69986d612cc82cad2adf53e4c3b1415154301' ` | |
| -ExpectedA0TupleSha256 '99ef24bf101dc83543f26f86cb23a80c82607e0f1b35c32e9dbb431368ecc7c4' ` | |
| -ExpectedA0RunnerSha256 'ce4da58e24730899f970a7566dc65d82eb0c07d38f74efcaeeb02c450a011b68' ` | |
| -ExpectedGgFacadeSha256 'e5a944c1bb86bf9af11bfc9d1d137566ac6659d5f56ddabd08cdb49792afbb46' ` | |
| -ExpectedGgNoFlagSha256 'ad528c64cf18bce9415dd0e50513fb87d8d0b58c8ac4a99025a5c8955e7d9549' ` | |
| -ExpectedGgServiceTypesSha256 '9f17334ba5e5aff51f26d55476c83878856a8494a890aa64ee6434a52c1ecfeb' ` | |
| -ExpectedAppSha256 'af32eec55c119907a8bbf544842131018d36d3887347e26486e067a79d78a946' ` | |
| -ExpectedTypesSha256 '0a9058ba7928945e24284c867eb6182336ea3b1d41e1337786c71105b1fe93b3' ` | |
| -ExpectedBackendSha256 'dcd0f088c235ae030f8bbc9ab63082c38d93f6f1194373e74d8dcb454d100a3f' ` | |
| -ExpectedServiceApiSha256 'b7e4bc26e85f897a72387e82f4a7a3d545f21230be5c6b9df4fa40a4c82b701f' ` | |
| -ExpectedServiceTypesSha256 'cd8326b81201727618e758d79970b7a77223fd6418e18afda44a526a3b0b4267' ` | |
| -ExpectedServiceRegistrySha256 'db244497fd23974c1739d6c7a8bc57a2e3137c8765d4bc7f789efd80a59066b7' ` | |
| -ExpectedEventDeliverySha256 'd38c868f574c02fc46e047da25e770e5b9f672500d796694b5ef35bf042cdae0' ` | |
| -ExpectedPublicRoutingSurfaceSha256 '3993513f6865922d0dd47daa32e5ea0a7fd4d7e6c2480b79d1db8f568802aad2' ` | |
| -ExpectedServiceBackendSha256 '8ad39d63360446ef7049c726544200780eff61ff39917830f7024243dfd363be' ` | |
| -ExpectedEventDispatchSha256 '7ef6c7cbd34511d6c19c1a3a269b46876db791b9412bb88e3a8d4dcd543bfd4e' ` | |
| -ExpectedWin32BackendSha256 '57b7e02241fb3624ffde0619cf99441b0ae91cc112734cffb29433adbfe7b191' ` | |
| -ExpectedWin32BackendHelpersSha256 'ba0021ce46731b25d540a68bf7c7832c7302a7343a90e1398df91cc5e409754d' ` | |
| -ExpectedWin32ServiceBackendSha256 'faaf67be3e0381ea8a0e7a753b477b7965dde6e655f83f220eca036da19c5df6' ` | |
| -ExpectedWin32ServiceNativeSha256 '2ffc93e245a43c4a557fd7cc66ebcdda8874b9783ec3050ba754657a97efd033' ` | |
| -ExpectedGreenProductionSurfaceSha256 'c1796663110d256b5ba6bc59e3ea0d2ec28863ab2c8b697dd8ee39882afe0928' ` | |
| -ExpectedRunnerSha256 '1a3b1c562843a641faaaf79c4bd6fd6ab58594d5a75d9ae7b488c7d23d934112' | |
| - name: Public gg Win32 controls/state native diagnostic | |
| if: ${{ always() }} | |
| shell: pwsh | |
| run: | | |
| $testFile = (Resolve-Path ` | |
| '.\vlib\gg\multiwindow_win32_public_services_contract_windows_test.v').Path | |
| $test = 'test_win32_public_controls_publish_observed_state_red' | |
| $discoveredTests = @( | |
| Select-String -LiteralPath $testFile -Pattern '^fn (test_[A-Za-z0-9_]+)\(\)' | | |
| ForEach-Object { $_.Matches[0].Groups[1].Value } | |
| ) | |
| if ($discoveredTests -cnotcontains $test) { | |
| throw "controls/state native diagnostic test was not discovered: $test" | |
| } | |
| Write-Host "W1_TCC_NATIVE_DIAG_BEGIN name=$test" | |
| $startInfo = [System.Diagnostics.ProcessStartInfo]::new() | |
| $startInfo.FileName = (Resolve-Path '.\v.exe').Path | |
| $startInfo.UseShellExecute = $false | |
| $startInfo.RedirectStandardOutput = $true | |
| $startInfo.RedirectStandardError = $true | |
| $startInfo.CreateNoWindow = $true | |
| foreach ($argument in @( | |
| '-d', 'gg_multiwindow', | |
| '-run-only', $test, | |
| 'test', $testFile | |
| )) { | |
| [void]$startInfo.ArgumentList.Add($argument) | |
| } | |
| $process = [System.Diagnostics.Process]::new() | |
| $process.StartInfo = $startInfo | |
| try { | |
| if (-not $process.Start()) { | |
| throw "failed to start controls/state native diagnostic $test" | |
| } | |
| $stdoutTask = $process.StandardOutput.ReadToEndAsync() | |
| $stderrTask = $process.StandardError.ReadToEndAsync() | |
| $timedOut = -not $process.WaitForExit(45000) | |
| if ($timedOut) { | |
| $process.Kill($true) | |
| [void]$process.WaitForExit(5000) | |
| } else { | |
| $process.WaitForExit() | |
| } | |
| $stdout = $stdoutTask.GetAwaiter().GetResult() | |
| $stderr = $stderrTask.GetAwaiter().GetResult() | |
| if ($stdout) { | |
| Write-Host $stdout.TrimEnd() | |
| } | |
| if ($stderr) { | |
| [Console]::Error.WriteLine($stderr.TrimEnd()) | |
| } | |
| $exitCode = if ($timedOut) { 'timeout' } else { [string]$process.ExitCode } | |
| Write-Host "W1_TCC_NATIVE_DIAG_END name=$test timeout=$timedOut exit=$exitCode" | |
| if ($timedOut) { | |
| throw "controls/state native diagnostic timed out: $test" | |
| } | |
| if ($process.ExitCode -ne 0) { | |
| throw "controls/state native diagnostic failed: $test (exit $($process.ExitCode))" | |
| } | |
| $summaryLines = @( | |
| ([string]$stdout -split "\r?\n") | | |
| Where-Object { $_ -cmatch '^Summary for all V _test\.v files:' } | |
| ) | |
| $combinedOutput = ([string]$stdout) + "`n" + ([string]$stderr) | |
| $selectionAnomalies = @( | |
| ($combinedOutput -split "\r?\n") | | |
| Where-Object { $_ -match '(?i)\bretrying\b|\bSKIP(?:PED)?\b' } | |
| ) | |
| $summaryMatchesSelection = ( | |
| $summaryLines.Count -eq 1 -and | |
| $summaryLines[0] -cmatch '^Summary for all V _test\.v files: 1 passed, 1 total\.' -and | |
| $selectionAnomalies.Count -eq 0 | |
| ) | |
| if (-not $summaryMatchesSelection) { | |
| $foundSummary = if ($summaryLines.Count -eq 0) { | |
| '<none>' | |
| } else { | |
| $summaryLines -join ' | ' | |
| } | |
| $foundAnomalies = if ($selectionAnomalies.Count -eq 0) { | |
| '<none>' | |
| } else { | |
| $selectionAnomalies -join ' | ' | |
| } | |
| throw "selection/summary mismatch for ${test}: expected exactly one '1 passed, 1 total' summary without skip/retry; summary=$foundSummary anomalies=$foundAnomalies" | |
| } | |
| } finally { | |
| $process.Dispose() | |
| } |