Пример #1
0
        public void PusherShouldUnsubscribeSuccessfullyWhenTheRequestIsMadeViaTheChannel()
        {
            // Arrange
            var            pusher = PusherFactory.GetPusher();
            AutoResetEvent reset  = new AutoResetEvent(false);

            pusher.Connected += sender =>
            {
                reset.Set();
            };

            AsyncContext.Run(() => pusher.ConnectAsync());
            reset.WaitOne(TimeSpan.FromSeconds(5));
            reset.Reset();

            var mockChannelName = ChannelNameFactory.CreateUniqueChannelName();

            var channel = AsyncContext.Run(() => pusher.SubscribeAsync(mockChannelName));

            channel.Subscribed += sender =>
            {
                reset.Set();
            };

            reset.WaitOne(TimeSpan.FromSeconds(5));

            // Act
            channel.Unsubscribe();

            // Assert
            Assert.IsNotNull(channel);
            StringAssert.Contains(mockChannelName, channel.Name);
            Assert.IsFalse(channel.IsSubscribed);
        }
Пример #2
0
        public void PusherShouldNotAttemptASecondChannelSubscriptionToAnExistingChannelWhileTheFirstRequestIsWaitingForAResponse()
        {
            // Arrange
            var pusher         = PusherFactory.GetPusher();
            var connectedEvent = new AutoResetEvent(false);

            pusher.Connected += sender =>
            {
                connectedEvent.Set();
            };


            AsyncContext.Run(() => pusher.ConnectAsync());
            connectedEvent.WaitOne(TimeSpan.FromSeconds(5));
            connectedEvent.Reset();

            var mockChannelName = ChannelNameFactory.CreateUniqueChannelName();

            var subscribedEvent = new AutoResetEvent(false);

            var firstChannel = AsyncContext.Run(() => pusher.SubscribeAsync(mockChannelName));

            firstChannel.Subscribed += sender =>
            {
                subscribedEvent.Set();
            };

            // Act
            var secondChannel = AsyncContext.Run(() => pusher.SubscribeAsync(mockChannelName));

            subscribedEvent.WaitOne(TimeSpan.FromSeconds(5));

            // Assert
            Assert.AreEqual(firstChannel, secondChannel);
        }
Пример #3
0
        public void PusherShouldSubscribeAllPreviouslySubscribedChannelsWhenTheConnectionIsReconnected()
        {
            // Arrange
            var pusher = PusherFactory.GetPusher();

            var connectedEvent = new AutoResetEvent(false);

            pusher.Connected += sender =>
            {
                connectedEvent.Set();
            };

            AsyncContext.Run(() => pusher.ConnectAsync());
            connectedEvent.WaitOne(TimeSpan.FromSeconds(5));

            var subscribedEvent1 = new AutoResetEvent(false);
            var subscribedEvent2 = new AutoResetEvent(false);
            var subscribedEvent3 = new AutoResetEvent(false);

            var mockChannelName1 = ChannelNameFactory.CreateUniqueChannelName(channelNamePostfix: "1");
            var mockChannelName2 = ChannelNameFactory.CreateUniqueChannelName(channelNamePostfix: "2");
            var mockChannelName3 = ChannelNameFactory.CreateUniqueChannelName(channelNamePostfix: "3");

            var channel1 = SubscribeToChannel(pusher, mockChannelName1, subscribedEvent1);
            var channel2 = SubscribeToChannel(pusher, mockChannelName2, subscribedEvent2);
            var channel3 = SubscribeToChannel(pusher, mockChannelName3, subscribedEvent3);

            subscribedEvent1.WaitOne(TimeSpan.FromSeconds(5));
            subscribedEvent2.WaitOne(TimeSpan.FromSeconds(5));
            subscribedEvent3.WaitOne(TimeSpan.FromSeconds(5));

            AsyncContext.Run(() => pusher.DisconnectAsync());

            subscribedEvent1.Reset();
            subscribedEvent2.Reset();
            subscribedEvent3.Reset();

            // Act
            AsyncContext.Run(() => pusher.ConnectAsync());

            subscribedEvent1.WaitOne(TimeSpan.FromSeconds(5));
            subscribedEvent2.WaitOne(TimeSpan.FromSeconds(5));
            subscribedEvent3.WaitOne(TimeSpan.FromSeconds(5));

            // Assert
            Assert.IsNotNull(channel1);
            StringAssert.Contains(mockChannelName1, channel1.Name);
            Assert.IsTrue(channel1.IsSubscribed);

            Assert.IsNotNull(channel2);
            StringAssert.Contains(mockChannelName2, channel2.Name);
            Assert.IsTrue(channel2.IsSubscribed);

            Assert.IsNotNull(channel3);
            StringAssert.Contains(mockChannelName3, channel3.Name);
            Assert.IsTrue(channel3.IsSubscribed);
        }
Пример #4
0
        private static List <string> CreateChannelNames(int numberOfChannels = 3)
        {
            List <string> result = new List <string>(numberOfChannels);

            for (int i = 0; i < numberOfChannels; i++)
            {
                result.Add(ChannelNameFactory.CreateUniqueChannelName(channelType: (ChannelTypes)(i % 3)));
            }

            return(result);
        }
