Skip to content

Commit

Permalink
Added validation synchronization context for the unit tests to detect…
Browse files Browse the repository at this point in the history
… missing ConfigureAwait(false) calls.
  • Loading branch information
yallie committed Jan 10, 2025
1 parent f8ca295 commit d8abe00
Show file tree
Hide file tree
Showing 9 changed files with 205 additions and 40 deletions.
7 changes: 5 additions & 2 deletions CoreRemoting.Tests/AsyncTests.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using CoreRemoting.Tests.Tools;
using Xunit;

Expand All @@ -13,8 +14,9 @@ public AsyncTests(ServerFixture serverFixture)
_serverFixture = serverFixture;
_serverFixture.Start();
}

[Fact]
[SuppressMessage("Usage", "xUnit1030:Do not call ConfigureAwait in test method", Justification = "<Pending>")]
public async void AsyncMethods_should_work()
{
using var client = new RemotingClient(new ClientConfig()
Expand All @@ -34,9 +36,10 @@ public async void AsyncMethods_should_work()
}

/// <summary>
/// Awaiting for ordinary non-generic task method should not hangs.
/// Awaiting for ordinary non-generic task method should not hangs.
/// </summary>
[Fact(Timeout = 15000)]
[SuppressMessage("Usage", "xUnit1030:Do not call ConfigureAwait in test method", Justification = "<Pending>")]
public async void AwaitingNonGenericTask_should_not_hang_forever()
{
using var client = new RemotingClient(new ClientConfig()
Expand Down
81 changes: 74 additions & 7 deletions CoreRemoting.Tests/RpcTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Data;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Security;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -39,11 +40,21 @@ public RpcTests(ServerFixture serverFixture, ITestOutputHelper testOutputHelper)
_serverFixture.Start(ServerChannel);
}

[Fact]
public void ValidationSyncContext_is_installed()
{
using var ctx = ValidationSyncContext.Install();

Assert.IsType<ValidationSyncContext>(SynchronizationContext.Current);
}

[Fact]
public void Call_on_Proxy_should_be_invoked_on_remote_service()
{
void ClientAction()
{
using var ctx = ValidationSyncContext.Install();

try
{
var stopWatch = new Stopwatch();
Expand Down Expand Up @@ -117,6 +128,8 @@ public void Call_on_Proxy_should_be_invoked_on_remote_service_with_MessageEncryp

void ClientAction()
{
using var ctx = ValidationSyncContext.Install();

try
{
var stopWatch = new Stopwatch();
Expand Down Expand Up @@ -188,6 +201,8 @@ public void Delegate_invoked_on_server_should_callback_client()

void ClientAction()
{
using var ctx = ValidationSyncContext.Install();

try
{
using var client = new RemotingClient(
Expand Down Expand Up @@ -222,8 +237,10 @@ void ClientAction()
[Fact]
public void Events_should_work_remotely()
{
bool serviceEventCalled = false;
bool customDelegateEventCalled = false;
using var ctx = ValidationSyncContext.Install();

var serviceEventCalled = false;
var customDelegateEventCalled = false;

using var client = new RemotingClient(
new ClientConfig()
Expand Down Expand Up @@ -278,6 +295,8 @@ public void External_types_should_work_as_remote_service_parameters()

void ClientAction()
{
using var ctx = ValidationSyncContext.Install();

try
{
using var client = new RemotingClient(new ClientConfig()
Expand Down Expand Up @@ -313,6 +332,8 @@ void ClientAction()
[Fact]
public void Generic_methods_should_be_called_correctly()
{
using var ctx = ValidationSyncContext.Install();

using var client = new RemotingClient(new ClientConfig()
{
ConnectionTimeout = 0,
Expand All @@ -333,6 +354,8 @@ public void Generic_methods_should_be_called_correctly()
[Fact]
public void Inherited_methods_should_be_called_correctly()
{
using var ctx = ValidationSyncContext.Install();

using var client = new RemotingClient(new ClientConfig()
{
ConnectionTimeout = 0,
Expand All @@ -353,6 +376,8 @@ public void Inherited_methods_should_be_called_correctly()
[Fact]
public void Enum_arguments_should_be_passed_correctly()
{
using var ctx = ValidationSyncContext.Install();

using var client = new RemotingClient(new ClientConfig()
{
ConnectionTimeout = 0,
Expand All @@ -375,6 +400,8 @@ public void Enum_arguments_should_be_passed_correctly()
[Fact]
public void Missing_method_throws_RemoteInvocationException()
{
using var ctx = ValidationSyncContext.Install();

using var client = new RemotingClient(new ClientConfig()
{
ConnectionTimeout = 0,
Expand Down Expand Up @@ -412,6 +439,8 @@ public void Missing_method_throws_RemoteInvocationException()
[Fact]
public void Missing_service_throws_RemoteInvocationException()
{
using var ctx = ValidationSyncContext.Install();

using var client = new RemotingClient(new ClientConfig()
{
ConnectionTimeout = 0,
Expand All @@ -436,6 +465,8 @@ public void Missing_service_throws_RemoteInvocationException()
[Fact]
public void Error_method_throws_Exception()
{
using var ctx = ValidationSyncContext.Install();

try
{
using var client = new RemotingClient(new ClientConfig()
Expand Down Expand Up @@ -466,8 +497,11 @@ public void Error_method_throws_Exception()
}

[Fact]
[SuppressMessage("Usage", "xUnit1030:Do not call ConfigureAwait in test method", Justification = "<Pending>")]
public async Task ErrorAsync_method_throws_Exception()
{
// using var ctx = ValidationSyncContext.Install(); // fails?

try
{
using var client = new RemotingClient(new ClientConfig()
Expand All @@ -484,8 +518,10 @@ public async Task ErrorAsync_method_throws_Exception()

var proxy = client.CreateProxy<ITestService>();
var ex = (await Assert.ThrowsAsync<RemoteInvocationException>(async () =>
await proxy.ErrorAsync(nameof(ErrorAsync_method_throws_Exception))))
.GetInnermostException();
{
await proxy.ErrorAsync(nameof(ErrorAsync_method_throws_Exception)).ConfigureAwait(false);
})
.ConfigureAwait(false)).GetInnermostException();

Assert.NotNull(ex);
Assert.Equal(nameof(ErrorAsync_method_throws_Exception), ex.Message);
Expand All @@ -500,6 +536,8 @@ await proxy.ErrorAsync(nameof(ErrorAsync_method_throws_Exception))))
[Fact]
public void NonSerializableError_method_throws_Exception()
{
using var ctx = ValidationSyncContext.Install();

try
{
using var client = new RemotingClient(new ClientConfig()
Expand Down Expand Up @@ -550,7 +588,9 @@ void AfterCall(object sender, ServerRpcContext ctx)
ctx.Exception);
}

using var ctx = ValidationSyncContext.Install();
_serverFixture.Server.AfterCall += AfterCall;

try
{
using var client = new RemotingClient(new ClientConfig()
Expand Down Expand Up @@ -588,6 +628,8 @@ void AfterCall(object sender, ServerRpcContext ctx)
[Fact]
public void Failing_component_constructor_throws_RemoteInvocationException()
{
using var ctx = ValidationSyncContext.Install();

using var client = new RemotingClient(new ClientConfig()
{
ConnectionTimeout = 3,
Expand All @@ -608,8 +650,11 @@ public void Failing_component_constructor_throws_RemoteInvocationException()
}

[Fact]
[SuppressMessage("Usage", "xUnit1030:Do not call ConfigureAwait in test method", Justification = "<Pending>")]
public async Task Disposed_client_subscription_doesnt_break_other_clients()
{
using var ctx = ValidationSyncContext.Install();

async Task Roundtrip(bool encryption)
{
var oldEncryption = _serverFixture.Server.Config.MessageEncryption;
Expand Down Expand Up @@ -642,7 +687,7 @@ async Task Roundtrip(bool encryption)
client1.Disconnect();

proxy2.FireServiceEvent();
Assert.True(await fired2.Task);
Assert.True(await fired2.Task.ConfigureAwait(false));
Assert.True(fired2.Task.IsCompleted);
Assert.False(fired1.Task.IsCompleted);
}
Expand All @@ -656,15 +701,17 @@ async Task Roundtrip(bool encryption)
}

// works!
await Roundtrip(encryption: false);
await Roundtrip(encryption: false).ConfigureAwait(false);

// fails!
await Roundtrip(encryption: true);
await Roundtrip(encryption: true).ConfigureAwait(false);
}

[Fact]
public void DataTable_roundtrip_works_issue60()
{
using var ctx = ValidationSyncContext.Install();

using var client = new RemotingClient(new ClientConfig()
{
ConnectionTimeout = 0,
Expand Down Expand Up @@ -694,6 +741,8 @@ public void Large_messages_are_sent_and_received()
// max payload size, in bytes
var maxSize = 2 * 1024 * 1024 + 1;

using var ctx = ValidationSyncContext.Install();

using var client = new RemotingClient(new ClientConfig()
{
ConnectionTimeout = 0,
Expand Down Expand Up @@ -748,6 +797,7 @@ void BeforeCall(object sender, ServerRpcContext e) =>
void AfterCall(object sender, ServerRpcContext e) =>
Interlocked.Increment(ref afterCallFired);

using var ctx = ValidationSyncContext.Install();
_serverFixture.Server.BeforeCall += BeforeCall;
_serverFixture.Server.AfterCall += AfterCall;

Expand Down Expand Up @@ -793,6 +843,7 @@ void BeforeCall(object sender, ServerRpcContext e) =>
void AfterCall(object sender, ServerRpcContext e) =>
Interlocked.Increment(ref afterCallFired);

using var ctx = ValidationSyncContext.Install();
_serverFixture.Server.BeforeCall += BeforeCall;
_serverFixture.Server.AfterCall += AfterCall;

Expand Down Expand Up @@ -848,7 +899,9 @@ void InterceptMethodCalls(object sender, ServerRpcContext e)
}
}

using var ctx = ValidationSyncContext.Install();
_serverFixture.Server.BeginCall += InterceptMethodCalls;

try
{
using var client = new RemotingClient(new ClientConfig()
Expand Down Expand Up @@ -893,6 +946,8 @@ void RejectCall(object sender, ServerRpcContext e) =>
server.RejectCall += RejectCall;
server.Config.AuthenticationRequired = true;

using var ctx = ValidationSyncContext.Install();

try
{
using var client = new RemotingClient(new ClientConfig()
Expand Down Expand Up @@ -934,6 +989,8 @@ public void Authentication_handler_has_access_to_the_current_session()
AuthenticateFake = c => RemotingSession.Current != null
};

using var ctx = ValidationSyncContext.Install();

try
{
using var client = new RemotingClient(new ClientConfig()
Expand Down Expand Up @@ -970,6 +1027,8 @@ public void Broken_auhentication_handler_doesnt_break_the_server()
AuthenticateFake = c => throw new Exception("Broken")
};

using var ctx = ValidationSyncContext.Install();

try
{
using var client = new RemotingClient(new ClientConfig()
Expand Down Expand Up @@ -1015,6 +1074,8 @@ public void Authentication_handler_can_check_client_address()
}
};

using var ctx = ValidationSyncContext.Install();

try
{
using var client = new RemotingClient(new ClientConfig()
Expand Down Expand Up @@ -1043,6 +1104,8 @@ public void Authentication_handler_can_check_client_address()
[Fact]
public void ServerComponent_can_track_client_network_address()
{
using var ctx = ValidationSyncContext.Install();

using var client = new RemotingClient(new ClientConfig()
{
ConnectionTimeout = 0,
Expand All @@ -1064,6 +1127,8 @@ public void ServerComponent_can_track_client_network_address()
[Fact]
public void Logon_and_logoff_events_are_triggered()
{
using var ctx = ValidationSyncContext.Install();

void CheckSession(string operation)
{
var rs = RemotingSession.Current;
Expand Down Expand Up @@ -1135,8 +1200,10 @@ void BypassAuthorizationForEcho(object sender, ServerRpcContext e) =>
e.AuthenticationRequired =
e.MethodCallMessage.MethodName != "Echo";

using var ctx = ValidationSyncContext.Install();
_serverFixture.Server.Config.AuthenticationRequired = true;
_serverFixture.Server.BeginCall += BypassAuthorizationForEcho;

try
{
using var client = new RemotingClient(new ClientConfig()
Expand Down
Loading

0 comments on commit d8abe00

Please sign in to comment.