public void DomainEvents_must_be_produced_for_convergence_changes()
        {
            var g1 = new Gossip(ImmutableSortedSet.Create(aUp, bUp, eJoining))
                     .Seen(aUp.UniqueAddress)
                     .Seen(bUp.UniqueAddress)
                     .Seen(eJoining.UniqueAddress);
            var g2 = new Gossip(ImmutableSortedSet.Create(aUp, bUp, eJoining))
                     .Seen(aUp.UniqueAddress)
                     .Seen(bUp.UniqueAddress);

            ClusterEvent.DiffMemberEvents(g1, g2)
            .Should()
            .BeEquivalentTo(ImmutableList.Create <ClusterEvent.IMemberEvent>());
            ClusterEvent.DiffUnreachable(g1, g2, selfDummyAddress)
            .Should()
            .BeEquivalentTo(ImmutableList.Create <ClusterEvent.UnreachableMember>());
            ClusterEvent.DiffSeen(g1, g2, selfDummyAddress)
            .Should()
            .BeEquivalentTo(ImmutableList.Create(new ClusterEvent.SeenChanged(true, ImmutableHashSet.Create(aUp.Address, bUp.Address))));
            ClusterEvent.DiffMemberEvents(g2, g1)
            .Should()
            .BeEquivalentTo(ImmutableList.Create <ClusterEvent.IMemberEvent>());
            ClusterEvent.DiffUnreachable(g1, g1, selfDummyAddress)
            .Should()
            .BeEquivalentTo(ImmutableList.Create <ClusterEvent.UnreachableMember>());
            ClusterEvent.DiffSeen(g2, g1, selfDummyAddress)
            .Should()
            .BeEquivalentTo(ImmutableList.Create(new ClusterEvent.SeenChanged(true, ImmutableHashSet.Create(aUp.Address, bUp.Address, eJoining.Address))));
        }
        public void DomainEventMustBeProducedForMembersInUnreachable()
        {
            var reachability1 = Reachability.Empty.
                                Unreachable(aUp.UniqueAddress, cUp.UniqueAddress).
                                Unreachable(aUp.UniqueAddress, eUp.UniqueAddress);
            var g1            = new Gossip(ImmutableSortedSet.Create(aUp, bUp, cUp, eUp), new GossipOverview(reachability1));
            var reachability2 = reachability1.
                                Unreachable(aUp.UniqueAddress, bDown.UniqueAddress);
            var g2 = new Gossip(ImmutableSortedSet.Create(aUp, cUp, bDown, eDown), new GossipOverview(reachability2));

            Assert.Equal(ImmutableList.Create(new ClusterEvent.UnreachableMember(bDown)), ClusterEvent.DiffUnreachable(g1, g2));
            Assert.Equal(ImmutableList.Create <ClusterEvent.SeenChanged>(), ClusterEvent.DiffSeen(g1, g2, selfDummyAddress));
        }
        public void DomainEvents_must_be_produced_for_changed_status_of_members()
        {
            var t1 = Converge(new Gossip(ImmutableSortedSet.Create(aJoining, bUp, cUp)));
            var t2 = Converge(new Gossip(ImmutableSortedSet.Create(aUp, bUp, cLeaving, eJoining)));

            var g1 = t1.Item1;
            var g2 = t2.Item1;
            var s2 = t2.Item2;

            ClusterEvent.DiffMemberEvents(g1, g2)
            .Should()
            .BeEquivalentTo(ImmutableList.Create <ClusterEvent.IMemberEvent>(new ClusterEvent.MemberUp(aUp), new ClusterEvent.MemberLeft(cLeaving), new ClusterEvent.MemberJoined(eJoining)));

            ClusterEvent.DiffUnreachable(g1, g2, selfDummyAddress)
            .Should()
            .BeEquivalentTo(ImmutableList.Create <ClusterEvent.UnreachableMember>());

            ClusterEvent.DiffSeen(g1, g2, selfDummyAddress)
            .Should()
            .BeEquivalentTo(ImmutableList.Create(new ClusterEvent.SeenChanged(true, s2.Select(s => s.Address).ToImmutableHashSet())));
        }
        public void DomainEvents_must_be_produced_for_removed_members()
        {
            var t1 = Converge(new Gossip(ImmutableSortedSet.Create(aUp, dExiting)));
            var t2 = Converge(new Gossip(ImmutableSortedSet.Create(aUp)));

            var g1 = t1.Item1;
            var g2 = t2.Item1;
            var s2 = t2.Item2;

            ClusterEvent.DiffMemberEvents(g1, g2)
            .Should()
            .BeEquivalentTo(ImmutableList.Create <ClusterEvent.IMemberEvent>(new ClusterEvent.MemberRemoved(dRemoved, MemberStatus.Exiting)));

            ClusterEvent.DiffUnreachable(g1, g2, selfDummyAddress)
            .Should()
            .BeEquivalentTo(ImmutableList.Create <ClusterEvent.UnreachableMember>());

            ClusterEvent.DiffSeen(g1, g2, selfDummyAddress)
            .Should()
            .BeEquivalentTo(ImmutableList.Create(new ClusterEvent.SeenChanged(true, s2.Select(s => s.Address).ToImmutableHashSet())));
        }
        public void DomainEvents_must_be_produced_for_leader_changes()
        {
            var t1 = Converge(new Gossip(ImmutableSortedSet.Create(aUp, bUp, eJoining)));
            var t2 = Converge(new Gossip(ImmutableSortedSet.Create(bUp, eJoining)));

            var g1 = t1.Item1;
            var g2 = t2.Item1;
            var s2 = t2.Item2;

            ClusterEvent.DiffMemberEvents(g1, g2)
            .Should()
            .BeEquivalentTo(ImmutableList.Create(new ClusterEvent.MemberRemoved(aRemoved, MemberStatus.Up)));
            ClusterEvent.DiffUnreachable(g1, g2, selfDummyAddress)
            .Should()
            .BeEquivalentTo(ImmutableList.Create <ClusterEvent.UnreachableMember>());
            ClusterEvent.DiffSeen(g1, g2, selfDummyAddress)
            .Should()
            .BeEquivalentTo(ImmutableList.Create(new ClusterEvent.SeenChanged(true, s2.Select(a => a.Address).ToImmutableHashSet())));
            ClusterEvent.DiffLeader(g1, g2, selfDummyAddress)
            .Should()
            .BeEquivalentTo(ImmutableList.Create(new ClusterEvent.LeaderChanged(bUp.Address)));
        }
        public void DomainEvents_must_be_produced_for_members_in_unreachable()
        {
            var reachability1 = Reachability.Empty.
                                Unreachable(aUp.UniqueAddress, cUp.UniqueAddress).
                                Unreachable(aUp.UniqueAddress, eUp.UniqueAddress);
            var g1            = new Gossip(ImmutableSortedSet.Create(aUp, bUp, cUp, eUp), new GossipOverview(reachability1));
            var reachability2 = reachability1.
                                Unreachable(aUp.UniqueAddress, bDown.UniqueAddress);
            var g2 = new Gossip(ImmutableSortedSet.Create(aUp, cUp, bDown, eDown), new GossipOverview(reachability2));

            ClusterEvent.DiffUnreachable(g1, g2, selfDummyAddress)
            .Should()
            .BeEquivalentTo(ImmutableList.Create(new ClusterEvent.UnreachableMember(bDown)));

            // never include self member in unreachable
            ClusterEvent.DiffUnreachable(g1, g2, bDown.UniqueAddress)
            .Should()
            .BeEquivalentTo(ImmutableList.Create <ClusterEvent.UnreachableMember>());

            ClusterEvent.DiffSeen(g1, g2, selfDummyAddress)
            .Should()
            .BeEquivalentTo(ImmutableList.Create <ClusterEvent.SeenChanged>());
        }
        public void DomainEventMustBeProducedForChangedStatusOfMembers()
        {
            var t1 = Converge(new Gossip(ImmutableSortedSet.Create(aJoining, bUp, cUp)));
            var t2 = Converge(new Gossip(ImmutableSortedSet.Create(aUp, bUp, cLeaving, eJoining)));

            var g1 = t1.Item1;
            var g2 = t2.Item1;
            var s2 = t2.Item2;

            Assert.Equal(ImmutableList.Create(new ClusterEvent.MemberUp(aUp)), ClusterEvent.DiffMemberEvents(g1, g2));
            Assert.Equal(ImmutableList.Create <ClusterEvent.UnreachableMember>(), ClusterEvent.DiffUnreachable(g1, g2));
            Assert.Equal(ImmutableList.Create(new ClusterEvent.SeenChanged(true, s2.Select(s => s.Address).ToImmutableHashSet())), ClusterEvent.DiffSeen(g1, g2, selfDummyAddress));
        }
        public void DomainEventMustBeProducedForLeaderChanges()
        {
            var t1 = Converge(new Gossip(ImmutableSortedSet.Create(aUp, bUp, eJoining)));
            var t2 = Converge(new Gossip(ImmutableSortedSet.Create(bUp, eJoining)));

            var g1 = t1.Item1;
            var g2 = t2.Item1;
            var s2 = t2.Item2;

            Assert.Equal(ImmutableList.Create(new ClusterEvent.MemberRemoved(aRemoved, MemberStatus.Up)), ClusterEvent.DiffMemberEvents(g1, g2));
            Assert.Equal(ImmutableList.Create <ClusterEvent.UnreachableMember>(), ClusterEvent.DiffUnreachable(g1, g2));
            Assert.Equal(ImmutableList.Create(new ClusterEvent.SeenChanged(true, s2.Select(a => a.Address).ToImmutableHashSet())), ClusterEvent.DiffSeen(g1, g2, selfDummyAddress));
            Assert.Equal(ImmutableList.Create(new ClusterEvent.LeaderChanged(bUp.Address)), ClusterEvent.DiffLeader(g1, g2, selfDummyAddress));
        }
        public void DomainEventMustBeProducedForConvergenceChanges()
        {
            var g1 =
                new Gossip(ImmutableSortedSet.Create(aUp, bUp, eJoining)).Seen(aUp.UniqueAddress)
                .Seen(bUp.UniqueAddress)
                .Seen(eJoining.UniqueAddress);
            var g2 = new Gossip(ImmutableSortedSet.Create(aUp, bUp, eJoining)).Seen(aUp.UniqueAddress).Seen(bUp.UniqueAddress);

            Assert.Equal(ImmutableList.Create <ClusterEvent.IMemberEvent>(), ClusterEvent.DiffMemberEvents(g1, g2));
            Assert.Equal(ImmutableList.Create <ClusterEvent.UnreachableMember>(), ClusterEvent.DiffUnreachable(g1, g2));
            Assert.Equal(ImmutableList.Create(new ClusterEvent.SeenChanged(true, ImmutableHashSet.Create(aUp.Address, bUp.Address))), ClusterEvent.DiffSeen(g1, g2, selfDummyAddress));
            Assert.Equal(ImmutableList.Create <ClusterEvent.IMemberEvent>(), ClusterEvent.DiffMemberEvents(g2, g1));
            Assert.Equal(ImmutableList.Create <ClusterEvent.UnreachableMember>(), ClusterEvent.DiffUnreachable(g2, g1));
            Assert.Equal(ImmutableList.Create(new ClusterEvent.SeenChanged(true, ImmutableHashSet.Create(aUp.Address, bUp.Address, eJoining.Address))), ClusterEvent.DiffSeen(g2, g1, selfDummyAddress));
        }