Пример #5
0
        private async Task SubscribeWithoutConnectingTestAsync(ChannelTypes channelType)
        {
            // Arrange
            Pusher pusher          = PusherFactory.GetPusher(channelType: channelType, saveTo: _clients);
            string mockChannelName = ChannelNameFactory.CreateUniqueChannelName(channelType: channelType);

            // Act
            Channel subscribedChannel = await pusher.SubscribeAsync(mockChannelName).ConfigureAwait(false);

            // Assert
            ValidateDisconnectedChannel(pusher, mockChannelName, subscribedChannel, channelType);
        }
        public async Task UnsubscribeAsync()
        {
            // Arrange
            ChannelTypes channelType = ChannelTypes.Presence;
            string       channelName = ChannelNameFactory.CreateUniqueChannelName(channelType: channelType);
            Pusher       pusher      = PusherFactory.GetPusher(channelType: channelType, saveTo: _clients);
            Channel      channel     = await SubscribeAsync(connectBeforeSubscribing : true, pusher : pusher, channelName : channelName).ConfigureAwait(false);

            // Act
            await pusher.UnsubscribeAsync(channelName).ConfigureAwait(false);

            // Assert
            SubscriptionTest.ValidateUnsubscribedChannel(pusher, channel);
        }
        public async Task PusherShouldErrorWhenSubscribeTimesOutAsync()
        {
            // Arrange
            AutoResetEvent  errorEvent      = new AutoResetEvent(false);
            PusherException exception       = null;
            PusherException caughtException = null;

            ChannelTypes channelType = ChannelTypes.Presence;
            string       channelName = ChannelNameFactory.CreateUniqueChannelName(channelType: channelType);
            var          pusher      = PusherFactory.GetPusher(channelType: channelType, saveTo: _clients);
            await pusher.ConnectAsync().ConfigureAwait(false);

            ((IPusher)pusher).PusherOptions.ClientTimeout = TimeSpan.FromMilliseconds(20);

            pusher.Error += (sender, error) =>
            {
                exception = error;
                errorEvent.Set();
            };

            // Act

            // Try to generate the error multiple times as it does not always error the first time
            for (int attempt = 0; attempt < TimeoutRetryAttempts; attempt++)
            {
                try
                {
                    await pusher.SubscribePresenceAsync <FakeUserInfo>(channelName).ConfigureAwait(false);
                }
                catch (Exception error)
                {
                    caughtException = error as PusherException;
                }

                if (caughtException != null)
                {
                    break;
                }
            }

            // Assert
            // This test does not always work on the build server, requires more than 2 CPU(s) for better reliability
            if (caughtException != null)
            {
                Assert.IsTrue(errorEvent.WaitOne(TimeSpan.FromSeconds(5)));
                Assert.IsNotNull(exception, $"Error expected to be {nameof(PusherException)}");
                Assert.AreEqual(exception.Message, caughtException.Message);
                Assert.AreEqual(ErrorCodes.ClientTimeout, exception.PusherCode, "Unexpected error: " + exception.Message);
            }
        }
        private async Task SubscribeSameChannelTwiceAsync(bool connectBeforeSubscribing)
        {
            // Arrange
            var            pusher            = PusherFactory.GetPusher(ChannelTypes.Presence, saveTo: _clients);
            AutoResetEvent subscribedEvent   = new AutoResetEvent(false);
            var            mockChannelName   = ChannelNameFactory.CreateUniqueChannelName(ChannelTypes.Presence);
            var            numberOfCalls     = 0;
            var            channelSubscribed = false;

            pusher.Subscribed += (sender, channel) =>
            {
                if (channel.Name == mockChannelName)
                {
                    numberOfCalls++;
                    channelSubscribed = true;
                    subscribedEvent.Set();
                }
            };

            Channel firstChannel;
            Channel secondChannel;

            // Act
            if (connectBeforeSubscribing)
            {
                await pusher.ConnectAsync().ConfigureAwait(false);

                firstChannel = await pusher.SubscribePresenceAsync <FakeUserInfo>(mockChannelName).ConfigureAwait(false);

                secondChannel = await pusher.SubscribePresenceAsync <FakeUserInfo>(mockChannelName).ConfigureAwait(false);
            }
            else
            {
                firstChannel = await pusher.SubscribePresenceAsync <FakeUserInfo>(mockChannelName).ConfigureAwait(false);

                secondChannel = await pusher.SubscribePresenceAsync <FakeUserInfo>(mockChannelName).ConfigureAwait(false);

                await pusher.ConnectAsync().ConfigureAwait(false);
            }

            subscribedEvent.WaitOne(TimeSpan.FromSeconds(5));

            // Assert
            Assert.IsTrue(channelSubscribed);
            Assert.AreEqual(1, numberOfCalls);
            Assert.AreEqual(firstChannel, secondChannel);
            Assert.AreEqual(firstChannel.IsSubscribed, secondChannel.IsSubscribed);
            Assert.AreEqual(firstChannel.Name, secondChannel.Name);
            Assert.AreEqual(firstChannel.ChannelType, secondChannel.ChannelType);
        }
Пример #9
0
        public async Task PublicChannelConnectThenSubscribeWithoutAnyEventHandlersAsync()
        {
            // Arrange
            var pusher          = PusherFactory.GetPusher(saveTo: _clients);
            var mockChannelName = ChannelNameFactory.CreateUniqueChannelName();

            // Act
            await pusher.ConnectAsync().ConfigureAwait(false);

            var channel = await pusher.SubscribeAsync(mockChannelName).ConfigureAwait(false);

            // Assert
            ValidateSubscribedChannel(pusher, mockChannelName, channel, ChannelTypes.Public);
        }
Пример #10
0
        public async Task PublicChannelUnsubscribeUsingChannelUnsubscribeAsync()
        {
            // Arrange
            var pusher          = PusherFactory.GetPusher(saveTo: _clients);
            var mockChannelName = ChannelNameFactory.CreateUniqueChannelName();

            // Act
            await pusher.ConnectAsync().ConfigureAwait(false);

            var channel = await pusher.SubscribeAsync(mockChannelName).ConfigureAwait(false);

            channel.Unsubscribe();

            // Assert
            ValidateUnsubscribedChannel(pusher, channel);
        }
