Esempio n. 1
0
        public async Task when_sending_publish_with_retain_then_retain_message_is_replaced()
        {
            var clientId = Guid.NewGuid().ToString();

            var configuration      = Mock.Of <MqttConfiguration> ();
            var topicEvaluator     = new Mock <IMqttTopicEvaluator> ();
            var connectionProvider = new Mock <IConnectionProvider> ();
            var publishSenderFlow  = new Mock <IPublishSenderFlow> ();
            var retainedRepository = new Mock <IRepository <RetainedMessage> > ();
            var sessionRepository  = new Mock <IRepository <ClientSession> > ();
            var willRepository     = new Mock <IRepository <ConnectionWill> >();

            sessionRepository.Setup(r => r.Get(It.IsAny <Expression <Func <ClientSession, bool> > > ()))
            .Returns(new ClientSession {
                ClientId        = clientId,
                PendingMessages = new List <PendingMessage> {
                    new PendingMessage()
                }
            });

            var packetIdProvider            = Mock.Of <IPacketIdProvider> ();
            var undeliveredMessagesListener = new Subject <MqttUndeliveredMessage> ();

            var topic = "foo/bar";

            var sessions = new List <ClientSession> {
                new ClientSession {
                    ClientId = Guid.NewGuid().ToString(), Clean = false
                }
            };

            var existingRetainedMessage = new RetainedMessage();

            retainedRepository.Setup(r => r.Get(It.IsAny <Expression <Func <RetainedMessage, bool> > >())).Returns(existingRetainedMessage);
            sessionRepository.Setup(r => r.GetAll(It.IsAny <Expression <Func <ClientSession, bool> > > ())).Returns(sessions.AsQueryable());

            var qos     = MqttQualityOfService.AtMostOnce;
            var payload = "Publish Flow Test";
            var publish = new Publish(topic, qos, retain: true, duplicated: false);

            publish.Payload = Encoding.UTF8.GetBytes(payload);

            var receiver = new Subject <IPacket> ();
            var channel  = new Mock <IMqttChannel <IPacket> > ();

            channel.Setup(c => c.ReceiverStream).Returns(receiver);

            var flow = new ServerPublishReceiverFlow(topicEvaluator.Object, connectionProvider.Object, publishSenderFlow.Object,
                                                     retainedRepository.Object, sessionRepository.Object, willRepository.Object, packetIdProvider, undeliveredMessagesListener, configuration);

            await flow.ExecuteAsync(clientId, publish, channel.Object)
            .ConfigureAwait(continueOnCapturedContext: false);

            retainedRepository.Verify(r => r.Delete(It.Is <RetainedMessage> (m => m == existingRetainedMessage)));
            retainedRepository.Verify(r => r.Create(It.Is <RetainedMessage> (m => m.Topic == topic && m.QualityOfService == qos && m.Payload.ToList().SequenceEqual(publish.Payload))));
            channel.Verify(c => c.SendAsync(It.IsAny <IPacket> ()), Times.Never);
        }
