diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 97f37dcc4..b5033590c 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -8,6 +8,13 @@ "csharpier" ], "rollForward": false + }, + "husky": { + "version": "0.9.1", + "commands": [ + "husky" + ], + "rollForward": false } } } \ No newline at end of file diff --git a/.editorconfig b/.editorconfig index 2a559ae38..1808efad5 100644 --- a/.editorconfig +++ b/.editorconfig @@ -14,6 +14,7 @@ indent_size = 4 indent_size = 4 csharp_style_namespace_declarations = file_scoped:warning csharp_prefer_braces = true:warning +dotnet_diagnostic.IDE0005.severity = error [*.json] indent_size = 2 diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 4e91882ef..e6c934618 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -2,11 +2,11 @@ name: .NET on: push: - branches: ["master"] + branches: [ "master" ] pull_request: - branches: ["master"] + branches: [ "master" ] merge_group: - types: [checks_requested] + types: [ checks_requested ] release: types: - published @@ -19,13 +19,14 @@ jobs: format: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup .NET - uses: actions/setup-dotnet@v4 + uses: actions/setup-dotnet@v5 with: dotnet-version: | 8.0.x 9.0.x + 10.0.x - name: Install tools run: dotnet tool restore - name: check format @@ -34,13 +35,14 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup .NET - uses: actions/setup-dotnet@v4 + uses: actions/setup-dotnet@v5 with: dotnet-version: | 8.0.x 9.0.x + 10.0.x - name: Install dependencies run: dotnet restore Motor.NET.sln - name: Build @@ -50,47 +52,38 @@ jobs: - name: Publish Bridge run: dotnet publish --framework net9.0 -v minimal -c Release --no-restore -o ./artifacts-bridge ./src/Motor.Extensions.Hosting.Bridge/Motor.Extensions.Hosting.Bridge.csproj - name: Upload Artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: artifacts path: | ./artifacts/*.nupkg ./artifacts/*.snupkg - name: Upload Artifact Bridge - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: artifacts-bridge path: ./artifacts-bridge/* - test-net8: + test: + strategy: + matrix: + dotnet_version: + - "8.0" + - "9.0" + - "10.0" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup .NET - uses: actions/setup-dotnet@v4 + uses: actions/setup-dotnet@v5 with: dotnet-version: | - 8.0.x - - name: Install dependencies - run: dotnet restore Motor.NET.sln - - name: Test .NET8 - run: dotnet test --no-restore Motor.NET.sln --framework net8.0 - - test-net9: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Setup .NET - uses: actions/setup-dotnet@v4 - with: - dotnet-version: | - 8.0.x + ${{ matrix.dotnet_version }}.x - name: Install dependencies run: dotnet restore Motor.NET.sln - - name: Test .NET9 - run: dotnet test --no-restore Motor.NET.sln --framework net9.0 + - name: Test + run: dotnet test --no-restore Motor.NET.sln --framework net${{ matrix.dotnet_version }} - #code-ql: # runs-on: ubuntu-latest # steps: @@ -111,17 +104,17 @@ jobs: # uses: github/codeql-action/analyze@v1 deploy: - needs: [build, format, test-net8, test-net9] + needs: [ build, format, test ] if: github.event_name == 'release' runs-on: ubuntu-latest steps: - name: Download Artifact id: download - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: name: artifacts - name: Setup .NET - uses: actions/setup-dotnet@v4 + uses: actions/setup-dotnet@v5 with: dotnet-version: | 8.0.x @@ -130,12 +123,12 @@ jobs: run: dotnet nuget push "${{ steps.download.outputs.download-path }}/*.nupkg" --skip-duplicate --source $NUGET_FEED --api-key $NUGET_KEY build-bridge: - needs: [build, format, test-net8, test-net9] + needs: [ build, format, test ] runs-on: ubuntu-latest steps: - name: Download Artifact id: download - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: name: artifacts-bridge - name: Prepare @@ -155,13 +148,13 @@ jobs: echo "tags=${TAGS}" >> $GITHUB_OUTPUT echo "created=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT - name: Login to Github Registry - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Push to GitHub Packages - uses: docker/build-push-action@v6 + uses: docker/build-push-action@v7 with: push: ${{ github.event_name == 'release' }} context: "${{ steps.download.outputs.download-path }}" diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 000000000..7ee538b6e --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,20 @@ +#!/bin/sh +. "$(dirname "$0")/_/husky.sh" + +## husky task runner examples ------------------- +## Note : for local installation use 'dotnet' prefix. e.g. 'dotnet husky' + +## run all tasks +dotnet husky run + +### run all tasks with group: 'group-name' +#husky run --group group-name + +## run task with name: 'task-name' +#husky run --name task-name + +## pass hook arguments to task +#husky run --args "$1" "$2" + +## or put your custom commands ------------------- +#echo 'Husky.Net is awesome!' diff --git a/.husky/task-runner.json b/.husky/task-runner.json new file mode 100644 index 000000000..9e847ce99 --- /dev/null +++ b/.husky/task-runner.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://alirezanet.github.io/Husky.Net/schema.json", + "tasks": [ + { + "name": "Run csharpier", + "command": "dotnet", + "args": ["csharpier", "format", "${staged}"], + "include": ["**/*.cs", "**/*.csx", "**/*.csproj", "**/*.props", "**/*.targets", "**/*.xml", "**/*.config"] + } + ] +} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml deleted file mode 100644 index 9cbe8140f..000000000 --- a/.pre-commit-config.yaml +++ /dev/null @@ -1,13 +0,0 @@ -# See https://pre-commit.com for more information -# See https://pre-commit.com/hooks.html for more hooks -repos: - - repo: https://github.com/dotnet/format - rev: "v5.1.225507" # Specify a tag or sha here, or run "pre-commit autoupdate" - hooks: - - id: dotnet-format - args: - - "" - - --folder - - --check - - --verbosity=detailed - - --include diff --git a/Directory.Packages.props b/Directory.Packages.props new file mode 100644 index 000000000..84d39b1eb --- /dev/null +++ b/Directory.Packages.props @@ -0,0 +1,77 @@ + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Motor.NET.sln b/Motor.NET.sln index d148d1385..974a7478a 100644 --- a/Motor.NET.sln +++ b/Motor.NET.sln @@ -11,7 +11,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution ProjectSection(SolutionItems) = preProject .gitignore = .gitignore Readme.md = Readme.md - shared.csproj = shared.csproj .editorconfig = .editorconfig .pre-commit-config.yaml = .pre-commit-config.yaml EndProjectSection diff --git a/examples/AspNetExample/AspNetExample.csproj b/examples/AspNetExample/AspNetExample.csproj index c7072bf04..d63c212bf 100644 --- a/examples/AspNetExample/AspNetExample.csproj +++ b/examples/AspNetExample/AspNetExample.csproj @@ -1,7 +1,7 @@  Exe - net8.0;net9.0 + net10.0 enable Motor.NET @@ -10,11 +10,11 @@ true - - + + - + diff --git a/examples/AspNetExample_IntegrationTest/AspNetExample_IntegrationTest.csproj b/examples/AspNetExample_IntegrationTest/AspNetExample_IntegrationTest.csproj index 11997f61c..ca9b7d2ad 100644 --- a/examples/AspNetExample_IntegrationTest/AspNetExample_IntegrationTest.csproj +++ b/examples/AspNetExample_IntegrationTest/AspNetExample_IntegrationTest.csproj @@ -1,19 +1,15 @@  - net8.0;net9.0 + net10.0 false enable - - - - - + + + + + diff --git a/examples/ConsumeAndPublishWithKafka_IntegrationTest/ConsumeAndPublishWithKafka_IntegrationTest.csproj b/examples/ConsumeAndPublishWithKafka_IntegrationTest/ConsumeAndPublishWithKafka_IntegrationTest.csproj index 62576df49..bfa745900 100644 --- a/examples/ConsumeAndPublishWithKafka_IntegrationTest/ConsumeAndPublishWithKafka_IntegrationTest.csproj +++ b/examples/ConsumeAndPublishWithKafka_IntegrationTest/ConsumeAndPublishWithKafka_IntegrationTest.csproj @@ -6,10 +6,10 @@ false - - - - + + + + diff --git a/shared.csproj b/src/Directory.Build.props similarity index 85% rename from shared.csproj rename to src/Directory.Build.props index 32ced0cf0..83ab600d0 100644 --- a/shared.csproj +++ b/src/Directory.Build.props @@ -1,9 +1,11 @@ 0.16.0 + net8.0;net9.0;net10.0; 11 enable CS8600;CS8602;CS8625;CS8618;CS8604;CS8601 + true true @@ -24,6 +26,6 @@ - + diff --git a/src/Motor.Extensions.ContentEncoding.Abstractions/Motor.Extensions.ContentEncoding.Abstractions.csproj b/src/Motor.Extensions.ContentEncoding.Abstractions/Motor.Extensions.ContentEncoding.Abstractions.csproj index 97ae36b41..a08451df3 100644 --- a/src/Motor.Extensions.ContentEncoding.Abstractions/Motor.Extensions.ContentEncoding.Abstractions.csproj +++ b/src/Motor.Extensions.ContentEncoding.Abstractions/Motor.Extensions.ContentEncoding.Abstractions.csproj @@ -1,12 +1,8 @@ - - net8.0;net9.0 - - + - diff --git a/src/Motor.Extensions.ContentEncoding.Gzip/Motor.Extensions.ContentEncoding.Gzip.csproj b/src/Motor.Extensions.ContentEncoding.Gzip/Motor.Extensions.ContentEncoding.Gzip.csproj index 97887a6b0..3c2f1af54 100644 --- a/src/Motor.Extensions.ContentEncoding.Gzip/Motor.Extensions.ContentEncoding.Gzip.csproj +++ b/src/Motor.Extensions.ContentEncoding.Gzip/Motor.Extensions.ContentEncoding.Gzip.csproj @@ -1,10 +1,6 @@ - - net8.0;net9.0 - - diff --git a/src/Motor.Extensions.Conversion.Abstractions/Motor.Extensions.Conversion.Abstractions.csproj b/src/Motor.Extensions.Conversion.Abstractions/Motor.Extensions.Conversion.Abstractions.csproj index 3681de29b..e6c35ecaf 100644 --- a/src/Motor.Extensions.Conversion.Abstractions/Motor.Extensions.Conversion.Abstractions.csproj +++ b/src/Motor.Extensions.Conversion.Abstractions/Motor.Extensions.Conversion.Abstractions.csproj @@ -1,6 +1 @@ - - - net8.0;net9.0 - - - + diff --git a/src/Motor.Extensions.Conversion.JsonNet/Motor.Extensions.Conversion.JsonNet.csproj b/src/Motor.Extensions.Conversion.JsonNet/Motor.Extensions.Conversion.JsonNet.csproj index 3d479440e..e449241e5 100644 --- a/src/Motor.Extensions.Conversion.JsonNet/Motor.Extensions.Conversion.JsonNet.csproj +++ b/src/Motor.Extensions.Conversion.JsonNet/Motor.Extensions.Conversion.JsonNet.csproj @@ -1,15 +1,11 @@ - - net8.0;net9.0 - - - - + + + - diff --git a/src/Motor.Extensions.Conversion.Protobuf/Motor.Extensions.Conversion.Protobuf.csproj b/src/Motor.Extensions.Conversion.Protobuf/Motor.Extensions.Conversion.Protobuf.csproj index fe66623d5..4cd087903 100644 --- a/src/Motor.Extensions.Conversion.Protobuf/Motor.Extensions.Conversion.Protobuf.csproj +++ b/src/Motor.Extensions.Conversion.Protobuf/Motor.Extensions.Conversion.Protobuf.csproj @@ -1,15 +1,11 @@ - - net8.0;net9.0 - - - - + + + - diff --git a/src/Motor.Extensions.Conversion.SystemJson/Motor.Extensions.Conversion.SystemJson.csproj b/src/Motor.Extensions.Conversion.SystemJson/Motor.Extensions.Conversion.SystemJson.csproj index 9816eca1c..163feb761 100644 --- a/src/Motor.Extensions.Conversion.SystemJson/Motor.Extensions.Conversion.SystemJson.csproj +++ b/src/Motor.Extensions.Conversion.SystemJson/Motor.Extensions.Conversion.SystemJson.csproj @@ -1,15 +1,11 @@ - - net8.0;net9.0 - - - - + + + - diff --git a/src/Motor.Extensions.Diagnostics.HealthChecks/Motor.Extensions.Diagnostics.HealthChecks.csproj b/src/Motor.Extensions.Diagnostics.HealthChecks/Motor.Extensions.Diagnostics.HealthChecks.csproj index dc7947e9e..90fbca3b7 100644 --- a/src/Motor.Extensions.Diagnostics.HealthChecks/Motor.Extensions.Diagnostics.HealthChecks.csproj +++ b/src/Motor.Extensions.Diagnostics.HealthChecks/Motor.Extensions.Diagnostics.HealthChecks.csproj @@ -1,9 +1,5 @@ - - net8.0;net9.0 - - diff --git a/src/Motor.Extensions.Diagnostics.Logging/Motor.Extensions.Diagnostics.Logging.csproj b/src/Motor.Extensions.Diagnostics.Logging/Motor.Extensions.Diagnostics.Logging.csproj index 69b655162..04a173a8d 100644 --- a/src/Motor.Extensions.Diagnostics.Logging/Motor.Extensions.Diagnostics.Logging.csproj +++ b/src/Motor.Extensions.Diagnostics.Logging/Motor.Extensions.Diagnostics.Logging.csproj @@ -1,18 +1,14 @@ - - net8.0;net9.0 - - - - - - + + + + + - + - diff --git a/src/Motor.Extensions.Diagnostics.Metrics.Abstractions/Motor.Extensions.Diagnostics.Metrics.Abstractions.csproj b/src/Motor.Extensions.Diagnostics.Metrics.Abstractions/Motor.Extensions.Diagnostics.Metrics.Abstractions.csproj index a4f3e28d3..1d7f161fc 100644 --- a/src/Motor.Extensions.Diagnostics.Metrics.Abstractions/Motor.Extensions.Diagnostics.Metrics.Abstractions.csproj +++ b/src/Motor.Extensions.Diagnostics.Metrics.Abstractions/Motor.Extensions.Diagnostics.Metrics.Abstractions.csproj @@ -1,9 +1,5 @@ - - net8.0;net9.0 - - + - diff --git a/src/Motor.Extensions.Diagnostics.Metrics/Motor.Extensions.Diagnostics.Metrics.csproj b/src/Motor.Extensions.Diagnostics.Metrics/Motor.Extensions.Diagnostics.Metrics.csproj index bfeb031f0..1ab0e99bc 100644 --- a/src/Motor.Extensions.Diagnostics.Metrics/Motor.Extensions.Diagnostics.Metrics.csproj +++ b/src/Motor.Extensions.Diagnostics.Metrics/Motor.Extensions.Diagnostics.Metrics.csproj @@ -1,7 +1,4 @@ - - net8.0;net9.0 - @@ -11,18 +8,17 @@ - - - - - - + + + + + + - + - diff --git a/src/Motor.Extensions.Diagnostics.Queue.Abstractions/Motor.Extensions.Diagnostics.Queue.Abstractions.csproj b/src/Motor.Extensions.Diagnostics.Queue.Abstractions/Motor.Extensions.Diagnostics.Queue.Abstractions.csproj index 3681de29b..e6c35ecaf 100644 --- a/src/Motor.Extensions.Diagnostics.Queue.Abstractions/Motor.Extensions.Diagnostics.Queue.Abstractions.csproj +++ b/src/Motor.Extensions.Diagnostics.Queue.Abstractions/Motor.Extensions.Diagnostics.Queue.Abstractions.csproj @@ -1,6 +1 @@ - - - net8.0;net9.0 - - - + diff --git a/src/Motor.Extensions.Diagnostics.Queue.Metrics/Motor.Extensions.Diagnostics.Queue.Metrics.csproj b/src/Motor.Extensions.Diagnostics.Queue.Metrics/Motor.Extensions.Diagnostics.Queue.Metrics.csproj index 88459b540..181766b5a 100644 --- a/src/Motor.Extensions.Diagnostics.Queue.Metrics/Motor.Extensions.Diagnostics.Queue.Metrics.csproj +++ b/src/Motor.Extensions.Diagnostics.Queue.Metrics/Motor.Extensions.Diagnostics.Queue.Metrics.csproj @@ -1,14 +1,10 @@ - - net8.0;net9.0 - - - + + - diff --git a/src/Motor.Extensions.Diagnostics.Sentry/Motor.Extensions.Diagnostics.Sentry.csproj b/src/Motor.Extensions.Diagnostics.Sentry/Motor.Extensions.Diagnostics.Sentry.csproj index aa49adb97..1f7f1ed11 100644 --- a/src/Motor.Extensions.Diagnostics.Sentry/Motor.Extensions.Diagnostics.Sentry.csproj +++ b/src/Motor.Extensions.Diagnostics.Sentry/Motor.Extensions.Diagnostics.Sentry.csproj @@ -1,15 +1,11 @@ - - net8.0;net9.0 - - - - + + + - + - diff --git a/src/Motor.Extensions.Diagnostics.Telemetry/Motor.Extensions.Diagnostics.Telemetry.csproj b/src/Motor.Extensions.Diagnostics.Telemetry/Motor.Extensions.Diagnostics.Telemetry.csproj index 518adeafb..e53daf17c 100644 --- a/src/Motor.Extensions.Diagnostics.Telemetry/Motor.Extensions.Diagnostics.Telemetry.csproj +++ b/src/Motor.Extensions.Diagnostics.Telemetry/Motor.Extensions.Diagnostics.Telemetry.csproj @@ -1,21 +1,17 @@ - - net8.0;net9.0 - - - - - - - - - + + + + + + + + - + - diff --git a/src/Motor.Extensions.Diagnostics.Tracing/Motor.Extensions.Diagnostics.Tracing.csproj b/src/Motor.Extensions.Diagnostics.Tracing/Motor.Extensions.Diagnostics.Tracing.csproj index a58b241f4..0e14aade9 100644 --- a/src/Motor.Extensions.Diagnostics.Tracing/Motor.Extensions.Diagnostics.Tracing.csproj +++ b/src/Motor.Extensions.Diagnostics.Tracing/Motor.Extensions.Diagnostics.Tracing.csproj @@ -1,9 +1,5 @@ - - net8.0;net9.0 - - diff --git a/src/Motor.Extensions.Hosting.Abstractions/Motor.Extensions.Hosting.Abstractions.csproj b/src/Motor.Extensions.Hosting.Abstractions/Motor.Extensions.Hosting.Abstractions.csproj index 679733f45..270455d45 100644 --- a/src/Motor.Extensions.Hosting.Abstractions/Motor.Extensions.Hosting.Abstractions.csproj +++ b/src/Motor.Extensions.Hosting.Abstractions/Motor.Extensions.Hosting.Abstractions.csproj @@ -1,18 +1,14 @@ - - net8.0;net9.0 - - - - - + + + + - + - diff --git a/src/Motor.Extensions.Hosting.BackgroundService/Motor.Extensions.Hosting.BackgroundService.csproj b/src/Motor.Extensions.Hosting.BackgroundService/Motor.Extensions.Hosting.BackgroundService.csproj index c20794989..f2b77fc6f 100644 --- a/src/Motor.Extensions.Hosting.BackgroundService/Motor.Extensions.Hosting.BackgroundService.csproj +++ b/src/Motor.Extensions.Hosting.BackgroundService/Motor.Extensions.Hosting.BackgroundService.csproj @@ -1,9 +1,5 @@ - - - net8.0;net9.0 - + - + - diff --git a/src/Motor.Extensions.Hosting.Bridge/Motor.Extensions.Hosting.Bridge.csproj b/src/Motor.Extensions.Hosting.Bridge/Motor.Extensions.Hosting.Bridge.csproj index e9d0b677a..049b625c5 100644 --- a/src/Motor.Extensions.Hosting.Bridge/Motor.Extensions.Hosting.Bridge.csproj +++ b/src/Motor.Extensions.Hosting.Bridge/Motor.Extensions.Hosting.Bridge.csproj @@ -1,6 +1,5 @@ - net8.0;net9.0 Exe Motor.NET/bridge @@ -19,5 +18,4 @@ PreserveNewest - diff --git a/src/Motor.Extensions.Hosting.CloudEvents/Motor.Extensions.Hosting.CloudEvents.csproj b/src/Motor.Extensions.Hosting.CloudEvents/Motor.Extensions.Hosting.CloudEvents.csproj index 8755a50a5..90af88d2f 100644 --- a/src/Motor.Extensions.Hosting.CloudEvents/Motor.Extensions.Hosting.CloudEvents.csproj +++ b/src/Motor.Extensions.Hosting.CloudEvents/Motor.Extensions.Hosting.CloudEvents.csproj @@ -1,9 +1,5 @@ - - net8.0;net9.0 - - + - diff --git a/src/Motor.Extensions.Hosting.Consumer/Motor.Extensions.Hosting.Consumer.csproj b/src/Motor.Extensions.Hosting.Consumer/Motor.Extensions.Hosting.Consumer.csproj index 7b83a1b08..2728d38da 100644 --- a/src/Motor.Extensions.Hosting.Consumer/Motor.Extensions.Hosting.Consumer.csproj +++ b/src/Motor.Extensions.Hosting.Consumer/Motor.Extensions.Hosting.Consumer.csproj @@ -1,7 +1,4 @@ - - net8.0;net9.0 - @@ -9,5 +6,4 @@ - diff --git a/src/Motor.Extensions.Hosting.Kafka/Motor.Extensions.Hosting.Kafka.csproj b/src/Motor.Extensions.Hosting.Kafka/Motor.Extensions.Hosting.Kafka.csproj index 8a9dbdbc1..0e069df1e 100644 --- a/src/Motor.Extensions.Hosting.Kafka/Motor.Extensions.Hosting.Kafka.csproj +++ b/src/Motor.Extensions.Hosting.Kafka/Motor.Extensions.Hosting.Kafka.csproj @@ -1,23 +1,19 @@ - - net8.0;net9.0 - - - - - - - - - + + + + + + + + - diff --git a/src/Motor.Extensions.Hosting.NATS/Motor.Extensions.Hosting.NATS.csproj b/src/Motor.Extensions.Hosting.NATS/Motor.Extensions.Hosting.NATS.csproj index c2e66770d..a4de09cde 100644 --- a/src/Motor.Extensions.Hosting.NATS/Motor.Extensions.Hosting.NATS.csproj +++ b/src/Motor.Extensions.Hosting.NATS/Motor.Extensions.Hosting.NATS.csproj @@ -1,19 +1,15 @@ - - net8.0;net9.0 - - - - - - - + + + + + + - diff --git a/src/Motor.Extensions.Hosting.Publisher/Motor.Extensions.Hosting.Publisher.csproj b/src/Motor.Extensions.Hosting.Publisher/Motor.Extensions.Hosting.Publisher.csproj index 398289d05..fa26f1447 100644 --- a/src/Motor.Extensions.Hosting.Publisher/Motor.Extensions.Hosting.Publisher.csproj +++ b/src/Motor.Extensions.Hosting.Publisher/Motor.Extensions.Hosting.Publisher.csproj @@ -1,7 +1,4 @@ - - net8.0;net9.0 - @@ -10,5 +7,4 @@ - diff --git a/src/Motor.Extensions.Hosting.RabbitMQ/Motor.Extensions.Hosting.RabbitMQ.csproj b/src/Motor.Extensions.Hosting.RabbitMQ/Motor.Extensions.Hosting.RabbitMQ.csproj index de1a99b32..78065e759 100644 --- a/src/Motor.Extensions.Hosting.RabbitMQ/Motor.Extensions.Hosting.RabbitMQ.csproj +++ b/src/Motor.Extensions.Hosting.RabbitMQ/Motor.Extensions.Hosting.RabbitMQ.csproj @@ -1,14 +1,11 @@ - - net8.0;net9.0 - - - - - - - + + + + + + @@ -20,5 +17,4 @@ <_Parameter1>$(AssemblyName)_UnitTest - diff --git a/src/Motor.Extensions.Hosting.SQS/Motor.Extensions.Hosting.SQS.csproj b/src/Motor.Extensions.Hosting.SQS/Motor.Extensions.Hosting.SQS.csproj index 76e4bc91e..5b196d6e2 100644 --- a/src/Motor.Extensions.Hosting.SQS/Motor.Extensions.Hosting.SQS.csproj +++ b/src/Motor.Extensions.Hosting.SQS/Motor.Extensions.Hosting.SQS.csproj @@ -1,17 +1,13 @@ - - net8.0;net9.0 - - - - - - + + + + + - diff --git a/src/Motor.Extensions.Hosting.Timer/Motor.Extensions.Hosting.Timer.csproj b/src/Motor.Extensions.Hosting.Timer/Motor.Extensions.Hosting.Timer.csproj index f3fc0959c..6f6b5f96d 100644 --- a/src/Motor.Extensions.Hosting.Timer/Motor.Extensions.Hosting.Timer.csproj +++ b/src/Motor.Extensions.Hosting.Timer/Motor.Extensions.Hosting.Timer.csproj @@ -1,16 +1,12 @@ - - net8.0;net9.0 - - - - - + + + + - diff --git a/src/Motor.Extensions.Hosting/Internal/BackgroundTaskQueue.cs b/src/Motor.Extensions.Hosting/Internal/BackgroundTaskQueue.cs index 58d056854..def2a7ab4 100644 --- a/src/Motor.Extensions.Hosting/Internal/BackgroundTaskQueue.cs +++ b/src/Motor.Extensions.Hosting/Internal/BackgroundTaskQueue.cs @@ -11,6 +11,7 @@ namespace Motor.Extensions.Hosting.Internal; public class BackgroundTaskQueue : IBackgroundTaskQueue, IDisposable where T : notnull { + private int _itemCount; private readonly IGauge? _elementsInQueue; private readonly SemaphoreSlim _signal = new(0); private readonly ICounter? _totalMessages; @@ -40,10 +41,10 @@ public Task QueueBackgroundWorkItem(T item) LastDequeuedAt = DateTimeOffset.UtcNow; } _workItems.Enqueue(new QueueItem(item, taskCompletionStatus)); + Interlocked.Increment(ref _itemCount); _elementsInQueue?.Inc(); _totalMessages?.Inc(); _signal.Release(); - ItemCount++; return taskCompletionStatus.Task; } @@ -53,15 +54,19 @@ public Task QueueBackgroundWorkItem(T item) _workItems.TryDequeue(out var workItem); _elementsInQueue?.Dec(); LastDequeuedAt = DateTimeOffset.UtcNow; - ItemCount--; + Interlocked.Decrement(ref _itemCount); return workItem; } - public int ItemCount { get; private set; } + public int ItemCount + { + get => _itemCount; + } public DateTimeOffset LastDequeuedAt { get; private set; } public void Dispose() { + GC.SuppressFinalize(this); _signal.Dispose(); } } diff --git a/src/Motor.Extensions.Hosting/Motor.Extensions.Hosting.csproj b/src/Motor.Extensions.Hosting/Motor.Extensions.Hosting.csproj index 2316d869e..b17d21f0b 100644 --- a/src/Motor.Extensions.Hosting/Motor.Extensions.Hosting.csproj +++ b/src/Motor.Extensions.Hosting/Motor.Extensions.Hosting.csproj @@ -1,7 +1,4 @@ - - net8.0;net9.0 - @@ -9,9 +6,8 @@ - - - + + + - diff --git a/src/Motor.Extensions.Http/Motor.Extensions.Http.csproj b/src/Motor.Extensions.Http/Motor.Extensions.Http.csproj index 573ffa5d2..c59184dd3 100644 --- a/src/Motor.Extensions.Http/Motor.Extensions.Http.csproj +++ b/src/Motor.Extensions.Http/Motor.Extensions.Http.csproj @@ -1,17 +1,13 @@ - - net8.0;net9.0 - - - - - - + + + + + - + - diff --git a/src/Motor.Extensions.TestUtilities/Motor.Extensions.TestUtilities.csproj b/src/Motor.Extensions.TestUtilities/Motor.Extensions.TestUtilities.csproj index b35c541c8..4961f060a 100644 --- a/src/Motor.Extensions.TestUtilities/Motor.Extensions.TestUtilities.csproj +++ b/src/Motor.Extensions.TestUtilities/Motor.Extensions.TestUtilities.csproj @@ -1,18 +1,16 @@ - net8.0;net9.0 false - - - - + + + + - diff --git a/src/Motor.Extensions.TestUtilities/MotorWebApplicationFactory.cs b/src/Motor.Extensions.TestUtilities/MotorWebApplicationFactory.cs index bf0c4ffd8..ef07ae4f3 100644 --- a/src/Motor.Extensions.TestUtilities/MotorWebApplicationFactory.cs +++ b/src/Motor.Extensions.TestUtilities/MotorWebApplicationFactory.cs @@ -1,4 +1,5 @@ using System; +using System.Net.Http; using System.Threading.Tasks; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc.Testing; @@ -47,17 +48,17 @@ protected override void ConfigureWebHost(IWebHostBuilder builder) public async Task IsHealthy() { - var client = CreateClient(); - var response = await client.GetAsync("/health"); + using var client = CreateClient(); + using var response = await client.GetAsync("/health"); return response.IsSuccessStatusCode; } public async Task WaitUntilHealthy() { - CreateClient(); - var retryPolicy = Policy .HandleResult(healthy => !healthy) + .Or() + .Or() .WaitAndRetryAsync(10, retryAttempt => TimeSpan.FromMilliseconds(Math.Pow(2, retryAttempt))); await retryPolicy.ExecuteAsync(async () => await IsHealthy()); diff --git a/src/Motor.Extensions.Utilities.Abstractions/Motor.Extensions.Utilities.Abstractions.csproj b/src/Motor.Extensions.Utilities.Abstractions/Motor.Extensions.Utilities.Abstractions.csproj index dc7947e9e..90fbca3b7 100644 --- a/src/Motor.Extensions.Utilities.Abstractions/Motor.Extensions.Utilities.Abstractions.csproj +++ b/src/Motor.Extensions.Utilities.Abstractions/Motor.Extensions.Utilities.Abstractions.csproj @@ -1,9 +1,5 @@ - - net8.0;net9.0 - - diff --git a/src/Motor.Extensions.Utilities/Motor.Extensions.Utilities.csproj b/src/Motor.Extensions.Utilities/Motor.Extensions.Utilities.csproj index 5efdec701..79a5b7a63 100644 --- a/src/Motor.Extensions.Utilities/Motor.Extensions.Utilities.csproj +++ b/src/Motor.Extensions.Utilities/Motor.Extensions.Utilities.csproj @@ -1,7 +1,4 @@ - - net8.0;net9.0 - @@ -16,5 +13,4 @@ - diff --git a/src/Motor.Extensions.Utilities/MotorHostBuilderHelper.cs b/src/Motor.Extensions.Utilities/MotorHostBuilderHelper.cs index b5b96fb7c..b0e6f4897 100644 --- a/src/Motor.Extensions.Utilities/MotorHostBuilderHelper.cs +++ b/src/Motor.Extensions.Utilities/MotorHostBuilderHelper.cs @@ -16,7 +16,7 @@ public static void ConfigureWebHost(IWebHostBuilder builder, Func + + net8.0;net9.0;net10.0; + 14 + enable + enable + false + true + + diff --git a/test/Motor.Extensions.ContentEncoding.Abstractions_UnitTest/Motor.Extensions.ContentEncoding.Abstractions_UnitTest.csproj b/test/Motor.Extensions.ContentEncoding.Abstractions_UnitTest/Motor.Extensions.ContentEncoding.Abstractions_UnitTest.csproj index bbfd35af6..8bc98d717 100644 --- a/test/Motor.Extensions.ContentEncoding.Abstractions_UnitTest/Motor.Extensions.ContentEncoding.Abstractions_UnitTest.csproj +++ b/test/Motor.Extensions.ContentEncoding.Abstractions_UnitTest/Motor.Extensions.ContentEncoding.Abstractions_UnitTest.csproj @@ -1,16 +1,12 @@ - - net8.0;net9.0 - false - - - - + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/test/Motor.Extensions.ContentEncoding.Gzip_UnitTest/Motor.Extensions.ContentEncoding.Gzip_UnitTest.csproj b/test/Motor.Extensions.ContentEncoding.Gzip_UnitTest/Motor.Extensions.ContentEncoding.Gzip_UnitTest.csproj index c7086a6cf..221f07962 100644 --- a/test/Motor.Extensions.ContentEncoding.Gzip_UnitTest/Motor.Extensions.ContentEncoding.Gzip_UnitTest.csproj +++ b/test/Motor.Extensions.ContentEncoding.Gzip_UnitTest/Motor.Extensions.ContentEncoding.Gzip_UnitTest.csproj @@ -1,12 +1,8 @@ - - net8.0;net9.0 - false - - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/Motor.Extensions.Conversion.JsonNet_UnitTest/Motor.Extensions.Conversion.JsonNet_UnitTest.csproj b/test/Motor.Extensions.Conversion.JsonNet_UnitTest/Motor.Extensions.Conversion.JsonNet_UnitTest.csproj index f8bb42ef5..d424efd06 100644 --- a/test/Motor.Extensions.Conversion.JsonNet_UnitTest/Motor.Extensions.Conversion.JsonNet_UnitTest.csproj +++ b/test/Motor.Extensions.Conversion.JsonNet_UnitTest/Motor.Extensions.Conversion.JsonNet_UnitTest.csproj @@ -1,14 +1,10 @@ - - net8.0;net9.0 - false - - - - - - + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/Motor.Extensions.Conversion.Protobuf_UnitTest/Motor.Extensions.Conversion.Protobuf_UnitTest.csproj b/test/Motor.Extensions.Conversion.Protobuf_UnitTest/Motor.Extensions.Conversion.Protobuf_UnitTest.csproj index 7e3c172ca..54539a54d 100644 --- a/test/Motor.Extensions.Conversion.Protobuf_UnitTest/Motor.Extensions.Conversion.Protobuf_UnitTest.csproj +++ b/test/Motor.Extensions.Conversion.Protobuf_UnitTest/Motor.Extensions.Conversion.Protobuf_UnitTest.csproj @@ -1,20 +1,16 @@ - - net8.0;net9.0 - false - - - - - - + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/test/Motor.Extensions.Conversion.SystemJson_UnitTest/Motor.Extensions.Conversion.SystemJson_UnitTest.csproj b/test/Motor.Extensions.Conversion.SystemJson_UnitTest/Motor.Extensions.Conversion.SystemJson_UnitTest.csproj index 847eee1dd..d3e235f0e 100644 --- a/test/Motor.Extensions.Conversion.SystemJson_UnitTest/Motor.Extensions.Conversion.SystemJson_UnitTest.csproj +++ b/test/Motor.Extensions.Conversion.SystemJson_UnitTest/Motor.Extensions.Conversion.SystemJson_UnitTest.csproj @@ -1,14 +1,10 @@ - - net8.0;net9.0 - false - - - - - - + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/Motor.Extensions.Diagnostics.Metrics_UnitTest/Motor.Extensions.Diagnostics.Metrics_UnitTest.csproj b/test/Motor.Extensions.Diagnostics.Metrics_UnitTest/Motor.Extensions.Diagnostics.Metrics_UnitTest.csproj index 4927da232..5e21d5f48 100644 --- a/test/Motor.Extensions.Diagnostics.Metrics_UnitTest/Motor.Extensions.Diagnostics.Metrics_UnitTest.csproj +++ b/test/Motor.Extensions.Diagnostics.Metrics_UnitTest/Motor.Extensions.Diagnostics.Metrics_UnitTest.csproj @@ -1,13 +1,9 @@ - - net8.0;net9.0 - false - - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/Motor.Extensions.Diagnostics.Telemetry_IntegrationTest/Motor.Extensions.Diagnostics.Telemetry_IntegrationTest.csproj b/test/Motor.Extensions.Diagnostics.Telemetry_IntegrationTest/Motor.Extensions.Diagnostics.Telemetry_IntegrationTest.csproj index 900cbbe05..cd9492198 100644 --- a/test/Motor.Extensions.Diagnostics.Telemetry_IntegrationTest/Motor.Extensions.Diagnostics.Telemetry_IntegrationTest.csproj +++ b/test/Motor.Extensions.Diagnostics.Telemetry_IntegrationTest/Motor.Extensions.Diagnostics.Telemetry_IntegrationTest.csproj @@ -1,17 +1,11 @@ - - net8.0;net9.0 - enable - enable - false - - - - - - - + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/test/Motor.Extensions.Diagnostics.Telemetry_IntegrationTest/ReverseStringConverter.cs b/test/Motor.Extensions.Diagnostics.Telemetry_IntegrationTest/ReverseStringConverter.cs index f1f708340..b8311cbc6 100644 --- a/test/Motor.Extensions.Diagnostics.Telemetry_IntegrationTest/ReverseStringConverter.cs +++ b/test/Motor.Extensions.Diagnostics.Telemetry_IntegrationTest/ReverseStringConverter.cs @@ -31,15 +31,15 @@ IMetricsFactory metricsFactory ) { _logger.LogInformation("log your request"); - var tmpChar = dataCloudEvent.TypedData.ToCharArray(); if (!ActivitySource.HasListeners()) { throw new ArgumentException(); } - var reversed = tmpChar.Reverse().ToArray(); _summary.WithLabels("collect_your_metrics").Observe(1.0); - return Task.FromResult?>(dataCloudEvent.CreateNew(new string(reversed))); + return Task.FromResult?>( + dataCloudEvent.CreateNew(new string([.. dataCloudEvent.TypedData.Reverse()])) + ); } } diff --git a/test/Motor.Extensions.Hosting.AspNet_IntegrationTest/Motor.Extensions.Hosting.AspNet_IntegrationTest.csproj b/test/Motor.Extensions.Hosting.AspNet_IntegrationTest/Motor.Extensions.Hosting.AspNet_IntegrationTest.csproj index 2f127aa90..984620e23 100644 --- a/test/Motor.Extensions.Hosting.AspNet_IntegrationTest/Motor.Extensions.Hosting.AspNet_IntegrationTest.csproj +++ b/test/Motor.Extensions.Hosting.AspNet_IntegrationTest/Motor.Extensions.Hosting.AspNet_IntegrationTest.csproj @@ -1,15 +1,12 @@ - + - net8.0;net9.0 test - false - Motor.NET - enable + Motor.NET Integration Test - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/Motor.Extensions.Hosting.BackgroundService_IntegrationTest/BackgroundServiceTests.cs b/test/Motor.Extensions.Hosting.BackgroundService_IntegrationTest/BackgroundServiceTests.cs index a1abdd395..c4171e783 100644 --- a/test/Motor.Extensions.Hosting.BackgroundService_IntegrationTest/BackgroundServiceTests.cs +++ b/test/Motor.Extensions.Hosting.BackgroundService_IntegrationTest/BackgroundServiceTests.cs @@ -1,6 +1,3 @@ -using System; -using System.Threading; -using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; @@ -21,11 +18,18 @@ public async Task WaitUntilHealthy_UnsafeHostedService_ThrowsException() .ConfigureServices(services => { services.AddHostedService(); - services.AddHostedService(); }) .Build(); - Assert.Throws(() => host.Services.GetRequiredService()); + await Assert.ThrowsAnyAsync(async () => + { + while (true) + { + await host.WaitUntilHealthy(); + await Task.Delay(10); + } + // ReSharper disable once FunctionNeverReturns + }); } private class UnsafeHostedService(ISharedService service) : Microsoft.Extensions.Hosting.BackgroundService @@ -53,8 +57,11 @@ public async Task WaitUntilHealthy_SafeHostedService_StartsSuccessfully() services.AddHostedService(); }) .Build(); + var sharedService = host.Services.GetRequiredService(); + await host.WaitUntilHealthy(); + Assert.True(sharedService.IsFinished()); } @@ -64,7 +71,7 @@ public class SafeHostedService( ILogger logger ) : StartedBackgroundService(appLifetime, logger) { - protected override Task ExecuteWhenStartedAsync(CancellationToken ct) + protected override async Task ExecuteWhenStartedAsync(CancellationToken ct) { if (!service.IsStarted()) { @@ -72,7 +79,7 @@ protected override Task ExecuteWhenStartedAsync(CancellationToken ct) } service.Finish(); - return Task.CompletedTask; + await Task.Delay(1000, ct); } } diff --git a/test/Motor.Extensions.Hosting.BackgroundService_IntegrationTest/Motor.Extensions.Hosting.BackgroundService_IntegrationTest.csproj b/test/Motor.Extensions.Hosting.BackgroundService_IntegrationTest/Motor.Extensions.Hosting.BackgroundService_IntegrationTest.csproj index b61376483..ae49ce369 100644 --- a/test/Motor.Extensions.Hosting.BackgroundService_IntegrationTest/Motor.Extensions.Hosting.BackgroundService_IntegrationTest.csproj +++ b/test/Motor.Extensions.Hosting.BackgroundService_IntegrationTest/Motor.Extensions.Hosting.BackgroundService_IntegrationTest.csproj @@ -1,14 +1,11 @@ - + - net8.0;net9.0 - false - enable Motor.NET Integration Test - - - + + + diff --git a/test/Motor.Extensions.Hosting.BackgroundService_IntegrationTest/TestExample/SharedService.cs b/test/Motor.Extensions.Hosting.BackgroundService_IntegrationTest/TestExample/SharedService.cs index 45f8592b2..39da7e4f3 100644 --- a/test/Motor.Extensions.Hosting.BackgroundService_IntegrationTest/TestExample/SharedService.cs +++ b/test/Motor.Extensions.Hosting.BackgroundService_IntegrationTest/TestExample/SharedService.cs @@ -18,18 +18,12 @@ public void Start() _started = true; } - public bool IsStarted() - { - return _started; - } + public bool IsStarted() => _started; public void Finish() { _finished = true; } - public bool IsFinished() - { - return _finished; - } + public bool IsFinished() => _finished; } diff --git a/test/Motor.Extensions.Hosting.CloudEvents_UnitTest/Motor.Extensions.Hosting.CloudEvents_UnitTest.csproj b/test/Motor.Extensions.Hosting.CloudEvents_UnitTest/Motor.Extensions.Hosting.CloudEvents_UnitTest.csproj index 386f2b1e8..141ebd272 100644 --- a/test/Motor.Extensions.Hosting.CloudEvents_UnitTest/Motor.Extensions.Hosting.CloudEvents_UnitTest.csproj +++ b/test/Motor.Extensions.Hosting.CloudEvents_UnitTest/Motor.Extensions.Hosting.CloudEvents_UnitTest.csproj @@ -1,17 +1,13 @@ - - net8.0;net9.0 - false - - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/Motor.Extensions.Hosting.Consumer_UnitTest/Motor.Extensions.Hosting.Consumer_UnitTest.csproj b/test/Motor.Extensions.Hosting.Consumer_UnitTest/Motor.Extensions.Hosting.Consumer_UnitTest.csproj index 1964fcf38..f8d425f08 100644 --- a/test/Motor.Extensions.Hosting.Consumer_UnitTest/Motor.Extensions.Hosting.Consumer_UnitTest.csproj +++ b/test/Motor.Extensions.Hosting.Consumer_UnitTest/Motor.Extensions.Hosting.Consumer_UnitTest.csproj @@ -1,14 +1,9 @@ - - net8.0;net9.0 - false - enable - - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/Motor.Extensions.Hosting.Kafka_IntegrationTest/Motor.Extensions.Hosting.Kafka_IntegrationTest.csproj b/test/Motor.Extensions.Hosting.Kafka_IntegrationTest/Motor.Extensions.Hosting.Kafka_IntegrationTest.csproj index 7d1d2f1ab..70694fc3b 100644 --- a/test/Motor.Extensions.Hosting.Kafka_IntegrationTest/Motor.Extensions.Hosting.Kafka_IntegrationTest.csproj +++ b/test/Motor.Extensions.Hosting.Kafka_IntegrationTest/Motor.Extensions.Hosting.Kafka_IntegrationTest.csproj @@ -1,17 +1,13 @@ - - net8.0;net9.0 - false - - - - - - - - - + + + + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/Motor.Extensions.Hosting.Kafka_UnitTest/Motor.Extensions.Hosting.Kafka_UnitTest.csproj b/test/Motor.Extensions.Hosting.Kafka_UnitTest/Motor.Extensions.Hosting.Kafka_UnitTest.csproj index 7ff95a4e5..461870684 100644 --- a/test/Motor.Extensions.Hosting.Kafka_UnitTest/Motor.Extensions.Hosting.Kafka_UnitTest.csproj +++ b/test/Motor.Extensions.Hosting.Kafka_UnitTest/Motor.Extensions.Hosting.Kafka_UnitTest.csproj @@ -1,13 +1,9 @@ - - net8.0;net9.0 - false - - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/Motor.Extensions.Hosting.NATS_IntegrationTest/Motor.Extensions.Hosting.NATS_IntegrationTest.csproj b/test/Motor.Extensions.Hosting.NATS_IntegrationTest/Motor.Extensions.Hosting.NATS_IntegrationTest.csproj index 7d112101e..eea9c1810 100644 --- a/test/Motor.Extensions.Hosting.NATS_IntegrationTest/Motor.Extensions.Hosting.NATS_IntegrationTest.csproj +++ b/test/Motor.Extensions.Hosting.NATS_IntegrationTest/Motor.Extensions.Hosting.NATS_IntegrationTest.csproj @@ -1,20 +1,16 @@ - - net8.0;net9.0 - false - - - - - - - - + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/test/Motor.Extensions.Hosting.Publisher_UnitTest/Motor.Extensions.Hosting.Publisher_UnitTest.csproj b/test/Motor.Extensions.Hosting.Publisher_UnitTest/Motor.Extensions.Hosting.Publisher_UnitTest.csproj index 7a9bfce87..8bdd259f3 100644 --- a/test/Motor.Extensions.Hosting.Publisher_UnitTest/Motor.Extensions.Hosting.Publisher_UnitTest.csproj +++ b/test/Motor.Extensions.Hosting.Publisher_UnitTest/Motor.Extensions.Hosting.Publisher_UnitTest.csproj @@ -1,14 +1,9 @@ - - net8.0;net9.0 - false - enable - - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/Motor.Extensions.Hosting.RabbitMQ_IntegrationTest/Motor.Extensions.Hosting.RabbitMQ_IntegrationTest.csproj b/test/Motor.Extensions.Hosting.RabbitMQ_IntegrationTest/Motor.Extensions.Hosting.RabbitMQ_IntegrationTest.csproj index 8b7dee3a7..ce4dd9496 100644 --- a/test/Motor.Extensions.Hosting.RabbitMQ_IntegrationTest/Motor.Extensions.Hosting.RabbitMQ_IntegrationTest.csproj +++ b/test/Motor.Extensions.Hosting.RabbitMQ_IntegrationTest/Motor.Extensions.Hosting.RabbitMQ_IntegrationTest.csproj @@ -1,31 +1,27 @@ - - net8.0;net9.0 - false - - - - - - - - + + + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - + + + + + - + diff --git a/test/Motor.Extensions.Hosting.RabbitMQ_IntegrationTest/RabbitMQFixture.cs b/test/Motor.Extensions.Hosting.RabbitMQ_IntegrationTest/RabbitMQFixture.cs index 5c29de08c..454bee144 100644 --- a/test/Motor.Extensions.Hosting.RabbitMQ_IntegrationTest/RabbitMQFixture.cs +++ b/test/Motor.Extensions.Hosting.RabbitMQ_IntegrationTest/RabbitMQFixture.cs @@ -1,5 +1,3 @@ -using System; -using System.Threading.Tasks; using DotNet.Testcontainers.Builders; using Motor.Extensions.Hosting.RabbitMQ; using Polly; @@ -14,10 +12,12 @@ public class RabbitMQFixture : IAsyncLifetime { private const int RabbitMqPort = 5672; - private readonly RabbitMqContainer _container = new RabbitMqBuilder() + private readonly RabbitMqContainer _container = new RabbitMqBuilder("rabbitmq:4.2-alpine") .WithUsername("guest") .WithPassword("guest") - .WithWaitStrategy(Wait.ForUnixContainer().UntilMessageIsLogged("Server startup complete")) + .WithPortBinding(RabbitMqPort) + .WithPortBinding("15672") + .WithWaitStrategy(Wait.ForUnixContainer().UntilExternalTcpPortIsAvailable(RabbitMqPort)) .Build(); public Task InitializeAsync() @@ -38,8 +38,7 @@ public IRabbitMQConnectionFactory ConnectionFactory() => public int Port => _container.GetMappedPublicPort(RabbitMqPort); public string Hostname => _container.Hostname; - private IConnectionFactory CreateConnectionFactory() => - new ConnectionFactory { Uri = new Uri(_container.GetConnectionString()) }; + private ConnectionFactory CreateConnectionFactory() => new() { Uri = new Uri(_container.GetConnectionString()) }; private async Task CreateConnectionAsync() { diff --git a/test/Motor.Extensions.Hosting.RabbitMQ_UnitTest/Motor.Extensions.Hosting.RabbitMQ_UnitTest.csproj b/test/Motor.Extensions.Hosting.RabbitMQ_UnitTest/Motor.Extensions.Hosting.RabbitMQ_UnitTest.csproj index cb15abdfb..9c6c6179c 100644 --- a/test/Motor.Extensions.Hosting.RabbitMQ_UnitTest/Motor.Extensions.Hosting.RabbitMQ_UnitTest.csproj +++ b/test/Motor.Extensions.Hosting.RabbitMQ_UnitTest/Motor.Extensions.Hosting.RabbitMQ_UnitTest.csproj @@ -1,17 +1,12 @@ - - net8.0;net9.0 - false - enable - - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/test/Motor.Extensions.Hosting.RabbitMQ_UnitTest/RabbitMQMessageHostBuilderExtensionsTests.cs b/test/Motor.Extensions.Hosting.RabbitMQ_UnitTest/RabbitMQMessageHostBuilderExtensionsTests.cs index f4e47ef7a..b15f32350 100644 --- a/test/Motor.Extensions.Hosting.RabbitMQ_UnitTest/RabbitMQMessageHostBuilderExtensionsTests.cs +++ b/test/Motor.Extensions.Hosting.RabbitMQ_UnitTest/RabbitMQMessageHostBuilderExtensionsTests.cs @@ -1,6 +1,3 @@ -using System; -using System.Collections.Generic; -using System.Linq; using System.Text; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -35,6 +32,15 @@ private static IMotorHostBuilder GetHostBuilder() mock.Setup(t => t.GetSource()).Returns(new Uri("motor://test")); return mock.Object; }); + services.AddTransient(_ => + { + var mock = new Mock>(); + + return mock.Object; + }); + services.AddTransient>(_ => + new Mock>().Object + ); } ); } diff --git a/test/Motor.Extensions.Hosting.SQS_IntegrationTest/Motor.Extensions.Hosting.SQS_IntegrationTest.csproj b/test/Motor.Extensions.Hosting.SQS_IntegrationTest/Motor.Extensions.Hosting.SQS_IntegrationTest.csproj index 4480d818c..4912f959f 100644 --- a/test/Motor.Extensions.Hosting.SQS_IntegrationTest/Motor.Extensions.Hosting.SQS_IntegrationTest.csproj +++ b/test/Motor.Extensions.Hosting.SQS_IntegrationTest/Motor.Extensions.Hosting.SQS_IntegrationTest.csproj @@ -1,21 +1,19 @@ - net8.0;net9.0 - false Motor.Extensions.Hosting.SQS_IntegrationTest - - - - - - - + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/test/Motor.Extensions.Hosting.Timer_IntegrationTest/Motor.Extensions.Hosting.Timer_IntegrationTest.csproj b/test/Motor.Extensions.Hosting.Timer_IntegrationTest/Motor.Extensions.Hosting.Timer_IntegrationTest.csproj index 8d86e7fd0..357de9702 100644 --- a/test/Motor.Extensions.Hosting.Timer_IntegrationTest/Motor.Extensions.Hosting.Timer_IntegrationTest.csproj +++ b/test/Motor.Extensions.Hosting.Timer_IntegrationTest/Motor.Extensions.Hosting.Timer_IntegrationTest.csproj @@ -1,17 +1,14 @@ - - net8.0;net9.0 - - - - - - + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/test/Motor.Extensions.Hosting_IntegrationTest/GenericHostingTests.cs b/test/Motor.Extensions.Hosting_IntegrationTest/GenericHostingTests.cs index 3f50f9ed9..300cfca98 100644 --- a/test/Motor.Extensions.Hosting_IntegrationTest/GenericHostingTests.cs +++ b/test/Motor.Extensions.Hosting_IntegrationTest/GenericHostingTests.cs @@ -233,15 +233,14 @@ IMetricsFactory metricsFactory ) { _logger.LogInformation("log your request"); - var tmpChar = dataCloudEvent.TypedData.ToCharArray(); if (!ActivitySource.HasListeners()) { throw new ArgumentException(); } - var reversed = tmpChar.Reverse().ToArray(); + var reversed = new string(dataCloudEvent.TypedData.Reverse().ToArray()); _summary.WithLabels("collect_your_metrics").Observe(1.0); - return Task.FromResult?>(dataCloudEvent.CreateNew(new string(reversed))); + return Task.FromResult?>(dataCloudEvent.CreateNew(reversed)); } } diff --git a/test/Motor.Extensions.Hosting_IntegrationTest/Motor.Extensions.Hosting_IntegrationTest.csproj b/test/Motor.Extensions.Hosting_IntegrationTest/Motor.Extensions.Hosting_IntegrationTest.csproj index f309e9c16..2bf8c5fca 100644 --- a/test/Motor.Extensions.Hosting_IntegrationTest/Motor.Extensions.Hosting_IntegrationTest.csproj +++ b/test/Motor.Extensions.Hosting_IntegrationTest/Motor.Extensions.Hosting_IntegrationTest.csproj @@ -1,21 +1,16 @@ - - net8.0;net9.0 - false - enable - - - - - - + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + diff --git a/test/Motor.Extensions.Hosting_UnitTest/HealthChecks/MessageProcessingHealthCheckTest.cs b/test/Motor.Extensions.Hosting_UnitTest/HealthChecks/MessageProcessingHealthCheckTest.cs index 202308f01..1b20e50f5 100644 --- a/test/Motor.Extensions.Hosting_UnitTest/HealthChecks/MessageProcessingHealthCheckTest.cs +++ b/test/Motor.Extensions.Hosting_UnitTest/HealthChecks/MessageProcessingHealthCheckTest.cs @@ -21,7 +21,7 @@ public async Task CheckHealthAsync_QueueHasMessagesWithoutRecentAcknowledgement_ { var queue = CreateEmptyQueue(); var healthCheck = CreateHealthCheck(queue); - queue.QueueBackgroundWorkItem(MotorCloudEvent.CreateTestCloudEvent("message")); + queue.QueueBackgroundWorkItem(MotorCloudEvent.CreateTestCloudEvent("message")); await Task.Delay(_timeout * 2); var result = (await healthCheck.CheckHealthAsync(new HealthCheckContext())).Status; @@ -34,9 +34,9 @@ public async Task CheckHealthAsync_QueueHasMessagesButMessageWasRecentlyAcknowle { var queue = CreateEmptyQueue(); var healthCheck = CreateHealthCheck(queue); - queue.QueueBackgroundWorkItem(MotorCloudEvent.CreateTestCloudEvent("message0")); + queue.QueueBackgroundWorkItem(MotorCloudEvent.CreateTestCloudEvent("message0")); await queue.DequeueAsync(CancellationToken.None); - queue.QueueBackgroundWorkItem(MotorCloudEvent.CreateTestCloudEvent("message1")); + queue.QueueBackgroundWorkItem(MotorCloudEvent.CreateTestCloudEvent("message1")); var result = (await healthCheck.CheckHealthAsync(new HealthCheckContext())).Status; @@ -60,7 +60,7 @@ public async Task CheckHealthAsync_QueueBecomesEmptyLongerThanTimeout_ServiceIsH { var queue = CreateEmptyQueue(); var healthCheck = CreateHealthCheck(queue); - queue.QueueBackgroundWorkItem(MotorCloudEvent.CreateTestCloudEvent("message")); + queue.QueueBackgroundWorkItem(MotorCloudEvent.CreateTestCloudEvent("message")); await queue.DequeueAsync(CancellationToken.None); await Task.Delay(_timeout * 2); @@ -74,7 +74,7 @@ public async Task CheckHealthAsync_QueueIsEmptyAndMessageWasRecentlyAcknowledged { var queue = CreateEmptyQueue(); var healthCheck = CreateHealthCheck(queue); - queue.QueueBackgroundWorkItem(MotorCloudEvent.CreateTestCloudEvent("message")); + queue.QueueBackgroundWorkItem(MotorCloudEvent.CreateTestCloudEvent("message")); await queue.DequeueAsync(CancellationToken.None); var result = (await healthCheck.CheckHealthAsync(new HealthCheckContext())).Status; @@ -88,7 +88,7 @@ public async Task CheckHealthAsync_MessageAppearsInQueueAfterQueueHasBeenEmpty_S var queue = CreateEmptyQueue(); var healthCheck = CreateHealthCheck(queue); await Task.Delay(_timeout * 2); - queue.QueueBackgroundWorkItem(MotorCloudEvent.CreateTestCloudEvent("message")); + queue.QueueBackgroundWorkItem(MotorCloudEvent.CreateTestCloudEvent("message")); var result = (await healthCheck.CheckHealthAsync(new HealthCheckContext())).Status; @@ -100,7 +100,7 @@ public async Task CheckHealthAsync_MessageRemainsInQueueLongerThanTimeout_Servic { var queue = CreateEmptyQueue(); var healthCheck = CreateHealthCheck(queue); - queue.QueueBackgroundWorkItem(MotorCloudEvent.CreateTestCloudEvent("message")); + _ = queue.QueueBackgroundWorkItem(MotorCloudEvent.CreateTestCloudEvent("message")); await Task.Delay(_timeout * 2); var result = (await healthCheck.CheckHealthAsync(new HealthCheckContext())).Status; diff --git a/test/Motor.Extensions.Hosting_UnitTest/Motor.Extensions.Hosting_UnitTest.csproj b/test/Motor.Extensions.Hosting_UnitTest/Motor.Extensions.Hosting_UnitTest.csproj index 37e67cddb..a88c741dd 100644 --- a/test/Motor.Extensions.Hosting_UnitTest/Motor.Extensions.Hosting_UnitTest.csproj +++ b/test/Motor.Extensions.Hosting_UnitTest/Motor.Extensions.Hosting_UnitTest.csproj @@ -1,15 +1,12 @@ - net8.0;net9.0 - false - enable Test - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/Motor.Extensions.Http_UnitTest/Motor.Extensions.Http_UnitTest.csproj b/test/Motor.Extensions.Http_UnitTest/Motor.Extensions.Http_UnitTest.csproj index 0e17e0ae4..6bb79aa85 100644 --- a/test/Motor.Extensions.Http_UnitTest/Motor.Extensions.Http_UnitTest.csproj +++ b/test/Motor.Extensions.Http_UnitTest/Motor.Extensions.Http_UnitTest.csproj @@ -1,15 +1,11 @@ - - net8.0;net9.0 - false - - - - - - - + + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/Motor.Extensions.Utilities_IntegrationTest/DemonstrationTests.cs b/test/Motor.Extensions.Utilities_IntegrationTest/DemonstrationTests.cs index 6223809df..6ee4e90c6 100644 --- a/test/Motor.Extensions.Utilities_IntegrationTest/DemonstrationTests.cs +++ b/test/Motor.Extensions.Utilities_IntegrationTest/DemonstrationTests.cs @@ -1,8 +1,6 @@ -using System; -using System.Linq; using System.Text; -using System.Threading; -using System.Threading.Tasks; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; @@ -23,32 +21,32 @@ namespace Motor.Extensions.Utilities_IntegrationTest; [Collection("GenericHosting")] -public class DemonstrationTests : GenericHostingTestBase, IClassFixture +public class DemonstrationTests(RabbitMQFixture fixture) + : GenericHostingTestBase(fixture), + IClassFixture { - public DemonstrationTests(RabbitMQFixture fixture) - : base(fixture) { } - - [Fact(Timeout = 60000)] + [Fact] public async Task StartAsync_SetupAndStartReverseStringServiceAndPublishMessageIntoServiceQueue_MessageInDestinationQueueIsReversed() { - PrepareQueues(); - const string message = "12345"; - using var host = GetReverseStringService(); - var channel = await (await Fixture.ConnectionAsync()).CreateChannelAsync(); - await CreateQueueForServicePublisherWithPublisherBindingFromConfigAsync(channel); + using var host = GetReverseStringService(RandomHttpPort); + await using var connection = await Fixture.ConnectionAsync(); + var publisherChannel = await connection.CreateChannelAsync(); + await CreateQueueForServicePublisherWithPublisherBindingFromConfigAsync(publisherChannel); await host.StartAsync(); - PublishMessageIntoQueueOfServiceAsync(channel, message); + await PublishMessageIntoQueueOfServiceAsync(publisherChannel, message); + + await using var consumerChannel = await connection.CreateChannelAsync(); - var actual = await GetMessageFromDestinationQueue(channel); + var actual = await GetMessageFromDestinationQueue(consumerChannel); Assert.Equal("54321", actual); await host.StopAsync(); } - private static IHost GetReverseStringService() + private IHost GetReverseStringService(ushort listenerPort, int prefetchCount = 1) { - var host = MotorHost + var builder = MotorHost .CreateDefaultBuilder() .ConfigureSingleOutputService() .ConfigureServices( @@ -71,15 +69,34 @@ private static IHost GetReverseStringService() builder.AddSerializer(); } ) - .Build(); + .ConfigureAppConfiguration(config => + { + config.AddInMemoryCollection( + new Dictionary + { + { "RabbitMQConsumer:Port", Fixture.Port.ToString() }, + { "RabbitMQConsumer:Host", Fixture.Hostname }, + { "RabbitMQConsumer:Queue:Name", ConsumerQueueName }, + { "RabbitMQConsumer:PrefetchCount", prefetchCount.ToString() }, + { "RabbitMQPublisher:PublishingTarget:RoutingKey", RoutingKey }, + { "RabbitMQPublisher:Port", Fixture.Port.ToString() }, + { "RabbitMQPublisher:Host", Fixture.Hostname }, + { "DestinationQueueName", DestinationQueueName }, + } + ); + }); + + if (builder is MotorHostBuilder motorHostBuilder) + { + motorHostBuilder.UseSetting(WebHostDefaults.ServerUrlsKey, $"http://0.0.0.0:{listenerPort}"); + } - return host; + return builder.Build(); } - private static async Task GetMessageFromDestinationQueue(IChannel channel) + private async Task GetMessageFromDestinationQueue(IChannel channel) { var taskCompletionSource = new TaskCompletionSource(); - var destinationQueueName = Environment.GetEnvironmentVariable("DestinationQueueName") ?? "DefaultQueueName"; var consumer = new AsyncEventingBasicConsumer(channel); var messageFromDestinationQueue = string.Empty; consumer.ReceivedAsync += (_, args) => @@ -89,25 +106,23 @@ private static async Task GetMessageFromDestinationQueue(IChannel channe taskCompletionSource.TrySetResult(); return Task.CompletedTask; }; - await channel.BasicConsumeAsync(destinationQueueName, false, consumer); - await Task.WhenAny(taskCompletionSource.Task, Task.Delay(TimeSpan.FromSeconds(10))); + await channel.BasicConsumeAsync(DestinationQueueName, false, consumer); + await Task.WhenAny(taskCompletionSource.Task, Task.Delay(TimeSpan.FromSeconds(60))); return messageFromDestinationQueue; } - protected class ReverseStringConverter : ISingleOutputService + protected class ReverseStringConverter( + ILogger logger, + IMetricsFactory metricsFactory + ) : ISingleOutputService { - private readonly ILogger _logger; - private readonly IMetricFamily _summary; - - public ReverseStringConverter( - ILogger logger, - IMetricsFactory metricsFactory - ) - { - _logger = logger; - _summary = metricsFactory.CreateSummary("summaryName", "summaryHelpString", new[] { "someLabel" }); - } + private readonly ILogger _logger = logger; + private readonly IMetricFamily _summary = metricsFactory.CreateSummary( + "summaryName", + "summaryHelpString", + new[] { "someLabel" } + ); public Task?> ConvertMessageAsync( MotorCloudEvent dataCloudEvent, @@ -117,10 +132,16 @@ IMetricsFactory metricsFactory var parentContext = dataCloudEvent.GetActivityContext(); Assert.NotEqual(default, parentContext); _logger.LogInformation("log your request"); - var tmpChar = dataCloudEvent.TypedData.ToCharArray(); - var reversed = tmpChar.Reverse().ToArray(); + + var chars = dataCloudEvent.TypedData.ToCharArray(); + for (var i = 0; i < chars.Length / 2; i++) + { + (chars[chars.Length - 1 - i], chars[i]) = (chars[i], chars[chars.Length - 1 - i]); + } + + var reversed = new string(chars); _summary.WithLabels("collect_your_metrics").Observe(1.0); - return Task.FromResult?>(dataCloudEvent.CreateNew(new string(reversed))); + return Task.FromResult?>(dataCloudEvent.CreateNew(reversed)); } } } diff --git a/test/Motor.Extensions.Utilities_IntegrationTest/GenericHostingTestBase.cs b/test/Motor.Extensions.Utilities_IntegrationTest/GenericHostingTestBase.cs index 313269b73..856f9081e 100644 --- a/test/Motor.Extensions.Utilities_IntegrationTest/GenericHostingTestBase.cs +++ b/test/Motor.Extensions.Utilities_IntegrationTest/GenericHostingTestBase.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; using System.Text; -using System.Threading.Tasks; using Motor.Extensions.Conversion.Abstractions; using Motor.Extensions.Hosting.RabbitMQ_IntegrationTest; using RabbitMQ.Client; @@ -12,43 +9,36 @@ namespace Motor.Extensions.Utilities_IntegrationTest; public abstract class GenericHostingTestBase { + private static readonly Random Random = new(); + protected RabbitMQFixture Fixture { get; } + protected string RoutingKey { get; } + protected string ConsumerQueueName { get; } + protected string DestinationQueueName { get; } protected GenericHostingTestBase(RabbitMQFixture fixture) { Fixture = fixture; - } - protected void PrepareQueues(int prefetchCount = 1) - { var randomizerString = RandomizerFactory.GetRandomizer(new FieldOptionsTextRegex { Pattern = @"^[A-Z]{10}" }); - Environment.SetEnvironmentVariable("RabbitMQConsumer__Port", Fixture.Port.ToString()); - Environment.SetEnvironmentVariable("RabbitMQConsumer__Host", Fixture.Hostname); - Environment.SetEnvironmentVariable("RabbitMQConsumer__Queue__Name", randomizerString.Generate()); - Environment.SetEnvironmentVariable("RabbitMQConsumer__PrefetchCount", prefetchCount.ToString()); - Environment.SetEnvironmentVariable( - "RabbitMQPublisher__PublishingTarget__RoutingKey", - randomizerString.Generate() - ); - Environment.SetEnvironmentVariable("RabbitMQPublisher__Port", Fixture.Port.ToString()); - Environment.SetEnvironmentVariable("RabbitMQPublisher__Host", Fixture.Hostname); - Environment.SetEnvironmentVariable("DestinationQueueName", randomizerString.Generate()); + + RoutingKey = randomizerString.Generate()!; + ConsumerQueueName = randomizerString.Generate()!; + DestinationQueueName = randomizerString.Generate()!; } - protected static async Task CreateQueueForServicePublisherWithPublisherBindingFromConfigAsync(IChannel channel) + protected ushort RandomHttpPort { get; } = (ushort)Random.Next(ushort.MaxValue); + + protected async Task CreateQueueForServicePublisherWithPublisherBindingFromConfigAsync(IChannel channel) { - var destinationQueueName = Environment.GetEnvironmentVariable("DestinationQueueName") ?? "DefaultQueueName"; const string destinationExchange = "amq.topic"; - var destinationRoutingKey = - Environment.GetEnvironmentVariable("RabbitMQPublisher__PublishingTarget__RoutingKey") - ?? "DefaultRoutingKey"; var emptyArguments = new Dictionary(); - await channel.QueueDeclareAsync(destinationQueueName, true, false, false, emptyArguments); - await channel.QueueBindAsync(destinationQueueName, destinationExchange, destinationRoutingKey, emptyArguments); + await channel.QueueDeclareAsync(DestinationQueueName, true, false, false, emptyArguments); + await channel.QueueBindAsync(DestinationQueueName, destinationExchange, RoutingKey, emptyArguments); await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false); } - protected static async Task PublishMessageIntoQueueOfServiceAsync( + protected async Task PublishMessageIntoQueueOfServiceAsync( IChannel channel, string messageToPublish, IDictionary? rabbitMqHeaders = null diff --git a/test/Motor.Extensions.Utilities_IntegrationTest/GenericHostingTests.cs b/test/Motor.Extensions.Utilities_IntegrationTest/GenericHostingTests.cs index 2cda3431c..cb6c42c3e 100644 --- a/test/Motor.Extensions.Utilities_IntegrationTest/GenericHostingTests.cs +++ b/test/Motor.Extensions.Utilities_IntegrationTest/GenericHostingTests.cs @@ -1,8 +1,5 @@ -using System; using System.Net; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; +using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Diagnostics.HealthChecks; @@ -19,42 +16,47 @@ using Motor.Extensions.Http; using Motor.Extensions.Utilities; using Polly; +using RandomDataGenerator.FieldOptions; +using RandomDataGenerator.Randomizers; using Xunit; namespace Motor.Extensions.Utilities_IntegrationTest; [Collection("GenericHosting")] -public class GenericHostingTests : GenericHostingTestBase, IClassFixture +public class GenericHostingTests(RabbitMQFixture fixture) + : GenericHostingTestBase(fixture), + IClassFixture { - public GenericHostingTests(RabbitMQFixture fixture) - : base(fixture) { } - [Fact(Timeout = 60000)] public async Task StartAsync_UseConfigureDefaultMessageHandlerWithMessageProcessingHealthCheck_HealthCheckUnhealthy() { const string maxTimeSinceLastProcessedMessage = "00:00:00.1"; - Environment.SetEnvironmentVariable( - "HealthChecks__MessageProcessingHealthCheck__MaxTimeSinceLastProcessedMessage", - maxTimeSinceLastProcessedMessage - ); + var messageCount = Environment.ProcessorCount + 1; - PrepareQueues(messageCount); const string message = "somestring"; - using var host = GetStringService(); - var channel = await (await Fixture.ConnectionAsync()).CreateChannelAsync(); + using var host = GetStringService( + listenerPort: RandomHttpPort, + prefetchCount: messageCount, + additionalOverrides: new KeyValuePair( + "HealthChecks:MessageProcessingHealthCheck:MaxTimeSinceLastProcessedMessage", + maxTimeSinceLastProcessedMessage + ) + ); + await using var connection = await Fixture.ConnectionAsync(); + await using var channel = await connection.CreateChannelAsync(); await CreateQueueForServicePublisherWithPublisherBindingFromConfigAsync(channel); await host.StartAsync(); + for (var i = 0; i < messageCount; i++) { await PublishMessageIntoQueueOfServiceAsync(channel, message); } - var httpClient = new HttpClient(); + using var httpClient = HttpClient(); await WaitUntilAsync(async () => { - var healthResponse = await httpClient.GetAsync("http://localhost:9110/health"); - + using var healthResponse = await httpClient.GetAsync($"http://localhost:{RandomHttpPort}/health"); Assert.Equal(HttpStatusCode.ServiceUnavailable, healthResponse.StatusCode); Assert.Equal(nameof(HealthStatus.Unhealthy), await healthResponse.Content.ReadAsStringAsync()); }); @@ -65,25 +67,29 @@ await WaitUntilAsync(async () => public async Task StartAsync_UseConfigureDefaultMessageHandlerWithMessageProcessingHealthCheck_HealthCheckHealthy() { const string maxTimeSinceLastProcessedMessage = "00:01:00"; - Environment.SetEnvironmentVariable( - "HealthChecks__MessageProcessingHealthCheck__MaxTimeSinceLastProcessedMessage", - maxTimeSinceLastProcessedMessage - ); var messageCount = Environment.ProcessorCount + 1; - PrepareQueues(messageCount); const string message = "somestring"; - using var host = GetStringService(); - var channel = await (await Fixture.ConnectionAsync()).CreateChannelAsync(); + using var host = GetStringService( + listenerPort: RandomHttpPort, + prefetchCount: messageCount, + additionalOverrides: new KeyValuePair( + "HealthChecks:MessageProcessingHealthCheck:MaxTimeSinceLastProcessedMessage", + maxTimeSinceLastProcessedMessage + ) + ); + await using var connection = await Fixture.ConnectionAsync(); + await using var channel = await connection.CreateChannelAsync(); await CreateQueueForServicePublisherWithPublisherBindingFromConfigAsync(channel); await host.StartAsync(); + for (var i = 0; i < messageCount; i++) { await PublishMessageIntoQueueOfServiceAsync(channel, message); } - var httpClient = new HttpClient(); + using var httpClient = HttpClient(); - var healthResponse = await httpClient.GetAsync("http://localhost:9110/health"); + var healthResponse = await httpClient.GetAsync($"http://localhost:{RandomHttpPort}/health"); Assert.Equal(HttpStatusCode.OK, healthResponse.StatusCode); Assert.Equal(nameof(HealthStatus.Healthy), await healthResponse.Content.ReadAsStringAsync()); @@ -94,22 +100,26 @@ public async Task StartAsync_UseConfigureDefaultMessageHandlerWithMessageProcess public async Task StartAsync_UseConfigureDefaultMessageHandlerWithTooManyTemporaryFailuresHealthCheck_HealthCheckUnhealthy() { const int messageCount = 20; - PrepareQueues(messageCount); const string message = "somestring"; - using var host = GetStringService(); - var channel = await (await Fixture.ConnectionAsync()).CreateChannelAsync(); + using var host = GetStringService( + listenerPort: RandomHttpPort, + prefetchCount: messageCount + ); + await using var connection = await Fixture.ConnectionAsync(); + await using var channel = await connection.CreateChannelAsync(); await CreateQueueForServicePublisherWithPublisherBindingFromConfigAsync(channel); await host.StartAsync(); + for (var i = 0; i < messageCount; i++) { await PublishMessageIntoQueueOfServiceAsync(channel, message); } - var httpClient = new HttpClient(); + using var httpClient = HttpClient(); await WaitUntilAsync(async () => { - var healthResponse = await httpClient.GetAsync("http://localhost:9110/health"); + var healthResponse = await httpClient.GetAsync($"http://localhost:{RandomHttpPort}/health"); Assert.Equal(HttpStatusCode.ServiceUnavailable, healthResponse.StatusCode); Assert.Equal(nameof(HealthStatus.Unhealthy), await healthResponse.Content.ReadAsStringAsync()); }); @@ -120,22 +130,26 @@ await WaitUntilAsync(async () => public async Task StartAsync_UseConfigureDefaultMessageHandlerWithTooManyTemporaryFailuresHealthCheck_HealthCheckHealthy() { const int messageCount = 20; - PrepareQueues(messageCount); const string message = "somestring"; - using var host = GetStringService(); - var channel = await (await Fixture.ConnectionAsync()).CreateChannelAsync(); + using var host = GetStringService( + listenerPort: RandomHttpPort, + prefetchCount: messageCount + ); + await using var connection = await Fixture.ConnectionAsync(); + await using var channel = await connection.CreateChannelAsync(); await CreateQueueForServicePublisherWithPublisherBindingFromConfigAsync(channel); await host.StartAsync(); + for (var i = 0; i < messageCount; i++) { await PublishMessageIntoQueueOfServiceAsync(channel, message); } - var httpClient = new HttpClient(); + using var httpClient = HttpClient(); await WaitUntilAsync(async () => { - var healthResponse = await httpClient.GetAsync("http://localhost:9110/health"); + var healthResponse = await httpClient.GetAsync($"http://localhost:{RandomHttpPort}/health"); Assert.Equal(HttpStatusCode.OK, healthResponse.StatusCode); Assert.Equal(nameof(HealthStatus.Healthy), await healthResponse.Content.ReadAsStringAsync()); @@ -143,10 +157,16 @@ await WaitUntilAsync(async () => await host.StopAsync(); } - private static IHost GetStringService() + private IHost GetStringService( + ushort listenerPort = 9110, + int prefetchCount = 1, + params KeyValuePair[] additionalOverrides + ) where TConverter : class, ISingleOutputService { - var host = new MotorHostBuilder(new HostBuilder()) + var randomizerString = RandomizerFactory.GetRandomizer(new FieldOptionsTextRegex { Pattern = @"^[A-Z]{10}" }); + + var builder = new MotorHostBuilder(new HostBuilder()) .UseSetting(MotorHostDefaults.EnablePrometheusEndpointKey, false.ToString()) .ConfigureSerilog() .ConfigurePrometheus() @@ -182,17 +202,41 @@ private static IHost GetStringService() .ConfigureAppConfiguration( (_, config) => { + var settingOverrides = new Dictionary + { + { "RabbitMQConsumer:Port", Fixture.Port.ToString() }, + { "RabbitMQConsumer:Host", Fixture.Hostname }, + { "RabbitMQConsumer:Queue:Name", randomizerString.Generate() }, + { "RabbitMQConsumer:PrefetchCount", prefetchCount.ToString() }, + { "RabbitMQPublisher:PublishingTarget:RoutingKey", randomizerString.Generate() }, + { "RabbitMQPublisher:Port", Fixture.Port.ToString() }, + { "RabbitMQPublisher:Host", Fixture.Hostname }, + { "DestinationQueueName", randomizerString.Generate() }, + { "Prometheus:Port", $"{listenerPort}" }, + }; + config.AddJsonFile("appsettings.json", true, false); - config.AddEnvironmentVariables(); + config.AddInMemoryCollection(settingOverrides); + config.AddInMemoryCollection(additionalOverrides); } ) - .ConfigureDefaultHttpClient() - .Build(); - return host; + .ConfigureDefaultHttpClient(); + + if (builder is MotorHostBuilder motorHostBuilder) + { + motorHostBuilder.UseSetting(WebHostDefaults.ServerUrlsKey, $"http://0.0.0.0:{listenerPort}"); + } + + return builder.Build(); } + private static HttpClient HttpClient() => new() { Timeout = TimeSpan.FromSeconds(5) }; + private static Task WaitUntilAsync(Func action) => - Policy.Handle().RetryForeverAsync().ExecuteAsync(async () => await action()); + Policy + .Handle() + .WaitAndRetryForeverAsync(_ => TimeSpan.FromMilliseconds(250)) + .ExecuteAsync(async () => await action()); private class TimingOutMessageConverter : ISingleOutputService { diff --git a/test/Motor.Extensions.Utilities_IntegrationTest/Motor.Extensions.Utilities_IntegrationTest.csproj b/test/Motor.Extensions.Utilities_IntegrationTest/Motor.Extensions.Utilities_IntegrationTest.csproj index e5f5dd6ea..809c673ba 100644 --- a/test/Motor.Extensions.Utilities_IntegrationTest/Motor.Extensions.Utilities_IntegrationTest.csproj +++ b/test/Motor.Extensions.Utilities_IntegrationTest/Motor.Extensions.Utilities_IntegrationTest.csproj @@ -1,16 +1,13 @@ - net8.0;net9.0 test - false Motor.NET - enable - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/Motor.Extensions.Utilities_IntegrationTest/appsettings.json b/test/Motor.Extensions.Utilities_IntegrationTest/appsettings.json index 9dd22d772..78f802c0c 100644 --- a/test/Motor.Extensions.Utilities_IntegrationTest/appsettings.json +++ b/test/Motor.Extensions.Utilities_IntegrationTest/appsettings.json @@ -3,7 +3,7 @@ "MinimumLevel": { "Default": "Information", "Override": { - "Microsoft": "Information", + "Microsoft": "Warning", "System": "Warning", "Motor.Extensions.Hosting.SingleOutputServiceAdapter": "Fatal", "Motor.Extensions.Utilities_IntegrationTest.DemonstrationTests": "Warning" @@ -49,4 +49,4 @@ "Port": 9110 }, "TestConfig": "appsettings.json" -} \ No newline at end of file +}