Пример #11
0
        public async Task PublicChannelUnsubscribeUsingChannelUnsubscribeDeadlockBugAsync()
        {
            // Arrange
            var pusher          = PusherFactory.GetPusher(saveTo: _clients);
            var mockChannelName = ChannelNameFactory.CreateUniqueChannelName();

            // Act
            await pusher.ConnectAsync().ConfigureAwait(false);

            var channel = await pusher.SubscribeAsync(mockChannelName).ConfigureAwait(false);

            // Assert
            ValidateSubscribedChannel(pusher, mockChannelName, channel, ChannelTypes.Public);

            await DeadlockBugShutdown(channel, pusher);
        }
Пример #12
0
        private async Task SubscribeSameChannelMultipleTimesTestAsync(bool connectBeforeSubscribing, ChannelTypes channelType)
        {
            // Arrange
            var pusher            = PusherFactory.GetPusher(channelType, saveTo: _clients);
            var subscribedEvent   = new AutoResetEvent(false);
            var mockChannelName   = ChannelNameFactory.CreateUniqueChannelName(channelType);
            var numberOfCalls     = 0;
            var channelSubscribed = false;

            pusher.Subscribed += (sender, channel) =>
            {
                if (channel.Name == mockChannelName)
                {
                    numberOfCalls++;
                    channelSubscribed = true;
                    subscribedEvent.Set();
                }
            };

            // Act
            if (connectBeforeSubscribing)
            {
                await pusher.ConnectAsync().ConfigureAwait(false);

                for (int i = 0; i < 4; i++)
                {
                    await pusher.SubscribeAsync(mockChannelName).ConfigureAwait(false);
                }
                ;
            }
            else
            {
                for (int i = 0; i < 4; i++)
                {
                    await pusher.SubscribeAsync(mockChannelName).ConfigureAwait(false);
                }
                ;

                await pusher.ConnectAsync().ConfigureAwait(false);
            }

            subscribedEvent.WaitOne(TimeSpan.FromSeconds(5));

            // Assert
            Assert.IsTrue(channelSubscribed);
            Assert.AreEqual(1, numberOfCalls);
        }
        private static PusherEvent CreatePusherEvent(ChannelTypes channelType, string eventName)
        {
            EventTestData data = new EventTestData
            {
                TextField    = ExpectedTextField,
                IntegerField = ExpectedIntegerField,
            };
            Dictionary <string, object> properties = new Dictionary <string, object>
            {
                { "channel", ChannelNameFactory.CreateUniqueChannelName(channelType: channelType) },
                { "event", eventName },
                { "data", data },
            };

            PusherEvent result = new PusherEvent(properties, JsonConvert.SerializeObject(properties));

            return(result);
        }
        private async Task DynamicEventEmitterTestAsync(ChannelTypes channelType)
        {
            // Arrange
            Pusher         localPusher          = PusherFactory.GetPusher(channelType: ChannelTypes.Presence, saveTo: _clients);
            string         testEventName        = "client-dynamic-event-test";
            AutoResetEvent globalEventReceived  = new AutoResetEvent(false);
            AutoResetEvent channelEventReceived = new AutoResetEvent(false);
            dynamic        globalEvent          = null;
            dynamic        channelEvent         = null;
            dynamic        dynamicEventData     = CreateDynamicEventData();
            string         channelName          = ChannelNameFactory.CreateUniqueChannelName(channelType: channelType);

            await localPusher.ConnectAsync().ConfigureAwait(false);

            Channel remoteChannel = await _remoteClient.SubscribeAsync(channelName).ConfigureAwait(false);

            Channel localChannel = await localPusher.SubscribeAsync(channelName).ConfigureAwait(false);

            void GeneralListener(string eventName, dynamic eventData)
            {
                if (eventName == testEventName)
                {
                    globalEvent = eventData;
                    globalEventReceived.Set();
                }
            }

            void Listener(dynamic eventData)
            {
                channelEvent = eventData;
                channelEventReceived.Set();
            }

            // Act
            localPusher.BindAll(GeneralListener);
            localChannel.Bind(testEventName, Listener);
            remoteChannel.Trigger(testEventName, dynamicEventData);

            // Assert
            Assert.IsTrue(globalEventReceived.WaitOne(TimeSpan.FromSeconds(5)));
            Assert.IsTrue(channelEventReceived.WaitOne(TimeSpan.FromSeconds(5)));
            ValidateDynamicEvent(channelName, testEventName, globalEvent);
            ValidateDynamicEvent(channelName, testEventName, channelEvent);
        }
        public void PresenceChannelShouldAddATypedMemberWhenGivenAMemberAsync()
        {
            // Arrange
            var stubOptions = new PusherOptions
            {
                Authorizer = new FakeAuthoriser(UserNameFactory.CreateUniqueUserName())
            };

            var            pusher = PusherFactory.GetPusher(stubOptions);
            AutoResetEvent reset  = new AutoResetEvent(false);

            pusher.Connected += sender =>
            {
                reset.Set();
            };

            AsyncContext.Run(() => pusher.ConnectAsync());
            reset.WaitOne(TimeSpan.FromSeconds(5));
            reset.Reset();

            var mockChannelName = ChannelNameFactory.CreateUniqueChannelName(presenceChannel: true);

            var channelSubscribed = false;

            // Act
            var channel = AsyncContext.Run(() => pusher.SubscribePresenceAsync <FakeUserInfo>(mockChannelName));

            channel.Subscribed += sender =>
            {
                channelSubscribed = true;
                reset.Set();
            };

            reset.WaitOne(TimeSpan.FromSeconds(10));

            // Assert
            Assert.IsNotNull(channel);
            StringAssert.Contains(mockChannelName, channel.Name);
            Assert.IsTrue(channel.IsSubscribed);
            Assert.IsTrue(channelSubscribed);

            CollectionAssert.IsNotEmpty(channel.Members);
        }
        public void PusherShouldSubscribeToAChannelWhenGivenAPopulatedPrivateChannelName()
        {
            // Arrange
            var stubOptions = new PusherOptions
            {
                Authorizer = new FakeAuthoriser(UserNameFactory.CreateUniqueUserName())
            };

            var            pusher = PusherFactory.GetPusher(stubOptions);
            AutoResetEvent reset  = new AutoResetEvent(false);

            pusher.Connected += sender =>
            {
                reset.Set();
            };

            pusher.Connect();
            reset.WaitOne(TimeSpan.FromSeconds(5));
            reset.Reset();

            var mockChannelName = ChannelNameFactory.CreateUniqueChannelName(privateChannel: true);

            var channelSubscribed = false;

            // Act
            var channel = AsyncContext.Run(() => pusher.Subscribe(mockChannelName));

            channel.Subscribed += sender =>
            {
                channelSubscribed = true;
                reset.Set();
            };

            reset.WaitOne(TimeSpan.FromSeconds(5));

            // Assert
            Assert.IsNotNull(channel);
            StringAssert.Contains(mockChannelName, channel.Name);
            Assert.IsTrue(channel.IsSubscribed);
            Assert.IsTrue(channelSubscribed);
        }
        public async Task ConcurrentSubscribesShouldBeIdempotentAsync()
        {
            // Arrange
            Channel        presenceChannel = null;
            AutoResetEvent subscribedEvent = new AutoResetEvent(false);
            int            subscribedCount = 0;
            ChannelTypes   channelType     = ChannelTypes.Presence;
            string         channelName     = ChannelNameFactory.CreateUniqueChannelName(channelType: channelType);
            Pusher         pusher          = PusherFactory.GetPusher(channelType: channelType, saveTo: _clients);
            await pusher.ConnectAsync().ConfigureAwait(false);

            pusher.Subscribed += (sender, channel) =>
            {
                if (channel.Name == channelName)
                {
                    subscribedCount++;
                    presenceChannel = channel;
                    subscribedEvent.Set();
                }
            };

            // Act
            List <Task> tasks = new List <Task>();

            for (int i = 0; i < 4; i++)
            {
                tasks.Add(Task.Run(() =>
                {
                    return(pusher.SubscribePresenceAsync <FakeUserInfo>(channelName).ConfigureAwait(false));
                }));
            }

            Task.WaitAll(tasks.ToArray());

            // Assert
            Assert.IsTrue(subscribedEvent.WaitOne(TimeSpan.FromSeconds(5)), nameof(subscribedEvent));
            Assert.AreEqual(1, subscribedCount, nameof(subscribedCount));
            ValidateSubscribedChannel(pusher, channelName, presenceChannel);
        }
