@@ -56,57 +56,169 @@ jobs:
5656 - name : Setup test environment (Unix)
5757 if : runner.os != 'Windows'
5858 run : |
59+ echo "Setting up test environment for Unix..."
60+
61+ # Create test results directory
5962 mkdir -p test-results
60- # Install test dependencies
61- go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
62- setup-envtest use 1.29.0 --bin-dir ~/.local/bin || true
63- echo "KUBEBUILDER_ASSETS=$(setup-envtest use 1.29.0 --bin-dir ~/.local/bin -p path 2>/dev/null || echo '')" >> $GITHUB_ENV
63+
64+ # Install setup-envtest with a specific version for stability
65+ echo "Installing setup-envtest tool..."
66+ go install sigs.k8s.io/controller-runtime/tools/setup-envtest@v0.17.0
67+
68+ # Create local bin directory
69+ mkdir -p ~/.local/bin
70+
71+ # Download and setup envtest binaries
72+ echo "Downloading Kubernetes 1.29.0 envtest binaries..."
73+ if setup-envtest use 1.29.0 --bin-dir ~/.local/bin; then
74+ KUBEBUILDER_ASSETS=$(setup-envtest use 1.29.0 --bin-dir ~/.local/bin -p path 2>/dev/null)
75+ if [ -n "$KUBEBUILDER_ASSETS" ] && [ -d "$KUBEBUILDER_ASSETS" ]; then
76+ echo "✅ KUBEBUILDER_ASSETS path: $KUBEBUILDER_ASSETS"
77+ echo "KUBEBUILDER_ASSETS=$KUBEBUILDER_ASSETS" >> $GITHUB_ENV
78+ else
79+ echo "⚠️ Warning: Could not set KUBEBUILDER_ASSETS. Envtest may not work properly."
80+ echo "KUBEBUILDER_ASSETS=" >> $GITHUB_ENV
81+ fi
82+ else
83+ echo "⚠️ Warning: setup-envtest failed. Tests that don't require envtest will still run."
84+ echo "KUBEBUILDER_ASSETS=" >> $GITHUB_ENV
85+ fi
6486
6587 - name : Setup test environment (Windows)
6688 if : runner.os == 'Windows'
89+ shell : pwsh
6790 run : |
68- mkdir test-results
69- # Install test dependencies for Windows
70- go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
71- $env:PATH += ";$env:USERPROFILE\go\bin"
72- setup-envtest.exe use 1.29.0 --bin-dir "$env:USERPROFILE\.local\bin" -ErrorAction SilentlyContinue
73- $kubeAssets = setup-envtest.exe use 1.29.0 --bin-dir "$env:USERPROFILE\.local\bin" -p path -ErrorAction SilentlyContinue
74- if ($kubeAssets) { echo "KUBEBUILDER_ASSETS=$kubeAssets" >> $env:GITHUB_ENV }
91+ Write-Host "Setting up test environment for Windows..."
92+
93+ # Create test results directory
94+ New-Item -ItemType Directory -Path test-results -Force | Out-Null
95+
96+ # Install setup-envtest with a specific version for stability
97+ Write-Host "Installing setup-envtest tool..."
98+ go install sigs.k8s.io/controller-runtime/tools/setup-envtest@v0.17.0
99+
100+ # Add Go bin to PATH for this session
101+ $goPath = go env GOPATH
102+ $goBin = Join-Path $goPath "bin"
103+ $env:PATH = "$goBin;$env:PATH"
104+
105+ # Create local bin directory
106+ $localBin = Join-Path $env:USERPROFILE ".local" "bin"
107+ New-Item -ItemType Directory -Path $localBin -Force | Out-Null
108+
109+ # Download and setup envtest binaries
110+ Write-Host "Downloading Kubernetes 1.29.0 envtest binaries..."
111+ try {
112+ # First attempt: download the binaries
113+ $output = & setup-envtest.exe use 1.29.0 --bin-dir $localBin 2>&1
114+ if ($LASTEXITCODE -ne 0) {
115+ Write-Host "Warning: First setup-envtest attempt failed with exit code $LASTEXITCODE"
116+ Write-Host "Output: $output"
117+ }
118+
119+ # Second attempt: get the path to the binaries
120+ $kubeAssets = & setup-envtest.exe use 1.29.0 --bin-dir $localBin -p path 2>&1
121+ if ($LASTEXITCODE -eq 0 -and $kubeAssets -and $kubeAssets -notmatch "Error" -and (Test-Path $kubeAssets)) {
122+ Write-Host "✅ KUBEBUILDER_ASSETS path: $kubeAssets"
123+ echo "KUBEBUILDER_ASSETS=$kubeAssets" >> $env:GITHUB_ENV
124+ } else {
125+ Write-Host "⚠️ Warning: Could not set KUBEBUILDER_ASSETS. Envtest may not work properly."
126+ Write-Host "setup-envtest output: $kubeAssets"
127+ # Don't fail the build, as some tests may not require envtest
128+ echo "KUBEBUILDER_ASSETS=" >> $env:GITHUB_ENV
129+ }
130+ } catch {
131+ Write-Host "⚠️ Warning: Exception during envtest setup: $_"
132+ Write-Host "Tests that don't require envtest will still run."
133+ echo "KUBEBUILDER_ASSETS=" >> $env:GITHUB_ENV
134+ }
75135
76136 - name : Run tests with retry (Unix)
77137 if : runner.os != 'Windows'
78138 env :
79139 USE_EXISTING_CLUSTER : false
80140 ENVTEST_K8S_VERSION : 1.29.0
81141 GOMAXPROCS : 2
82- CGO_ENABLED : 0
83142 GOTRACEBACK : all
143+ # Note: CGO is required for -race flag, but we disable CGO for static builds
144+ CGO_ENABLED : 0
84145 run : |
85146 # Test with retry for flaky tests
147+ test_passed=false
86148 for attempt in 1 2; do
87149 echo "=== Test attempt $attempt of 2 ==="
88- if go test -v -timeout=30m -count=1 -race \
150+ echo "🔧 Running tests without -race flag due to CGO_ENABLED=0"
151+ echo "📋 Command: go test -v -timeout=30m -count=1 -coverprofile=test-results/coverage-$attempt.out -covermode=atomic ./cmd/conductor-loop ./internal/loop"
152+
153+ # Run tests on all packages with coverage
154+ # Note: -race flag requires CGO_ENABLED=1, we use CGO_ENABLED=0 for static builds
155+ if go test -v -timeout=30m -count=1 \
89156 -coverprofile=test-results/coverage-$attempt.out \
90157 -covermode=atomic \
91158 ./cmd/conductor-loop ./internal/loop \
92159 2>&1 | tee test-results/test-attempt-$attempt.log; then
93160 echo "✅ Tests passed on attempt $attempt"
94- cp test-results/coverage-$attempt.out test-results/coverage.out
161+ test_passed=true
162+
163+ # Verify coverage file was generated with expected name
164+ coverage_file="test-results/coverage-$attempt.out"
165+ if [ -f "$coverage_file" ]; then
166+ cp "$coverage_file" test-results/coverage.out
167+ echo "✅ Coverage file generated and copied: $coverage_file -> test-results/coverage.out"
168+
169+ # Show file size for verification
170+ ls -la "$coverage_file" test-results/coverage.out
171+ else
172+ echo "❌ ERROR: Expected coverage file '$coverage_file' was not generated despite tests passing!"
173+ echo "📁 Files in test-results directory:"
174+ ls -la test-results/ || echo "test-results directory not found"
175+ exit 1
176+ fi
95177 break
96- elif [ $attempt -eq 2 ]; then
97- echo "❌ Tests failed after 2 attempts"
98- cat test-results/test-attempt-*.log > test-results/combined-test.log
99- exit 1
100178 else
101- echo "⚠️ Test attempt $attempt failed, retrying in 10s..."
102- sleep 10
179+ exit_code=$?
180+ echo "⚠️ Test attempt $attempt failed with exit code $exit_code"
181+
182+ # Check if partial coverage was generated even though tests failed
183+ coverage_file="test-results/coverage-$attempt.out"
184+ if [ -f "$coverage_file" ]; then
185+ echo "📊 Partial coverage file found despite test failure: $coverage_file"
186+ cp "$coverage_file" test-results/coverage-partial-$attempt.out
187+ # Keep the last attempt's coverage as the main one
188+ cp "$coverage_file" test-results/coverage.out
189+ echo "💾 Preserved partial coverage for analysis"
190+ else
191+ echo "📁 No coverage file generated. Files in test-results:"
192+ ls -la test-results/ || echo "test-results directory not found"
193+ fi
194+
195+ if [ $attempt -eq 2 ]; then
196+ echo "❌ Tests failed after 2 attempts"
197+ cat test-results/test-attempt-*.log > test-results/combined-test.log
198+ # Exit with failure after preserving any partial coverage
199+ exit 1
200+ else
201+ echo "⚠️ Retrying in 10s..."
202+ sleep 10
203+ fi
103204 fi
104205 done
105206
106- # Generate coverage report if available
107- if [ -f test-results/coverage.out ]; then
108- go tool cover -html=test-results/coverage.out -o test-results/coverage.html
109- go tool cover -func=test-results/coverage.out > test-results/coverage-summary.txt
207+ # Verify coverage file exists before processing
208+ if [ ! -f test-results/coverage.out ]; then
209+ echo "❌ ERROR: No coverage.out file found after successful tests!"
210+ exit 1
211+ fi
212+
213+ # Generate coverage report
214+ echo "📊 Generating coverage reports..."
215+ go tool cover -html=test-results/coverage.out -o test-results/coverage.html || echo "Warning: Failed to generate HTML coverage"
216+ go tool cover -func=test-results/coverage.out > test-results/coverage-summary.txt || echo "Warning: Failed to generate coverage summary"
217+
218+ # Display coverage percentage
219+ if [ -f test-results/coverage-summary.txt ]; then
220+ echo "📈 Coverage Summary:"
221+ tail -5 test-results/coverage-summary.txt
110222 fi
111223
112224 - name : Run tests with retry (Windows)
@@ -115,40 +227,114 @@ jobs:
115227 USE_EXISTING_CLUSTER : false
116228 ENVTEST_K8S_VERSION : 1.29.0
117229 GOMAXPROCS : 2
118- CGO_ENABLED : 0
119230 GOTRACEBACK : all
231+ # Note: CGO is required for -race flag, but we disable CGO for static builds
232+ CGO_ENABLED : 0
120233 run : |
121234 # Test with retry for flaky tests on Windows
122235 $success = $false
123236 for ($attempt = 1; $attempt -le 2; $attempt++) {
124237 Write-Host "=== Test attempt $attempt of 2 ==="
238+ Write-Host "🔧 Running tests without -race flag due to CGO_ENABLED=0"
239+ Write-Host "📋 Command: go test -v -timeout=30m -count=1 -coverprofile=test-results/coverage-$attempt.out -covermode=atomic ./cmd/conductor-loop ./internal/loop"
125240 try {
126- $testResult = go test -v -timeout=30m -count=1 -race -coverprofile=test-results/coverage-$attempt.out -covermode=atomic ./cmd/conductor-loop ./internal/loop 2>&1
241+ # Run tests on all packages with coverage
242+ # Note: -race flag requires CGO_ENABLED=1, we use CGO_ENABLED=0 for static builds
243+ $testResult = go test -v -timeout=30m -count=1 -coverprofile=test-results/coverage-$attempt.out -covermode=atomic ./cmd/conductor-loop ./internal/loop 2>&1
127244 $testResult | Tee-Object test-results/test-attempt-$attempt.log
128245 if ($LASTEXITCODE -eq 0) {
129246 Write-Host "✅ Tests passed on attempt $attempt"
130- Copy-Item test-results/coverage-$attempt.out test-results/coverage.out -ErrorAction SilentlyContinue
247+
248+ # Verify coverage file was generated with expected name
249+ $coverageFile = "test-results/coverage-$attempt.out"
250+ if (Test-Path $coverageFile) {
251+ Copy-Item $coverageFile test-results/coverage.out -Force
252+ Write-Host "✅ Coverage file generated and copied: $coverageFile -> test-results/coverage.out"
253+
254+ # Show file info for verification
255+ Get-ChildItem $coverageFile, test-results/coverage.out | Format-Table Name, Length, LastWriteTime
256+ } else {
257+ Write-Host "❌ ERROR: Expected coverage file '$coverageFile' was not generated despite tests passing!"
258+ Write-Host "📁 Files in test-results directory:"
259+ if (Test-Path "test-results") {
260+ Get-ChildItem test-results/ | Format-Table Name, Length, LastWriteTime
261+ } else {
262+ Write-Host "test-results directory not found"
263+ }
264+ exit 1
265+ }
131266 $success = $true
132267 break
133- } elseif ($attempt -eq 2) {
134- Write-Host "❌ Tests failed after 2 attempts"
135- Get-Content test-results/test-attempt-*.log | Out-File test-results/combined-test.log
136- exit 1
137268 } else {
138- Write-Host "⚠️ Test attempt $attempt failed, retrying in 10s..."
139- Start-Sleep 10
269+ Write-Host "⚠️ Test attempt $attempt failed with exit code $LASTEXITCODE"
270+
271+ # Check if partial coverage was generated even though tests failed
272+ $coverageFile = "test-results/coverage-$attempt.out"
273+ if (Test-Path $coverageFile) {
274+ Write-Host "📊 Partial coverage file found despite test failure: $coverageFile"
275+ Copy-Item $coverageFile test-results/coverage-partial-$attempt.out -Force
276+ # Keep the last attempt's coverage as the main one
277+ Copy-Item $coverageFile test-results/coverage.out -Force
278+ Write-Host "💾 Preserved partial coverage for analysis"
279+ } else {
280+ Write-Host "📁 No coverage file generated. Files in test-results:"
281+ if (Test-Path "test-results") {
282+ Get-ChildItem test-results/ | Format-Table Name, Length, LastWriteTime
283+ } else {
284+ Write-Host "test-results directory not found"
285+ }
286+ }
287+
288+ if ($attempt -eq 2) {
289+ Write-Host "❌ Tests failed after 2 attempts"
290+ Get-Content test-results/test-attempt-*.log | Out-File test-results/combined-test.log
291+ # Exit with failure after preserving any partial coverage
292+ exit 1
293+ } else {
294+ Write-Host "⚠️ Retrying in 10s..."
295+ Start-Sleep 10
296+ }
140297 }
141298 } catch {
142299 Write-Host "Error in test attempt $attempt: $_"
300+
301+ # Check for partial coverage even on exception
302+ $coverageFile = "test-results/coverage-$attempt.out"
303+ if (Test-Path $coverageFile) {
304+ Write-Host "📊 Partial coverage file found despite error: $coverageFile"
305+ Copy-Item $coverageFile test-results/coverage-partial-$attempt.out -Force -ErrorAction SilentlyContinue
306+ Copy-Item $coverageFile test-results/coverage.out -Force -ErrorAction SilentlyContinue
307+ Write-Host "💾 Preserved partial coverage for analysis"
308+ }
309+
143310 if ($attempt -eq 2) { exit 1 }
144311 Start-Sleep 10
145312 }
146313 }
147314
148- # Generate coverage report if available
149- if (Test-Path test-results/coverage.out) {
315+ # Verify coverage file exists before processing
316+ if (-not (Test-Path test-results/coverage.out)) {
317+ Write-Host "❌ ERROR: No coverage.out file found after successful tests!"
318+ exit 1
319+ }
320+
321+ # Generate coverage report
322+ Write-Host "📊 Generating coverage reports..."
323+ try {
150324 go tool cover -html=test-results/coverage.out -o test-results/coverage.html
325+ } catch {
326+ Write-Host "Warning: Failed to generate HTML coverage"
327+ }
328+ try {
151329 go tool cover -func=test-results/coverage.out | Out-File test-results/coverage-summary.txt
330+ } catch {
331+ Write-Host "Warning: Failed to generate coverage summary"
332+ }
333+
334+ # Display coverage percentage
335+ if (Test-Path test-results/coverage-summary.txt) {
336+ Write-Host "📈 Coverage Summary:"
337+ Get-Content test-results/coverage-summary.txt -Tail 5
152338 }
153339
154340 - name : Upload test artifacts
0 commit comments