Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 63 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ jobs:
dotnet: ${{ steps.classify.outputs.dotnet }}
aep: ${{ steps.classify.outputs.aep }}
container: ${{ steps.classify.outputs.container }}
storage: ${{ steps.classify.outputs.storage }}
steps:
- name: Check out repository
uses: actions/checkout@v7
Expand Down Expand Up @@ -62,15 +63,20 @@ jobs:
$container = $runEverything -or @($changedFiles | Where-Object {
$_ -match '^(src/|aep/src/|deploy/|Dockerfile$|\.dockerignore$|global\.json$|Agentstration\.slnx$|Directory\.(Build|Packages)\.(props|targets)$|\.github/workflows/ci\.yml$)'
}).Count -gt 0
$storage = $runEverything -or @($changedFiles | Where-Object {
$_ -match '^(src/Agentstration\.(Application|Flow|Infrastructure|Management|Runtime|Web|Work)|tests/Agentstration\.(Application|Performance|Web)\.Tests/|Agentstration\.Tests\.Performance\.slnx$|Directory\.(Build|Packages)\.(props|targets)$|global\.json$|\.github/workflows/(ci|storage-performance)\.yml$)'
}).Count -gt 0

"dotnet=$($dotnet.ToString().ToLowerInvariant())" >> $env:GITHUB_OUTPUT
"aep=$($aep.ToString().ToLowerInvariant())" >> $env:GITHUB_OUTPUT
"container=$($container.ToString().ToLowerInvariant())" >> $env:GITHUB_OUTPUT
"storage=$($storage.ToString().ToLowerInvariant())" >> $env:GITHUB_OUTPUT

Write-Host "Changed files: $($changedFiles.Count)"
Write-Host "Run .NET validation: $dotnet"
Write-Host "Run complete AEP validation: $aep"
Write-Host "Build container: $container"
Write-Host "Run storage smoke: $storage"

windows-host-lifecycle:
name: windows-host-lifecycle
Expand All @@ -97,7 +103,7 @@ jobs:
- name: Build web tests
run: dotnet build tests/Agentstration.Web.Tests/Agentstration.Web.Tests.csproj --configuration Release --no-restore
- name: Verify Windows host lifecycle
run: dotnet tests/Agentstration.Web.Tests/bin/Release/net10.0/Agentstration.Web.Tests.dll --filter "FullyQualifiedName~QuartzHostLifecycleTests|FullyQualifiedName~StartupDoesNotCreateLegacyDataJson" --progress off
run: dotnet tests/Agentstration.Web.Tests/bin/Release/net10.0/Agentstration.Web.Tests.dll --filter "FullyQualifiedName~QuartzHostLifecycleTests|FullyQualifiedName~StartupDoesNotCreateLegacyDataJson" --minimum-expected-tests 2 --progress off

