mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-10-17 10:09:05 +02:00
ci: build Go test binaries while fixtures are provisioned (#2656)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
465fccbe69
commit
d25d2328f2
@@ -0,0 +1,51 @@
|
||||
# Builds the race-enabled test binaries ahead of time, so CI can link them in
|
||||
# the background while Windows fixtures are provisioned. run-go-tests.ps1 runs
|
||||
# the binaries listed in manifest.json.
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[string]$OutputDirectory
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
Set-StrictMode -Version 3
|
||||
|
||||
New-Item -ItemType Directory -Force -Path $OutputDirectory | Out-Null
|
||||
$OutputDirectory = (Resolve-Path $OutputDirectory).Path
|
||||
|
||||
$listing = go list -f '{{if or .TestGoFiles .XTestGoFiles}}{{.ImportPath}}{{"\t"}}{{.Dir}}{{end}}' ./...
|
||||
if ($LASTEXITCODE -ne 0) { throw "go list failed with exit code $LASTEXITCODE" }
|
||||
|
||||
$packages = @($listing | Where-Object { $_ } | ForEach-Object {
|
||||
$importPath, $dir = $_ -split "`t", 2
|
||||
[pscustomobject]@{
|
||||
ImportPath = $importPath
|
||||
Dir = $dir
|
||||
Base = $importPath.Split('/')[-1]
|
||||
Binary = $null
|
||||
}
|
||||
})
|
||||
|
||||
# `go test -c -o dir/` names binaries after the last import path element, so
|
||||
# packages sharing that name (internal/collector, pkg/collector) build separately.
|
||||
$groups = $packages | Group-Object Base
|
||||
$shared = @($groups | Where-Object Count -eq 1 | ForEach-Object { $_.Group[0] })
|
||||
$clashing = @($groups | Where-Object Count -gt 1 | ForEach-Object { $_.Group })
|
||||
|
||||
foreach ($package in $shared) {
|
||||
$package.Binary = "$($package.Base).test.exe"
|
||||
}
|
||||
|
||||
go test -race -c -o "$OutputDirectory/" @($shared.ImportPath)
|
||||
if ($LASTEXITCODE -ne 0) { throw "go test -c failed with exit code $LASTEXITCODE" }
|
||||
|
||||
foreach ($package in $clashing) {
|
||||
$package.Binary = ($package.ImportPath -replace '[/.]', '_') + '.test.exe'
|
||||
go test -race -c -o (Join-Path $OutputDirectory $package.Binary) $package.ImportPath
|
||||
if ($LASTEXITCODE -ne 0) { throw "go test -c $($package.ImportPath) failed with exit code $LASTEXITCODE" }
|
||||
}
|
||||
|
||||
$packages | Select-Object ImportPath, Dir, Binary |
|
||||
ConvertTo-Json -AsArray |
|
||||
Set-Content -Encoding utf8 (Join-Path $OutputDirectory 'manifest.json')
|
||||
|
||||
Write-Host "Built $($packages.Count) test binaries in $OutputDirectory"
|
||||
@@ -0,0 +1,49 @@
|
||||
# Runs the test binaries built by build-go-tests.ps1 like `go test -v ./...`:
|
||||
# each binary runs in its package directory and packages run in parallel.
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[string]$BinaryDirectory,
|
||||
[string]$Timeout = '10m',
|
||||
[int]$ThrottleLimit = [Environment]::ProcessorCount
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
Set-StrictMode -Version 3
|
||||
|
||||
$BinaryDirectory = (Resolve-Path $BinaryDirectory).Path
|
||||
$manifest = Get-Content (Join-Path $BinaryDirectory 'manifest.json') -Raw | ConvertFrom-Json
|
||||
|
||||
$runs = $manifest | ForEach-Object -ThrottleLimit $ThrottleLimit -Parallel {
|
||||
$package = $_
|
||||
$timeout = $using:Timeout
|
||||
$binary = Join-Path $using:BinaryDirectory $package.Binary
|
||||
|
||||
# Native commands start in the runspace location, so tests see their
|
||||
# package directory as the working directory, as with `go test`.
|
||||
Set-Location $package.Dir
|
||||
$started = Get-Date
|
||||
$output = & $binary '-test.v' "-test.timeout=$timeout" 2>&1 |
|
||||
ForEach-Object { $_.ToString() }
|
||||
$exitCode = $LASTEXITCODE
|
||||
$elapsed = ((Get-Date) - $started).TotalSeconds
|
||||
|
||||
$status = if ($exitCode -eq 0) { 'ok ' } else { 'FAIL' }
|
||||
[pscustomobject]@{
|
||||
ImportPath = $package.ImportPath
|
||||
ExitCode = $exitCode
|
||||
# Print each package as one block so parallel output does not interleave.
|
||||
Text = (@($output) + ("{0}`t{1}`t{2:N3}s" -f $status, $package.ImportPath, $elapsed)) -join "`n"
|
||||
}
|
||||
} | ForEach-Object {
|
||||
Write-Host $_.Text
|
||||
$_
|
||||
}
|
||||
|
||||
$failed = @($runs | Where-Object ExitCode -ne 0)
|
||||
if ($failed.Count -gt 0) {
|
||||
Write-Host "Failed packages:"
|
||||
$failed | ForEach-Object { Write-Host " $($_.ImportPath) (exit code $($_.ExitCode))" }
|
||||
exit 1
|
||||
}
|
||||
|
||||
exit 0
|
||||
@@ -1,64 +0,0 @@
|
||||
param([int]$TestExitCode)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
$prefix = "github.com/prometheus-community/windows_exporter/internal/collector/"
|
||||
$required = @($env:WINDOWS_EXPORTER_TEST_COLLECTORS.Split(','))
|
||||
$results = @{}
|
||||
$text = [System.Text.StringBuilder]::new()
|
||||
|
||||
$lines = if (Test-Path test-results.jsonl) { Get-Content test-results.jsonl } else { @() }
|
||||
foreach ($line in $lines) {
|
||||
try {
|
||||
$event = $line | ConvertFrom-Json -ErrorAction Stop
|
||||
} catch {
|
||||
[void]$text.AppendLine($line)
|
||||
continue
|
||||
}
|
||||
if ($event.Output) { [void]$text.Append($event.Output) }
|
||||
if (-not $event.Package -or -not $event.Package.StartsWith($prefix) -or $event.Test -ne "TestCollector") {
|
||||
continue
|
||||
}
|
||||
$name = $event.Package.Substring($prefix.Length)
|
||||
if (-not $results.ContainsKey($name)) {
|
||||
$results[$name] = @{ State = "not completed"; Notes = @() }
|
||||
}
|
||||
if ($event.Action -in @("pass", "skip", "fail")) {
|
||||
$results[$name].State = $event.Action
|
||||
}
|
||||
if ($event.Output -match 'collector \S+ (?:is not supported|has empty optional instance groups): (.+)') {
|
||||
$results[$name].Notes += $Matches[1].Trim()
|
||||
}
|
||||
}
|
||||
$text.ToString() | Set-Content test-output.txt -NoNewline -Encoding utf8
|
||||
|
||||
# Aborted tests must leave required fixtures visible as not run.
|
||||
foreach ($name in $required) {
|
||||
if (-not $results.ContainsKey($name)) {
|
||||
$results[$name] = @{ State = "not run"; Notes = @() }
|
||||
}
|
||||
}
|
||||
$testState = if (-not $lines) { "not run" } elseif ($TestExitCode -eq 0) { "passed" } else { "failed" }
|
||||
$summary = @(
|
||||
"### Windows feature tests: $env:WINDOWS_TEST_OS"
|
||||
""
|
||||
"Go suite: **$testState**. Required fixtures cannot skip. Empty optional instance groups remain listed below."
|
||||
""
|
||||
"| Collector | Required | Live test | Unavailable features / notes |"
|
||||
"| --- | --- | --- | --- |"
|
||||
)
|
||||
foreach ($name in $results.Keys | Sort-Object) {
|
||||
$fixture = if ($name -in $required) { "yes" } else { "no" }
|
||||
$state = switch ($results[$name].State) {
|
||||
"pass" { "passed" }
|
||||
"skip" { "unavailable" }
|
||||
"fail" { "failed" }
|
||||
default { $results[$name].State }
|
||||
}
|
||||
$notes = ($results[$name].Notes | Sort-Object -Unique) -join '; '
|
||||
$notes = $notes.Replace('|', '\|')
|
||||
$summary += "| $name | $fixture | $state | $notes |"
|
||||
}
|
||||
$summary | Set-Content feature-summary.md -Encoding utf8
|
||||
if ($env:GITHUB_STEP_SUMMARY) {
|
||||
$summary | Add-Content $env:GITHUB_STEP_SUMMARY
|
||||
}
|
||||
Reference in New Issue
Block a user