Esempio n. 2
0
        public void when_sending_publish_with_qos_higher_than_zero_and_without_packet_id_then_fails()
        {
            var clientId = Guid.NewGuid().ToString();

            var configuration = new MqttConfiguration {
                MaximumQualityOfService = MqttQualityOfService.ExactlyOnce
            };
            var topicEvaluator     = new Mock <IMqttTopicEvaluator> ();
            var connectionProvider = new Mock <IConnectionProvider> ();
            var publishSenderFlow  = new Mock <IPublishSenderFlow> ();
            var retainedRepository = Mock.Of <IRepository <RetainedMessage> > ();
            var sessionRepository  = new Mock <IRepository <ClientSession> > ();
            var willRepository     = new Mock <IRepository <ConnectionWill> >();

            sessionRepository.Setup(r => r.Get(It.IsAny <Expression <Func <ClientSession, bool> > > ()))
            .Returns(new ClientSession {
                ClientId        = clientId,
                PendingMessages = new List <PendingMessage> {
                    new PendingMessage()
                }
            });

            var packetIdProvider            = Mock.Of <IPacketIdProvider> ();
            var undeliveredMessagesListener = new Subject <MqttUndeliveredMessage> ();

            var topic = "foo/bar";

            var subscribedClientId = Guid.NewGuid().ToString();
            var sessions           = new List <ClientSession> {
                new ClientSession {
                    ClientId = subscribedClientId, Clean = false
                }
            };

            sessionRepository.Setup(r => r.GetAll(It.IsAny <Expression <Func <ClientSession, bool> > > ())).Returns(sessions.AsQueryable());

            var publish = new Publish(topic, MqttQualityOfService.AtLeastOnce, retain: false, duplicated: false);

            publish.Payload = Encoding.UTF8.GetBytes("Publish Flow Test");

            var receiver = new Subject <IPacket> ();
            var channel  = new Mock <IMqttChannel <IPacket> > ();

            channel.Setup(c => c.ReceiverStream).Returns(receiver);

            var flow = new ServerPublishReceiverFlow(topicEvaluator.Object, connectionProvider.Object, publishSenderFlow.Object,
                                                     retainedRepository, sessionRepository.Object, willRepository.Object, packetIdProvider, undeliveredMessagesListener, configuration);

            var ex = Assert.Throws <AggregateException> (() => flow.ExecuteAsync(clientId, publish, channel.Object).Wait());

            Assert.True(ex.InnerException is MqttException);
        }
Esempio n. 3
0
        public async Task when_sending_publish_to_a_system_topic_with_private_client_then_succeeds()
        {
            var clientId = Guid.NewGuid().ToString();

            var configuration      = new Mock <MqttConfiguration> ();
            var topicEvaluator     = new Mock <IMqttTopicEvaluator> ();
            var connectionProvider = new Mock <IConnectionProvider> ();
            var publishSenderFlow  = new Mock <IPublishSenderFlow> ();
            var retainedRepository = new Mock <IRepository <RetainedMessage> > ();
            var sessionRepository  = new Mock <IRepository <ClientSession> > ();
            var willRepository     = new Mock <IRepository <ConnectionWill> > ();

            connectionProvider.Setup(p => p.PrivateClients)
            .Returns(new[] { clientId });

            sessionRepository.Setup(r => r.Get(It.IsAny <Expression <Func <ClientSession, bool> > > ()))
            .Returns(new ClientSession
            {
                ClientId        = clientId,
                PendingMessages = new List <PendingMessage> {
                    new PendingMessage()
                }
            });

            var packetIdProvider            = Mock.Of <IPacketIdProvider> ();
            var undeliveredMessagesListener = new Subject <MqttUndeliveredMessage> ();

            var systemTopic = "$SYS/foo";

            var flow = new ServerPublishReceiverFlow(topicEvaluator.Object, connectionProvider.Object,
                                                     publishSenderFlow.Object, retainedRepository.Object, sessionRepository.Object, willRepository.Object,
                                                     packetIdProvider, undeliveredMessagesListener, configuration.Object);

            var publish = new Publish(systemTopic, MqttQualityOfService.AtMostOnce, retain: false, duplicated: false);

            publish.Payload = Encoding.UTF8.GetBytes("Publish Receiver Flow Test");

            var receiver = new Subject <IPacket> ();
            var channel  = new Mock <IMqttChannel <IPacket> > ();

            channel.Setup(c => c.ReceiverStream).Returns(receiver);

            await flow.ExecuteAsync(clientId, publish, channel.Object);

            retainedRepository.Verify(r => r.Create(It.IsAny <RetainedMessage> ()), Times.Never);
            channel.Verify(c => c.SendAsync(It.IsAny <IPacket> ()), Times.Never);
            publishSenderFlow.Verify(s => s.SendPublishAsync(It.IsAny <string> (),
                                                             It.IsAny <Publish> (), It.IsAny <IMqttChannel <IPacket> > (), It.IsAny <PendingMessageStatus> ()), Times.Never);
        }
