diff --git a/.github/workflows/runtime-tests.yml b/.github/workflows/runtime-tests.yml new file mode 100644 index 0000000..d6cb25a --- /dev/null +++ b/.github/workflows/runtime-tests.yml @@ -0,0 +1,336 @@ +name: Runtime Tests + +on: + push: + branches: [ main, master ] + pull_request: + branches: [ main, master ] + +permissions: + contents: read + pull-requests: write + +jobs: + runtime-tests: + runs-on: windows-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup MSVC + uses: ilammy/msvc-dev-cmd@v1 + + - name: Initialize test results + run: | + @" + BUILD=⏳ + HELP=⏳ + VERSION=⏳ + PID_TESTS=⏳ + ERROR_HANDLING=⏳ + PROCESS_LOOKUP=⏳ + OUTPUT_VALIDATION=⏳ + STRESS_TESTS=⏳ + UNICODE=⏳ + "@ | Out-File -FilePath test-results.txt + + - name: Build win-witr + id: build + continue-on-error: true + run: | + cl.exe /EHsc /std:c++20 main.cpp /Fe:win-witr.exe advapi32.lib iphlpapi.lib ws2_32.lib shell32.lib /DUNICODE /D_UNICODE + if ($LASTEXITCODE -ne 0) { + (Get-Content test-results.txt) -replace 'BUILD=⏳', 'BUILD=❌' | Set-Content test-results.txt + throw "Build failed!" + } + (Get-Content test-results.txt) -replace 'BUILD=⏳', 'BUILD=✅' | Set-Content test-results.txt + + # ============ HELP COMMAND TESTS ============ + - name: Test help commands + id: help + continue-on-error: true + run: | + Write-Host "Testing --help flag..." -ForegroundColor Cyan + ./win-witr.exe --help + if ($LASTEXITCODE -ne 0) { + (Get-Content test-results.txt) -replace 'HELP=⏳', 'HELP=❌' | Set-Content test-results.txt + throw "❌ Help command failed" + } + + Write-Host "Testing -h flag..." -ForegroundColor Cyan + ./win-witr.exe -h + if ($LASTEXITCODE -ne 0) { + (Get-Content test-results.txt) -replace 'HELP=⏳', 'HELP=❌' | Set-Content test-results.txt + throw "❌ Short help failed" + } + + (Get-Content test-results.txt) -replace 'HELP=⏳', 'HELP=✅' | Set-Content test-results.txt + Write-Host "✅ Help tests passed" -ForegroundColor Green + + # ============ VERSION COMMAND TESTS ============ + - name: Test version commands + id: version + continue-on-error: true + run: | + Write-Host "Testing --version flag..." -ForegroundColor Cyan + $output = ./win-witr.exe --version | Out-String + Write-Host $output + if ($output -notmatch "win-witr v\d+\.\d+\.\d+") { + (Get-Content test-results.txt) -replace 'VERSION=⏳', 'VERSION=❌' | Set-Content test-results.txt + throw "❌ Version format incorrect: $output" + } + + Write-Host "Testing -v flag..." -ForegroundColor Cyan + ./win-witr.exe -v + if ($LASTEXITCODE -ne 0) { + (Get-Content test-results.txt) -replace 'VERSION=⏳', 'VERSION=❌' | Set-Content test-results.txt + throw "❌ Short version failed" + } + + (Get-Content test-results.txt) -replace 'VERSION=⏳', 'VERSION=✅' | Set-Content test-results.txt + Write-Host "✅ Version tests passed" -ForegroundColor Green + + # ============ PID INSPECTION TESTS ============ + - name: Test PID inspection + id: pid + continue-on-error: true + run: | + Write-Host "Testing --pid 0 (System Idle)..." -ForegroundColor Cyan + ./win-witr.exe --pid 0 2>&1 | Out-Null + + Write-Host "Testing --pid 4 (System)..." -ForegroundColor Cyan + ./win-witr.exe --pid 4 2>&1 | Out-Null + + Write-Host "Testing --pid with current process ($PID)..." -ForegroundColor Cyan + $output = ./win-witr.exe --pid $PID | Out-String + Write-Host $output + if ($LASTEXITCODE -ne 0) { + (Get-Content test-results.txt) -replace 'PID_TESTS=⏳', 'PID_TESTS=❌' | Set-Content test-results.txt + throw "❌ Current process PID inspection failed" + } + if ($output -notmatch "Process Ancestry") { + (Get-Content test-results.txt) -replace 'PID_TESTS=⏳', 'PID_TESTS=❌' | Set-Content test-results.txt + throw "❌ Output missing 'Process Ancestry'" + } + + Write-Host "Testing --pid with explorer.exe..." -ForegroundColor Cyan + $explorerPid = (Get-Process explorer -ErrorAction SilentlyContinue | Select-Object -First 1).Id + if ($explorerPid) { + Write-Host "Found explorer.exe with PID: $explorerPid" + ./win-witr.exe --pid $explorerPid 2>&1 | Out-Null + } + + (Get-Content test-results.txt) -replace 'PID_TESTS=⏳', 'PID_TESTS=✅' | Set-Content test-results.txt + Write-Host "✅ PID tests passed" -ForegroundColor Green + + # ============ ERROR HANDLING TESTS ============ + - name: Test error handling + id: errors + continue-on-error: true + run: | + $failed = $false + + Write-Host "Testing --pid with non-existent PID (99999)..." -ForegroundColor Cyan + $ErrorActionPreference = 'Continue' + $output = cmd /c "win-witr.exe --pid 99999 2>&1" + if ($LASTEXITCODE -eq 0) { + Write-Host "❌ Should fail with non-existent PID" -ForegroundColor Red + $failed = $true + } else { + Write-Host "✅ Correctly failed with non-existent PID" -ForegroundColor Green + } + + Write-Host "Testing --pid with non-numeric argument..." -ForegroundColor Cyan + $output = cmd /c "win-witr.exe --pid notanumber 2>&1" + if ($LASTEXITCODE -eq 0) { + Write-Host "❌ Should fail with non-numeric PID" -ForegroundColor Red + $failed = $true + } elseif (($output -join " ") -notmatch "not a valid number") { + Write-Host "❌ Missing proper error message for non-numeric PID" -ForegroundColor Red + $failed = $true + } else { + Write-Host "✅ Correctly failed with non-numeric PID" -ForegroundColor Green + } + + Write-Host "Testing --pid without argument..." -ForegroundColor Cyan + $output = cmd /c "win-witr.exe --pid 2>&1" + if ($LASTEXITCODE -eq 0) { + Write-Host "❌ Should fail when --pid has no argument" -ForegroundColor Red + $failed = $true + } elseif (($output -join " ") -notmatch "requires an argument") { + Write-Host "❌ Missing 'requires argument' error" -ForegroundColor Red + $failed = $true + } else { + Write-Host "✅ Correctly failed with missing argument" -ForegroundColor Green + } + + if ($failed) { + (Get-Content test-results.txt) -replace 'ERROR_HANDLING=⏳', 'ERROR_HANDLING=❌' | Set-Content test-results.txt + Write-Host "❌ Error handling tests failed" -ForegroundColor Red + } else { + (Get-Content test-results.txt) -replace 'ERROR_HANDLING=⏳', 'ERROR_HANDLING=✅' | Set-Content test-results.txt + Write-Host "✅ Error handling tests passed" -ForegroundColor Green + } + + # ============ PROCESS NAME LOOKUP TESTS ============ + - name: Test process name lookup + id: lookup + continue-on-error: true + run: | + $failed = $false + + Write-Host "Testing process name lookup for svchost.exe..." -ForegroundColor Cyan + ./win-witr.exe svchost.exe 2>&1 | Out-Null + + Write-Host "Testing process name lookup for explorer.exe..." -ForegroundColor Cyan + ./win-witr.exe explorer.exe 2>&1 | Out-Null + + Write-Host "Testing with non-existent process name..." -ForegroundColor Cyan + $ErrorActionPreference = 'Continue' + $output = cmd /c "win-witr.exe totallyFakeProcess.exe 2>&1" + if ($LASTEXITCODE -eq 0) { + Write-Host "❌ Should fail for non-existent process" -ForegroundColor Red + $failed = $true + } elseif (($output -join " ") -notmatch "Could not find process") { + Write-Host "❌ Missing proper error message for non-existent process" -ForegroundColor Red + $failed = $true + } else { + Write-Host "✅ Correctly failed with non-existent process" -ForegroundColor Green + } + + if ($failed) { + (Get-Content test-results.txt) -replace 'PROCESS_LOOKUP=⏳', 'PROCESS_LOOKUP=❌' | Set-Content test-results.txt + Write-Host "❌ Process lookup tests failed" -ForegroundColor Red + } else { + (Get-Content test-results.txt) -replace 'PROCESS_LOOKUP=⏳', 'PROCESS_LOOKUP=✅' | Set-Content test-results.txt + Write-Host "✅ Process lookup tests passed" -ForegroundColor Green + } + + # ============ OUTPUT FORMAT VALIDATION ============ + - name: Test output validation + id: output + continue-on-error: true + run: | + Write-Host "Validating output format..." -ForegroundColor Cyan + $output = ./win-witr.exe --pid $PID | Out-String + $requiredFields = @("Executable Path", "Process Ancestry", "Started") + foreach ($field in $requiredFields) { + if ($output -notmatch [regex]::Escape($field)) { + (Get-Content test-results.txt) -replace 'OUTPUT_VALIDATION=⏳', 'OUTPUT_VALIDATION=❌' | Set-Content test-results.txt + throw "❌ Output missing required field: $field" + } + } + + Write-Host "Testing ancestry tree formatting..." -ForegroundColor Cyan + if ($output -notmatch "PID") { + (Get-Content test-results.txt) -replace 'OUTPUT_VALIDATION=⏳', 'OUTPUT_VALIDATION=❌' | Set-Content test-results.txt + throw "❌ Ancestry tree not properly formatted" + } + + Write-Host "Testing timestamp format..." -ForegroundColor Cyan + if ($output -notmatch "ago") { + (Get-Content test-results.txt) -replace 'OUTPUT_VALIDATION=⏳', 'OUTPUT_VALIDATION=❌' | Set-Content test-results.txt + throw "❌ Timestamp format incorrect" + } + + (Get-Content test-results.txt) -replace 'OUTPUT_VALIDATION=⏳', 'OUTPUT_VALIDATION=✅' | Set-Content test-results.txt + Write-Host "✅ Output validation passed" -ForegroundColor Green + + # ============ STRESS TESTS ============ + - name: Test stress and performance + id: stress + continue-on-error: true + run: | + Write-Host "Running stress test (50 rapid requests)..." -ForegroundColor Cyan + for ($i = 0; $i -lt 50; $i++) { + ./win-witr.exe --pid $PID | Out-Null + if ($LASTEXITCODE -ne 0) { + (Get-Content test-results.txt) -replace 'STRESS_TESTS=⏳', 'STRESS_TESTS=❌' | Set-Content test-results.txt + throw "❌ Stress test failed at iteration $i" + } + } + + Write-Host "Testing against multiple running processes..." -ForegroundColor Cyan + $processes = Get-Process | Where-Object { $_.Id -ne 0 -and $_.Id -ne 4 } | Select-Object -First 5 + foreach ($proc in $processes) { + Write-Host " Testing PID $($proc.Id) ($($proc.Name))..." + ./win-witr.exe --pid $proc.Id 2>&1 | Out-Null + } + + (Get-Content test-results.txt) -replace 'STRESS_TESTS=⏳', 'STRESS_TESTS=✅' | Set-Content test-results.txt + Write-Host "✅ Stress tests passed (50 iterations)" -ForegroundColor Green + + # ============ UNICODE HANDLING ============ + - name: Test Unicode handling + id: unicode + continue-on-error: true + run: | + Write-Host "Testing Unicode character handling..." -ForegroundColor Cyan + [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 + $output = ./win-witr.exe --pid $PID 2>&1 | Out-String + if ($LASTEXITCODE -ne 0) { + (Get-Content test-results.txt) -replace 'UNICODE=⏳', 'UNICODE=❌' | Set-Content test-results.txt + throw "❌ Unicode handling failed" + } + + (Get-Content test-results.txt) -replace 'UNICODE=⏳', 'UNICODE=✅' | Set-Content test-results.txt + Write-Host "✅ Unicode test passed" -ForegroundColor Green + + # ============ FINAL SUMMARY ============ + - name: Display summary + if: always() + run: | + Write-Host "" + Write-Host "========================================" -ForegroundColor Magenta + Write-Host " 🎉 RUNTIME TESTS COMPLETED! 🎉" -ForegroundColor Magenta + Write-Host "========================================" -ForegroundColor Magenta + Get-Content test-results.txt + Write-Host "" + + # ============ POST PR COMMENT ============ + - name: Post PR comment with results + if: github.event_name == 'pull_request' && always() + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + $results = Get-Content test-results.txt | ConvertFrom-StringData + + $allPassed = $true + foreach ($value in $results.Values) { + if ($value -ne '✅') { + $allPassed = $false + break + } + } + + $emoji = if ($allPassed) { '🎉' } else { '⚠️' } + $status = if ($allPassed) { 'All Tests Passed!' } else { 'Some Tests Failed' } + + $comment = @" + ## $emoji Runtime Tests Report + + **Status:** $status + **Run:** [#${{ github.run_number }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) + + | Test Category | Result | + |---------------|--------| + | 🔨 Build | $($results.BUILD) | + | 📖 Help Commands | $($results.HELP) | + | 🏷️ Version Commands | $($results.VERSION) | + | 🔍 PID Inspection | $($results.PID_TESTS) | + | ⚠️ Error Handling | $($results.ERROR_HANDLING) | + | 🔎 Process Lookup | $($results.PROCESS_LOOKUP) | + | ✏️ Output Validation | $($results.OUTPUT_VALIDATION) | + | 🚀 Stress Tests | $($results.STRESS_TESTS) | + | 🌐 Unicode Handling | $($results.UNICODE) | + + --- + 🤖 Automated test report by GitHub Actions + "@ + + $comment | Out-File -FilePath comment.txt -Encoding utf8 + + gh pr comment ${{ github.event.pull_request.number }} --body-file comment.txt + + Write-Host "✅ Posted comment to PR #${{ github.event.pull_request.number }}" -ForegroundColor Green \ No newline at end of file