Skip to content

Commit c805391

Browse files
author
dilucesr
committed
Add validation scripts for all sample apps
1 parent 8f6fc88 commit c805391

14 files changed

Lines changed: 1121 additions & 0 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ bld/
4040
# Visual Studio 2017 auto generated files
4141
Generated\ Files/
4242

43+
# Local validation logs
44+
**/.validation/
45+
4346
# MSTest test Results
4447
[Tt]est[Rr]esult*/
4548
[Bb]uild[Ll]og.*

AI/mcp-server/validate-sample.ps1

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
param(
2+
[switch]$SkipInstall,
3+
[switch]$SkipTests,
4+
[switch]$SkipBrowser,
5+
[switch]$KeepProcesses,
6+
[switch]$Headed,
7+
[int]$TimeoutSec = 90
8+
)
9+
10+
Set-StrictMode -Version Latest
11+
$ErrorActionPreference = 'Stop'
12+
13+
. (Join-Path $PSScriptRoot '..\..\Tools\powershell\SampleValidation.ps1')
14+
15+
$appRoot = $PSScriptRoot
16+
$envFile = Join-Path $appRoot '.env'
17+
$runtimeHandle = $null
18+
19+
try {
20+
Write-Step 'Preflight checks'
21+
Assert-CommandExists 'node'
22+
Assert-CommandExists 'npm'
23+
24+
if (-not $SkipInstall) {
25+
Write-Step 'Installing dependencies'
26+
Invoke-ExternalCommand -FilePath 'npm' -Arguments @('install') -WorkingDirectory $appRoot
27+
}
28+
29+
Write-Step 'Building MCP server'
30+
Invoke-ExternalCommand -FilePath 'npm' -Arguments @('run', 'build') -WorkingDirectory $appRoot
31+
32+
if ($SkipTests) {
33+
Write-Host 'Skipping tests because -SkipTests was specified.' -ForegroundColor Yellow
34+
}
35+
else {
36+
Write-Host 'No automated test script is defined for this sample.' -ForegroundColor Yellow
37+
}
38+
39+
if (-not (Test-Path $envFile)) {
40+
Write-Host 'Skipping runtime smoke check because .env is missing.' -ForegroundColor Yellow
41+
Write-Host 'Build validation completed.' -ForegroundColor Green
42+
return
43+
}
44+
45+
$environment = Get-DotEnvMap -Path $envFile
46+
if (-not $environment.ContainsKey('PORT')) {
47+
$environment['PORT'] = '3100'
48+
}
49+
50+
Write-Step 'Starting MCP server'
51+
$logPath = New-ValidationLogPath -WorkingDirectory $appRoot -Name 'mcp-server'
52+
$runtimeHandle = Start-LoggedProcess -FilePath 'npm' -Arguments @('run', 'start') -WorkingDirectory $appRoot -LogPath $logPath -Environment $environment
53+
54+
$healthUrl = "http://localhost:$($environment['PORT'])/health"
55+
$healthResponse = Wait-ForHttpEndpoint -Url $healthUrl -TimeoutSec $TimeoutSec -AllowedStatusCodes @(200)
56+
$body = [string]$healthResponse.Content
57+
if ($body -notmatch '"status"\s*:\s*"ok"') {
58+
throw "Health endpoint returned an unexpected response: $body"
59+
}
60+
61+
Write-Host "Runtime smoke check passed at $healthUrl" -ForegroundColor Green
62+
}
63+
finally {
64+
if ($null -ne $runtimeHandle -and -not $KeepProcesses) {
65+
Stop-LoggedProcess -Handle $runtimeHandle
66+
}
67+
}