Esempio n. 4
0
        public void when_sending_publish_to_a_system_topic_with_remote_client_then_fails()
        {
            var clientId = Guid.NewGuid().ToString();

            var configuration      = new Mock <MqttConfiguration> ();
            var topicEvaluator     = new Mock <IMqttTopicEvaluator> ();
            var connectionProvider = new Mock <IConnectionProvider> ();
            var publishSenderFlow  = new Mock <IPublishSenderFlow> ();
            var retainedRepository = new Mock <IRepository <RetainedMessage> > ();
            var sessionRepository  = new Mock <IRepository <ClientSession> > ();
            var willRepository     = new Mock <IRepository <ConnectionWill> > ();

            sessionRepository.Setup(r => r.Get(It.IsAny <Expression <Func <ClientSession, bool> > > ()))
            .Returns(new ClientSession
            {
                ClientId        = clientId,
                PendingMessages = new List <PendingMessage> {
                    new PendingMessage()
                }
            });

            var packetIdProvider            = Mock.Of <IPacketIdProvider> ();
            var undeliveredMessagesListener = new Subject <MqttUndeliveredMessage> ();

            var systemTopic = "$SYS/foo";

            var flow = new ServerPublishReceiverFlow(topicEvaluator.Object, connectionProvider.Object,
                                                     publishSenderFlow.Object, retainedRepository.Object, sessionRepository.Object, willRepository.Object,
                                                     packetIdProvider, undeliveredMessagesListener, configuration.Object);

            var publish = new Publish(systemTopic, MqttQualityOfService.AtMostOnce, retain: false, duplicated: false);

            publish.Payload = Encoding.UTF8.GetBytes("Publish Receiver Flow Test");

            var receiver = new Subject <IPacket> ();
            var channel  = new Mock <IMqttChannel <IPacket> > ();

            channel.Setup(c => c.ReceiverStream).Returns(receiver);

            var ex = Assert.Throws <AggregateException> (() => flow.ExecuteAsync(clientId, publish, channel.Object).Wait());

            Assert.NotNull(ex);
            Assert.NotNull(ex.InnerException);
            Assert.True(ex.InnerException is MqttException);
            Assert.Equal(Resources.ServerPublishReceiverFlow_SystemMessageNotAllowedForClient, ex.InnerException.Message);
        }
        public void when_getting_explicit_server_flow_from_type_then_succeeds()
        {
            IMqttAuthenticationProvider authenticationProvider = Mock.Of <IMqttAuthenticationProvider>(p => p.Authenticate(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>()) == true);
            ServerProtocolFlowProvider  flowProvider           = new ServerProtocolFlowProvider(authenticationProvider, Mock.Of <IConnectionProvider>(), Mock.Of <IMqttTopicEvaluator>(),
                                                                                                Mock.Of <IRepositoryProvider>(), Mock.Of <IPacketIdProvider>(), Mock.Of <ISubject <MqttUndeliveredMessage> >(), new MqttConfiguration());

            ServerConnectFlow         connectFlow     = flowProvider.GetFlow <ServerConnectFlow>();
            PublishSenderFlow         senderFlow      = flowProvider.GetFlow <PublishSenderFlow>();
            ServerPublishReceiverFlow receiverFlow    = flowProvider.GetFlow <ServerPublishReceiverFlow>();
            ServerSubscribeFlow       subscribeFlow   = flowProvider.GetFlow <ServerSubscribeFlow>();
            ServerUnsubscribeFlow     unsubscribeFlow = flowProvider.GetFlow <ServerUnsubscribeFlow>();
            DisconnectFlow            disconnectFlow  = flowProvider.GetFlow <DisconnectFlow>();

            Assert.NotNull(connectFlow);
            Assert.NotNull(senderFlow);
            Assert.NotNull(receiverFlow);
            Assert.NotNull(subscribeFlow);
            Assert.NotNull(unsubscribeFlow);
            Assert.NotNull(disconnectFlow);
        }
