Skip to content

Instantly share code, notes, and snippets.

@Havret
Created January 10, 2019 22:39
Show Gist options
  • Save Havret/78409e91c9adf62aed3392574a3d0446 to your computer and use it in GitHub Desktop.
Save Havret/78409e91c9adf62aed3392574a3d0446 to your computer and use it in GitHub Desktop.
RepeatedScheduleTest
using Akka.Actor;
using Akka.TestKit;
using Akka.TestKit.NUnit;
using NUnit.Framework;
using System;
using System.Linq;
namespace akkaSchedulerTest.Test
{
public class RepeatedScheduleTest_Standard_Scheduler : TestKit
{
/// <summary>
/// This test passes
/// </summary>
[Test]
public void Sender_Actor_Sends_Out_Message_Expected_Number_Of_Times()
{
var interval = TimeSpan.FromSeconds(1);
var testDuration = TimeSpan.FromSeconds(2.1);
int expectedMessageCount = 2;
var recipientActorRef = this.TestActor;
var messageText = "Message";
var senderActor = Sys.ActorOf(Props.Create(() => new RepeatedMessageSenderActor(recipientActorRef, messageText, interval)));
IgnoreMessages<RepeatedMessageSenderActor.Initialized>();
// verify that the other actor receives the right number of messages over the expected time
var allExpectedMessages = Enumerable.Repeat(messageText, expectedMessageCount).ToArray();
ExpectMsgAllOf(testDuration, allExpectedMessages);
}
}
public class RepeatedScheduleTest_Test_Scheduler : TestKit
{
// REF: https://petabridge.com/blog/how-to-unit-test-akkadotnet-actors-akka-testkit/#how-do-i-test-scheduled-messages
public RepeatedScheduleTest_Test_Scheduler()
: base(@"akka.scheduler.implementation = ""Akka.TestKit.TestScheduler, Akka.TestKit""") { }
private TestScheduler Scheduler => (TestScheduler)Sys.Scheduler;
/// <summary>
/// This test fails with the error:
/// Timeout (00:00:03) while expecting 5 messages. Only got 0 after 00:00:02.9992044.
/// In realtime it should last many hours. This is an attempt to verify the scheduled behavior in a quick test.
/// </summary>
[Test]
public void Sender_Actor_Sends_Out_Message_Expected_Number_Of_Times()
{
var interval = TimeSpan.FromHours(1);
var testDuration = TimeSpan.FromHours(5);
int expectedMessageCount = 5;
var recipientActorRef = this.TestActor;
var messageText = "Message";
var senderActor = Sys.ActorOf(Props
.Create(() => new RepeatedMessageSenderActor(recipientActorRef, messageText, interval))
.WithDispatcher(CallingThreadDispatcher.Id));
// We have to be sure that our actor is initialized before we can start
// playing with time
ExpectMsg<RepeatedMessageSenderActor.Initialized>();
// now the fun begins. We have to advance scheduler by expected interval
// in this case it is an hour. We expect that for each hour one message will be send
// thus we have to advance scheduler 5 times to get 5 messages
Scheduler.Advance(TimeSpan.FromHours(1));
Scheduler.Advance(TimeSpan.FromHours(1));
Scheduler.Advance(TimeSpan.FromHours(1));
Scheduler.Advance(TimeSpan.FromHours(1));
Scheduler.Advance(TimeSpan.FromHours(1));
// verify that the other actor receives the right number of messages over the expected time
var allExpectedMessages = Enumerable.Repeat(messageText, expectedMessageCount).ToArray();
ExpectMsgAllOf(allExpectedMessages);
}
}
public class RepeatedMessageSenderActor : ReceiveActor
{
private readonly IActorRef _recipientActorRef;
private readonly string _messageText;
private readonly TimeSpan _interval;
public RepeatedMessageSenderActor(IActorRef recipientActorRef, string messageText, TimeSpan interval)
{
_recipientActorRef = recipientActorRef;
_messageText = messageText;
_interval = interval;
Receive<SendOutMessage>(msg => HandleSendOutMessage());
// use the scheduler to repeatedly tell this actor to send out a message at a regular interval
Context.System.Scheduler
.ScheduleTellRepeatedly(_interval, _interval, Self, new SendOutMessage(), Self);
}
/// <summary>
/// in the failing test, this method never gets called
/// </summary>
private void HandleSendOutMessage()
{
_recipientActorRef.Tell(_messageText);
}
protected override void PreStart()
{
_recipientActorRef.Tell(new Initialized());
base.PreStart();
}
public class SendOutMessage { }
public class Initialized { }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment