1 module tagion.testbench.actor.handler; 2 3 import tagion.testbench.actor.util; 4 5 // Default import list for bdd 6 import core.time; 7 import std.stdio; 8 import std.typecons : Tuple; 9 import tagion.actor.actor; 10 import tagion.behaviour; 11 import tagion.hibon.Document; 12 import tagion.testbench.tools.Environment; 13 import tagion.utils.pretend_safe_concurrency; 14 15 enum feature = Feature( 16 "Actor handler request", 17 ["This feature should verify that you can request a handler for an actor that you don\\'t own"]); 18 19 alias FeatureContext = Tuple!( 20 SendAMessageToAnActorYouDontOwn, "SendAMessageToAnActorYouDontOwn", 21 FeatureGroup*, "result" 22 ); 23 24 enum child_task_name = "handle_child_task"; 25 enum super_task_name = "handle_super_task"; 26 27 @safe 28 struct MyActor { 29 int status = 0; 30 31 void setstatus(Msg!"setstatus", int i, Tid returnTid) { 32 status = i; 33 send(returnTid, "hey we received that number"); 34 } 35 36 void task() nothrow { 37 run(&setstatus); 38 } 39 } 40 41 @safe 42 struct MySuperActor { 43 ActorHandle childHandle; 44 45 void task() { 46 childHandle = spawn!MyActor(child_task_name); 47 waitforChildren(Ctrl.ALIVE); 48 run(); 49 } 50 } 51 52 @safe @Scenario("send a message to an actor you don't own", 53 []) 54 class SendAMessageToAnActorYouDontOwn { 55 ActorHandle super_actor_handler; 56 ActorHandle child_handler; 57 58 @Given("a supervisor #super and one child actor #child") 59 Document actorChild() { 60 super_actor_handler = spawn!MySuperActor(super_task_name); 61 62 check(waitforChildren(Ctrl.ALIVE), "Supervisor did not alive"); 63 return result_ok; 64 } 65 66 @When("#we request the handler for #child") 67 Document forChild() { 68 child_handler = ActorHandle(child_task_name); 69 check(child_handler.tid !is Tid.init, "Child task was not running"); 70 return result_ok; 71 } 72 73 @When("#we send a message to #child") 74 Document toChild() { 75 child_handler.send(Msg!"setstatus"(), 42, thisTid); 76 return result_ok; 77 } 78 79 @When("#we receive confirmation that shild has received the message.") 80 Document theMessage() { 81 string message = receiveOnlyTimeout!string; 82 83 check(message !is string.init, "Never got the confirmation from the child"); 84 writeln(message); 85 return result_ok; 86 } 87 88 @Then("stop the #super") 89 Document theSuper() { 90 super_actor_handler.send(Sig.STOP); 91 check(waitforChildren(Ctrl.END), "Child did not end"); 92 return result_ok; 93 } 94 95 }