Esempio n. 6
0
        public async Task when_sending_publish_release_then_publish_complete_is_sent()
        {
            var clientId = Guid.NewGuid().ToString();

            var configuration      = Mock.Of <MqttConfiguration> ();
            var topicEvaluator     = new Mock <IMqttTopicEvaluator> ();
            var connectionProvider = new Mock <IConnectionProvider> ();
            var publishSenderFlow  = new Mock <IPublishSenderFlow> ();
            var retainedRepository = Mock.Of <IRepository <RetainedMessage> > ();
            var sessionRepository  = new Mock <IRepository <ClientSession> > ();
            var willRepository     = new Mock <IRepository <ConnectionWill> >();

            sessionRepository.Setup(r => r.Get(It.IsAny <Expression <Func <ClientSession, bool> > > ()))
            .Returns(new ClientSession {
                ClientId        = clientId,
                PendingMessages = new List <PendingMessage> {
                    new PendingMessage()
                }
            });

            var packetIdProvider            = Mock.Of <IPacketIdProvider> ();
            var undeliveredMessagesListener = new Subject <MqttUndeliveredMessage> ();

            var flow = new ServerPublishReceiverFlow(topicEvaluator.Object, connectionProvider.Object, publishSenderFlow.Object,
                                                     retainedRepository, sessionRepository.Object, willRepository.Object, packetIdProvider, undeliveredMessagesListener, configuration);

            var packetId       = (ushort)new Random().Next(0, ushort.MaxValue);
            var publishRelease = new PublishRelease(packetId);

            var channel = new Mock <IMqttChannel <IPacket> > ();

            channel.Setup(c => c.IsConnected).Returns(true);

            await flow.ExecuteAsync(clientId, publishRelease, channel.Object)
            .ConfigureAwait(continueOnCapturedContext: false);

            channel.Verify(c => c.SendAsync(It.Is <IPacket> (p => p is PublishComplete && (p as PublishComplete).PacketId == packetId)));
        }
Esempio n. 7
0
        public async Task when_sending_publish_and_subscriber_with_qos2_send_publish_received_then_publish_is_not_re_transmitted()
        {
            var clientId = Guid.NewGuid().ToString();

            var configuration = new MqttConfiguration {
                MaximumQualityOfService = MqttQualityOfService.ExactlyOnce,
                WaitTimeoutSecs         = 2
            };
            var topicEvaluator     = new Mock <IMqttTopicEvaluator> ();
            var connectionProvider = new Mock <IConnectionProvider> ();
            var publishSenderFlow  = new Mock <IPublishSenderFlow> ();
            var retainedRepository = new Mock <IRepository <RetainedMessage> > ();
            var sessionRepository  = new Mock <IRepository <ClientSession> > ();
            var willRepository     = new Mock <IRepository <ConnectionWill> >();

            sessionRepository.Setup(r => r.Get(It.IsAny <Expression <Func <ClientSession, bool> > > ()))
            .Returns(new ClientSession {
                ClientId        = clientId,
                PendingMessages = new List <PendingMessage> {
                    new PendingMessage()
                }
            });

            var packetIdProvider            = Mock.Of <IPacketIdProvider> ();
            var undeliveredMessagesListener = new Subject <MqttUndeliveredMessage> ();

            var topic = "foo/bar";

            var flow = new ServerPublishReceiverFlow(topicEvaluator.Object, connectionProvider.Object, publishSenderFlow.Object,
                                                     retainedRepository.Object, sessionRepository.Object, willRepository.Object, packetIdProvider, undeliveredMessagesListener, configuration);

            var subscribedClientId = Guid.NewGuid().ToString();
            var requestedQoS       = MqttQualityOfService.ExactlyOnce;
            var sessions           = new List <ClientSession> {
                new ClientSession {
                    ClientId      = subscribedClientId,
                    Clean         = false,
                    Subscriptions = new List <ClientSubscription> {
                        new ClientSubscription {
                            ClientId = subscribedClientId, MaximumQualityOfService = requestedQoS, TopicFilter = topic
                        }
                    }
                }
            };

            var clientReceiver = new Subject <IPacket> ();
            var clientSender   = new Subject <IPacket> ();
            var clientChannel  = new Mock <IMqttChannel <IPacket> > ();

            clientSender.OfType <Publish>().Subscribe(p => {
                clientReceiver.OnNext(new PublishReceived(p.PacketId.Value));
            });

            clientChannel.Setup(c => c.ReceiverStream).Returns(clientReceiver);
            clientChannel.Setup(c => c.SenderStream).Returns(clientSender);
            clientChannel.Setup(c => c.SendAsync(It.IsAny <IPacket> ()))
            .Callback <IPacket> (packet => clientSender.OnNext(packet))
            .Returns(Task.Delay(0));
            topicEvaluator.Setup(e => e.Matches(It.IsAny <string> (), It.IsAny <string> ())).Returns(true);
            sessionRepository.Setup(r => r.GetAll(It.IsAny <Expression <Func <ClientSession, bool> > >())).Returns(sessions.AsQueryable());

            connectionProvider
            .Setup(p => p.GetConnection(It.Is <string> (s => s == subscribedClientId)))
            .Returns(clientChannel.Object);

            var packetId = (ushort?)new Random().Next(0, ushort.MaxValue);
            var publish  = new Publish(topic, MqttQualityOfService.ExactlyOnce, retain: false, duplicated: false, packetId: packetId);

            publish.Payload = Encoding.UTF8.GetBytes("Publish Receiver Flow Test");

            var receiver = new Subject <IPacket> ();
            var channel  = new Mock <IMqttChannel <IPacket> > ();

            channel.Setup(c => c.ReceiverStream).Returns(receiver);

            await flow.ExecuteAsync(clientId, publish, channel.Object)
            .ConfigureAwait(continueOnCapturedContext: false);

            publishSenderFlow.Verify(s => s.SendPublishAsync(It.Is <string>(x => x == subscribedClientId),
                                                             It.Is <Publish> (p => p.Topic == publish.Topic &&
                                                                              p.Payload.ToList().SequenceEqual(publish.Payload)),
                                                             It.Is <IMqttChannel <IPacket> >(c => c == clientChannel.Object), It.Is <PendingMessageStatus>(x => x == PendingMessageStatus.PendingToSend)), Times.Once);
            clientChannel.Verify(c => c.SendAsync(It.Is <IPacket> (p => p is Publish)), Times.Never);
        }
