diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index fec32a6db..bd3318b99 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -6,6 +6,10 @@ on: - docs/** - '*.md' +concurrency: + group: pr-build-and-test-${{ github.ref }} + cancel-in-progress: true + jobs: event_file: name: "Event File" @@ -17,16 +21,15 @@ jobs: name: Event File path: ${{ github.event_path }} - build-and-test: - name: "Build and test" + unit-tests: + # Container-less test projects. Run across all target frameworks — these exercise the + # library code paths, so multi-TFM coverage matters here. No Docker needed. + name: "Build and test core (${{ matrix.dotnet-version }})" runs-on: ubuntu-latest -# runs-on: [ self-hosted, type-cpx52, setup-docker, volume-cache-50GB ] strategy: + fail-fast: false matrix: dotnet-version: [ '8.0', '9.0', '10.0' ] -# env: -# NUGET_PACKAGES: "/mnt/cache/.nuget/packages" -# DOTNET_INSTALL_DIR: "/mnt/cache/.dotnet" steps: - name: Checkout @@ -40,23 +43,98 @@ jobs: 9.0.x 10.0.x - - name: Login to Docker Hub - if: ${{ github.event.pull_request.head.repo.fork == false }} - uses: docker/login-action@v4 + name: Run tests + run: | + set -euo pipefail + projects=" + src/Core/test/Eventuous.Tests/Eventuous.Tests.csproj + src/Core/test/Eventuous.Tests.Application/Eventuous.Tests.Application.csproj + src/Core/test/Eventuous.Tests.Subscriptions/Eventuous.Tests.Subscriptions.csproj + src/Core/test/Eventuous.Tests.Shared.Analyzers/Eventuous.Tests.Shared.Analyzers.csproj + src/Extensions/test/Eventuous.Tests.DependencyInjection/Eventuous.Tests.DependencyInjection.csproj + src/Extensions/test/Eventuous.Tests.Extensions.AspNetCore/Eventuous.Tests.Extensions.AspNetCore.csproj + src/Extensions/test/Eventuous.Tests.Extensions.AspNetCore.Analyzers/Eventuous.Tests.Extensions.AspNetCore.Analyzers.csproj + src/Gateway/test/Eventuous.Tests.Gateway/Eventuous.Tests.Gateway.csproj + src/Experimental/test/Eventuous.Tests.Spyglass/Eventuous.Tests.Spyglass.csproj + src/Experimental/test/Eventuous.Tests.Spyglass.Generators/Eventuous.Tests.Spyglass.Generators.csproj + src/Sqlite/test/Eventuous.Tests.Sqlite/Eventuous.Tests.Sqlite.csproj + src/SignalR/test/Eventuous.Tests.SignalR/Eventuous.Tests.SignalR.csproj + " + for proj in $projects; do + echo "::group::dotnet test $proj (net${{ matrix.dotnet-version }})" + dotnet test "$proj" -c "Debug CI" -f net${{ matrix.dotnet-version }} + echo "::endgroup::" + done + - + name: Upload Test Results + if: always() + uses: actions/upload-artifact@v7 with: - username: ${{ secrets.DOCKER_USER }} - password: ${{ secrets.DOCKER_TOKEN }} + name: Test Results core ${{ matrix.dotnet-version }} + path: | + test-results/**/*.xml + test-results/**/*.trx + test-results/**/*.json + + integration-tests: + # One job per provider so a single runner only ever starts one container family — running + # the whole solution on one runner stacked KurrentDB + Postgres + SQL Server + Mongo + Kafka + # + RabbitMQ containers at once and made container startup (and the tests) flaky. + # + # Integration suites run on a single TFM: the DB adapter behaves the same across runtimes, so + # multi-TFM runs mostly re-pull the same images for little extra signal. max-parallel throttles + # concurrent Docker Hub image pulls to stay under the pull rate limit. + # + # When adding a new integration test project (one that uses Testcontainers), add a suite entry. + name: "Build and test ${{ matrix.suite.name }}" + runs-on: ubuntu-latest + strategy: + fail-fast: false + max-parallel: 4 + matrix: + suite: + - name: kurrentdb + project: src/KurrentDB/test/Eventuous.Tests.KurrentDB/Eventuous.Tests.KurrentDB.csproj + - name: postgres + project: src/Postgres/test/Eventuous.Tests.Postgres/Eventuous.Tests.Postgres.csproj + - name: sqlserver + project: src/SqlServer/test/Eventuous.Tests.SqlServer/Eventuous.Tests.SqlServer.csproj + - name: mongo + project: src/Mongo/test/Eventuous.Tests.Projections.MongoDB/Eventuous.Tests.Projections.MongoDB.csproj + - name: kafka + project: src/Kafka/test/Eventuous.Tests.Kafka/Eventuous.Tests.Kafka.csproj + - name: rabbitmq + project: src/RabbitMq/test/Eventuous.Tests.RabbitMq/Eventuous.Tests.RabbitMq.csproj + - name: redis + project: src/Redis/test/Eventuous.Tests.Redis/Eventuous.Tests.Redis.csproj + - name: azure-servicebus + project: src/Azure/test/Eventuous.Tests.Azure.ServiceBus/Eventuous.Tests.Azure.ServiceBus.csproj + - name: googlepubsub + project: src/GooglePubSub/test/Eventuous.Tests.GooglePubSub/Eventuous.Tests.GooglePubSub.csproj + - name: signalr-integration + project: src/SignalR/test/Eventuous.Tests.SignalR.Integration/Eventuous.Tests.SignalR.Integration.csproj + steps: + - + name: Checkout + uses: actions/checkout@v7 + - + name: Setup .NET + uses: actions/setup-dotnet@v5 + with: + dotnet-version: | + 8.0.x + 9.0.x + 10.0.x - name: Run tests - run: | - dotnet test -c "Debug CI" -f net${{ matrix.dotnet-version }} + run: dotnet test "${{ matrix.suite.project }}" -c "Debug CI" -f net10.0 - name: Upload Test Results if: always() uses: actions/upload-artifact@v7 with: - name: Test Results ${{ matrix.dotnet-version }} + name: Test Results ${{ matrix.suite.name }} path: | test-results/**/*.xml test-results/**/*.trx - test-results/**/*.json \ No newline at end of file + test-results/**/*.json diff --git a/src/Postgres/test/Eventuous.Tests.Postgres/Limiter.cs b/src/Postgres/test/Eventuous.Tests.Postgres/Limiter.cs new file mode 100644 index 000000000..450f26ec2 --- /dev/null +++ b/src/Postgres/test/Eventuous.Tests.Postgres/Limiter.cs @@ -0,0 +1,10 @@ +using Eventuous.Tests.Postgres; +using TUnit.Core.Interfaces; + +[assembly: ParallelLimiter] + +namespace Eventuous.Tests.Postgres; + +public class Limiter : IParallelLimit { + public int Limit => 4; +}