diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 824bd5f..36a597b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,30 +18,32 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + + - uses: actions/checkout@v4 with: fetch-depth: 1 + - run: | git fetch --prune --unshallow --tags echo exit code $? git tag --list - - uses: actions/setup-dotnet@v1 + + - uses: actions/setup-dotnet@v4 with: - dotnet-version: | - 5.0.x - 6.0.x - source-url: https://nuget.pkg.github.com/elastic/index.json - env: - NUGET_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}} + global-json-file: ./global.json - run: ./build.sh build -s true name: Build + - run: ./build.sh test -s true name: Test + - run: ./build.sh generatepackages -s true name: Generate local nuget packages + - run: ./build.sh validatepackages -s true name: "validate *.npkg files that were created" + - run: ./build.sh generateapichanges -s true name: "Inspect public API changes" @@ -49,7 +51,8 @@ jobs: if: github.event_name == 'push' && startswith(github.ref, 'refs/heads') shell: bash run: | - until dotnet nuget push 'build/output/*.nupkg' -k ${{secrets.GITHUB_TOKEN}} --skip-duplicate --no-symbols; do echo "Retrying"; sleep 1; done; + dotnet nuget add source --username USERNAME --password ${{secrets.GITHUB_TOKEN}} --store-password-in-clear-text --name github "https://nuget.pkg.github.com/elastic/index.json" + until dotnet nuget push 'build/output/*.nupkg' -k ${{secrets.GITHUB_TOKEN}} --skip-duplicate --no-symbols --source "github"; do echo "Retrying"; sleep 1; done; # Github packages requires authentication, this is likely going away in the future so for now we publish to feedz.io - run: dotnet nuget push 'build/output/*.nupkg' -k ${{secrets.FEEDZ_IO_API_KEY}} -s https://f.feedz.io/elastic/all/nuget/index.json --skip-duplicate --no-symbols @@ -59,6 +62,7 @@ jobs: - run: ./build.sh generatereleasenotes -s true name: Generate release notes for tag if: github.event_name == 'push' && startswith(github.ref, 'refs/tags') + - run: ./build.sh createreleaseongithub -s true --token ${{secrets.GITHUB_TOKEN}} if: github.event_name == 'push' && startswith(github.ref, 'refs/tags') name: Create or update release for tag on github diff --git a/.github/workflows/test-windows.yml b/.github/workflows/test-windows.yml index 3075bd3..1330bdc 100644 --- a/.github/workflows/test-windows.yml +++ b/.github/workflows/test-windows.yml @@ -20,6 +20,7 @@ on: permissions: contents: read + checks: write concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -32,10 +33,10 @@ defaults: jobs: tests: runs-on: windows-2022 - + steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 1 @@ -45,7 +46,7 @@ jobs: git tag --list name: Fetch Tags - - uses: actions/cache@v3 + - uses: actions/cache@v4 name: NuGet package cache with: path: ~/.nuget/packages @@ -54,10 +55,9 @@ jobs: ${{ runner.os }}-nuget - name: Setup dotnet - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 with: - dotnet-version: | - 6.0.x + global-json-file: ./global.json - run: ./build.bat build -s true name: Build @@ -67,7 +67,7 @@ jobs: - name: Test Results if: success() || failure() - uses: mikepenz/action-junit-report@v3 + uses: mikepenz/action-junit-report@v4 with: report_paths: 'build/output/junit-*.xml' github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 32b2f99..f5250c7 100644 --- a/.gitignore +++ b/.gitignore @@ -78,5 +78,6 @@ project.lock.json /src/.vs/restore.dg src/packages/ BenchmarkDotNet.Artifacts +*.received.* /.ionide/symbolCache.db \ No newline at end of file diff --git a/Directory.Build.props b/Directory.Build.props index b876476..0578304 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -18,6 +18,9 @@ - + + all + runtime; build; native; contentfiles; analyzers + \ No newline at end of file diff --git a/elastic-transport-net.sln b/Elastic.Transport.sln similarity index 100% rename from elastic-transport-net.sln rename to Elastic.Transport.sln diff --git a/elastic-transport-net.sln.DotSettings b/Elastic.Transport.sln.DotSettings similarity index 100% rename from elastic-transport-net.sln.DotSettings rename to Elastic.Transport.sln.DotSettings diff --git a/Playground/Playground.csproj b/Playground/Playground.csproj index ed2c1d5..b74430c 100644 --- a/Playground/Playground.csproj +++ b/Playground/Playground.csproj @@ -2,21 +2,17 @@ Exe - net6.0 + net8.0 enable enable - + - - - - diff --git a/benchmarks/Elastic.Transport.Benchmarks/Elastic.Transport.Benchmarks.csproj b/benchmarks/Elastic.Transport.Benchmarks/Elastic.Transport.Benchmarks.csproj index 24cb378..9020580 100644 --- a/benchmarks/Elastic.Transport.Benchmarks/Elastic.Transport.Benchmarks.csproj +++ b/benchmarks/Elastic.Transport.Benchmarks/Elastic.Transport.Benchmarks.csproj @@ -3,8 +3,7 @@ Exe false - net6.0 - 9.0 + net8.0 @@ -16,8 +15,4 @@ - - - - diff --git a/benchmarks/Elastic.Transport.Profiling/Elastic.Transport.Profiling.csproj b/benchmarks/Elastic.Transport.Profiling/Elastic.Transport.Profiling.csproj index 4f92533..64bebbe 100644 --- a/benchmarks/Elastic.Transport.Profiling/Elastic.Transport.Profiling.csproj +++ b/benchmarks/Elastic.Transport.Profiling/Elastic.Transport.Profiling.csproj @@ -2,19 +2,15 @@ Exe - net6.0 + net8.0 - + - - - - diff --git a/build/scripts/CommandLine.fs b/build/scripts/CommandLine.fs index 12a4cc5..545f2b0 100644 --- a/build/scripts/CommandLine.fs +++ b/build/scripts/CommandLine.fs @@ -29,11 +29,11 @@ with interface IArgParserTemplate with member this.Usage = match this with - | Clean _ -> "clean known output locations" - | Build _ -> "Run build" - | Test _ -> "Runs build then tests" - | Release _ -> "runs build, tests, and create and validates the packages shy of publishing them" - | Publish _ -> "Runs the full release" + | Clean -> "clean known output locations" + | Build -> "Run build" + | Test -> "Runs build then tests" + | Release -> "runs build, tests, and create and validates the packages shy of publishing them" + | Publish -> "Runs the full release" | SingleTarget _ -> "Runs the provided sub command without running their dependencies" | Token _ -> "Token to be used to authenticate with github" diff --git a/build/scripts/Targets.fs b/build/scripts/Targets.fs index f65d4f2..3b490f6 100644 --- a/build/scripts/Targets.fs +++ b/build/scripts/Targets.fs @@ -71,7 +71,7 @@ let private test (arguments:ParseResults) = let loggerPathArgs = sprintf "LogFilePath=%s" junitOutput let loggerArg = sprintf "--logger:\"junit;%s\"" loggerPathArgs let tfmArgs = - if getOS = OS.Windows then [] else ["-f"; "net6.0"] + if getOS = OS.Windows then [] else ["-f"; "net8.0"] exec "dotnet" (["test"; "-c"; "Release"; loggerArg] @ tfmArgs) |> ignore let private generatePackages (arguments:ParseResults) = diff --git a/build/scripts/scripts.fsproj b/build/scripts/scripts.fsproj index d5536cc..6adfd3b 100644 --- a/build/scripts/scripts.fsproj +++ b/build/scripts/scripts.fsproj @@ -1,15 +1,15 @@ - + Exe - net6.0 + net8.0 false - + - + @@ -19,8 +19,4 @@ - - - - diff --git a/dotnet-tools.json b/dotnet-tools.json index c0b6b3e..9348a47 100644 --- a/dotnet-tools.json +++ b/dotnet-tools.json @@ -9,19 +9,19 @@ ] }, "assembly-differ": { - "version": "0.13.0", + "version": "0.15.0", "commands": [ "assembly-differ" ] }, "release-notes": { - "version": "0.3.0", + "version": "0.6.0", "commands": [ "release-notes" ] }, "nupkg-validator": { - "version": "0.5.0", + "version": "0.6.0", "commands": [ "nupkg-validator" ] diff --git a/global.json b/global.json index 4b23320..72d38cd 100644 --- a/global.json +++ b/global.json @@ -1,7 +1,7 @@ { "sdk": { - "version": "6.0.403", - "rollForward": "latestFeature", + "version": "8.0.100", + "rollForward": "latestMajor", "allowPrerelease": false } } \ No newline at end of file diff --git a/src/Elastic.Transport.VirtualizedCluster/Elastic.Transport.VirtualizedCluster.csproj b/src/Elastic.Transport.VirtualizedCluster/Elastic.Transport.VirtualizedCluster.csproj index 887484e..7527c3d 100644 --- a/src/Elastic.Transport.VirtualizedCluster/Elastic.Transport.VirtualizedCluster.csproj +++ b/src/Elastic.Transport.VirtualizedCluster/Elastic.Transport.VirtualizedCluster.csproj @@ -12,11 +12,12 @@ true netstandard2.0 + + - - + diff --git a/src/Elastic.Transport/Components/Serialization/Converters/ExceptionConverter.cs b/src/Elastic.Transport/Components/Serialization/Converters/ExceptionConverter.cs index a635f0a..f96d545 100644 --- a/src/Elastic.Transport/Components/Serialization/Converters/ExceptionConverter.cs +++ b/src/Elastic.Transport/Components/Serialization/Converters/ExceptionConverter.cs @@ -4,9 +4,6 @@ using System; using System.Collections.Generic; -using System.Globalization; -using System.Reflection; -using System.Runtime.Serialization; using System.Text.Json; using System.Text.Json.Serialization; using JsonSerializer = System.Text.Json.JsonSerializer; @@ -19,6 +16,8 @@ namespace Elastic.Transport; /// internal class ExceptionConverter : JsonConverter { + public override bool CanConvert(Type typeToConvert) => typeof(Exception).IsAssignableFrom(typeToConvert); + private static List> FlattenExceptions(Exception e) { var maxExceptions = 20; @@ -37,62 +36,21 @@ private static List> FlattenExceptions(Exception e) private static Dictionary ToDictionary(Exception e, int depth) { - var o = new Dictionary(10); - var si = new SerializationInfo(e.GetType(), new FormatterConverter()); - var sc = new StreamingContext(); - e.GetObjectData(si, sc); + var o = new Dictionary(7); - var helpUrl = si.GetString("HelpURL"); - var stackTrace = si.GetString("StackTraceString"); - var remoteStackTrace = si.GetString("RemoteStackTraceString"); - var remoteStackIndex = si.GetInt32("RemoteStackIndex"); - var exceptionMethod = si.GetString("ExceptionMethod"); - var hresult = si.GetInt32("HResult"); - var source = si.GetString("Source"); - var className = si.GetString("ClassName"); + var className = e.GetType().FullName; o.Add("Depth", depth); o.Add("ClassName", className); o.Add("Message", e.Message); - o.Add("Source", source); - o.Add("StackTraceString", stackTrace); - o.Add("RemoteStackTraceString", remoteStackTrace); - o.Add("RemoteStackIndex", remoteStackIndex); - o.Add("HResult", hresult); - o.Add("HelpURL", helpUrl); + o.Add("Source", e.Source); + o.Add("StackTraceString", e.StackTrace); + o.Add("HResult", e.HResult); + o.Add("HelpURL", e.HelpLink); - WriteStructuredExceptionMethod(o, exceptionMethod); return o; } - private static void WriteStructuredExceptionMethod(Dictionary o, string exceptionMethodString) - { - if (string.IsNullOrWhiteSpace(exceptionMethodString)) return; - - var args = exceptionMethodString.Split('\0', '\n'); - - if (args.Length != 5) return; - - var memberType = int.Parse(args[0], CultureInfo.InvariantCulture); - var name = args[1]; - var assemblyName = args[2]; - var className = args[3]; - var signature = args[4]; - var an = new AssemblyName(assemblyName); - var exceptionMethod = new Dictionary(7) - { - { "Name", name }, - { "AssemblyName", an.Name }, - { "AssemblyVersion", an.Version.ToString() }, - { "AssemblyCulture", an.CultureName }, - { "ClassName", className }, - { "Signature", signature }, - { "MemberType", memberType } - }; - - o.Add("ExceptionMethod", exceptionMethod); - } - public override Exception Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => throw new NotSupportedException(); diff --git a/src/Elastic.Transport/DistributedTransport.cs b/src/Elastic.Transport/DistributedTransport.cs index 8b9f0a8..ea89b49 100644 --- a/src/Elastic.Transport/DistributedTransport.cs +++ b/src/Elastic.Transport/DistributedTransport.cs @@ -198,6 +198,7 @@ private async ValueTask RequestCoreAsync( } } else + { foreach (var node in pipeline.NextNode()) { attemptedNodes++; @@ -261,7 +262,9 @@ private async ValueTask RequestCoreAsync( throw new UnexpectedTransportException(killerException, seenExceptions) { - Request = requestData, ApiCallDetails = response?.ApiCallDetails, AuditTrail = pipeline.AuditTrail + Request = requestData, + ApiCallDetails = response?.ApiCallDetails, + AuditTrail = pipeline.AuditTrail }; } @@ -276,6 +279,7 @@ private async ValueTask RequestCoreAsync( pipeline.MarkAlive(node); break; } + } #if NET6_0_OR_GREATER activity?.SetStatus(response.ApiCallDetails.HasSuccessfulStatusCodeAndExpectedContentType ? ActivityStatusCode.Ok : ActivityStatusCode.Error); diff --git a/src/Elastic.Transport/Elastic.Transport.csproj b/src/Elastic.Transport/Elastic.Transport.csproj index eb117dc..411f866 100644 --- a/src/Elastic.Transport/Elastic.Transport.csproj +++ b/src/Elastic.Transport/Elastic.Transport.csproj @@ -7,15 +7,11 @@ Client connectivity bits, exposes a potentially cluster aware request pipeline that can be resilient to nodes dropping out of rotation. This package is heavily optimized for the Elastic (elastic.co) product suite and Elastic Cloud (cloud.elastic.co) SAAS offering. - latest true annotations - - - true true - netstandard2.0;netstandard2.1;net462;net6.0 + netstandard2.0;netstandard2.1;net462;net6.0;net8.0 @@ -32,16 +28,18 @@ - + - - + + + + + - - + diff --git a/tests/Elastic.Elasticsearch.IntegrationTests/DefaultCluster.cs b/tests/Elastic.Elasticsearch.IntegrationTests/DefaultCluster.cs index d6b4e3e..cd90989 100644 --- a/tests/Elastic.Elasticsearch.IntegrationTests/DefaultCluster.cs +++ b/tests/Elastic.Elasticsearch.IntegrationTests/DefaultCluster.cs @@ -18,12 +18,12 @@ namespace Elastic.Elasticsearch.IntegrationTests; /// Declare our cluster that we want to inject into our test classes public class DefaultCluster : XunitClusterBase { - protected static string Version = "8.7.0"; - public DefaultCluster() : this(new XunitClusterConfiguration(Version) { StartingPortNumber = 9202, AutoWireKnownProxies = true }) { } public DefaultCluster(XunitClusterConfiguration xunitClusterConfiguration) : base(xunitClusterConfiguration) { } + protected static string Version => "8.7.0"; + public ITransport CreateClient(ITestOutputHelper output) => this.GetOrAddClient(cluster => { @@ -59,6 +59,5 @@ public class SecurityCluster : DefaultCluster public SecurityCluster() : base(new XunitClusterConfiguration(Version, ClusterFeatures.Security | ClusterFeatures.SSL | ClusterFeatures.XPack) { StartingPortNumber = 9202 - //, TrialMode = XPackTrialMode.Trial }) { } } diff --git a/tests/Elastic.Elasticsearch.IntegrationTests/Elastic - Backup.Elasticsearch.IntegrationTests.csproj b/tests/Elastic.Elasticsearch.IntegrationTests/Elastic - Backup.Elasticsearch.IntegrationTests.csproj deleted file mode 100644 index 8566ce5..0000000 --- a/tests/Elastic.Elasticsearch.IntegrationTests/Elastic - Backup.Elasticsearch.IntegrationTests.csproj +++ /dev/null @@ -1,32 +0,0 @@ - - - - net6.0 - enable - enable - - false - - - - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - - - - - - - - - diff --git a/tests/Elastic.Elasticsearch.IntegrationTests/Elastic.Elasticsearch.IntegrationTests.csproj b/tests/Elastic.Elasticsearch.IntegrationTests/Elastic.Elasticsearch.IntegrationTests.csproj index c7630ee..0aa147c 100644 --- a/tests/Elastic.Elasticsearch.IntegrationTests/Elastic.Elasticsearch.IntegrationTests.csproj +++ b/tests/Elastic.Elasticsearch.IntegrationTests/Elastic.Elasticsearch.IntegrationTests.csproj @@ -1,7 +1,7 @@ - net6.0 + net8.0 enable enable false diff --git a/tests/Elastic.Elasticsearch.IntegrationTests/IntegrationTestBase.cs b/tests/Elastic.Elasticsearch.IntegrationTests/IntegrationTestBase.cs index e1c0e0f..3971bed 100644 --- a/tests/Elastic.Elasticsearch.IntegrationTests/IntegrationTestBase.cs +++ b/tests/Elastic.Elasticsearch.IntegrationTests/IntegrationTestBase.cs @@ -12,13 +12,13 @@ public abstract class IntegrationTestBase : IntegrationTestBase { protected IntegrationTestBase(DefaultCluster cluster, ITestOutputHelper output) : base(cluster, output) { } } + public abstract class IntegrationTestBase : IClusterFixture where TCluster : DefaultCluster, new() { protected TCluster Cluster { get; } protected ITransport RequestHandler { get; } - protected IntegrationTestBase(TCluster cluster, ITestOutputHelper output) { Cluster = cluster; diff --git a/tests/Elastic.Transport.IntegrationTests/Elastic.Transport.IntegrationTests.csproj b/tests/Elastic.Transport.IntegrationTests/Elastic.Transport.IntegrationTests.csproj index e3c11dc..0c4a446 100644 --- a/tests/Elastic.Transport.IntegrationTests/Elastic.Transport.IntegrationTests.csproj +++ b/tests/Elastic.Transport.IntegrationTests/Elastic.Transport.IntegrationTests.csproj @@ -1,29 +1,29 @@ - net6.0 + net8.0 True false CS8002 - - - - + + + + - + runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all - - - + + + diff --git a/tests/Elastic.Transport.IntegrationTests/Http/TransferEncodingChunckedTests.cs b/tests/Elastic.Transport.IntegrationTests/Http/TransferEncodingChunckedTests.cs index ba80aec..1b5487f 100644 --- a/tests/Elastic.Transport.IntegrationTests/Http/TransferEncodingChunckedTests.cs +++ b/tests/Elastic.Transport.IntegrationTests/Http/TransferEncodingChunckedTests.cs @@ -63,7 +63,7 @@ [Fact] public async Task HttpClientUseProxyShouldBeFalseWhenDisabledAutoProxyDet requestInvoker.LastHttpClientHandler.UseProxy.Should().BeFalse(); r.Body.Should().Be(BodyString); - r = await transport.PostAsync(Path, Body, null, CancellationToken.None).ConfigureAwait(false); + r = await transport.PostAsync(Path, Body, null, CancellationToken.None); requestInvoker.LastHttpClientHandler.UseProxy.Should().BeFalse(); r.Body.Should().Be(BodyString); } @@ -75,7 +75,7 @@ [Fact] public async Task HttpClientUseProxyShouldBeTrueWhenEnabledAutoProxyDetec transport.Post(Path, Body); requestInvoker.LastHttpClientHandler.UseProxy.Should().BeTrue(); - await transport.PostAsync(Path, Body, null, CancellationToken.None).ConfigureAwait(false); + await transport.PostAsync(Path, Body, null, CancellationToken.None); requestInvoker.LastHttpClientHandler.UseProxy.Should().BeTrue(); } @@ -88,7 +88,7 @@ [Fact] public async Task HttpClientUseTransferEncodingChunkedWhenTransferEncodin var transport = Setup(requestInvoker, transferEncodingChunked: true); transport.Post(Path, Body); - await transport.PostAsync(Path, Body, null, CancellationToken.None).ConfigureAwait(false); + await transport.PostAsync(Path, Body, null, CancellationToken.None); } [Fact] public async Task HttpClientSetsContentLengthWhenTransferEncodingChunkedFalse() @@ -100,7 +100,7 @@ [Fact] public async Task HttpClientSetsContentLengthWhenTransferEncodingChunkedF var transport = Setup(trackingRequestInvoker, transferEncodingChunked: false); transport.Post(Path, Body); - await transport.PostAsync(Path, Body, null, CancellationToken.None).ConfigureAwait(false); + await transport.PostAsync(Path, Body, null, CancellationToken.None); } [Fact] public async Task HttpClientSetsContentLengthWhenTransferEncodingChunkedHttpCompression() @@ -112,7 +112,7 @@ [Fact] public async Task HttpClientSetsContentLengthWhenTransferEncodingChunkedH var transport = Setup(trackingRequestInvoker, transferEncodingChunked: false, httpCompression: true); transport.Post(Path, Body); - await transport.PostAsync(Path, Body, null, CancellationToken.None).ConfigureAwait(false); + await transport.PostAsync(Path, Body, null, CancellationToken.None); } } } diff --git a/tests/Elastic.Transport.IntegrationTests/OpenTelemetry/OpenTelemetryTests.cs b/tests/Elastic.Transport.IntegrationTests/OpenTelemetry/OpenTelemetryTests.cs index da87aaa..500af63 100644 --- a/tests/Elastic.Transport.IntegrationTests/OpenTelemetry/OpenTelemetryTests.cs +++ b/tests/Elastic.Transport.IntegrationTests/OpenTelemetry/OpenTelemetryTests.cs @@ -13,6 +13,7 @@ using Elastic.Transport.IntegrationTests.Plumbing.Stubs; using Elastic.Transport.Products.Elasticsearch; using FluentAssertions; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Xunit; @@ -92,8 +93,8 @@ public class OpenTelemetryController : ControllerBase [HttpGet()] public Task Get() { - Response.Headers.Add(ElasticsearchProductRegistration.XFoundHandlingClusterHeader, OpenTelemetryTests.Cluster); - Response.Headers.Add(ElasticsearchProductRegistration.XFoundHandlingInstanceHeader, OpenTelemetryTests.Instance); + Response.Headers.Append(ElasticsearchProductRegistration.XFoundHandlingClusterHeader, OpenTelemetryTests.Cluster); + Response.Headers.Append(ElasticsearchProductRegistration.XFoundHandlingInstanceHeader, OpenTelemetryTests.Instance); return Task.CompletedTask; } diff --git a/tests/Elastic.Transport.IntegrationTests/Plumbing/AssemblyServerTestsBase.cs b/tests/Elastic.Transport.IntegrationTests/Plumbing/AssemblyServerTestsBase.cs index e3efa68..d7a14d7 100644 --- a/tests/Elastic.Transport.IntegrationTests/Plumbing/AssemblyServerTestsBase.cs +++ b/tests/Elastic.Transport.IntegrationTests/Plumbing/AssemblyServerTestsBase.cs @@ -2,21 +2,21 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information +using Xunit; using Xunit.Extensions.Ordering; namespace Elastic.Transport.IntegrationTests.Plumbing { - public class AssemblyServerTestsBase : IAssemblyFixture where TServer : class, HttpTransportTestServer + public class AssemblyServerTestsBase(TServer instance) + : IAssemblyFixture, IClassFixture where TServer : class, HttpTransportTestServer { - public AssemblyServerTestsBase(TServer instance) => Server = instance; - - protected TServer Server { get; } + protected TServer Server { get; } = instance; protected ITransport RequestHandler => Server.DefaultRequestHandler; } - public class AssemblyServerTestsBase : AssemblyServerTestsBase + public class AssemblyServerTestsBase(TransportTestServer instance) + : AssemblyServerTestsBase(instance) { - public AssemblyServerTestsBase(TransportTestServer instance) : base(instance) { } } } diff --git a/tests/Elastic.Transport.IntegrationTests/Plumbing/ClassServerTestsBase.cs b/tests/Elastic.Transport.IntegrationTests/Plumbing/ClassServerTestsBase.cs index b736b39..cba6c9e 100644 --- a/tests/Elastic.Transport.IntegrationTests/Plumbing/ClassServerTestsBase.cs +++ b/tests/Elastic.Transport.IntegrationTests/Plumbing/ClassServerTestsBase.cs @@ -6,11 +6,9 @@ namespace Elastic.Transport.IntegrationTests.Plumbing { - public class ClassServerTestsBase : IClassFixture where TServer : class, HttpTransportTestServer + public class ClassServerTestsBase(TServer instance) : IClassFixture where TServer : class, HttpTransportTestServer { - public ClassServerTestsBase(TServer instance) => Server = instance; - - protected TServer Server { get; } + protected TServer Server { get; } = instance; protected ITransport RequestHandler => Server.DefaultRequestHandler; } diff --git a/tests/Elastic.Transport.IntegrationTests/Plumbing/TransportTestServer.cs b/tests/Elastic.Transport.IntegrationTests/Plumbing/TransportTestServer.cs index 382421b..a920b7c 100644 --- a/tests/Elastic.Transport.IntegrationTests/Plumbing/TransportTestServer.cs +++ b/tests/Elastic.Transport.IntegrationTests/Plumbing/TransportTestServer.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information using System; -using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Linq; diff --git a/tests/Elastic.Transport.Tests/Components/Serialization/LowLevelRequestResponseSerializerTests.cs b/tests/Elastic.Transport.Tests/Components/Serialization/LowLevelRequestResponseSerializerTests.cs new file mode 100644 index 0000000..64ee39a --- /dev/null +++ b/tests/Elastic.Transport.Tests/Components/Serialization/LowLevelRequestResponseSerializerTests.cs @@ -0,0 +1,81 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information + +using System; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text.Json; +using FluentAssertions; +using Xunit; + +namespace Elastic.Transport.Tests.Components.Serialization; + +public class LowLevelRequestResponseSerializerTests : SerializerTestBase +{ + [Fact] + public void SerializesException() + { + // NOTE: Any changes to this file, may change the assertion since we validate the full JSON which + // includes the stack trace line numbers. As we don't foresee this changing, this should be okay. + + const string urlValue = "https://www.elastic.co"; + const string messageValue = "Testing"; + + Exception e; + + try + { + throw new CustomException(messageValue) { HelpLink = urlValue }; + } + catch (Exception ex) + { + e = ex; + } + + using var stream = SerializeToStream(e); + + var jsonDocument = JsonDocument.Parse(stream); + + jsonDocument.RootElement.EnumerateArray().Should().HaveCount(1); + var exception = jsonDocument.RootElement.EnumerateArray().First(); + + exception.TryGetProperty("Depth", out var depth).Should().BeTrue(); + depth.ValueKind.Should().Be(JsonValueKind.Number); + depth.GetInt32().Should().Be(0); + + exception.TryGetProperty("ClassName", out var className).Should().BeTrue(); + className.ValueKind.Should().Be(JsonValueKind.String); + className.GetString().Should().Be("Elastic.Transport.Tests.Components.Serialization.CustomException"); + + exception.TryGetProperty("Message", out var message).Should().BeTrue(); + message.ValueKind.Should().Be(JsonValueKind.String); + message.GetString().Should().Be(messageValue); + + exception.TryGetProperty("Source", out var source).Should().BeTrue(); + source.ValueKind.Should().Be(JsonValueKind.String); + source.GetString().Should().Be("Elastic.Transport.Tests"); + + var windowsPath = "Components\\Serialization\\LowLevelRequestResponseSerializerTests.cs:line"; + var path = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + ? windowsPath + : windowsPath.Replace('\\', '/'); + + exception.TryGetProperty("StackTraceString", out var stackTrace).Should().BeTrue(); + stackTrace.ValueKind.Should().Be(JsonValueKind.String); + stackTrace.GetString().Should() + .Contain("at Elastic.Transport.Tests.Components.Serialization.LowLevelRequestResponseSerializerTests") + .And.Contain(path); + + exception.TryGetProperty("HResult", out var hResult).Should().BeTrue(); + hResult.ValueKind.Should().Be(JsonValueKind.Number); + hResult.GetInt32().Should().Be(-2146233088); + + exception.TryGetProperty("HelpURL", out var helpUrl).Should().BeTrue(); + helpUrl.ValueKind.Should().Be(JsonValueKind.String); + helpUrl.GetString().Should().Be(urlValue); + } +} + +internal class CustomException(string message) : Exception(message) +{ } diff --git a/tests/Elastic.Transport.Tests/Components/Serialization/SerializationTestBase.cs b/tests/Elastic.Transport.Tests/Components/Serialization/SerializationTestBase.cs new file mode 100644 index 0000000..cbc85b0 --- /dev/null +++ b/tests/Elastic.Transport.Tests/Components/Serialization/SerializationTestBase.cs @@ -0,0 +1,18 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information + +using System.IO; + +namespace Elastic.Transport.Tests.Components.Serialization; + +public abstract class SerializerTestBase +{ + protected static Stream SerializeToStream(T data) + { + var stream = new MemoryStream(); + LowLevelRequestResponseSerializer.Instance.Serialize(data, stream); + stream.Position = 0; + return stream; + } +} diff --git a/tests/Elastic.Transport.Tests/Elastic.Transport.Tests.csproj b/tests/Elastic.Transport.Tests/Elastic.Transport.Tests.csproj index a06f3c0..7976082 100644 --- a/tests/Elastic.Transport.Tests/Elastic.Transport.Tests.csproj +++ b/tests/Elastic.Transport.Tests/Elastic.Transport.Tests.csproj @@ -1,33 +1,29 @@ - net6.0;net462 + net8.0;net481 True false - - - + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all - - - + + + - - - - diff --git a/tests/Elastic.Transport.Tests/OpenTelemetryTests.cs b/tests/Elastic.Transport.Tests/OpenTelemetryTests.cs index 993cce1..60563d8 100644 --- a/tests/Elastic.Transport.Tests/OpenTelemetryTests.cs +++ b/tests/Elastic.Transport.Tests/OpenTelemetryTests.cs @@ -81,7 +81,7 @@ static void Assertions(Activity activity) .Subject.Value.Should().BeOfType() .Subject.Should().Be(OpenTelemetry.OpenTelemetrySchemaVersion); -#if !NETFRAMEWORK +#if NET8_0_OR_GREATER activity.Status.Should().Be(ActivityStatusCode.Ok); #endif }