Esempio n. 8
0
        public void when_sending_publish_with_qos2_and_no_release_is_sent_after_receiving_publish_received_then_publish_received_is_re_transmitted()
        {
            var clientId = Guid.NewGuid().ToString();

            var configuration = new MqttConfiguration {
                MaximumQualityOfService = MqttQualityOfService.ExactlyOnce,
                WaitTimeoutSecs         = 1
            };
            var topicEvaluator     = new Mock <IMqttTopicEvaluator> ();
            var connectionProvider = new Mock <IConnectionProvider> ();
            var publishSenderFlow  = new Mock <IPublishSenderFlow> ();
            var retainedRepository = new Mock <IRepository <RetainedMessage> > ();
            var sessionRepository  = new Mock <IRepository <ClientSession> > ();
            var willRepository     = new Mock <IRepository <ConnectionWill> >();

            sessionRepository.Setup(r => r.Get(It.IsAny <Expression <Func <ClientSession, bool> > > ()))
            .Returns(new ClientSession {
                ClientId        = clientId,
                PendingMessages = new List <PendingMessage> {
                    new PendingMessage()
                }
            });

            var packetIdProvider            = Mock.Of <IPacketIdProvider> ();
            var undeliveredMessagesListener = new Subject <MqttUndeliveredMessage> ();

            var topic = "foo/bar";

            var flow = new ServerPublishReceiverFlow(topicEvaluator.Object, connectionProvider.Object, publishSenderFlow.Object,
                                                     retainedRepository.Object, sessionRepository.Object, willRepository.Object, packetIdProvider, undeliveredMessagesListener, configuration);

            var subscribedClientId = Guid.NewGuid().ToString();
            var requestedQoS       = MqttQualityOfService.ExactlyOnce;
            var sessions           = new List <ClientSession> {
                new ClientSession {
                    ClientId      = subscribedClientId,
                    Clean         = false,
                    Subscriptions = new List <ClientSubscription> {
                        new ClientSubscription {
                            ClientId = subscribedClientId, MaximumQualityOfService = requestedQoS, TopicFilter = topic
                        }
                    }
                }
            };

            var clientReceiver = new Subject <IPacket> ();
            var clientChannel  = new Mock <IMqttChannel <IPacket> > ();

            clientChannel.Setup(c => c.ReceiverStream).Returns(clientReceiver);

            topicEvaluator.Setup(e => e.Matches(It.IsAny <string> (), It.IsAny <string> ())).Returns(true);
            sessionRepository.Setup(r => r.GetAll(It.IsAny <Expression <Func <ClientSession, bool> > >())).Returns(sessions.AsQueryable());

            var packetId = (ushort?)new Random().Next(0, ushort.MaxValue);
            var publish  = new Publish(topic, MqttQualityOfService.ExactlyOnce, retain: false, duplicated: false, packetId: packetId);

            publish.Payload = Encoding.UTF8.GetBytes("Publish Receiver Flow Test");

            var receiver = new Subject <IPacket> ();
            var sender   = new Subject <IPacket> ();
            var channel  = new Mock <IMqttChannel <IPacket> > ();

            channel.Setup(c => c.IsConnected).Returns(true);
            channel.Setup(c => c.ReceiverStream).Returns(receiver);
            channel.Setup(c => c.SenderStream).Returns(sender);
            channel.Setup(c => c.SendAsync(It.IsAny <IPacket> ()))
            .Callback <IPacket> (packet => sender.OnNext(packet))
            .Returns(Task.Delay(0));

            var publishReceivedSignal = new ManualResetEventSlim(initialState: false);
            var retries = 0;

            sender.Subscribe(packet => {
                if (packet is PublishReceived)
                {
                    retries++;
                }

                if (retries > 1)
                {
                    publishReceivedSignal.Set();
                }
            });

            var flowTask = flow.ExecuteAsync(clientId, publish, channel.Object);

            var retried = publishReceivedSignal.Wait(2000);

            Assert.True(retried);
            channel.Verify(c => c.SendAsync(It.Is <IPacket> (p => p is PublishReceived &&
                                                             (p as PublishReceived).PacketId == packetId)), Times.AtLeast(2));
        }
