public void An_actor_watching_a_remote_actor_in_the_cluster_must_receive_terminated_when_watched_node_becomes_down_removed()
{
Within(TimeSpan.FromSeconds(30), () =>
{
AwaitClusterUp(_config.First, _config.Second, _config.Third, _config.Fourth);
EnterBarrier("cluster-up");
RunOn(() =>
{
EnterBarrier("subjected-started");
var path2 = new RootActorPath(GetAddress(_config.Second)) / "user" / "subject";
var path3 = new RootActorPath(GetAddress(_config.Third)) / "user" / "subject";
var watchEstablished = new TestLatch(2);
Sys.ActorOf(Props.Create(() => new Observer(path2, path3, watchEstablished, TestActor))
.WithDeploy(Deploy.Local), "observer1");
watchEstablished.Ready();
EnterBarrier("watch-established");
ExpectMsg(path2);
ExpectNoMsg(TimeSpan.FromSeconds(2));
EnterBarrier("second-terminated");
MarkNodeAsUnavailable(GetAddress(_config.Third));
AwaitAssert(() => Assert.True(ClusterView.UnreachableMembers.Select(x => x.Address).Contains(GetAddress(_config.Third))));
Cluster.Down(GetAddress(_config.Third));
//removed
AwaitAssert(() => Assert.False(ClusterView.Members.Select(x => x.Address).Contains(GetAddress(_config.Third))));
AwaitAssert(() => Assert.False(ClusterView.UnreachableMembers.Select(x => x.Address).Contains(GetAddress(_config.Third))));
ExpectMsg(path3);
EnterBarrier("third-terminated");
}, _config.First);
RunOn(() =>
{
Sys.ActorOf(BlackHoleActor.Props, "subject");
EnterBarrier("subjected-started");
EnterBarrier("watch-established");
RunOn(() =>
{
MarkNodeAsUnavailable(GetAddress(_config.Second));
AwaitAssert(() => Assert.True(ClusterView.UnreachableMembers.Select(x => x.Address).Contains(GetAddress(_config.Second))));
Cluster.Down(GetAddress(_config.Second));
//removed
AwaitAssert(() => Assert.False(ClusterView.Members.Select(x => x.Address).Contains(GetAddress(_config.Second))));
AwaitAssert(() => Assert.False(ClusterView.UnreachableMembers.Select(x => x.Address).Contains(GetAddress(_config.Second))));
}, _config.Third);
EnterBarrier("second-terminated");
EnterBarrier("third-terminated");
}, _config.Second, _config.Third, _config.Fourth);
RunOn(() =>
{
EnterBarrier("subjected-started");
EnterBarrier("watch-established");
EnterBarrier("second-terminated");
EnterBarrier("third-terminated");
}, _config.Fifth);
EnterBarrier("after-1");
});
}