Пример #18
0
        public void PusherShouldNotCreateAnotherSubscriptionToAChannelIfTheChannelHasAlreadyBeenSubscribedTo()
        {
            // Arrange
            var            pusher = PusherFactory.GetPusher();
            AutoResetEvent reset  = new AutoResetEvent(false);

            pusher.Connected += sender =>
            {
                reset.Set();
            };

            AsyncContext.Run(() => pusher.ConnectAsync());
            reset.WaitOne(TimeSpan.FromSeconds(5));
            reset.Reset();

            var mockChannelName = ChannelNameFactory.CreateUniqueChannelName();

            var channelSubscribed = false;
            var numberOfCalls     = 0;

            var firstChannel = AsyncContext.Run(() => pusher.SubscribeAsync(mockChannelName));

            firstChannel.Subscribed += sender =>
            {
                channelSubscribed = true;
                numberOfCalls++;
                reset.Set();
            };

            reset.WaitOne(TimeSpan.FromSeconds(5));

            // Act
            var secondChannel = AsyncContext.Run(() => pusher.SubscribeAsync(mockChannelName));

            // Assert
            Assert.AreEqual(firstChannel, secondChannel);
            Assert.IsTrue(channelSubscribed);
            Assert.AreEqual(1, numberOfCalls);
        }
        public async Task ConcurrentUnsubscribesShouldBeIdempotentAsync()
        {
            // Arrange
            ChannelTypes channelType = ChannelTypes.Presence;
            string       channelName = ChannelNameFactory.CreateUniqueChannelName(channelType: channelType);
            Pusher       pusher      = PusherFactory.GetPusher(channelType: channelType, saveTo: _clients);
            Channel      channel     = await SubscribeAsync(connectBeforeSubscribing : true, pusher : pusher, channelName : channelName).ConfigureAwait(false);

            // Act
            List <Task> tasks = new List <Task>();

            for (int i = 0; i < 4; i++)
            {
                tasks.Add(Task.Run(() =>
                {
                    return(pusher.UnsubscribeAsync(channelName));
                }));
            }

            Task.WaitAll(tasks.ToArray());

            // Assert
            SubscriptionTest.ValidateUnsubscribedChannel(pusher, channel);
        }
        private async Task RemoveMemberAsync(bool connectBeforeSubscribing, int numberOfMembers = 2, bool raiseMemberRemovedError = false)
        {
            // Arrange
            int            numMemberRemovedEvents              = 0;
            int            expectedNumMemberRemovedEvents      = numberOfMembers - 1;
            int            expectedNumMemberRemovedErrorEvents = raiseMemberRemovedError ? expectedNumMemberRemovedEvents : 0;
            int            numMemberRemovedErrors              = 0;
            string         channelName             = ChannelNameFactory.CreateUniqueChannelName(channelType: ChannelTypes.Presence);
            AutoResetEvent memberRemovedEvent      = new AutoResetEvent(false);
            AutoResetEvent memberRemovedErrorEvent = raiseMemberRemovedError ? new AutoResetEvent(false) : null;

            void RemoveMemberErrorHandler(object sender, PusherException error)
            {
                System.Diagnostics.Trace.TraceError($"Pusher.Error handled:{Environment.NewLine}{error}");
                numMemberRemovedErrors++;
                ValidateMemberRemovedEventHandlerException(error, expectedNumMemberRemovedErrorEvents, numMemberRemovedErrors, memberRemovedErrorEvent);
            }

            void MemberRemovedEventHandler(object sender, KeyValuePair <string, FakeUserInfo> member)
            {
                string memberName  = "Unknown";
                bool   memberValid = ValidateMember(member);

                if (memberValid)
                {
                    memberName = member.Value.name;
                }

                if (memberValid)
                {
                    numMemberRemovedEvents++;
                }

                try
                {
                    if (raiseMemberRemovedError)
                    {
                        throw new InvalidOperationException($"Simulated error for member '{memberName}' when calling GenericPresenceChannel.MemberRemoved.");
                    }
                }
                finally
                {
                    if (numMemberRemovedEvents == expectedNumMemberRemovedEvents)
                    {
                        memberRemovedEvent.Set();
                    }
                }
            }

            // Act
            IList <Pusher> pusherMembers = await SubscribeMultipleMembersAsync(connectBeforeSubscribing : connectBeforeSubscribing, numberOfMembers, channelName).ConfigureAwait(false);

            for (int i = 0; i < pusherMembers.Count; i++)
            {
                pusherMembers[i].Error += RemoveMemberErrorHandler;
                var presenceChannel = await pusherMembers[i].SubscribePresenceAsync <FakeUserInfo>(channelName).ConfigureAwait(false);
                presenceChannel.MemberRemoved += MemberRemovedEventHandler;
            }

            await pusherMembers[0].DisconnectAsync().ConfigureAwait(false);

            // Assert
            Assert.IsTrue(memberRemovedEvent.WaitOne(TimeSpan.FromSeconds(7)), $"# Member removed events = {numMemberRemovedEvents}, expected {expectedNumMemberRemovedEvents}");
            if (raiseMemberRemovedError)
            {
                Assert.IsTrue(memberRemovedErrorEvent.WaitOne(TimeSpan.FromSeconds(5)));
            }

            Assert.AreEqual(expectedNumMemberRemovedErrorEvents, numMemberRemovedErrors, "# MemberRemoved errors");
        }
        public async Task ConnectThenSubscribeChannelMultipleMembersWithMemberAddedErrorAsync()
        {
            string channelName = ChannelNameFactory.CreateUniqueChannelName(channelType: ChannelTypes.Presence);

            await ConnectThenSubscribeMultipleMembersAsync(3, channelName, raiseMemberAddedError : true).ConfigureAwait(false);
        }
        public async Task ConnectThenSubscribeChannelMultipleMembersAsync()
        {
            string channelName = ChannelNameFactory.CreateUniqueChannelName(channelType: ChannelTypes.Presence);

            await ConnectThenSubscribeMultipleMembersAsync(4, channelName).ConfigureAwait(false);
        }
        private async Task <Channel> SubscribeAsync(bool connectBeforeSubscribing, Pusher pusher = null, string channelName = null, bool raiseError = false)
        {
            // Arrange
            const int      PusherSubcribedIndex  = 0;
            const int      ChannelSubcribedIndex = 1;
            ChannelTypes   channelType           = ChannelTypes.Presence;
            AutoResetEvent subscribedEvent       = new AutoResetEvent(false);

            AutoResetEvent[] errorEvent      = { null, null };
            string           mockChannelName = channelName;

            if (mockChannelName == null)
            {
                mockChannelName = ChannelNameFactory.CreateUniqueChannelName(channelType: channelType);
            }

            if (pusher == null)
            {
                pusher = PusherFactory.GetPusher(channelType: channelType, saveTo: _clients);
            }

            bool[] subscribed = { false, false };
            pusher.Subscribed += (sender, channel) =>
            {
                if (channel.Name == mockChannelName)
                {
                    subscribed[PusherSubcribedIndex] = true;
                    subscribedEvent.Set();
                    if (raiseError)
                    {
                        throw new InvalidOperationException($"Simulated error for {nameof(Pusher)}.{nameof(Pusher.Subscribed)} {channel.Name}.");
                    }
                }
            };

            SubscribedEventHandlerException[] errors = { null, null };
            if (raiseError)
            {
                errorEvent[PusherSubcribedIndex]  = new AutoResetEvent(false);
                errorEvent[ChannelSubcribedIndex] = new AutoResetEvent(false);
                pusher.Error += (sender, error) =>
                {
                    if (error.ToString().Contains($"{nameof(Pusher)}.{nameof(Pusher.Subscribed)}"))
                    {
                        errors[PusherSubcribedIndex] = error as SubscribedEventHandlerException;
                        errorEvent[PusherSubcribedIndex].Set();
                    }
                    else if (error.ToString().Contains($"{nameof(Channel)}.{nameof(Pusher.Subscribed)}"))
                    {
                        errors[ChannelSubcribedIndex] = error as SubscribedEventHandlerException;
                        errorEvent[ChannelSubcribedIndex].Set();
                    }
                };
            }

            void SubscribedEventHandler(object sender)
            {
                subscribed[ChannelSubcribedIndex] = true;
                if (raiseError)
                {
                    throw new InvalidOperationException($"Simulated error for {nameof(Channel)}.{nameof(Pusher.Subscribed)} {mockChannelName}.");
                }
            }

            GenericPresenceChannel <FakeUserInfo> presenceChannel;

            // Act
            if (connectBeforeSubscribing)
            {
                await pusher.ConnectAsync().ConfigureAwait(false);

                presenceChannel = await pusher.SubscribePresenceAsync <FakeUserInfo>(mockChannelName, SubscribedEventHandler).ConfigureAwait(false);
            }
            else
            {
                presenceChannel = await pusher.SubscribePresenceAsync <FakeUserInfo>(mockChannelName, SubscribedEventHandler).ConfigureAwait(false);

                await pusher.ConnectAsync().ConfigureAwait(false);
            }

            subscribedEvent.WaitOne(TimeSpan.FromSeconds(5));
            errorEvent[PusherSubcribedIndex]?.WaitOne(TimeSpan.FromSeconds(5));
            errorEvent[ChannelSubcribedIndex]?.WaitOne(TimeSpan.FromSeconds(5));

            // Assert
            ValidateSubscribedChannel(pusher, mockChannelName, presenceChannel);
            Assert.IsTrue(subscribed[PusherSubcribedIndex]);
            Assert.IsTrue(subscribed[ChannelSubcribedIndex]);
            if (raiseError)
            {
                ValidateSubscribedExceptions(mockChannelName, errors);
            }

            return(presenceChannel);
        }
