Skip to content

Commit

Permalink
harden racy ActorCellSpecs (#6395)
Browse files Browse the repository at this point in the history
also modernized these specs to use built-in `TestKit` methods and `async Task` unit tests.
  • Loading branch information
Aaronontheweb committed Feb 9, 2023
1 parent 06b1d29 commit 9a55cba
Showing 1 changed file with 26 additions and 25 deletions.
51 changes: 26 additions & 25 deletions src/core/Akka.Tests/Actor/ActorCellSpec.cs
Expand Up @@ -22,54 +22,55 @@ public class ActorCellSpec : AkkaSpec
{
public class DummyActor : ReceiveActor
{
public DummyActor(AutoResetEvent autoResetEvent)
public DummyActor()
{
ReceiveAny(m => autoResetEvent.Set());
ReceiveAny(m => Sender.Tell(m));
}
}

public class DummyAsyncActor : ReceiveActor
{
public DummyAsyncActor(AutoResetEvent autoResetEvent)
public DummyAsyncActor()
{
ReceiveAsync<string>(async m =>
{
await Task.Delay(500);
autoResetEvent.Set();
await Task.Delay(5);
Sender.Tell(m);
});
}
}

[Fact]
public void Cell_should_clear_current_message_after_receive()
public async Task Cell_should_clear_current_message_after_receive()
{
AutoResetEvent autoResetEvent = new AutoResetEvent(false);
var actor = Sys.ActorOf(Props.Create(() => new DummyActor(autoResetEvent)));
actor.Tell("hello");
//ensure the message was received
autoResetEvent.WaitOne();
var refCell = actor as ActorRefWithCell;
var cell = refCell.Underlying as ActorCell;
// arrange
var actor = Sys.ActorOf(Props.Create(() => new DummyActor()));

// act
await actor.Ask<string>("hello", RemainingOrDefault);

// assert
var refCell = (ActorRefWithCell)actor;
//wait while current message is not null (that is, receive is not yet completed/exited)
SpinWait.SpinUntil(() => cell.CurrentMessage == null, TimeSpan.FromSeconds(2));

cell.CurrentMessage.ShouldBe(null);
AwaitCondition(() => refCell.Underlying is ActorCell { CurrentMessage: null });
}

[Fact]
public void Cell_should_clear_current_message_after_async_receive()
public async Task Cell_should_clear_current_message_after_async_receive()
{
AutoResetEvent autoResetEvent = new AutoResetEvent(false);
var actor = Sys.ActorOf(Props.Create(() => new DummyAsyncActor(autoResetEvent)));
actor.Tell("hello");
//ensure the message was received
Assert.True(autoResetEvent.WaitOne(TimeSpan.FromSeconds(3)), "Timed out while waiting for autoreset event");
var refCell = actor as ActorRefWithCell;
var cell = refCell.Underlying as ActorCell;
// arrange
var actor = Sys.ActorOf(Props.Create(() => new DummyAsyncActor()));

// act
await actor.Ask<string>("hello", RemainingOrDefault);

// assert

var refCell = (ActorRefWithCell)actor;
//wait while current message is not null (that is, receive is not yet completed/exited)
SpinWait.SpinUntil(() => cell.CurrentMessage == null, TimeSpan.FromSeconds(2));

cell.CurrentMessage.ShouldBe(null);
AwaitCondition(() => refCell.Underlying is ActorCell { CurrentMessage: null });
}
}
}

0 comments on commit 9a55cba

Please sign in to comment.