Esempio n. 9
0
        public async Task when_sending_publish_with_qos0_then_publish_is_sent_to_subscribers_and_no_ack_is_sent()
        {
            var clientId = Guid.NewGuid().ToString();

            var configuration = new MqttConfiguration {
                MaximumQualityOfService = MqttQualityOfService.ExactlyOnce
            };
            var topicEvaluator     = new Mock <IMqttTopicEvaluator> ();
            var connectionProvider = new Mock <IConnectionProvider> ();
            var publishSenderFlow  = new Mock <IPublishSenderFlow> ();
            var retainedRepository = new Mock <IRepository <RetainedMessage> > ();
            var sessionRepository  = new Mock <IRepository <ClientSession> > ();
            var willRepository     = new Mock <IRepository <ConnectionWill> >();

            sessionRepository.Setup(r => r.Get(It.IsAny <Expression <Func <ClientSession, bool> > > ()))
            .Returns(new ClientSession {
                ClientId        = clientId,
                PendingMessages = new List <PendingMessage> {
                    new PendingMessage()
                }
            });

            var packetIdProvider            = Mock.Of <IPacketIdProvider> ();
            var undeliveredMessagesListener = new Subject <MqttUndeliveredMessage> ();

            var topic = "foo/bar";

            var flow = new ServerPublishReceiverFlow(topicEvaluator.Object, connectionProvider.Object,
                                                     publishSenderFlow.Object, retainedRepository.Object, sessionRepository.Object, willRepository.Object,
                                                     packetIdProvider, undeliveredMessagesListener, configuration);

            var subscribedClientId1 = Guid.NewGuid().ToString();
            var subscribedClientId2 = Guid.NewGuid().ToString();
            var requestedQoS1       = MqttQualityOfService.AtLeastOnce;
            var requestedQoS2       = MqttQualityOfService.ExactlyOnce;
            var sessions            = new List <ClientSession> {
                new ClientSession {
                    ClientId      = subscribedClientId1,
                    Clean         = false,
                    Subscriptions = new List <ClientSubscription> {
                        new ClientSubscription {
                            ClientId = subscribedClientId1,
                            MaximumQualityOfService = requestedQoS1, TopicFilter = topic
                        }
                    }
                },
                new ClientSession {
                    ClientId      = subscribedClientId2,
                    Clean         = false,
                    Subscriptions = new List <ClientSubscription> {
                        new ClientSubscription {
                            ClientId = subscribedClientId2,
                            MaximumQualityOfService = requestedQoS2, TopicFilter = topic
                        }
                    }
                }
            };

            var client1Receiver = new Subject <IPacket> ();
            var client1Channel  = new Mock <IMqttChannel <IPacket> > ();

            client1Channel.Setup(c => c.ReceiverStream).Returns(client1Receiver);

            var client2Receiver = new Subject <IPacket> ();
            var client2Channel  = new Mock <IMqttChannel <IPacket> > ();

            client2Channel.Setup(c => c.ReceiverStream).Returns(client2Receiver);

            topicEvaluator.Setup(e => e.Matches(It.IsAny <string> (), It.IsAny <string> ())).Returns(true);
            sessionRepository.Setup(r => r.GetAll(It.IsAny <Expression <Func <ClientSession, bool> > >())).Returns(sessions.AsQueryable());

            connectionProvider
            .Setup(p => p.GetConnection(It.Is <string> (s => s == subscribedClientId1)))
            .Returns(client1Channel.Object);
            connectionProvider
            .Setup(p => p.GetConnection(It.Is <string> (s => s == subscribedClientId2)))
            .Returns(client2Channel.Object);

            var publish = new Publish(topic, MqttQualityOfService.AtMostOnce, retain: false, duplicated: false);

            publish.Payload = Encoding.UTF8.GetBytes("Publish Receiver Flow Test");

            var receiver = new Subject <IPacket> ();
            var channel  = new Mock <IMqttChannel <IPacket> > ();

            channel.Setup(c => c.ReceiverStream).Returns(receiver);

            await flow.ExecuteAsync(clientId, publish, channel.Object)
            .ConfigureAwait(continueOnCapturedContext: false);

            retainedRepository.Verify(r => r.Create(It.IsAny <RetainedMessage> ()), Times.Never);
            publishSenderFlow.Verify(s => s.SendPublishAsync(It.Is <string>(x => x == subscribedClientId1),
                                                             It.Is <Publish> (p => p.Topic == publish.Topic &&
                                                                              p.Payload.ToList().SequenceEqual(publish.Payload)),
                                                             It.Is <IMqttChannel <IPacket> >(c => c == client1Channel.Object), It.Is <PendingMessageStatus>(x => x == PendingMessageStatus.PendingToSend)));
            publishSenderFlow.Verify(s => s.SendPublishAsync(It.Is <string>(x => x == subscribedClientId2),
                                                             It.Is <Publish> (p => p.Topic == publish.Topic &&
                                                                              p.Payload.ToList().SequenceEqual(publish.Payload)),
                                                             It.Is <IMqttChannel <IPacket> >(c => c == client2Channel.Object), It.Is <PendingMessageStatus>(x => x == PendingMessageStatus.PendingToSend)));
            channel.Verify(c => c.SendAsync(It.IsAny <IPacket> ()), Times.Never);
        }