Пример #24
0
        private async Task SubscribeTestAsync(bool connectBeforeSubscribing, ChannelTypes channelType, Pusher pusher = null, bool raiseSubscribedError = false)
        {
            // Arrange
            AutoResetEvent subscribedEvent = new AutoResetEvent(false);

            AutoResetEvent[] errorEvent      = { null, null };
            string           mockChannelName = ChannelNameFactory.CreateUniqueChannelName(channelType: channelType);

            if (pusher == null)
            {
                pusher = PusherFactory.GetPusher(channelType: channelType, saveTo: _clients);
            }

            bool[] channelSubscribed = { false, false };

            void PusherSubscribedEventHandler(object sender, Channel channel)
            {
                if (channel.Name == mockChannelName)
                {
                    channelSubscribed[0] = true;
                    subscribedEvent.Set();
                    if (raiseSubscribedError)
                    {
                        throw new InvalidOperationException($"Simulated error for {nameof(Pusher)}.{nameof(Pusher.Subscribed)} {channel.Name}.");
                    }
                }
            }

            pusher.Subscribed += PusherSubscribedEventHandler;

            SubscribedEventHandlerException[] errors = { null, null };
            if (raiseSubscribedError)
            {
                errorEvent[0] = new AutoResetEvent(false);
                errorEvent[1] = new AutoResetEvent(false);

                void ErrorHandler(object sender, PusherException error)
                {
                    if (error.ToString().Contains($"{nameof(Pusher)}.{nameof(Pusher.Subscribed)}"))
                    {
                        errors[0] = error as SubscribedEventHandlerException;
                        errorEvent[0].Set();
                    }
                    else if (error.ToString().Contains($"{nameof(Channel)}.{nameof(Pusher.Subscribed)}"))
                    {
                        errors[1] = error as SubscribedEventHandlerException;
                        errorEvent[1].Set();
                    }
                }

                pusher.Error += ErrorHandler;
            }

            void ChannelSubscribedEventHandler(object sender)
            {
                channelSubscribed[1] = true;
                if (raiseSubscribedError)
                {
                    throw new InvalidOperationException($"Simulated error for {nameof(Channel)}.{nameof(Pusher.Subscribed)} {mockChannelName}.");
                }
            }

            // Act
            Channel subscribedChannel;

            if (connectBeforeSubscribing)
            {
                await pusher.ConnectAsync().ConfigureAwait(false);

                subscribedChannel = await pusher.SubscribeAsync(mockChannelName, ChannelSubscribedEventHandler).ConfigureAwait(false);
            }
            else
            {
                subscribedChannel = await pusher.SubscribeAsync(mockChannelName, ChannelSubscribedEventHandler).ConfigureAwait(false);

                await pusher.ConnectAsync().ConfigureAwait(false);
            }

            subscribedEvent.WaitOne(TimeSpan.FromSeconds(5));
            errorEvent[0]?.WaitOne(TimeSpan.FromSeconds(5));
            errorEvent[1]?.WaitOne(TimeSpan.FromSeconds(5));

            // Assert
            ValidateSubscribedChannel(pusher, mockChannelName, subscribedChannel, channelType);
            Assert.IsTrue(channelSubscribed[0]);
            Assert.IsTrue(channelSubscribed[1]);
            if (raiseSubscribedError)
            {
                ValidateSubscribedExceptions(mockChannelName, errors);
            }
        }
