public async Task X509DeviceCanSendMessageTest()
        {
            var connMgr = new Mock <IConnectionManager>();

            connMgr.Setup(c => c.AddDeviceConnection(It.IsAny <IIdentity>(), It.IsAny <IDeviceProxy>()));
            var identity = Mock.Of <IModuleIdentity>(m => m.DeviceId == "device1" && m.ModuleId == "module1" && m.Id == "device1/module1");
            var edgeHub  = Mock.Of <IEdgeHub>();
            Option <ICloudProxy> cloudProxy = Option.None <ICloudProxy>();
            bool   messageReceived          = false;
            string lockToken             = null;
            var    underlyingDeviceProxy = new Mock <IDeviceProxy>();

            underlyingDeviceProxy.Setup(d => d.SendMessageAsync(It.IsAny <IMessage>(), It.IsAny <string>()))
            .Callback <IMessage, string>(
                (m, i) =>
            {
                messageReceived = true;
                lockToken       = m.SystemProperties[SystemProperties.LockToken];
            })
            .Returns(Task.CompletedTask);
            connMgr.Setup(c => c.GetCloudConnection(It.IsAny <string>())).Returns(Task.FromResult(cloudProxy));
            var deviceMessageHandler = new DeviceMessageHandler(identity, edgeHub, connMgr.Object, DefaultMessageAckTimeout, Option.None <string>());

            deviceMessageHandler.BindDeviceProxy(underlyingDeviceProxy.Object);

            IMessage message = new EdgeMessage.Builder(new byte[0]).Build();
            // send message to x509 device
            Task sendMessageTask = deviceMessageHandler.SendMessageAsync(message, "input1");
            await deviceMessageHandler.ProcessMessageFeedbackAsync(lockToken, FeedbackStatus.Complete);

            await Task.Delay(TimeSpan.FromSeconds(1));

            Assert.True(messageReceived);
            Assert.True(sendMessageTask.IsCompletedSuccessfully);
        }
        public async Task MessageCompletionLongAckTimeoutTest()
        {
            var connMgr = new Mock <IConnectionManager>();

            connMgr.Setup(c => c.AddDeviceConnection(It.IsAny <IIdentity>(), It.IsAny <IDeviceProxy>()));
            var      identity              = Mock.Of <IModuleIdentity>(m => m.DeviceId == "device1" && m.ModuleId == "module1" && m.Id == "device1/module1");
            var      cloudProxy            = new Mock <ICloudProxy>();
            var      edgeHub               = Mock.Of <IEdgeHub>();
            var      underlyingDeviceProxy = new Mock <IDeviceProxy>();
            IMessage receivedMessage       = null;

            underlyingDeviceProxy.Setup(d => d.SendMessageAsync(It.IsAny <IMessage>(), It.IsAny <string>()))
            .Callback <IMessage, string>((m, s) => receivedMessage = m)
            .Returns(Task.CompletedTask);
            connMgr.Setup(c => c.GetCloudConnection(It.IsAny <string>())).Returns(Task.FromResult(Option.Some(cloudProxy.Object)));
            TimeSpan messageAckTimeout    = TimeSpan.FromSeconds(15);
            var      deviceMessageHandler = new DeviceMessageHandler(identity, edgeHub, connMgr.Object, messageAckTimeout, Option.None <string>());

            deviceMessageHandler.BindDeviceProxy(underlyingDeviceProxy.Object);

            IMessage message         = new EdgeMessage.Builder(new byte[0]).Build();
            Task     sendMessageTask = deviceMessageHandler.SendMessageAsync(message, "input1");

            Assert.False(sendMessageTask.IsCompleted);

            await Task.Delay(TimeSpan.FromSeconds(10));

            string messageId = receivedMessage.SystemProperties[SystemProperties.LockToken];
            await deviceMessageHandler.ProcessMessageFeedbackAsync(messageId, FeedbackStatus.Complete);

            await Task.Delay(TimeSpan.FromSeconds(1));

            Assert.True(sendMessageTask.IsCompleted);
        }
        public async Task MessageCompletionMismatchedResponseTest()
        {
            var connMgr = new Mock <IConnectionManager>();

            connMgr.Setup(c => c.AddDeviceConnection(It.IsAny <IIdentity>(), It.IsAny <IDeviceProxy>()));
            var identity              = Mock.Of <IModuleIdentity>(m => m.DeviceId == "device1" && m.ModuleId == "module1" && m.Id == "device1/module1");
            var cloudProxy            = new Mock <ICloudProxy>();
            var edgeHub               = Mock.Of <IEdgeHub>();
            var underlyingDeviceProxy = new Mock <IDeviceProxy>();

            underlyingDeviceProxy.Setup(d => d.SendMessageAsync(It.IsAny <IMessage>(), It.IsAny <string>()))
            .Returns(Task.CompletedTask);
            connMgr.Setup(c => c.GetCloudConnection(It.IsAny <string>())).Returns(Task.FromResult(Option.Some(cloudProxy.Object)));
            var deviceMessageHandler = new DeviceMessageHandler(identity, edgeHub, connMgr.Object, DefaultMessageAckTimeout, Option.None <string>());

            deviceMessageHandler.BindDeviceProxy(underlyingDeviceProxy.Object);

            IMessage message         = new EdgeMessage.Builder(new byte[0]).Build();
            Task     sendMessageTask = deviceMessageHandler.SendMessageAsync(message, "input1");

            Assert.False(sendMessageTask.IsCompleted);

            await deviceMessageHandler.ProcessMessageFeedbackAsync(Guid.NewGuid().ToString(), FeedbackStatus.Complete);

            await Task.Delay(TimeSpan.FromSeconds(1));

            Assert.False(sendMessageTask.IsCompleted);
        }
        public async Task MessageCompletionTimeoutTest()
        {
            var connMgr = new Mock <IConnectionManager>();

            connMgr.Setup(c => c.AddDeviceConnection(It.IsAny <IIdentity>(), It.IsAny <IDeviceProxy>()));
            var identity   = Mock.Of <IModuleIdentity>(m => m.DeviceId == "device1" && m.ModuleId == "module1" && m.Id == "device1/module1");
            var cloudProxy = new Mock <ICloudProxy>();

            cloudProxy.Setup(c => c.BindCloudListener(It.IsAny <ICloudListener>()));
            var edgeHub = Mock.Of <IEdgeHub>();
            var underlyingDeviceProxy = new Mock <IDeviceProxy>();

            underlyingDeviceProxy.Setup(d => d.SendMessageAsync(It.IsAny <IMessage>(), It.IsAny <string>()))
            .Returns(Task.CompletedTask);
            connMgr.Setup(c => c.GetCloudConnection(It.IsAny <string>())).Returns(Option.Some(cloudProxy.Object));
            var deviceMessageHandler = new DeviceMessageHandler(identity, edgeHub, connMgr.Object);

            deviceMessageHandler.BindDeviceProxy(underlyingDeviceProxy.Object);

            IMessage message         = new EdgeMessage.Builder(new byte[0]).Build();
            Task     sendMessageTask = deviceMessageHandler.SendMessageAsync(message, "input1");

            Assert.False(sendMessageTask.IsCompleted);

            await Assert.ThrowsAsync <TimeoutException>(async() => await sendMessageTask);
        }