Skip to content

Commit

Permalink
Add graceful stop specs (#6103)
Browse files Browse the repository at this point in the history
* added `GracefulStop` specs

* added one more use case

* fixing up some buggy `ActorLifeCycleSpec`s
  • Loading branch information
Aaronontheweb committed Sep 17, 2022
1 parent 4c2f30e commit daa2b9b
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 16 deletions.
27 changes: 11 additions & 16 deletions src/core/Akka.Tests/Actor/ActorLifeCycleSpec.cs
Expand Up @@ -213,31 +213,21 @@ public class Become
}
public class BecomeActor : UntypedActor
{
private IActorRef testActor;
private readonly IActorRef _testActor;
public BecomeActor(IActorRef testActor)
{
this.testActor = testActor;
}

protected override void PreRestart(Exception cause, object message)
{
base.PreRestart(cause, message);
}

protected override void PostRestart(Exception cause)
{
base.PostRestart(cause);
_testActor = testActor;
}
protected override void OnReceive(object message)
{
if (message is Become)
{
Context.Become(OnBecome);
testActor.Tell("ok");
_testActor.Tell("ok");
}
else
{
testActor.Tell(42);
_testActor.Tell(42);
}
}

Expand All @@ -249,7 +239,7 @@ protected void OnBecome(object message)
}
else
{
testActor.Tell(43);
_testActor.Tell(43);
}
}
}
Expand All @@ -266,7 +256,12 @@ public async Task Clear_behavior_stack_upon_restart()
a.Tell("hello");
await ExpectMsgAsync(43);

await EventFilter.Exception<Exception>("buh").ExpectOneAsync(async () => a.Tell("fail"));
await EventFilter.Exception<Exception>("buh").ExpectOneAsync(async () =>
{
a.Tell("fail");
await Task.CompletedTask;
});

a.Tell("hello");
await ExpectMsgAsync(42);
}
Expand Down
71 changes: 71 additions & 0 deletions src/core/Akka.Tests/Actor/GracefulStopSpecs.cs
@@ -0,0 +1,71 @@
//-----------------------------------------------------------------------
// <copyright file="GracefulStopSpecs.cs" company="Akka.NET Project">
// Copyright (C) 2009-2022 Lightbend Inc. <http://www.lightbend.com>
// Copyright (C) 2013-2022 .NET Foundation <https://github.com/akkadotnet/akka.net>
// </copyright>
//-----------------------------------------------------------------------

using System;
using System.Threading.Tasks;
using Akka.Actor;
using Akka.Actor.Dsl;
using Akka.TestKit;
using Akka.TestKit.TestActors;
using Xunit;
using FluentAssertions;

namespace Akka.Tests.Actor
{
public class GracefulStopSpecs : AkkaSpec
{
[Fact(DisplayName = "GracefulStop should terminate target actor on-time")]
public async Task GracefulStopShouldTerminateOnTime()
{
// arrange
var actor = Sys.ActorOf(BlackHoleActor.Props);
Watch(actor);

// act
var stopped = await actor.GracefulStop(TimeSpan.FromSeconds(3));
await ExpectTerminatedAsync(actor);

// assert
stopped.Should().BeTrue();
}

[Fact(DisplayName = "GracefulStop should return true for an already terminated actor")]
public async Task GracefulStopShouldReturnTrueForAlreadyDeadActor()
{
// arrange
var actor = Sys.ActorOf(BlackHoleActor.Props);
Watch(actor);

// act
Sys.Stop(actor);
await ExpectTerminatedAsync(actor);
var stopped = await actor.GracefulStop(TimeSpan.FromSeconds(3));

// assert
stopped.Should().BeTrue();
}

private class CustomShutdown{}

[Fact(DisplayName = "GracefulStop should return false if shutdown goes overtime", Skip = "GracefulStop currently throws a TaskCancellationException, which seems wrong")]
public async Task GracefulStopShouldThrowIfShutdownGoesOvertime()
{
// arrange
var actor = Sys.ActorOf(act => act.ReceiveAsync<CustomShutdown>(async (a, ctx) =>
{
await Task.Delay(200);
ctx.Stop(ctx.Self);
}));

// act
var stopped = await actor.GracefulStop(TimeSpan.FromMilliseconds(10), new CustomShutdown());

// assert
stopped.Should().BeFalse();
}
}
}

0 comments on commit daa2b9b

Please sign in to comment.