public void An_actor_watching_a_remote_actor_in_the_cluster_must_be_able_to_watch_actor_before_node_joins_cluster_and_cluster_remote_watcher_takes_over_from_remote_watcher()
{
Within(TimeSpan.FromSeconds(20), () =>
{
RunOn(() => Sys.ActorOf(BlackHoleActor.Props.WithDeploy(Deploy.Local), "subject5"), _config.Fifth);
EnterBarrier("subjected-started");
RunOn(() =>
{
Sys.ActorSelection(new RootActorPath(GetAddress(_config.Fifth)) / "user" / "subject5").Tell(new Identify("subject5"), TestActor);
var subject5 = ExpectMsg<ActorIdentity>().Subject;
Watch(subject5);
//fifth is not a cluster member, so the watch is handled by the RemoteWatcher
AwaitAssert(() =>
{
RemoteWatcher.Tell(Remote.RemoteWatcher.Stats.Empty);
var stats = ExpectMsg<Remote.RemoteWatcher.Stats>();
stats.WatchingRefs.Contains(new Tuple<IActorRef, IActorRef>(subject5, TestActor)).ShouldBeTrue();
stats.WatchingAddresses.Contains(GetAddress(_config.Fifth)).ShouldBeTrue();
});
}, _config.First);
EnterBarrier("remote-watch");
// second and third are already removed
AwaitClusterUp(_config.First, _config.Fourth, _config.Fifth);
RunOn(() =>
{
// fifth is member, so the watch is handled by the ClusterRemoteWatcher,
// and cleaned up from RemoteWatcher
AwaitAssert(() =>
{
RemoteWatcher.Tell(Remote.RemoteWatcher.Stats.Empty);
var stats = ExpectMsg<Remote.RemoteWatcher.Stats>();
stats.WatchingRefs.Select(x => x.Item1.Path.Name).Contains("subject5").ShouldBeTrue();
stats.WatchingAddresses.Contains(GetAddress(_config.Fifth)).ShouldBeFalse();
});
}, _config.First);
EnterBarrier("cluster-watch");
RunOn(() =>
{
MarkNodeAsUnavailable(GetAddress(_config.Fifth));
AwaitAssert(() => ClusterView.UnreachableMembers.Select(x => x.Address).Contains(GetAddress(_config.Fifth)).ShouldBeTrue());
Cluster.Down(GetAddress(_config.Fifth));
// removed
AwaitAssert(() => Assert.False(ClusterView.UnreachableMembers.Select(x => x.Address).Contains(GetAddress(_config.Fifth))));
AwaitAssert(() => Assert.False(ClusterView.Members.Select(x => x.Address).Contains(GetAddress(_config.Fifth))));
}, _config.Fourth);
EnterBarrier("fifth-terminated");
RunOn(() =>
{
ExpectMsg<Terminated>().ActorRef.Path.Name.ShouldBe("subject5");
}, _config.First);
EnterBarrier("after-3");
});
}