Esempio n. 10
0
        public async Task when_sending_publish_with_qos2_then_publish_is_sent_to_subscribers_and_publish_received_is_sent()
        {
            var clientId = Guid.NewGuid().ToString();

            var configuration = new MqttConfiguration {
                MaximumQualityOfService = MqttQualityOfService.ExactlyOnce
            };
            var topicEvaluator     = new Mock <IMqttTopicEvaluator> ();
            var connectionProvider = new Mock <IConnectionProvider> ();
            var publishSenderFlow  = new Mock <IPublishSenderFlow> ();
            var retainedRepository = new Mock <IRepository <RetainedMessage> > ();
            var sessionRepository  = new Mock <IRepository <ClientSession> > ();
            var willRepository     = new Mock <IRepository <ConnectionWill> >();

            publishSenderFlow.Setup(f => f.SendPublishAsync(It.IsAny <string> (), It.IsAny <Publish> (), It.IsAny <IMqttChannel <IPacket> > (), It.IsAny <PendingMessageStatus> ()))
            .Returns(Task.Delay(0));

            sessionRepository.Setup(r => r.Get(It.IsAny <Expression <Func <ClientSession, bool> > > ()))
            .Returns(new ClientSession {
                ClientId        = clientId,
                PendingMessages = new List <PendingMessage> {
                    new PendingMessage()
                }
            });

            var packetId                    = (ushort?)new Random().Next(0, ushort.MaxValue);
            var packetIdProvider            = Mock.Of <IPacketIdProvider> ();
            var undeliveredMessagesListener = new Subject <MqttUndeliveredMessage> ();

            var topic = "foo/bar";

            var flow = new ServerPublishReceiverFlow(topicEvaluator.Object, connectionProvider.Object, publishSenderFlow.Object,
                                                     retainedRepository.Object, sessionRepository.Object, willRepository.Object, packetIdProvider, undeliveredMessagesListener, configuration);

            var subscribedClientId = Guid.NewGuid().ToString();
            var requestedQoS       = MqttQualityOfService.ExactlyOnce;
            var sessions           = new List <ClientSession> {
                new ClientSession {
                    ClientId      = subscribedClientId,
                    Clean         = false,
                    Subscriptions = new List <ClientSubscription> {
                        new ClientSubscription {
                            ClientId = subscribedClientId, MaximumQualityOfService = requestedQoS, TopicFilter = topic
                        }
                    }
                }
            };

            var clientReceiver = new Subject <IPacket> ();
            var clientChannel  = new Mock <IMqttChannel <IPacket> > ();

            clientChannel.Setup(c => c.ReceiverStream).Returns(clientReceiver);

            topicEvaluator.Setup(e => e.Matches(It.IsAny <string> (), It.IsAny <string> ())).Returns(true);
            sessionRepository.Setup(r => r.GetAll(It.IsAny <Expression <Func <ClientSession, bool> > >())).Returns(sessions.AsQueryable());

            connectionProvider
            .Setup(p => p.GetConnection(It.Is <string> (s => s == subscribedClientId)))
            .Returns(clientChannel.Object);

            var publish = new Publish(topic, MqttQualityOfService.ExactlyOnce, retain: false, duplicated: false, packetId: packetId);

            publish.Payload = Encoding.UTF8.GetBytes("Publish Flow Test");

            var receiver    = new Subject <IPacket> ();
            var sender      = new Subject <IPacket> ();
            var channelMock = new Mock <IMqttChannel <IPacket> > ();

            channelMock.Setup(c => c.IsConnected).Returns(true);
            channelMock.Setup(c => c.ReceiverStream).Returns(receiver);
            channelMock.Setup(c => c.SenderStream).Returns(sender);
            channelMock.Setup(c => c.SendAsync(It.IsAny <IPacket> ()))
            .Callback <IPacket> (packet => sender.OnNext(packet))
            .Returns(Task.Delay(0));

            var channel       = channelMock.Object;
            var ackSentSignal = new ManualResetEventSlim(initialState: false);

            sender.Subscribe(p => {
                if (p is PublishReceived)
                {
                    ackSentSignal.Set();
                }
            });

            var flowTask = flow.ExecuteAsync(clientId, publish, channel);

            var ackSent = ackSentSignal.Wait(1000);

            receiver.OnNext(new PublishRelease(packetId.Value));

            await Task.Delay(TimeSpan.FromMilliseconds(1000));

            Assert.True(ackSent);
            publishSenderFlow.Verify(s => s.SendPublishAsync(It.Is <string>(x => x == subscribedClientId),
                                                             It.Is <Publish> (p => p.Topic == publish.Topic &&
                                                                              p.Payload.ToList().SequenceEqual(publish.Payload)),
                                                             It.Is <IMqttChannel <IPacket> >(c => c == clientChannel.Object), It.Is <PendingMessageStatus>(x => x == PendingMessageStatus.PendingToSend)));
            retainedRepository.Verify(r => r.Create(It.IsAny <RetainedMessage> ()), Times.Never);
            channelMock.Verify(c => c.SendAsync(It.Is <IPacket> (p => p is PublishReceived && (p as PublishReceived).PacketId == packetId.Value)));
        }