Пример #25
0
        private async Task SubscribeFailureChannelsAsync(bool connectBeforeSubscribing)
        {
            // Arrange
            var            pusher          = PusherFactory.GetPusher(new FakeAuthoriser("SabotagedUser"), saveTo: _clients);
            AutoResetEvent subscribedEvent = new AutoResetEvent(false);
            var            errorEvent      = new AutoResetEvent(false);
            int            errorCount      = 0;
            List <string>  channelNames    = new List <string>
            {
                ChannelNameFactory.CreateUniqueChannelName(channelType: ChannelTypes.Private) + FakeAuthoriser.TamperToken,
                ChannelNameFactory.CreateUniqueChannelName(channelType: ChannelTypes.Presence) + FakeAuthoriser.TamperToken,
                ChannelNameFactory.CreateUniqueChannelName(channelType: ChannelTypes.Public),
            };

            int expectedExceptionCount = 0;
            int exceptionCount         = 0;
            int expectedErrorCount     = 0;

            foreach (string name in channelNames)
            {
                if (Channel.GetChannelType(name) != ChannelTypes.Public)
                {
                    expectedErrorCount++;
                    if (connectBeforeSubscribing)
                    {
                        expectedExceptionCount++;
                    }
                }
            }

            pusher.Error += (sender, error) =>
            {
                if (!error.EmittedToErrorHandler && error is ChannelException)
                {
                    errorCount++;
                    if (errorCount == expectedErrorCount)
                    {
                        errorEvent.Set();
                    }
                }
            };

            pusher.Subscribed += (sender, channel) =>
            {
                if (channel.ChannelType == ChannelTypes.Public)
                {
                    subscribedEvent.Set();
                }
            };

            // Act
            if (connectBeforeSubscribing)
            {
                await pusher.ConnectAsync().ConfigureAwait(false);

                foreach (string channelName in channelNames)
                {
                    try
                    {
                        await pusher.SubscribeAsync(channelName).ConfigureAwait(false);
                    }
                    catch (ChannelException e)
                    {
                        exceptionCount++;
                        Assert.IsNotNull(e.ChannelName);
                        Assert.IsNotNull(e.SocketID);
                        Channel channel = e.Channel;
                        Assert.IsNotNull(channel);
                        Assert.IsFalse(channel.IsSubscribed);
                    }
                }
            }
            else
            {
                foreach (string channelName in channelNames)
                {
                    await pusher.SubscribeAsync(channelName).ConfigureAwait(false);
                }

                await pusher.ConnectAsync().ConfigureAwait(false);
            }

            subscribedEvent.WaitOne(TimeSpan.FromSeconds(5));
            errorEvent.WaitOne(TimeSpan.FromSeconds(5));

            // Assert
            Assert.AreEqual(expectedExceptionCount, exceptionCount, "Number of exceptions expected");
            Assert.AreEqual(expectedErrorCount, errorCount, "# Errors expected");
            AssertUnauthorized(pusher, channelNames);
        }
        private async Task PusherMultipleEventEmitterTestAsync(ChannelTypes channelType)
        {
            // Arrange
            byte[] encryptionKey = GenerateEncryptionMasterKey();
            string channelName   = ChannelNameFactory.CreateUniqueChannelName(channelType: channelType);
            var    pusherServer  = new PusherServer.Pusher(Config.AppId, Config.AppKey, Config.AppSecret, new PusherServer.PusherOptions
            {
                Cluster             = Config.Cluster,
                EncryptionMasterKey = encryptionKey,
            });

            Pusher localPusher = PusherFactory.GetPusher(channelType: ChannelTypes.Presence, saveTo: _clients, encryptionKey: encryptionKey);

            string[] eventNames = new string[] { "my-event-1", "my-event-2", "my-event-3" };
            Dictionary <string, AutoResetEvent> channelEventReceived      = new Dictionary <string, AutoResetEvent>(eventNames.Length);
            Dictionary <string, EventTestData>  channelEvent              = new Dictionary <string, EventTestData>(eventNames.Length);
            Dictionary <string, int>            channelEventReceivedCount = new Dictionary <string, int>(eventNames.Length);
            List <EventTestData> data = new List <EventTestData>(eventNames.Length);

            int count = 1;

            foreach (string eventName in eventNames)
            {
                channelEventReceived[eventName]      = new AutoResetEvent(false);
                channelEvent[eventName]              = null;
                channelEventReceivedCount[eventName] = 0;
                data.Add(new EventTestData {
                    TextField = $"{count}", IntegerField = count++,
                });
            }

            await localPusher.ConnectAsync().ConfigureAwait(false);

            Channel localChannel = await localPusher.SubscribeAsync(channelName).ConfigureAwait(false);

            void Listener1(PusherEvent eventData)
            {
                string key = eventNames[0];

                channelEventReceivedCount[key]++;
                if (eventData.EventName == key && eventData.ChannelName == channelName)
                {
                    channelEvent[key] = JsonConvert.DeserializeObject <EventTestData>(eventData.Data);
                    channelEventReceived[key].Set();
                }
            }

            void Listener2(PusherEvent eventData)
            {
                string key = eventNames[1];

                channelEventReceivedCount[key]++;
                if (eventData.EventName == key && eventData.ChannelName == channelName)
                {
                    channelEvent[key] = JsonConvert.DeserializeObject <EventTestData>(eventData.Data);
                    channelEventReceived[key].Set();
                }
            }

            void Listener3(PusherEvent eventData)
            {
                string key = eventNames[2];

                channelEventReceivedCount[key]++;
                if (eventData.EventName == key && eventData.ChannelName == channelName)
                {
                    channelEvent[key] = JsonConvert.DeserializeObject <EventTestData>(eventData.Data);
                    channelEventReceived[key].Set();
                }
            }

            // Act
            localChannel.Bind(eventNames[0], Listener1);
            localChannel.Bind(eventNames[1], Listener2);
            localChannel.Bind(eventNames[2], Listener3);
            for (int i = 0; i < eventNames.Length; i++)
            {
                await pusherServer.TriggerAsync(localChannel.Name, eventNames[i], data[i]).ConfigureAwait(false);
            }

            // Assert
            foreach (var eventReceived in channelEventReceived)
            {
                Assert.IsTrue(eventReceived.Value.WaitOne(TimeSpan.FromSeconds(5)), $"Event not received for {eventReceived.Key}");
            }

            foreach (var eventReceivedCount in channelEventReceivedCount)
            {
                Assert.AreEqual(1, eventReceivedCount.Value, $"#Events received for {eventReceivedCount.Key}");
            }

            for (int i = 0; i < eventNames.Length; i++)
            {
                string key = eventNames[i];
                Assert.AreEqual(data[i].IntegerField, channelEvent[key].IntegerField, $"{key} IntegerField");
                Assert.AreEqual(data[i].TextField, channelEvent[key].TextField, $"{key} TextField");
            }
        }
        private async Task DynamicEventEmitterUnbindTestAsync(ChannelTypes channelType, IList <int> listenersToUnbind)
        {
            // Arrange
            Pusher  localPusher      = PusherFactory.GetPusher(channelType: ChannelTypes.Presence, saveTo: _clients);
            string  testEventName    = "client-dynamic-event-test";
            dynamic dynamicEventData = CreateDynamicEventData();
            string  channelName      = ChannelNameFactory.CreateUniqueChannelName(channelType: channelType);

            string[]         testEventNames       = new string[] { testEventName, testEventName, testEventName, testEventName, };
            AutoResetEvent[] receivedEvents       = new AutoResetEvent[testEventNames.Length];
            int[]            numberEventsReceived = new int[testEventNames.Length];
            int[]            totalEventsExpected  = new int[testEventNames.Length];
            bool[]           eventExpected        = new bool[testEventNames.Length];
            for (int i = 0; i < testEventNames.Length; i++)
            {
                receivedEvents[i]       = new AutoResetEvent(false);
                numberEventsReceived[i] = 0;
                eventExpected[i]        = true;
                if (listenersToUnbind.Contains(i))
                {
                    totalEventsExpected[i] = 1;
                }
                else
                {
                    totalEventsExpected[i] = 2;
                }
            }

            await localPusher.ConnectAsync().ConfigureAwait(false);

            Channel remoteChannel = await _remoteClient.SubscribeAsync(channelName).ConfigureAwait(false);

            Channel localChannel = await localPusher.SubscribeAsync(channelName).ConfigureAwait(false);

            void Listener(int index, dynamic eventData)
            {
                string eventName = eventData.@event;

                if (eventName == testEventNames[index])
                {
                    numberEventsReceived[index]++;
                    if (eventExpected[index])
                    {
                        receivedEvents[index].Set();
                    }
                }
            }

            void GeneralListener0(string eventName, dynamic eventData)
            {
                Listener(0, eventData);
            }

            void GeneralListener1(string eventName, dynamic eventData)
            {
                Listener(1, eventData);
            }

            void Listener2(dynamic eventData)
            {
                Listener(2, eventData);
            }

            void Listener3(dynamic eventData)
            {
                Listener(3, eventData);
            }

            localPusher.BindAll(GeneralListener0);
            localPusher.BindAll(GeneralListener1);
            localChannel.Bind(testEventName, Listener2);
            localChannel.Bind(testEventName, Listener3);
            await remoteChannel.TriggerAsync(testEventName, dynamicEventData).ConfigureAwait(false);

            for (int i = 0; i < testEventNames.Length; i++)
            {
                Assert.IsTrue(receivedEvents[i].WaitOne(TimeSpan.FromSeconds(5)), $"receivedEvents[{i}]");
                receivedEvents[i].Reset();
            }

            TimeSpan delayAfterTrigger = TimeSpan.FromMilliseconds(0);

            foreach (int index in listenersToUnbind)
            {
                eventExpected[index] = false;
            }

            // Act
            if (listenersToUnbind.Count == testEventNames.Length)
            {
                // Not expecting any events, so wait a bit and ensure that none come in.
                delayAfterTrigger = TimeSpan.FromMilliseconds(500);
                localPusher.UnbindAll();
                localChannel.UnbindAll();
            }
            else
            {
                if (listenersToUnbind.Contains(0))
                {
                    localPusher.Unbind(GeneralListener0);
                }
                if (listenersToUnbind.Contains(1))
                {
                    localPusher.Unbind(GeneralListener1);
                }
                if (listenersToUnbind.Contains(2) && listenersToUnbind.Contains(3))
                {
                    localChannel.Unbind(testEventName);
                }
                else
                {
                    if (listenersToUnbind.Contains(2))
                    {
                        localChannel.Unbind(testEventName, Listener2);
                    }
                    if (listenersToUnbind.Contains(3))
                    {
                        localChannel.Unbind(testEventName, Listener3);
                    }
                }
            }

            await remoteChannel.TriggerAsync(testEventName, dynamicEventData).ConfigureAwait(false);

            await Task.Delay(delayAfterTrigger).ConfigureAwait(false);

            // Assert
            for (int i = 0; i < testEventNames.Length; i++)
            {
                if (eventExpected[i])
                {
                    Assert.IsTrue(receivedEvents[i].WaitOne(TimeSpan.FromSeconds(5)), $"receivedEvents[{i}]");
                }

                Assert.AreEqual(totalEventsExpected[i], numberEventsReceived[i], $"# Event[{i}]");
            }
        }