|
| 1 | +using Microsoft.Extensions.DependencyInjection; |
| 2 | +using Orleans.CodeGeneration; |
| 3 | +using Orleans.Runtime; |
| 4 | +using Orleans.Serialization.Invocation; |
| 5 | +using TestExtensions; |
| 6 | +using UnitTests.Messaging; |
| 7 | +using Xunit; |
| 8 | + |
| 9 | +namespace UnitTests.Runtime; |
| 10 | + |
| 11 | +[TestSuite("BVT")] |
| 12 | +[TestProvider("None")] |
| 13 | +[TestArea("Runtime")] |
| 14 | +public class GrainReferenceRuntimeTests |
| 15 | +{ |
| 16 | + [Fact, TestCategory("BVT")] |
| 17 | + public void TypedCompletionSourceReturnsToPoolWhenSendThrows() |
| 18 | + { |
| 19 | + var runtimeClient = new ThrowingRuntimeClient(); |
| 20 | + var runtime = CreateRuntime(runtimeClient); |
| 21 | + var request = new TestInvokableRequest(); |
| 22 | + |
| 23 | + Assert.Throws<InvalidOperationException>(() => runtime.InvokeMethodAsync<int>(null!, request, InvokeMethodOptions.None)); |
| 24 | + |
| 25 | + var captured = Assert.IsType<ResponseCompletionSource<int>>(runtimeClient.Context); |
| 26 | + var returned = ResponseCompletionSourcePool.Get<int>(); |
| 27 | + Assert.Same(captured, returned); |
| 28 | + Assert.Equal(1, request.DisposeCount); |
| 29 | + returned.Reset(); |
| 30 | + } |
| 31 | + |
| 32 | + [Fact, TestCategory("BVT")] |
| 33 | + public void UntypedCompletionSourceReturnsToPoolWhenSendThrows() |
| 34 | + { |
| 35 | + var runtimeClient = new ThrowingRuntimeClient(); |
| 36 | + var runtime = CreateRuntime(runtimeClient); |
| 37 | + var request = new TestInvokableRequest(); |
| 38 | + |
| 39 | + Assert.Throws<InvalidOperationException>(() => runtime.InvokeMethodAsync(null!, request, InvokeMethodOptions.None)); |
| 40 | + |
| 41 | + var captured = Assert.IsType<ResponseCompletionSource>(runtimeClient.Context); |
| 42 | + var returned = ResponseCompletionSourcePool.Get(); |
| 43 | + Assert.Same(captured, returned); |
| 44 | + Assert.Equal(1, request.DisposeCount); |
| 45 | + returned.Reset(); |
| 46 | + } |
| 47 | + |
| 48 | + private static GrainReferenceRuntime CreateRuntime(IRuntimeClient runtimeClient) |
| 49 | + => new(runtimeClient, null!, [], null!, null!); |
| 50 | + |
| 51 | + private sealed class ThrowingRuntimeClient : IRuntimeClient |
| 52 | + { |
| 53 | + public IResponseCompletionSource? Context { get; private set; } |
| 54 | + |
| 55 | + public TimeProvider TimeProvider => TimeProvider.System; |
| 56 | + public IInternalGrainFactory InternalGrainFactory => throw new NotSupportedException(); |
| 57 | + public string CurrentActivationIdentity => string.Empty; |
| 58 | + public IServiceProvider ServiceProvider => EmptyServiceProvider.Instance; |
| 59 | + public IGrainReferenceRuntime GrainReferenceRuntime => throw new NotSupportedException(); |
| 60 | + |
| 61 | + public TimeSpan GetResponseTimeout() => throw new NotSupportedException(); |
| 62 | + |
| 63 | + public void SetResponseTimeout(TimeSpan timeout) => throw new NotSupportedException(); |
| 64 | + |
| 65 | + public void SendRequest(GrainReference target, IInvokable request, IResponseCompletionSource? context, InvokeMethodOptions options) |
| 66 | + { |
| 67 | + Context = context; |
| 68 | + throw new InvalidOperationException("Send failed."); |
| 69 | + } |
| 70 | + |
| 71 | + public void SendResponse(Message request, Response response) => throw new NotSupportedException(); |
| 72 | + |
| 73 | + public void ReceiveResponse(Message message) => throw new NotSupportedException(); |
| 74 | + |
| 75 | + public IAddressable CreateObjectReference(IAddressable obj) => throw new NotSupportedException(); |
| 76 | + |
| 77 | + public void DeleteObjectReference(IAddressable obj) => throw new NotSupportedException(); |
| 78 | + |
| 79 | + public void BreakOutstandingMessagesToSilo(SiloAddress deadSilo) => throw new NotSupportedException(); |
| 80 | + |
| 81 | + public int GetRunningRequestsCount(GrainInterfaceType grainInterfaceType) => 0; |
| 82 | + } |
| 83 | + |
| 84 | + private sealed class EmptyServiceProvider : IServiceProvider |
| 85 | + { |
| 86 | + public static EmptyServiceProvider Instance { get; } = new(); |
| 87 | + |
| 88 | + public object? GetService(Type serviceType) => null; |
| 89 | + } |
| 90 | +} |
0 commit comments