build-and-test:
name: build-and-test
Expand Down Expand Up @@ -139,9 +145,44 @@ jobs:
- name: Build Agentstration
if: needs.changes.outputs.dotnet == 'true'
run: dotnet build Agentstration.slnx --configuration Release --no-restore
- name: Test Agentstration
- name: Test fast lane
if: needs.changes.outputs.dotnet == 'true'
run: dotnet test --solution Agentstration.Tests.Fast.slnx --configuration Release --no-build --minimum-expected-tests 139 --max-parallel-test-modules 4
- name: Test integration lane
if: needs.changes.outputs.dotnet == 'true'
run: dotnet test Agentstration.slnx --configuration Release --no-build
run: dotnet test --solution Agentstration.Tests.Integration.slnx --configuration Release --no-build --minimum-expected-tests 692 --max-parallel-test-modules 2
- name: Capture hosted module diagnostics
if: needs.changes.outputs.dotnet == 'true'
shell: pwsh
run: |
@(
'## Hosted test module diagnostics',
'',
'| Module | Tests | Duration (s) | Peak working set (MiB) | Peak private memory (MiB) | Aggregate dotnet working set (MiB) | Status |',
'| --- | ---: | ---: | ---: | ---: | ---: | --- |'
) | Add-Content -LiteralPath $env:GITHUB_STEP_SUMMARY -Encoding utf8
$modules = @(
@{ Name = 'Agentstration.Management.Api.Tests'; Tests = 43; Warning = 900; Failure = 1024 },
@{ Name = 'Agentstration.Management.Bootstrap.Tests'; Tests = 23; Warning = 500; Failure = 700 },
@{ Name = 'Agentstration.Management.Security.Tests'; Tests = 38; Warning = 800; Failure = 1024 },
@{ Name = 'Agentstration.Management.Aep.Tests'; Tests = 11; Warning = 450; Failure = 700 },
@{ Name = 'Agentstration.Management.Sources.Tests'; Tests = 93; Warning = 550; Failure = 900 }
)
foreach ($module in $modules) {
./scripts/ci/run-test-module-with-diagnostics.ps1 `
-AssemblyPath "tests/$($module.Name)/bin/Release/net10.0/$($module.Name).dll" `
-ReportPath "artifacts/test-diagnostics/$($module.Name).json" `
-MinimumExpectedTests $module.Tests `
-WarningWorkingSetMiB $module.Warning `
-FailureWorkingSetMiB $module.Failure
}
- name: Upload hosted module diagnostics
if: always() && needs.changes.outputs.dotnet == 'true'
uses: actions/upload-artifact@v6
with:
name: hosted-test-module-diagnostics
path: artifacts/test-diagnostics/*.json
if-no-files-found: warn
- name: Smoke-test Source Registry tool package
if: needs.changes.outputs.dotnet == 'true'
shell: pwsh
Expand All @@ -151,11 +192,14 @@ jobs:
run: dotnet build aep/Aep.slnx --configuration Release --no-restore
- name: Test complete AEP SDK
if: needs.changes.outputs.dotnet == 'true' && needs.changes.outputs.aep == 'true'
run: dotnet test aep/Aep.slnx --configuration Release --no-build
working-directory: aep
run: dotnet test --solution Aep.slnx --configuration Release --no-build --minimum-expected-tests 33 --max-parallel-test-modules 2

postgresql-storage:
name: postgresql-storage
runs-on: ubuntu-latest
needs: changes
if: needs.changes.outputs.storage == 'true'
timeout-minutes: 20
services:
postgres:
Expand All @@ -181,20 +225,31 @@ jobs:
with:
global-json-file: global.json
- name: Restore PostgreSQL integration tests
run: dotnet restore tests/Agentstration.Web.Tests/Agentstration.Web.Tests.csproj -p:NuGetAudit=true -p:NuGetAuditMode=all
run: |
dotnet restore tests/Agentstration.Web.Tests/Agentstration.Web.Tests.csproj -p:NuGetAudit=true -p:NuGetAuditMode=all
dotnet restore tests/Agentstration.Performance.Tests/Agentstration.Performance.Tests.csproj -p:NuGetAudit=true -p:NuGetAuditMode=all
- name: Build PostgreSQL integration tests
run: dotnet build tests/Agentstration.Web.Tests/Agentstration.Web.Tests.csproj --configuration Release --no-restore
run: |
dotnet build tests/Agentstration.Web.Tests/Agentstration.Web.Tests.csproj --configuration Release --no-restore
dotnet build tests/Agentstration.Performance.Tests/Agentstration.Performance.Tests.csproj --configuration Release --no-restore
- name: Run PostgreSQL migration and restart test
run: dotnet tests/Agentstration.Web.Tests/bin/Release/net10.0/Agentstration.Web.Tests.dll --filter "Name=EmptyDatabaseMigratesAndRemainsReadyAfterRestart" --progress off
run: dotnet tests/Agentstration.Web.Tests/bin/Release/net10.0/Agentstration.Web.Tests.dll --filter "Name=EmptyDatabaseMigratesAndRemainsReadyAfterRestart" --minimum-expected-tests 1 --progress off
- name: Run PostgreSQL storage concurrency benchmark
env:
AGENTSTRATION_STORAGE_BENCHMARK_PROVIDER: PostgreSql
AGENTSTRATION_STORAGE_BENCHMARK_OPERATIONS: 40
AGENTSTRATION_STORAGE_BENCHMARK_CONCURRENCY: 8
AGENTSTRATION_STORAGE_BENCHMARK_REPORT: ${{ runner.temp }}/agentstration-storage-benchmark-postgresql.json
run: |
dotnet tests/Agentstration.Web.Tests/bin/Release/net10.0/Agentstration.Web.Tests.dll --filter "Name=ReportsConcurrentRelationalWriteMetrics" --progress off
dotnet tests/Agentstration.Performance.Tests/bin/Release/net10.0/Agentstration.Performance.Tests.dll --filter "Name=ReportsConcurrentRelationalWriteMetrics" --minimum-expected-tests 1 --progress off
cat "$AGENTSTRATION_STORAGE_BENCHMARK_REPORT"
- name: Upload PostgreSQL storage smoke report
if: always()
uses: actions/upload-artifact@v6
with:
name: storage-benchmark-postgresql-smoke
path: ${{ runner.temp }}/agentstration-storage-benchmark-postgresql.json
if-no-files-found: error

container:
name: container
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/release-source-registry-tool.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,10 @@ jobs:
-p:Version=${{ steps.version.outputs.package-version }}
- name: Test tool
run: >-
dotnet test tests/Agentstration.Tools.SourceRegistry.Tests/Agentstration.Tools.SourceRegistry.Tests.csproj
dotnet test --project tests/Agentstration.Tools.SourceRegistry.Tests/Agentstration.Tools.SourceRegistry.Tests.csproj
--configuration Release
--no-build
--minimum-expected-tests 1
-p:Version=${{ steps.version.outputs.package-version }}
- name: Smoke-test package
shell: pwsh
Expand Down
9 changes: 6 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,17 @@ jobs:
run: dotnet restore Agentstration.slnx -p:NuGetAudit=true -p:NuGetAuditMode=all
- name: Build
run: dotnet build Agentstration.slnx --configuration Release --no-restore
- name: Test
run: dotnet test Agentstration.slnx --configuration Release --no-build
- name: Test fast lane
run: dotnet test --solution Agentstration.Tests.Fast.slnx --configuration Release --no-build --minimum-expected-tests 139 --max-parallel-test-modules 4
- name: Test integration lane
run: dotnet test --solution Agentstration.Tests.Integration.slnx --configuration Release --no-build --minimum-expected-tests 692 --max-parallel-test-modules 2
- name: Restore autonomous AEP SDK
run: dotnet restore aep/Aep.slnx -p:NuGetAudit=true -p:NuGetAuditMode=all
- name: Build autonomous AEP SDK
run: dotnet build aep/Aep.slnx --configuration Release --no-restore
- name: Test autonomous AEP SDK
run: dotnet test aep/Aep.slnx --configuration Release --no-build
working-directory: aep
run: dotnet test --solution Aep.slnx --configuration Release --no-build --minimum-expected-tests 33 --max-parallel-test-modules 2
- name: Publish framework-dependent applications
shell: pwsh
run: |
Expand Down
68 changes: 68 additions & 0 deletions .github/workflows/storage-performance.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: Storage performance

on:
workflow_dispatch:
schedule:
- cron: "23 3 * * 1"

permissions:
contents: read

concurrency:
group: storage-performance-${{ github.ref }}
cancel-in-progress: false

jobs:
benchmark:
name: ${{ matrix.provider }} full workload
runs-on: ubuntu-latest
timeout-minutes: 30
strategy:
fail-fast: false
max-parallel: 1
matrix:
provider: [Sqlite, PostgreSql]
services:
postgres:
image: postgres:17
env:
POSTGRES_DB: agentstration
POSTGRES_USER: agentstration
POSTGRES_PASSWORD: agentstration-ci-only
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U agentstration -d agentstration"
--health-interval 5s
--health-timeout 5s
--health-retries 12
env:
AGENTSTRATION_TEST_POSTGRES: Host=127.0.0.1;Port=5432;Database=agentstration;Username=agentstration;Password=agentstration-ci-only
AGENTSTRATION_STORAGE_BENCHMARK_PROVIDER: ${{ matrix.provider }}
AGENTSTRATION_STORAGE_BENCHMARK_OPERATIONS: 500
AGENTSTRATION_STORAGE_BENCHMARK_CONCURRENCY: 16
AGENTSTRATION_STORAGE_BENCHMARK_REPORT: ${{ runner.temp }}/storage-benchmark-${{ matrix.provider }}.json
steps:
- name: Check out repository
uses: actions/checkout@v7
- name: Set up .NET
uses: actions/setup-dotnet@v6
with:
global-json-file: global.json
- name: Restore performance tests
run: dotnet restore tests/Agentstration.Performance.Tests/Agentstration.Performance.Tests.csproj -p:NuGetAudit=true -p:NuGetAuditMode=all
- name: Build performance tests
run: dotnet build tests/Agentstration.Performance.Tests/Agentstration.Performance.Tests.csproj --configuration Release --no-restore
- name: Run full storage workload
run: dotnet tests/Agentstration.Performance.Tests/bin/Release/net10.0/Agentstration.Performance.Tests.dll --filter "Name=ReportsConcurrentRelationalWriteMetrics" --minimum-expected-tests 1 --progress off
- name: Display report
if: always()
shell: pwsh
run: if (Test-Path -LiteralPath $env:AGENTSTRATION_STORAGE_BENCHMARK_REPORT) { Get-Content -LiteralPath $env:AGENTSTRATION_STORAGE_BENCHMARK_REPORT }
- name: Upload storage report
if: always()
uses: actions/upload-artifact@v6
with:
name: storage-benchmark-${{ matrix.provider }}-full
path: ${{ runner.temp }}/storage-benchmark-${{ matrix.provider }}.json
if-no-files-found: error
14 changes: 11 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,14 @@ src/
tests/
Agentstration.Application.Tests/
Agentstration.ArchitectureTests/
Agentstration.Management.Tests/
Agentstration.Management.Core.Tests/
Agentstration.Management.Storage.Tests/
Agentstration.Management.Sources.Tests/
Agentstration.Management.Api.Tests/
Agentstration.Management.Bootstrap.Tests/
Agentstration.Management.Security.Tests/
Agentstration.Management.Aep.Tests/
Agentstration.Performance.Tests/
docs/
architecture.md
decisions/
Expand Down Expand Up @@ -180,10 +187,11 @@ Run from the repository root:
```powershell
dotnet restore Agentstration.slnx
dotnet build Agentstration.slnx --configuration Release --no-restore
dotnet test Agentstration.slnx --configuration Release --no-build
dotnet test --solution Agentstration.Tests.Fast.slnx --configuration Release --no-build --minimum-expected-tests 139 --max-parallel-test-modules 4
dotnet test --solution Agentstration.Tests.Integration.slnx --configuration Release --no-build --minimum-expected-tests 692 --max-parallel-test-modules 2
```

For a focused iteration, run the affected test project first, then run the full build and test suite before handoff. Do not suppress warnings or disable analyzers to make a change pass.
The two test solutions together form the required deterministic, offline functional suite. Performance and live-provider workloads are explicit opt-ins documented in `docs/contributing/testing.md`. For a focused iteration, run the affected test project first, then run both functional lanes before handoff. Do not suppress warnings or disable analyzers to make a change pass.

To smoke-test the executable default with the Development bootstrap when startup behavior changes:

Expand Down
10 changes: 10 additions & 0 deletions Agentstration.Tests.Fast.slnx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Solution>
<Folder Name="/tests/fast/">
<Project Path="tests/Agentstration.ArchitectureTests/Agentstration.ArchitectureTests.csproj" />
<Project Path="tests/Agentstration.Management.Core.Tests/Agentstration.Management.Core.Tests.csproj" />
<Project Path="tests/Agentstration.Tools.SourceRegistry.Tests/Agentstration.Tools.SourceRegistry.Tests.csproj" />
<Project Path="tests/Agentstration.Web.Components.Tests/Agentstration.Web.Components.Tests.csproj" />
<Project Path="tests/Agentstration.Web.FlowDesigner.Tests/Agentstration.Web.FlowDesigner.Tests.csproj" />
<Project Path="tests/Agentstration.Workplace.Components.Tests/Agentstration.Workplace.Components.Tests.csproj" />
</Folder>
</Solution>
17 changes: 17 additions & 0 deletions Agentstration.Tests.Integration.slnx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<Solution>
<Folder Name="/tests/integration/">
<Project Path="tests/Agentstration.Application.Tests/Agentstration.Application.Tests.csproj" />
<Project Path="tests/Agentstration.Management.Storage.Tests/Agentstration.Management.Storage.Tests.csproj" />
<Project Path="tests/Agentstration.Management.Sources.Tests/Agentstration.Management.Sources.Tests.csproj" />
<Project Path="tests/Agentstration.Management.Api.Tests/Agentstration.Management.Api.Tests.csproj" />
<Project Path="tests/Agentstration.Management.Bootstrap.Tests/Agentstration.Management.Bootstrap.Tests.csproj" />
<Project Path="tests/Agentstration.Management.Security.Tests/Agentstration.Management.Security.Tests.csproj" />
<Project Path="tests/Agentstration.Management.Aep.Tests/Agentstration.Management.Aep.Tests.csproj" />
<Project Path="tests/Agentstration.ModelProviders.Tests/Agentstration.ModelProviders.Tests.csproj" />
<Project Path="tests/Agentstration.Runtime.Tests/Agentstration.Runtime.Tests.csproj" />
<Project Path="tests/Agentstration.SourceProviders.Git.Tests/Agentstration.SourceProviders.Git.Tests.csproj" />
<Project Path="tests/Agentstration.Web.Tests/Agentstration.Web.Tests.csproj" />
<Project Path="tests/Agentstration.Work.Api.Tests/Agentstration.Work.Api.Tests.csproj" />
<Project Path="tests/Agentstration.Workplace.Web.Tests/Agentstration.Workplace.Web.Tests.csproj" />
</Folder>
</Solution>
5 changes: 5 additions & 0 deletions Agentstration.Tests.Performance.slnx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<Solution>
<Folder Name="/tests/performance/">
<Project Path="tests/Agentstration.Performance.Tests/Agentstration.Performance.Tests.csproj" />
</Folder>
</Solution>
9 changes: 8 additions & 1 deletion Agentstration.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,15 @@
<Folder Name="/tests/">
<Project Path="tests/Agentstration.Application.Tests/Agentstration.Application.Tests.csproj" />
<Project Path="tests/Agentstration.ArchitectureTests/Agentstration.ArchitectureTests.csproj" />
<Project Path="tests/Agentstration.Management.Tests/Agentstration.Management.Tests.csproj" />
<Project Path="tests/Agentstration.Management.Core.Tests/Agentstration.Management.Core.Tests.csproj" />
<Project Path="tests/Agentstration.Management.Storage.Tests/Agentstration.Management.Storage.Tests.csproj" />
<Project Path="tests/Agentstration.Management.Sources.Tests/Agentstration.Management.Sources.Tests.csproj" />
<Project Path="tests/Agentstration.Management.Api.Tests/Agentstration.Management.Api.Tests.csproj" />
<Project Path="tests/Agentstration.Management.Bootstrap.Tests/Agentstration.Management.Bootstrap.Tests.csproj" />
<Project Path="tests/Agentstration.Management.Security.Tests/Agentstration.Management.Security.Tests.csproj" />
<Project Path="tests/Agentstration.Management.Aep.Tests/Agentstration.Management.Aep.Tests.csproj" />
<Project Path="tests/Agentstration.ModelProviders.Tests/Agentstration.ModelProviders.Tests.csproj" />
<Project Path="tests/Agentstration.Performance.Tests/Agentstration.Performance.Tests.csproj" />
<Project Path="tests/Agentstration.SourceProviders.Git.Tests/Agentstration.SourceProviders.Git.Tests.csproj" />
<Project Path="tests/Agentstration.Tools.SourceRegistry.Tests/Agentstration.Tools.SourceRegistry.Tests.csproj" />
<Project Path="tests/Agentstration.Runtime.Tests/Agentstration.Runtime.Tests.csproj" />
Expand Down
5 changes: 3 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ Use MSTest for behavior changes and keep the default test suite deterministic an
```powershell
dotnet restore Agentstration.slnx
dotnet build Agentstration.slnx --configuration Release --no-restore
dotnet test Agentstration.slnx --configuration Release --no-build
dotnet test --solution Agentstration.Tests.Fast.slnx --configuration Release --no-build --minimum-expected-tests 1
dotnet test --solution Agentstration.Tests.Integration.slnx --configuration Release --no-build --minimum-expected-tests 1
./scripts/ci/verify-dotnet-format.ps1 -BaseRevision "origin/main"
```

The format script checks changed C# and Razor files in both solutions. The autonomous AEP subtree has a larger standalone solution; when it changes, also restore, build, and test `aep/Aep.slnx`.
The fast and integration lanes together cover the complete required functional suite. Performance and live-provider workloads are explicit opt-ins described in the [test lane guide](docs/contributing/testing.md). The format script checks changed C# and Razor files in both product solutions. The autonomous AEP subtree has a larger standalone solution; when it changes, also restore, build, and test `aep/Aep.slnx`.

If documentation changed, run:

Expand Down
Loading
Loading