AI/ocr/validate-sample.ps1

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
param(
2+
[switch]$SkipInstall,
3+
[switch]$SkipTests,
4+
[switch]$SkipBrowser,
5+
[switch]$KeepProcesses,
6+
[switch]$Headed,
7+
[int]$TimeoutSec = 120
8+
)
9+
10+
Set-StrictMode -Version Latest
11+
$ErrorActionPreference = 'Stop'
12+
13+
. (Join-Path $PSScriptRoot '..\..\Tools\powershell\SampleValidation.ps1')
14+
15+
$repoRoot = (Resolve-Path (Join-Path $PSScriptRoot '..\..')).Path
16+
$toolRoot = Join-Path $repoRoot 'Tools\sample-validation'
17+
$appRoot = $PSScriptRoot
18+
$envFile = Join-Path $appRoot '.env'
19+
$handles = @()
20+
21+
try {
22+
Write-Step 'Preflight checks'
23+
Assert-CommandExists 'node'
24+
Assert-CommandExists 'npm'
25+
26+
if (-not $SkipInstall) {
27+
Write-Step 'Installing dependencies'
28+
Invoke-ExternalCommand -FilePath 'npm' -Arguments @('install') -WorkingDirectory $appRoot
29+
}
30+
31+
Write-Step 'Building backend'
32+
Invoke-ExternalCommand -FilePath 'npm' -Arguments @('run', 'build:backend') -WorkingDirectory $appRoot
33+
34+
Write-Step 'Building frontend'
35+
Invoke-ExternalCommand -FilePath 'npm' -Arguments @('run', 'build-cre') -WorkingDirectory $appRoot
36+
37+
if ($SkipTests) {
38+
Write-Host 'Skipping frontend tests because -SkipTests was specified.' -ForegroundColor Yellow
39+
}
40+
else {
41+
Write-Step 'Running frontend tests'
42+
Invoke-ExternalCommand -FilePath 'npm' -Arguments @('run', 'test-cre', '--', '--watchAll=false') -WorkingDirectory $appRoot -Environment @{ CI = 'true' }
43+
}
44+
45+
if (-not (Test-Path $envFile)) {
46+
Write-Host 'Skipping runtime smoke checks because .env is missing.' -ForegroundColor Yellow
47+
Write-Host 'Build and test validation completed.' -ForegroundColor Green
48+
return
49+
}
50+
51+
Write-Step 'Starting backend'
52+
$backendLog = New-ValidationLogPath -WorkingDirectory $appRoot -Name 'ocr-backend'
53+
$backendHandle = Start-LoggedProcess -FilePath 'npm' -Arguments @('run', 'start:backend') -WorkingDirectory $appRoot -LogPath $backendLog -Environment @{ PORT = '3001' }
54+
$handles += $backendHandle
55+
[void](Wait-ForHttpEndpoint -Url 'http://127.0.0.1:3001/api/echo' -TimeoutSec $TimeoutSec -AllowedStatusCodes @(200) -ProcessHandle $backendHandle)
56+
57+
Write-Step 'Starting frontend'
58+
$frontendLog = New-ValidationLogPath -WorkingDirectory $appRoot -Name 'ocr-frontend'
59+
$frontendHandle = Start-LoggedProcess -FilePath 'npm' -Arguments @('run', 'start-cre') -WorkingDirectory $appRoot -LogPath $frontendLog -Environment @{ BROWSER = 'none'; PORT = '3102' }
60+
$handles += $frontendHandle
61+
[void](Wait-ForHttpEndpoint -Url 'http://127.0.0.1:3102' -TimeoutSec $TimeoutSec -AllowedStatusCodes @(200) -ProcessHandle $frontendHandle)
62+
63+
if ($SkipBrowser) {
64+
Write-Host 'Skipping browser smoke because -SkipBrowser was specified.' -ForegroundColor Yellow
65+
}
66+
else {
67+
Write-Step 'Running browser smoke'
68+
Invoke-BrowserSmoke -ToolRoot $toolRoot -Url 'http://127.0.0.1:3102' -SkipInstall:$SkipInstall -Headed:$Headed -TimeoutSec $TimeoutSec -ExpectSelector '#root'
69+
}
70+
71+
Write-Host 'OCR sample validation completed.' -ForegroundColor Green
72+
}
73+
finally {
74+
if (-not $KeepProcesses) {
75+
foreach ($handle in ($handles | Sort-Object -Descending -Property LogPath)) {
76+
Stop-LoggedProcess -Handle $handle
77+
}
78+
}
79+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
param(
2+
[switch]$SkipInstall,
3+
[switch]$SkipTests,
4+
[switch]$SkipBrowser,
5+
[switch]$KeepProcesses,
6+
[switch]$Headed,
7+
[int]$TimeoutSec = 120
8+
)
9+
10+
Set-StrictMode -Version Latest
11+
$ErrorActionPreference = 'Stop'
12+
13+
. (Join-Path $PSScriptRoot '..\..\Tools\powershell\SampleValidation.ps1')
14+
15+
$appRoot = $PSScriptRoot
16+
$appSettingsPath = Join-Path $appRoot 'appsettings.json'
17+
$runtimeHandle = $null
18+
19+
try {
20+
Write-Step 'Preflight checks'
21+
Assert-CommandExists 'dotnet'
22+
23+
Write-Step 'Restoring packages'
24+
Invoke-ExternalCommand -FilePath 'dotnet' -Arguments @('restore') -WorkingDirectory $appRoot
25+
26+
Write-Step 'Building app'
27+
Invoke-ExternalCommand -FilePath 'dotnet' -Arguments @('build') -WorkingDirectory $appRoot
28+
29+
Write-Host 'No automated test project is defined for this sample.' -ForegroundColor Yellow
30+
31+
if (-not (Test-Path $appSettingsPath)) {
32+
Write-Host 'Skipping runtime smoke check because appsettings.json is missing.' -ForegroundColor Yellow
33+
Write-Host 'Build validation completed.' -ForegroundColor Green
34+
return
35+
}
36+
37+
Write-Step 'Starting web app'
38+
$logPath = New-ValidationLogPath -WorkingDirectory $appRoot -Name 'aspnet-webservice'
39+
$runtimeHandle = Start-LoggedProcess -FilePath 'dotnet' -Arguments @('run', '--urls', 'http://127.0.0.1:5080') -WorkingDirectory $appRoot -LogPath $logPath
40+
[void](Wait-ForHttpEndpoint -Url 'http://127.0.0.1:5080' -TimeoutSec $TimeoutSec -AllowedStatusCodes @(200, 302) -ProcessHandle $runtimeHandle)
41+
42+
Write-Host 'ASP.NET sample validation completed.' -ForegroundColor Green
43+
}
44+
finally {
45+
if ($null -ne $runtimeHandle -and -not $KeepProcesses) {
46+
Stop-LoggedProcess -Handle $runtimeHandle
47+
}
48+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
param(
2+
[switch]$SkipInstall,
3+
[switch]$SkipTests,
4+
[switch]$SkipBrowser,
5+
[switch]$KeepProcesses,
6+
[switch]$Headed,
7+
[int]$TimeoutSec = 120
8+
)
9+
10+
Set-StrictMode -Version Latest
11+
$ErrorActionPreference = 'Stop'
12+
13+
. (Join-Path $PSScriptRoot '..\..\Tools\powershell\SampleValidation.ps1')
14+
15+
$repoRoot = (Resolve-Path (Join-Path $PSScriptRoot '..\..')).Path
16+
$toolRoot = Join-Path $repoRoot 'Tools\sample-validation'
17+
$appRoot = $PSScriptRoot
18+
$clientRoot = Join-Path $appRoot 'packages\client-app'
19+
$functionsRoot = Join-Path $appRoot 'packages\azure-functions'
20+
$clientEnvPath = Join-Path $clientRoot '.env'
21+
$localSettingsPath = Join-Path $functionsRoot 'local.settings.json'
22+
$handles = @()
23+
24+
try {
25+
Write-Step 'Preflight checks'
26+
Assert-CommandExists 'node'
27+
Assert-CommandExists 'npm'
28+
29+
if (-not $SkipInstall) {
30+
Write-Step 'Installing root dependencies'
31+
Invoke-ExternalCommand -FilePath 'npm' -Arguments @('install') -WorkingDirectory $appRoot
32+
33+
Write-Step 'Installing client-app dependencies'
34+
Invoke-ExternalCommand -FilePath 'npm' -Arguments @('install') -WorkingDirectory $clientRoot
35+
36+
Write-Step 'Installing azure-functions dependencies'
37+
Invoke-ExternalCommand -FilePath 'npm' -Arguments @('install') -WorkingDirectory $functionsRoot
38+
}
39+
40+
Write-Step 'Building client-app'
41+
Invoke-ExternalCommand -FilePath 'npm' -Arguments @('run', 'build') -WorkingDirectory $clientRoot
42+
43+
if ($SkipTests) {
44+
Write-Host 'Skipping client-app tests because -SkipTests was specified.' -ForegroundColor Yellow
45+
}
46+
else {
47+
Write-Step 'Running client-app tests'
48+
Invoke-ExternalCommand -FilePath 'npm' -Arguments @('run', 'test', '--', '--watchAll=false') -WorkingDirectory $clientRoot -Environment @{ CI = 'true' }
49+
}
50+
51+
if (Test-Path $localSettingsPath) {
52+
Assert-CommandExists 'func'
53+
Write-Step 'Starting Azure Functions host'
54+
$backendLog = New-ValidationLogPath -WorkingDirectory $appRoot -Name 'react-azure-functions-api'
55+
$backendHandle = Start-LoggedProcess -FilePath 'npm' -Arguments @('run', 'start') -WorkingDirectory $functionsRoot -LogPath $backendLog
56+
$handles += $backendHandle
57+
[void](Wait-ForHttpEndpoint -Url 'http://127.0.0.1:7071/api/ListContainers' -TimeoutSec $TimeoutSec -AllowedStatusCodes @(200, 401) -ProcessHandle $backendHandle)
58+
}
59+
else {
60+
Write-Host 'Skipping Azure Functions runtime smoke because local.settings.json is missing.' -ForegroundColor Yellow
61+
}
62+
63+
if (Test-Path $clientEnvPath) {
64+
Write-Step 'Starting client-app'
65+
$frontendLog = New-ValidationLogPath -WorkingDirectory $appRoot -Name 'react-azure-functions-client'
66+
$frontendHandle = Start-LoggedProcess -FilePath 'npm' -Arguments @('run', 'start') -WorkingDirectory $clientRoot -LogPath $frontendLog -Environment @{ BROWSER = 'none'; PORT = '3000' }
67+
$handles += $frontendHandle
68+
[void](Wait-ForHttpEndpoint -Url 'http://127.0.0.1:3000' -TimeoutSec $TimeoutSec -AllowedStatusCodes @(200) -ProcessHandle $frontendHandle)
69+
70+
if ($SkipBrowser) {
71+
Write-Host 'Skipping browser smoke because -SkipBrowser was specified.' -ForegroundColor Yellow
72+
}
73+
else {
74+
Write-Step 'Running browser smoke'
75+
Invoke-BrowserSmoke -ToolRoot $toolRoot -Url 'http://127.0.0.1:3000' -SkipInstall:$SkipInstall -Headed:$Headed -TimeoutSec $TimeoutSec -ExpectSelector '#root'
76+
}
77+
}
78+
else {
79+
Write-Host 'Skipping client-app runtime smoke because .env is missing.' -ForegroundColor Yellow
80+
}
81+
82+
Write-Host 'React Azure Functions sample validation completed.' -ForegroundColor Green
83+
}
84+
finally {
85+
if (-not $KeepProcesses) {
86+
foreach ($handle in ($handles | Sort-Object -Descending -Property LogPath)) {
87+
Stop-LoggedProcess -Handle $handle
88+
}
89+
}
90+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
param(
2+
[switch]$SkipInstall,
3+
[switch]$SkipTests,
4+
[switch]$SkipBrowser,
5+
[switch]$KeepProcesses,
6+
[switch]$Headed,
7+
[int]$TimeoutSec = 120
8+
)
9+
10+
Set-StrictMode -Version Latest
11+
$ErrorActionPreference = 'Stop'
12+
13+
. (Join-Path $PSScriptRoot '..\..\Tools\powershell\SampleValidation.ps1')
14+
15+
$repoRoot = (Resolve-Path (Join-Path $PSScriptRoot '..\..')).Path
16+
$toolRoot = Join-Path $repoRoot 'Tools\sample-validation'
17+
$appRoot = $PSScriptRoot
18+
$functionApiRoot = Join-Path $appRoot 'function-api'
19+
$clientRoot = Join-Path $appRoot 'react-client'
20+
$localSettingsPath = Join-Path $functionApiRoot 'local.settings.json'
21+
$clientEnvPath = Join-Path $clientRoot '.env'
22+
$handles = @()
23+
24+
try {
25+
Write-Step 'Preflight checks'
26+
Assert-CommandExists 'node'
27+
Assert-CommandExists 'npm'
28+
29+
if (-not $SkipInstall) {
30+
Write-Step 'Installing root dependencies'
31+
Invoke-ExternalCommand -FilePath 'npm' -Arguments @('install') -WorkingDirectory $appRoot
32+
33+
Write-Step 'Installing function-api dependencies'
34+
Invoke-ExternalCommand -FilePath 'npm' -Arguments @('install') -WorkingDirectory $functionApiRoot
35+
36+
Write-Step 'Installing react-client dependencies'
37+
Invoke-ExternalCommand -FilePath 'npm' -Arguments @('install') -WorkingDirectory $clientRoot
38+
}
39+
40+
Write-Step 'Building function-api'
41+
Invoke-ExternalCommand -FilePath 'npm' -Arguments @('run', 'build') -WorkingDirectory $functionApiRoot
42+
43+
Write-Step 'Building react-client'
44+
Invoke-ExternalCommand -FilePath 'npm' -Arguments @('run', 'build') -WorkingDirectory $clientRoot
45+
46+
if ($SkipTests) {
47+
Write-Host 'Skipping react-client tests because -SkipTests was specified.' -ForegroundColor Yellow
48+
}
49+
else {
50+
Write-Step 'Running react-client tests'
51+
Invoke-ExternalCommand -FilePath 'npm' -Arguments @('run', 'test', '--', '--watchAll=false') -WorkingDirectory $clientRoot -Environment @{ CI = 'true' }
52+
}
53+
54+
if (Test-Path $localSettingsPath) {
55+
Assert-CommandExists 'func'
56+
Write-Step 'Starting function-api host'
57+
$backendLog = New-ValidationLogPath -WorkingDirectory $appRoot -Name 'typescript-react-api'
58+
$backendHandle = Start-LoggedProcess -FilePath 'npm' -Arguments @('run', 'start') -WorkingDirectory $functionApiRoot -LogPath $backendLog
59+
$handles += $backendHandle
60+
[void](Wait-ForHttpEndpoint -Url 'http://127.0.0.1:7072/api/containers' -TimeoutSec $TimeoutSec -AllowedStatusCodes @(200, 401) -ProcessHandle $backendHandle)
61+
}
62+
else {
63+
Write-Host 'Skipping function-api runtime smoke because local.settings.json is missing.' -ForegroundColor Yellow
64+
}
65+
66+
if (Test-Path $clientEnvPath) {
67+
$clientEnv = Get-DotEnvMap -Path $clientEnvPath
68+
$clientPort = if ($clientEnv.ContainsKey('PORT')) { $clientEnv['PORT'] } else { '8080' }
69+
70+
Write-Step 'Starting react-client'
71+
$frontendLog = New-ValidationLogPath -WorkingDirectory $appRoot -Name 'typescript-react-client'
72+
$frontendHandle = Start-LoggedProcess -FilePath 'npm' -Arguments @('run', 'start') -WorkingDirectory $clientRoot -LogPath $frontendLog -Environment @{ BROWSER = 'none' }
73+
$handles += $frontendHandle
74+
[void](Wait-ForHttpEndpoint -Url "http://127.0.0.1:$clientPort" -TimeoutSec $TimeoutSec -AllowedStatusCodes @(200) -ProcessHandle $frontendHandle)
75+
76+
if ($SkipBrowser) {
77+
Write-Host 'Skipping browser smoke because -SkipBrowser was specified.' -ForegroundColor Yellow
78+
}
79+
else {
80+
Write-Step 'Running browser smoke'
81+
Invoke-BrowserSmoke -ToolRoot $toolRoot -Url "http://127.0.0.1:$clientPort" -SkipInstall:$SkipInstall -Headed:$Headed -TimeoutSec $TimeoutSec -ExpectSelector '#root'
82+
}
83+
}
84+
else {
85+
Write-Host 'Skipping react-client runtime smoke because .env is missing.' -ForegroundColor Yellow
86+
}
87+
88+
Write-Host 'TypeScript React sample validation completed.' -ForegroundColor Green
89+
}
90+
finally {
91+
if (-not $KeepProcesses) {
92+
foreach ($handle in ($handles | Sort-Object -Descending -Property LogPath)) {
93+
Stop-LoggedProcess -Handle $handle
94+
}
95+
}
96+
}

0 commit comments

Comments
 (0)