From b0a988c6c33328989f80f85047b108ee2c7117d7 Mon Sep 17 00:00:00 2001 From: Mayuki Sawatari Date: Wed, 17 Jul 2024 15:45:24 +0900 Subject: [PATCH 1/3] Fix internal errors when IsReturnExceptionStackTraceInErrorDetail is enabled. --- src/MagicOnion.Server/MethodHandler.cs | 4 +- .../MagicOnionApplicationFactory.cs | 15 ++ .../UnaryServiceTest.cs | 168 ++++++++++++++---- .../UnaryTestService.cs | 136 ++++++++++++++ .../BasicServerSample.csproj | 1 + .../Services/BasicUnaryService.cs | 123 ------------- 6 files changed, 287 insertions(+), 160 deletions(-) create mode 100644 tests/MagicOnion.Server.Tests/UnaryTestService.cs delete mode 100644 tests/samples/BasicServerSample/Services/BasicUnaryService.cs diff --git a/src/MagicOnion.Server/MethodHandler.cs b/src/MagicOnion.Server/MethodHandler.cs index 74852cfef..7931cdf9b 100644 --- a/src/MagicOnion.Server/MethodHandler.cs +++ b/src/MagicOnion.Server/MethodHandler.cs @@ -250,7 +250,7 @@ void BindHandlerTyped(ServiceBin { isErrorOrInterrupted = true; context.Status = ex.ToStatus(); - response = default; + response = default(TResponse?); // WORKAROUND: Grpc.AspNetCore.Server throws a `Cancelled` status exception when it receives `null` response. // To return the status code correctly, we needs to rethrow the exception here. @@ -292,7 +292,7 @@ void BindHandlerTyped(ServiceBin context.Status = new Status(StatusCode.Unknown, str); MagicOnionServerLog.Error(Logger, ex, context); - response = default; + response = default(TResponse?); } else { diff --git a/tests/MagicOnion.Server.Tests/MagicOnionApplicationFactory.cs b/tests/MagicOnion.Server.Tests/MagicOnionApplicationFactory.cs index b0515fca4..bdfda7046 100644 --- a/tests/MagicOnion.Server.Tests/MagicOnionApplicationFactory.cs +++ b/tests/MagicOnion.Server.Tests/MagicOnionApplicationFactory.cs @@ -1,16 +1,31 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.Extensions.DependencyInjection; +using System.Collections.Concurrent; +using Microsoft.Extensions.Logging; namespace MagicOnion.Server.Tests; #pragma warning disable CS1998 public class MagicOnionApplicationFactory : WebApplicationFactory { + public const string ItemsKey = "MagicOnionApplicationFactory.Items"; + public ConcurrentDictionary Items => Services.GetRequiredKeyedService>(ItemsKey); + public List Logs { get; } = new(); + protected override void ConfigureWebHost(IWebHostBuilder builder) { + builder.ConfigureLogging(logger => + { + logger.AddFakeLogging(options => + { + options.OutputFormatter = x => $"{x.Timestamp}\t{x.Level}\t{x.Id}\t{x.Message}\t{x.Exception}"; + options.OutputSink = x => Logs.Add(x); + }); + }); builder.ConfigureServices(services => { + services.AddKeyedSingleton>(ItemsKey); services.AddMagicOnion(new[] { typeof(TServiceImplementation) }); }); } diff --git a/tests/MagicOnion.Server.Tests/UnaryServiceTest.cs b/tests/MagicOnion.Server.Tests/UnaryServiceTest.cs index 4bc9af3b8..fb153be41 100644 --- a/tests/MagicOnion.Server.Tests/UnaryServiceTest.cs +++ b/tests/MagicOnion.Server.Tests/UnaryServiceTest.cs @@ -1,4 +1,3 @@ -using BasicServerSample.Services; using Grpc.Core; using Grpc.Net.Client; using MagicOnion.Client; @@ -7,30 +6,129 @@ namespace MagicOnion.Server.Tests; -public class UnaryServiceTest : IClassFixture> +public class UnaryServiceTest_ReturnExceptionStackTrace : IClassFixture> { - private readonly WebApplicationFactory factory; + readonly List logs; + readonly WebApplicationFactory factory; - public UnaryServiceTest(WebApplicationFactory factory) + public UnaryServiceTest_ReturnExceptionStackTrace(MagicOnionApplicationFactory factory) + { + this.factory = factory.WithMagicOnionOptions(options => + { + options.IsReturnExceptionStackTraceInErrorDetail = true; + }); + + this.logs = factory.Logs; + } + + [Fact] + public async Task ReturnTypeIsNilAndNonSuccessResponse() + { + var httpClient = factory.CreateDefaultClient(); + var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); + logs.Clear(); + + var ex = await Assert.ThrowsAsync(async () => await client.ReturnTypeIsNilAndNonSuccessResponseAsync(StatusCode.AlreadyExists)); + ex.StatusCode.Should().Be(StatusCode.AlreadyExists); + ex.Status.Detail.Should().Be(nameof(IUnaryTestService.ReturnTypeIsNilAndNonSuccessResponseAsync)); + logs.Should().HaveCount(1); + } + + [Fact] + public async Task Throw_NoParameterReturnNil() + { + var httpClient = factory.CreateDefaultClient(); + var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); + logs.Clear(); + + var ex = await Assert.ThrowsAsync(async () => await client.ThrowAsync()); + ex.StatusCode.Should().Be(StatusCode.Unknown); + logs.Should().HaveCount(1); + ex.Message.Should().Contain("Something went wrong"); + } + + [Fact] + public async Task Throw_OneParameterReturnNil() + { + var httpClient = factory.CreateDefaultClient(); + var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); + logs.Clear(); + + var ex = await Assert.ThrowsAsync(async () => await client.ThrowOneValueTypeParameterReturnNilAsync(1234)); + ex.StatusCode.Should().Be(StatusCode.Unknown); + logs.Should().HaveCount(1); + ex.Message.Should().Contain("Something went wrong"); + } + + [Fact] + public async Task Throw_TwoParameterReturnNil() + { + var httpClient = factory.CreateDefaultClient(); + var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); + logs.Clear(); + + var ex = await Assert.ThrowsAsync(async () => await client.ThrowTwoValueTypeParameterReturnNilAsync(1234, 5678)); + ex.StatusCode.Should().Be(StatusCode.Unknown); + logs.Should().HaveCount(1); + ex.Message.Should().Contain("Something went wrong"); + } +} + +public class UnaryServiceTest : IClassFixture> +{ + readonly List logs; + readonly WebApplicationFactory factory; + + public UnaryServiceTest(MagicOnionApplicationFactory factory) { this.factory = factory; + this.logs = factory.Logs; } [Fact] - public async Task Throw() + public async Task Throw_NoParameterReturnNil() { var httpClient = factory.CreateDefaultClient(); - var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); + var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); + logs.Clear(); var ex = await Assert.ThrowsAsync(async () => await client.ThrowAsync()); ex.StatusCode.Should().Be(StatusCode.Unknown); + logs.Should().HaveCount(1); + ex.Message.Should().NotContain("Something went wrong"); + } + + [Fact] + public async Task Throw_OneParameterReturnNil() + { + var httpClient = factory.CreateDefaultClient(); + var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); + logs.Clear(); + + var ex = await Assert.ThrowsAsync(async () => await client.ThrowOneValueTypeParameterReturnNilAsync(1234)); + ex.StatusCode.Should().Be(StatusCode.Unknown); + logs.Should().HaveCount(1); + ex.Message.Should().NotContain("Something went wrong"); + } + + [Fact] + public async Task Throw_TwoParameterReturnNil() + { + var httpClient = factory.CreateDefaultClient(); + var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); logs.Clear(); + logs.Clear(); + + var ex = await Assert.ThrowsAsync(async () => await client.ThrowTwoValueTypeParameterReturnNilAsync(1234, 5678)); + ex.StatusCode.Should().Be(StatusCode.Unknown); + logs.Should().HaveCount(1); + ex.Message.Should().NotContain("Something went wrong"); } [Fact] public async Task NoParameterReturnNil() { var httpClient = factory.CreateDefaultClient(); - var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); + var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); (await client.NoParameterReturnNilAsync()).Should().Be(Nil.Default); } @@ -39,7 +137,7 @@ public async Task NoParameterReturnNil() public async Task NoParameterReturnValueType() { var httpClient = factory.CreateDefaultClient(); - var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); + var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); (await client.NoParameterReturnValueTypeAsync()).Should().Be(1234); } @@ -48,7 +146,7 @@ public async Task NoParameterReturnValueType() public async Task NoParameterReturnRefType() { var httpClient = factory.CreateDefaultClient(); - var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); + var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); (await client.NoParameterReturnRefTypeAsync()).Value.Should().Be("1234"); } @@ -57,7 +155,7 @@ public async Task NoParameterReturnRefType() public async Task OneParameterReturnNil() { var httpClient = factory.CreateDefaultClient(); - var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); + var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); (await client.OneValueTypeParameterReturnNilAsync(123)).Should().Be(Nil.Default); } @@ -66,7 +164,7 @@ public async Task OneParameterReturnNil() public async Task OneValueTypeParameterReturnValueType() { var httpClient = factory.CreateDefaultClient(); - var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); + var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); (await client.OneValueTypeParameterReturnValueTypeAsync(123)).Should().Be(123); } @@ -75,7 +173,7 @@ public async Task OneValueTypeParameterReturnValueType() public async Task OneValueTypeParameterReturnRefType() { var httpClient = factory.CreateDefaultClient(); - var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); + var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); (await client.OneValueTypeParameterReturnRefTypeAsync(123)).Value.Should().Be("123"); } @@ -84,7 +182,7 @@ public async Task OneValueTypeParameterReturnRefType() public async Task TwoValueTypeParametersReturnNil() { var httpClient = factory.CreateDefaultClient(); - var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); + var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); (await client.TwoValueTypeParametersReturnNilAsync(123, 456)).Should().Be(Nil.Default); } @@ -93,7 +191,7 @@ public async Task TwoValueTypeParametersReturnNil() public async Task TwoValueTypeParametersReturnValueType() { var httpClient = factory.CreateDefaultClient(); - var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); + var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); (await client.TwoValueTypeParametersReturnValueTypeAsync(123, 456)).Should().Be(123 + 456); } @@ -102,7 +200,7 @@ public async Task TwoValueTypeParametersReturnValueType() public async Task TwoValueTypeParametersReturnRefType() { var httpClient = factory.CreateDefaultClient(); - var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); + var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); (await client.TwoValueTypeParametersReturnRefTypeAsync(123, 456)).Value.Should().Be((123 + 456).ToString()); } @@ -111,83 +209,83 @@ public async Task TwoValueTypeParametersReturnRefType() public async Task ReturnTypeIsNilAndNonSuccessResponse() { var httpClient = factory.CreateDefaultClient(); - var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); + var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); var ex = await Assert.ThrowsAsync(async () => await client.ReturnTypeIsNilAndNonSuccessResponseAsync(StatusCode.AlreadyExists)); ex.StatusCode.Should().Be(StatusCode.AlreadyExists); - ex.Status.Detail.Should().Be(nameof(IBasicUnaryService.ReturnTypeIsNilAndNonSuccessResponseAsync)); + ex.Status.Detail.Should().Be(nameof(IUnaryTestService.ReturnTypeIsNilAndNonSuccessResponseAsync)); } [Fact] public async Task ReturnTypeIsRefTypeAndNonSuccessResponse() { var httpClient = factory.CreateDefaultClient(); - var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); + var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); var ex = await Assert.ThrowsAsync(async () => await client.ReturnTypeIsRefTypeAndNonSuccessResponseAsync(StatusCode.AlreadyExists)); ex.StatusCode.Should().Be(StatusCode.AlreadyExists); - ex.Status.Detail.Should().Be(nameof(IBasicUnaryService.ReturnTypeIsRefTypeAndNonSuccessResponseAsync)); + ex.Status.Detail.Should().Be(nameof(IUnaryTestService.ReturnTypeIsRefTypeAndNonSuccessResponseAsync)); } [Fact] public async Task OneRefTypeParameterReturnNil() { var httpClient = factory.CreateDefaultClient(); - var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); + var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); - (await client.OneRefTypeParameterReturnNilAsync(new BasicServerSample.Services.MyRequest(123))).Should().Be(Nil.Default); + (await client.OneRefTypeParameterReturnNilAsync(new UnaryTestMyRequest(123))).Should().Be(Nil.Default); } [Fact] public async Task TwoRefTypeParametersReturnNil() { var httpClient = factory.CreateDefaultClient(); - var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); + var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); - (await client.TwoRefTypeParametersReturnNilAsync(new BasicServerSample.Services.MyRequest(123), new BasicServerSample.Services.MyRequest(456))).Should().Be(Nil.Default); + (await client.TwoRefTypeParametersReturnNilAsync(new UnaryTestMyRequest(123), new UnaryTestMyRequest(456))).Should().Be(Nil.Default); } [Fact] public async Task OneRefTypeParameterReturnValueType() { var httpClient = factory.CreateDefaultClient(); - var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); + var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); - (await client.OneRefTypeParameterReturnValueTypeAsync(new BasicServerSample.Services.MyRequest(123))).Should().Be(123); + (await client.OneRefTypeParameterReturnValueTypeAsync(new UnaryTestMyRequest(123))).Should().Be(123); } [Fact] public async Task TwoRefTypeParametersReturnValueType() { var httpClient = factory.CreateDefaultClient(); - var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); + var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); - (await client.TwoRefTypeParametersReturnValueTypeAsync(new BasicServerSample.Services.MyRequest(123), new BasicServerSample.Services.MyRequest(456))).Should().Be(123 + 456); + (await client.TwoRefTypeParametersReturnValueTypeAsync(new UnaryTestMyRequest(123), new UnaryTestMyRequest(456))).Should().Be(123 + 456); } [Fact] public async Task OneRefTypeParameterReturnRefType() { var httpClient = factory.CreateDefaultClient(); - var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); + var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); - (await client.OneRefTypeParameterReturnRefTypeAsync(new BasicServerSample.Services.MyRequest(123))).Value.Should().Be("123"); + (await client.OneRefTypeParameterReturnRefTypeAsync(new UnaryTestMyRequest(123))).Value.Should().Be("123"); } [Fact] public async Task TwoRefTypeParametersReturnRefType() { var httpClient = factory.CreateDefaultClient(); - var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); + var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); - (await client.TwoRefTypeParametersReturnRefTypeAsync(new BasicServerSample.Services.MyRequest(123), new BasicServerSample.Services.MyRequest(456))).Value.Should().Be((123 + 456).ToString()); + (await client.TwoRefTypeParametersReturnRefTypeAsync(new UnaryTestMyRequest(123), new UnaryTestMyRequest(456))).Value.Should().Be((123 + 456).ToString()); } [Fact] public async Task NonGeneric_NoParameter() { var httpClient = factory.CreateDefaultClient(); - var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); + var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); await client.NonGenericNoParameterAsync(); } @@ -196,7 +294,7 @@ public async Task NonGeneric_NoParameter() public async Task NonGeneric_OneValueTypeParameter() { var httpClient = factory.CreateDefaultClient(); - var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); + var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); await client.NonGenericOneValueTypeParameterAsync(123); } @@ -205,7 +303,7 @@ public async Task NonGeneric_OneValueTypeParameter() public async Task NonGeneric_TwoValueTypeParameters() { var httpClient = factory.CreateDefaultClient(); - var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); + var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); await client.NonGenericTwoValueTypeParameterAsync(123, 456); } @@ -214,7 +312,7 @@ public async Task NonGeneric_TwoValueTypeParameters() public async Task NullResponse() { var httpClient = factory.CreateDefaultClient(); - var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); + var client = MagicOnionClient.Create(GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions() { HttpClient = httpClient })); var result = await client.NullResponseAsync(null); diff --git a/tests/MagicOnion.Server.Tests/UnaryTestService.cs b/tests/MagicOnion.Server.Tests/UnaryTestService.cs new file mode 100644 index 000000000..ec9e0bae4 --- /dev/null +++ b/tests/MagicOnion.Server.Tests/UnaryTestService.cs @@ -0,0 +1,136 @@ +#nullable enable +using Grpc.Core; +using MagicOnion; +using MagicOnion.Server; +using MessagePack; + +namespace MagicOnion.Server.Tests; + +public interface IUnaryTestService : IService +{ + UnaryResult ThrowAsync(); + UnaryResult ThrowOneValueTypeParameterReturnNilAsync(int a); + UnaryResult ThrowTwoValueTypeParameterReturnNilAsync(int a, int b); + UnaryResult ThrowOneRefTypeParameterReturnNilAsync(UnaryTestMyRequest a); + UnaryResult ThrowTwoRefTypeParametersReturnNilAsync(UnaryTestMyRequest a, UnaryTestMyRequest b); + + UnaryResult ReturnTypeIsRefTypeAndNonSuccessResponseAsync(StatusCode statusCode); + UnaryResult ReturnTypeIsNilAndNonSuccessResponseAsync(StatusCode statusCode); + UnaryResult NoParameterReturnNilAsync(); + UnaryResult NoParameterReturnValueTypeAsync(); + UnaryResult NoParameterReturnRefTypeAsync(); + UnaryResult OneValueTypeParameterReturnNilAsync(int a); + UnaryResult TwoValueTypeParametersReturnNilAsync(int a, int b); + UnaryResult OneValueTypeParameterReturnValueTypeAsync(int a); + UnaryResult TwoValueTypeParametersReturnValueTypeAsync(int a, int b); + UnaryResult OneValueTypeParameterReturnRefTypeAsync(int a); + UnaryResult TwoValueTypeParametersReturnRefTypeAsync(int a, int b); + + UnaryResult OneRefTypeParameterReturnNilAsync(UnaryTestMyRequest a); + UnaryResult TwoRefTypeParametersReturnNilAsync(UnaryTestMyRequest a, UnaryTestMyRequest b); + UnaryResult OneRefTypeParameterReturnValueTypeAsync(UnaryTestMyRequest a); + UnaryResult TwoRefTypeParametersReturnValueTypeAsync(UnaryTestMyRequest a, UnaryTestMyRequest b); + UnaryResult OneRefTypeParameterReturnRefTypeAsync(UnaryTestMyRequest a); + UnaryResult TwoRefTypeParametersReturnRefTypeAsync(UnaryTestMyRequest a, UnaryTestMyRequest b); + + UnaryResult NonGenericNoParameterAsync(); + UnaryResult NonGenericOneValueTypeParameterAsync(int a); + UnaryResult NonGenericTwoValueTypeParameterAsync(int a, int b); + UnaryResult NullResponseAsync(UnaryTestMyRequest? a); +} + +[MessagePackObject(true)] +public class UnaryTestMyRequest +{ + public int Value { get; } + public UnaryTestMyRequest(int value) + { + Value = value; + } +} + +[MessagePackObject(true)] +public class UnaryTestMyResponse +{ + public string Value { get; } + public UnaryTestMyResponse(string value) + { + Value = value; + } +} + +public class UnaryTestService : ServiceBase, IUnaryTestService +{ + public UnaryResult ThrowAsync() + => throw new InvalidOperationException("Something went wrong"); + public UnaryResult ThrowOneValueTypeParameterReturnNilAsync(int a) + => throw new InvalidOperationException("Something went wrong"); + public UnaryResult ThrowTwoValueTypeParameterReturnNilAsync(int a, int b) + => throw new InvalidOperationException("Something went wrong"); + public UnaryResult ThrowOneRefTypeParameterReturnNilAsync(UnaryTestMyRequest a) + => throw new InvalidOperationException("Something went wrong"); + public UnaryResult ThrowTwoRefTypeParametersReturnNilAsync(UnaryTestMyRequest a, UnaryTestMyRequest b) + => throw new InvalidOperationException("Something went wrong"); + + public UnaryResult ReturnTypeIsRefTypeAndNonSuccessResponseAsync(StatusCode statusCode) + => throw new ReturnStatusException(statusCode, nameof(ReturnTypeIsRefTypeAndNonSuccessResponseAsync)); + public UnaryResult ReturnTypeIsNilAndNonSuccessResponseAsync(StatusCode statusCode) + => throw new ReturnStatusException(statusCode, nameof(ReturnTypeIsNilAndNonSuccessResponseAsync)); + + public UnaryResult NoParameterReturnNilAsync() + => UnaryResult.FromResult(Nil.Default); + + public UnaryResult NoParameterReturnValueTypeAsync() + => UnaryResult.FromResult(1234); + + public UnaryResult NoParameterReturnRefTypeAsync() + => UnaryResult.FromResult(new UnaryTestMyResponse("1234")); + + public UnaryResult OneValueTypeParameterReturnNilAsync(int a) + => UnaryResult.FromResult(Nil.Default); + + public UnaryResult TwoValueTypeParametersReturnNilAsync(int a, int b) + => UnaryResult.FromResult(Nil.Default); + + public UnaryResult OneValueTypeParameterReturnValueTypeAsync(int a) + => UnaryResult.FromResult(a); + + public UnaryResult TwoValueTypeParametersReturnValueTypeAsync(int a, int b) + => UnaryResult.FromResult(a + b); + + public UnaryResult OneValueTypeParameterReturnRefTypeAsync(int a) + => UnaryResult.FromResult(new UnaryTestMyResponse(a.ToString())); + + public UnaryResult TwoValueTypeParametersReturnRefTypeAsync(int a, int b) + => UnaryResult.FromResult(new UnaryTestMyResponse((a + b).ToString())); + + public UnaryResult OneRefTypeParameterReturnNilAsync(UnaryTestMyRequest a) + => UnaryResult.FromResult(Nil.Default); + + public UnaryResult TwoRefTypeParametersReturnNilAsync(UnaryTestMyRequest a, UnaryTestMyRequest b) + => UnaryResult.FromResult(Nil.Default); + + public UnaryResult OneRefTypeParameterReturnValueTypeAsync(UnaryTestMyRequest a) + => UnaryResult.FromResult(a.Value); + + public UnaryResult TwoRefTypeParametersReturnValueTypeAsync(UnaryTestMyRequest a, UnaryTestMyRequest b) + => UnaryResult.FromResult(a.Value + b.Value); + + public UnaryResult OneRefTypeParameterReturnRefTypeAsync(UnaryTestMyRequest a) + => UnaryResult.FromResult(new UnaryTestMyResponse(a.Value.ToString())); + + public UnaryResult TwoRefTypeParametersReturnRefTypeAsync(UnaryTestMyRequest a, UnaryTestMyRequest b) + => UnaryResult.FromResult(new UnaryTestMyResponse((a.Value + b.Value).ToString())); + + public UnaryResult NonGenericNoParameterAsync() + => MagicOnion.UnaryResult.CompletedResult; + + public UnaryResult NonGenericOneValueTypeParameterAsync(int a) + => MagicOnion.UnaryResult.CompletedResult; + + public UnaryResult NonGenericTwoValueTypeParameterAsync(int a, int b) + => MagicOnion.UnaryResult.CompletedResult; + + public UnaryResult NullResponseAsync(UnaryTestMyRequest? a) + => MagicOnion.UnaryResult.FromResult(default(UnaryTestMyResponse)); +} diff --git a/tests/samples/BasicServerSample/BasicServerSample.csproj b/tests/samples/BasicServerSample/BasicServerSample.csproj index 663ca915a..89dbeaa22 100644 --- a/tests/samples/BasicServerSample/BasicServerSample.csproj +++ b/tests/samples/BasicServerSample/BasicServerSample.csproj @@ -12,6 +12,7 @@ + diff --git a/tests/samples/BasicServerSample/Services/BasicUnaryService.cs b/tests/samples/BasicServerSample/Services/BasicUnaryService.cs deleted file mode 100644 index 4d93cfc97..000000000 --- a/tests/samples/BasicServerSample/Services/BasicUnaryService.cs +++ /dev/null @@ -1,123 +0,0 @@ -using Grpc.Core; -using MagicOnion; -using MagicOnion.Server; -using MessagePack; - -namespace BasicServerSample.Services; - -public interface IBasicUnaryService : IService -{ - UnaryResult ThrowAsync(); - - UnaryResult ReturnTypeIsRefTypeAndNonSuccessResponseAsync(StatusCode statusCode); - UnaryResult ReturnTypeIsNilAndNonSuccessResponseAsync(StatusCode statusCode); - UnaryResult NoParameterReturnNilAsync(); - UnaryResult NoParameterReturnValueTypeAsync(); - UnaryResult NoParameterReturnRefTypeAsync(); - UnaryResult OneValueTypeParameterReturnNilAsync(int a); - UnaryResult TwoValueTypeParametersReturnNilAsync(int a, int b); - UnaryResult OneValueTypeParameterReturnValueTypeAsync(int a); - UnaryResult TwoValueTypeParametersReturnValueTypeAsync(int a, int b); - UnaryResult OneValueTypeParameterReturnRefTypeAsync(int a); - UnaryResult TwoValueTypeParametersReturnRefTypeAsync(int a, int b); - - UnaryResult OneRefTypeParameterReturnNilAsync(MyRequest a); - UnaryResult TwoRefTypeParametersReturnNilAsync(MyRequest a, MyRequest b); - UnaryResult OneRefTypeParameterReturnValueTypeAsync(MyRequest a); - UnaryResult TwoRefTypeParametersReturnValueTypeAsync(MyRequest a, MyRequest b); - UnaryResult OneRefTypeParameterReturnRefTypeAsync(MyRequest a); - UnaryResult TwoRefTypeParametersReturnRefTypeAsync(MyRequest a, MyRequest b); - - UnaryResult NonGenericNoParameterAsync(); - UnaryResult NonGenericOneValueTypeParameterAsync(int a); - UnaryResult NonGenericTwoValueTypeParameterAsync(int a, int b); - UnaryResult NullResponseAsync(MyRequest? a); -} - -[MessagePackObject(true)] -public class MyRequest -{ - public int Value { get; } - public MyRequest(int value) - { - Value = value; - } -} - -[MessagePackObject(true)] -public class MyResponse -{ - public string Value { get; } - public MyResponse(string value) - { - Value = value; - } -} - -public class BasicUnaryService : ServiceBase, IBasicUnaryService -{ - public UnaryResult ThrowAsync() - => throw new InvalidOperationException("Something went wrong"); - - public UnaryResult ReturnTypeIsRefTypeAndNonSuccessResponseAsync(StatusCode statusCode) - => throw new ReturnStatusException(statusCode, nameof(ReturnTypeIsRefTypeAndNonSuccessResponseAsync)); - public UnaryResult ReturnTypeIsNilAndNonSuccessResponseAsync(StatusCode statusCode) - => throw new ReturnStatusException(statusCode, nameof(ReturnTypeIsNilAndNonSuccessResponseAsync)); - - public UnaryResult NoParameterReturnNilAsync() - => UnaryResult.FromResult(Nil.Default); - - public UnaryResult NoParameterReturnValueTypeAsync() - => UnaryResult.FromResult(1234); - - public UnaryResult NoParameterReturnRefTypeAsync() - => UnaryResult.FromResult(new MyResponse("1234")); - - public UnaryResult OneValueTypeParameterReturnNilAsync(int a) - => UnaryResult.FromResult(Nil.Default); - - public UnaryResult TwoValueTypeParametersReturnNilAsync(int a, int b) - => UnaryResult.FromResult(Nil.Default); - - public UnaryResult OneValueTypeParameterReturnValueTypeAsync(int a) - => UnaryResult.FromResult(a); - - public UnaryResult TwoValueTypeParametersReturnValueTypeAsync(int a, int b) - => UnaryResult.FromResult(a + b); - - public UnaryResult OneValueTypeParameterReturnRefTypeAsync(int a) - => UnaryResult.FromResult(new MyResponse(a.ToString())); - - public UnaryResult TwoValueTypeParametersReturnRefTypeAsync(int a, int b) - => UnaryResult.FromResult(new MyResponse((a + b).ToString())); - - public UnaryResult OneRefTypeParameterReturnNilAsync(MyRequest a) - => UnaryResult.FromResult(Nil.Default); - - public UnaryResult TwoRefTypeParametersReturnNilAsync(MyRequest a, MyRequest b) - => UnaryResult.FromResult(Nil.Default); - - public UnaryResult OneRefTypeParameterReturnValueTypeAsync(MyRequest a) - => UnaryResult.FromResult(a.Value); - - public UnaryResult TwoRefTypeParametersReturnValueTypeAsync(MyRequest a, MyRequest b) - => UnaryResult.FromResult(a.Value + b.Value); - - public UnaryResult OneRefTypeParameterReturnRefTypeAsync(MyRequest a) - => UnaryResult.FromResult(new MyResponse(a.Value.ToString())); - - public UnaryResult TwoRefTypeParametersReturnRefTypeAsync(MyRequest a, MyRequest b) - => UnaryResult.FromResult(new MyResponse((a.Value + b.Value).ToString())); - - public UnaryResult NonGenericNoParameterAsync() - => MagicOnion.UnaryResult.CompletedResult; - - public UnaryResult NonGenericOneValueTypeParameterAsync(int a) - => MagicOnion.UnaryResult.CompletedResult; - - public UnaryResult NonGenericTwoValueTypeParameterAsync(int a, int b) - => MagicOnion.UnaryResult.CompletedResult; - - public UnaryResult NullResponseAsync(MyRequest? a) - => MagicOnion.UnaryResult.FromResult(default(MyResponse)); -} From 449ca360cb48b3e17c99b6fb984867d1a6bebc49 Mon Sep 17 00:00:00 2001 From: Mayuki Sawatari Date: Wed, 17 Jul 2024 16:30:42 +0900 Subject: [PATCH 2/3] Update GitHub Actions --- .github/workflows/build-canary.yml | 2 +- .github/workflows/build-debug.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-canary.yml b/.github/workflows/build-canary.yml index 8e7a4ee0b..737df847a 100644 --- a/.github/workflows/build-canary.yml +++ b/.github/workflows/build-canary.yml @@ -4,7 +4,7 @@ on: push: branches: - main - - vNext + - release/** tags: - "!*" # not a tag push paths-ignore: diff --git a/.github/workflows/build-debug.yml b/.github/workflows/build-debug.yml index 1e66d10e6..687776b16 100644 --- a/.github/workflows/build-debug.yml +++ b/.github/workflows/build-debug.yml @@ -4,7 +4,7 @@ on: push: branches: - main - - vNext + - release/** tags: - "!*" # not a tag push paths-ignore: From c9cec17f493341b8187d2088b2f0d805db847a1a Mon Sep 17 00:00:00 2001 From: Mayuki Sawatari Date: Wed, 17 Jul 2024 16:32:22 +0900 Subject: [PATCH 3/3] Remove BasicServerSample --- MagicOnion.sln | 7 ------- .../MagicOnion.Server.Tests.csproj | 1 - .../BasicServerSample.csproj | 18 ---------------- tests/samples/BasicServerSample/Program.cs | 21 ------------------- .../Properties/launchSettings.json | 13 ------------ .../appsettings.Development.json | 8 ------- .../BasicServerSample/appsettings.json | 14 ------------- 7 files changed, 82 deletions(-) delete mode 100644 tests/samples/BasicServerSample/BasicServerSample.csproj delete mode 100644 tests/samples/BasicServerSample/Program.cs delete mode 100644 tests/samples/BasicServerSample/Properties/launchSettings.json delete mode 100644 tests/samples/BasicServerSample/appsettings.Development.json delete mode 100644 tests/samples/BasicServerSample/appsettings.json diff --git a/MagicOnion.sln b/MagicOnion.sln index 41869b4d8..1bc56ae3e 100644 --- a/MagicOnion.sln +++ b/MagicOnion.sln @@ -72,8 +72,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{B561 EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AuthSample", "tests\samples\AuthSample\AuthSample.csproj", "{4D5E8486-9A0D-444A-922B-1D94FD8A820A}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BasicServerSample", "tests\samples\BasicServerSample\BasicServerSample.csproj", "{BC29EA94-6C52-4FAA-8F26-9346DB85C58F}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MagicOnion.Client.Tests", "tests\MagicOnion.Client.Tests\MagicOnion.Client.Tests.csproj", "{6DF31417-D091-4E27-963F-75E1D5AC0EA0}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MagicOnion.Integration.Tests", "tests\MagicOnion.Integration.Tests\MagicOnion.Integration.Tests.csproj", "{EC4E0789-6A32-42FA-ABD7-7ED3A5004CFF}" @@ -188,10 +186,6 @@ Global {4D5E8486-9A0D-444A-922B-1D94FD8A820A}.Debug|Any CPU.Build.0 = Debug|Any CPU {4D5E8486-9A0D-444A-922B-1D94FD8A820A}.Release|Any CPU.ActiveCfg = Release|Any CPU {4D5E8486-9A0D-444A-922B-1D94FD8A820A}.Release|Any CPU.Build.0 = Release|Any CPU - {BC29EA94-6C52-4FAA-8F26-9346DB85C58F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BC29EA94-6C52-4FAA-8F26-9346DB85C58F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BC29EA94-6C52-4FAA-8F26-9346DB85C58F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BC29EA94-6C52-4FAA-8F26-9346DB85C58F}.Release|Any CPU.Build.0 = Release|Any CPU {6DF31417-D091-4E27-963F-75E1D5AC0EA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6DF31417-D091-4E27-963F-75E1D5AC0EA0}.Debug|Any CPU.Build.0 = Debug|Any CPU {6DF31417-D091-4E27-963F-75E1D5AC0EA0}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -303,7 +297,6 @@ Global {A8550C24-2486-49DA-8D1A-DB6BBB2E9905} = {42EBB7E4-52D7-4E57-80AD-79FDD4900E13} {B5617CC1-55FD-4F77-BA75-9450474C6527} = {7ACC27E8-8FBE-4807-B91F-B89AF3CFF7E0} {4D5E8486-9A0D-444A-922B-1D94FD8A820A} = {B5617CC1-55FD-4F77-BA75-9450474C6527} - {BC29EA94-6C52-4FAA-8F26-9346DB85C58F} = {B5617CC1-55FD-4F77-BA75-9450474C6527} {6DF31417-D091-4E27-963F-75E1D5AC0EA0} = {7ACC27E8-8FBE-4807-B91F-B89AF3CFF7E0} {EC4E0789-6A32-42FA-ABD7-7ED3A5004CFF} = {7ACC27E8-8FBE-4807-B91F-B89AF3CFF7E0} {D0555A91-D817-4322-B8D0-16641069D17B} = {B5617CC1-55FD-4F77-BA75-9450474C6527} diff --git a/tests/MagicOnion.Server.Tests/MagicOnion.Server.Tests.csproj b/tests/MagicOnion.Server.Tests/MagicOnion.Server.Tests.csproj index f67f8e07b..9a2d6dc27 100644 --- a/tests/MagicOnion.Server.Tests/MagicOnion.Server.Tests.csproj +++ b/tests/MagicOnion.Server.Tests/MagicOnion.Server.Tests.csproj @@ -29,7 +29,6 @@ - diff --git a/tests/samples/BasicServerSample/BasicServerSample.csproj b/tests/samples/BasicServerSample/BasicServerSample.csproj deleted file mode 100644 index 89dbeaa22..000000000 --- a/tests/samples/BasicServerSample/BasicServerSample.csproj +++ /dev/null @@ -1,18 +0,0 @@ - - - - net8.0 - enable - enable - - - - - - - - - - - - diff --git a/tests/samples/BasicServerSample/Program.cs b/tests/samples/BasicServerSample/Program.cs deleted file mode 100644 index 74b49df5e..000000000 --- a/tests/samples/BasicServerSample/Program.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace BasicServerSample; - -public class Program -{ - public static void Main(string[] args) - { - var builder = WebApplication.CreateBuilder(args); - - // Add services to the container. - builder.Services.AddGrpc(); - builder.Services.AddMagicOnion(new[] { typeof(BasicServerSample.Program).Assembly }); - - var app = builder.Build(); - - // Configure the HTTP request pipeline. - app.MapMagicOnionService(); - app.MapGet("/", () => "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909"); - - app.Run(); - } -} \ No newline at end of file diff --git a/tests/samples/BasicServerSample/Properties/launchSettings.json b/tests/samples/BasicServerSample/Properties/launchSettings.json deleted file mode 100644 index fb4a16809..000000000 --- a/tests/samples/BasicServerSample/Properties/launchSettings.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "profiles": { - "BasicServerSample": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": false, - "applicationUrl": "http://localhost:5168;https://localhost:7168", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} diff --git a/tests/samples/BasicServerSample/appsettings.Development.json b/tests/samples/BasicServerSample/appsettings.Development.json deleted file mode 100644 index 0c208ae91..000000000 --- a/tests/samples/BasicServerSample/appsettings.Development.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - } -} diff --git a/tests/samples/BasicServerSample/appsettings.json b/tests/samples/BasicServerSample/appsettings.json deleted file mode 100644 index 1aef5074f..000000000 --- a/tests/samples/BasicServerSample/appsettings.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - }, - "AllowedHosts": "*", - "Kestrel": { - "EndpointDefaults": { - "Protocols": "Http2" - } - } -}