Created
January 10, 2019 22:39
-
-
Save Havret/78409e91c9adf62aed3392574a3d0446 to your computer and use it in GitHub Desktop.
RepeatedScheduleTest
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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