Ejemplo n.º 1
0
        public async Task UpdateDeviceConnectionTest()
        {
            int receivedConnectedStatusCount = 0;
            ConnectionStatusChangesHandler connectionStatusChangesHandler = null;
            string hostname = "dummy.azure-devices.net";
            string deviceId = "device1";

            IClientCredentials GetClientCredentials(TimeSpan tokenExpiryDuration)
            {
                string token    = TokenHelper.CreateSasToken(hostname, DateTime.UtcNow.AddSeconds(tokenExpiryDuration.TotalSeconds));
                var    identity = new DeviceIdentity(hostname, deviceId);

                return(new TokenCredentials(identity, token, string.Empty));
            }

            IDeviceProxy GetMockDeviceProxy()
            {
                var deviceProxyMock1 = new Mock <IDeviceProxy>();

                deviceProxyMock1.SetupGet(dp => dp.IsActive).Returns(true);
                deviceProxyMock1.Setup(dp => dp.CloseAsync(It.IsAny <Exception>()))
                .Callback(() => deviceProxyMock1.SetupGet(dp => dp.IsActive).Returns(false))
                .Returns(Task.CompletedTask);
                return(deviceProxyMock1.Object);
            }

            IClient GetMockedDeviceClient()
            {
                var deviceClient = new Mock <IClient>();

                deviceClient.SetupGet(dc => dc.IsActive).Returns(true);
                deviceClient.Setup(dc => dc.CloseAsync())
                .Callback(() => deviceClient.SetupGet(dc => dc.IsActive).Returns(false))
                .Returns(Task.FromResult(true));

                deviceClient.Setup(dc => dc.SetConnectionStatusChangedHandler(It.IsAny <ConnectionStatusChangesHandler>()))
                .Callback <ConnectionStatusChangesHandler>(c => connectionStatusChangesHandler = c);

                deviceClient.Setup(dc => dc.OpenAsync())
                .Callback(() =>
                {
                    int currentCount = receivedConnectedStatusCount;
                    Assert.NotNull(connectionStatusChangesHandler);
                    connectionStatusChangesHandler.Invoke(ConnectionStatus.Connected, ConnectionStatusChangeReason.Connection_Ok);
                    Assert.Equal(receivedConnectedStatusCount, currentCount);
                })
                .Returns(Task.CompletedTask);
                return(deviceClient.Object);
            }

            IAuthenticationMethod authenticationMethod = null;
            var deviceClientProvider = new Mock <IClientProvider>();

            deviceClientProvider.Setup(dc => dc.Create(It.IsAny <IIdentity>(), It.IsAny <IAuthenticationMethod>(), It.IsAny <ITransportSettings[]>()))
            .Callback <IIdentity, IAuthenticationMethod, ITransportSettings[]>((s, a, t) => authenticationMethod = a)
            .Returns(() => GetMockedDeviceClient());

            var messageConverterProvider = Mock.Of <IMessageConverterProvider>();

            ICloudConnectionProvider cloudConnectionProvider = new CloudConnectionProvider(messageConverterProvider, 1, deviceClientProvider.Object, Option.None <UpstreamProtocol>(), TokenProvider, DeviceScopeIdentitiesCache, TimeSpan.FromMinutes(60), true);

            cloudConnectionProvider.BindEdgeHub(Mock.Of <IEdgeHub>());
            var credentialsCache = Mock.Of <ICredentialsCache>();
            IConnectionManager connectionManager = new ConnectionManager(cloudConnectionProvider, credentialsCache, deviceId, "$edgeHub");

            IClientCredentials clientCredentials1 = GetClientCredentials(TimeSpan.FromSeconds(10));
            Try <ICloudProxy>  cloudProxyTry1     = await connectionManager.CreateCloudConnectionAsync(clientCredentials1);

            Assert.True(cloudProxyTry1.Success);

            IDeviceProxy deviceProxy1 = GetMockDeviceProxy();
            await connectionManager.AddDeviceConnection(clientCredentials1.Identity, deviceProxy1);

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

            Assert.NotNull(authenticationMethod);
            var deviceTokenRefresher = authenticationMethod as DeviceAuthenticationWithTokenRefresh;

            Assert.NotNull(deviceTokenRefresher);
            Task <string> tokenGetter = deviceTokenRefresher.GetTokenAsync(hostname);

            Assert.False(tokenGetter.IsCompleted);

            IClientCredentials clientCredentials2 = GetClientCredentials(TimeSpan.FromMinutes(2));
            Try <ICloudProxy>  cloudProxyTry2     = await connectionManager.CreateCloudConnectionAsync(clientCredentials2);

            Assert.True(cloudProxyTry2.Success);

            IDeviceProxy deviceProxy2 = GetMockDeviceProxy();
            await connectionManager.AddDeviceConnection(clientCredentials2.Identity, deviceProxy2);

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

            Assert.False(tokenGetter.IsCompleted);

            IClientCredentials clientCredentials3 = GetClientCredentials(TimeSpan.FromMinutes(10));
            Try <ICloudProxy>  cloudProxyTry3     = await connectionManager.CreateCloudConnectionAsync(clientCredentials3);

            Assert.True(cloudProxyTry3.Success);

            IDeviceProxy deviceProxy3 = GetMockDeviceProxy();
            await connectionManager.AddDeviceConnection(clientCredentials3.Identity, deviceProxy3);

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

            Assert.True(tokenGetter.IsCompleted);
            Assert.Equal(tokenGetter.Result, (clientCredentials3 as ITokenCredentials)?.Token);
        }
Ejemplo n.º 2
0
        public async Task CloudConnectionCallbackTest()
        {
            int receivedConnectedStatusCount = 0;
            ConnectionStatusChangesHandler connectionStatusChangesHandler = (_, __) => { };

            IClient GetMockedDeviceClient()
            {
                var deviceClient = new Mock <IClient>();

                deviceClient.SetupGet(dc => dc.IsActive).Returns(true);
                deviceClient.Setup(dc => dc.CloseAsync())
                .Callback(() => deviceClient.SetupGet(dc => dc.IsActive).Returns(false))
                .Returns(Task.FromResult(true));

                deviceClient.Setup(dc => dc.SetConnectionStatusChangedHandler(It.IsAny <ConnectionStatusChangesHandler>()))
                .Callback <ConnectionStatusChangesHandler>(c => connectionStatusChangesHandler = c);

                deviceClient.Setup(dc => dc.OpenAsync())
                .Callback(() =>
                {
                    int currentCount = receivedConnectedStatusCount;
                    Assert.NotNull(connectionStatusChangesHandler);
                    connectionStatusChangesHandler.Invoke(ConnectionStatus.Connected, ConnectionStatusChangeReason.Connection_Ok);
                    Assert.Equal(receivedConnectedStatusCount, currentCount);
                })
                .Returns(Task.CompletedTask);
                return(deviceClient.Object);
            }

            var deviceClientProvider = new Mock <IClientProvider>();

            deviceClientProvider.Setup(dc => dc.Create(It.IsAny <IIdentity>(), It.IsAny <IAuthenticationMethod>(), It.IsAny <ITransportSettings[]>()))
            .Returns(() => GetMockedDeviceClient());

            var transportSettings = new ITransportSettings[] { new AmqpTransportSettings(TransportType.Amqp_Tcp_Only) };

            void ConnectionStatusHandler(string id, CloudConnectionStatus status)
            {
                if (status == CloudConnectionStatus.ConnectionEstablished)
                {
                    receivedConnectedStatusCount++;
                }
            }

            var messageConverterProvider = new MessageConverterProvider(new Dictionary <Type, IMessageConverter> {
                [typeof(TwinCollection)] = Mock.Of <IMessageConverter>()
            });
            var cloudConnection = new CloudConnection(ConnectionStatusHandler, transportSettings, messageConverterProvider, deviceClientProvider.Object, Mock.Of <ICloudListener>(), TokenProvider, DeviceScopeIdentitiesCache, TimeSpan.FromMinutes(60), true);

            IClientCredentials clientCredentialsWithExpiringToken1 = GetMockClientCredentialsWithToken();

            Assert.Equal(receivedConnectedStatusCount, 0);
            ICloudProxy cloudProxy1 = await cloudConnection.CreateOrUpdateAsync(clientCredentialsWithExpiringToken1);

            Assert.True(cloudProxy1.IsActive);
            Assert.Equal(cloudProxy1, cloudConnection.CloudProxy.OrDefault());
            Assert.Equal(receivedConnectedStatusCount, 0);

            Assert.NotNull(connectionStatusChangesHandler);
            connectionStatusChangesHandler.Invoke(ConnectionStatus.Connected, ConnectionStatusChangeReason.Connection_Ok);
            Assert.Equal(receivedConnectedStatusCount, 1);

            IClientCredentials clientCredentialsWithExpiringToken2 = GetMockClientCredentialsWithToken();
            ICloudProxy        cloudProxy2 = await cloudConnection.CreateOrUpdateAsync(clientCredentialsWithExpiringToken2);

            Assert.True(cloudProxy2.IsActive);
            Assert.Equal(cloudProxy2, cloudConnection.CloudProxy.OrDefault());
            Assert.Equal(receivedConnectedStatusCount, 1);

            connectionStatusChangesHandler.Invoke(ConnectionStatus.Connected, ConnectionStatusChangeReason.Connection_Ok);
            Assert.Equal(receivedConnectedStatusCount, 2);
        }
        public async Task UpdateDeviceConnectionTest()
        {
            int receivedConnectedStatusCount = 0;
            ConnectionStatusChangesHandler connectionStatusChangesHandler = null;
            string hostname = "dummy.azure-devices.net";
            string deviceId = "device1";

            ITokenCredentials GetClientCredentials(TimeSpan tokenExpiryDuration)
            {
                string token    = TokenHelper.CreateSasToken(hostname, DateTime.UtcNow.AddSeconds(tokenExpiryDuration.TotalSeconds));
                var    identity = new DeviceIdentity(hostname, deviceId);

                return(new TokenCredentials(identity, token, string.Empty, Option.None <string>(), Option.None <string>(), false));
            }

            IDeviceProxy GetMockDeviceProxy()
            {
                var deviceProxyMock1 = new Mock <IDeviceProxy>();

                deviceProxyMock1.SetupGet(dp => dp.IsActive).Returns(true);
                deviceProxyMock1.Setup(dp => dp.CloseAsync(It.IsAny <Exception>()))
                .Callback(() => deviceProxyMock1.SetupGet(dp => dp.IsActive).Returns(false))
                .Returns(Task.CompletedTask);
                return(deviceProxyMock1.Object);
            }

            IClient GetMockedDeviceClient()
            {
                var deviceClient = new Mock <IClient>();

                deviceClient.SetupGet(dc => dc.IsActive).Returns(true);
                deviceClient.Setup(dc => dc.CloseAsync())
                .Callback(() => deviceClient.SetupGet(dc => dc.IsActive).Returns(false))
                .Returns(Task.FromResult(true));

                deviceClient.Setup(dc => dc.SetConnectionStatusChangedHandler(It.IsAny <ConnectionStatusChangesHandler>()))
                .Callback <ConnectionStatusChangesHandler>(c => connectionStatusChangesHandler = c);

                deviceClient.Setup(dc => dc.OpenAsync())
                .Callback(
                    () =>
                {
                    int currentCount = receivedConnectedStatusCount;
                    Assert.NotNull(connectionStatusChangesHandler);
                    connectionStatusChangesHandler.Invoke(ConnectionStatus.Connected, ConnectionStatusChangeReason.Connection_Ok);
                    Assert.Equal(receivedConnectedStatusCount, currentCount);
                })
                .Returns(Task.CompletedTask);
                return(deviceClient.Object);
            }

            ITokenProvider tokenProvider        = null;
            var            deviceClientProvider = new Mock <IClientProvider>();

            deviceClientProvider.Setup(dc => dc.Create(It.IsAny <IIdentity>(), It.IsAny <ITokenProvider>(), It.IsAny <ITransportSettings[]>(), Option.None <string>()))
            .Callback <IIdentity, ITokenProvider, ITransportSettings[], Option <string> >((s, a, t, m) => tokenProvider = a)
            .Returns(GetMockedDeviceClient);

            var metadataStore = new Mock <IMetadataStore>();

            metadataStore.Setup(m => m.GetMetadata(It.IsAny <string>())).ReturnsAsync(new ConnectionMetadata("dummyValue"));
            var messageConverterProvider = Mock.Of <IMessageConverterProvider>();

            var deviceScopeIdentitiesCache = new Mock <IDeviceScopeIdentitiesCache>();

            deviceScopeIdentitiesCache.Setup(d => d.GetAuthChain(It.Is <string>(i => i == deviceId))).ReturnsAsync(Option.Some(deviceId));

            var credentialsCache = Mock.Of <ICredentialsCache>();
            ICloudConnectionProvider cloudConnectionProvider = new CloudConnectionProvider(
                messageConverterProvider,
                1,
                deviceClientProvider.Object,
                Option.None <UpstreamProtocol>(),
                TokenProvider,
                deviceScopeIdentitiesCache.Object,
                credentialsCache,
                Mock.Of <IIdentity>(i => i.Id == $"{deviceId}/$edgeHub"),
                TimeSpan.FromMinutes(60),
                true,
                TimeSpan.FromSeconds(20),
                false,
                Option.None <IWebProxy>(),
                metadataStore.Object,
                scopeAuthenticationOnly: true,
                trackDeviceState: true,
                true);

            cloudConnectionProvider.BindEdgeHub(Mock.Of <IEdgeHub>());
            var deviceConnectivityManager        = Mock.Of <IDeviceConnectivityManager>();
            IConnectionManager connectionManager = new ConnectionManager(cloudConnectionProvider, Mock.Of <ICredentialsCache>(), new IdentityProvider(hostname), deviceConnectivityManager);

            ITokenCredentials clientCredentials1 = GetClientCredentials(TimeSpan.FromSeconds(10));
            Try <ICloudProxy> cloudProxyTry1     = await connectionManager.CreateCloudConnectionAsync(clientCredentials1);

            Assert.True(cloudProxyTry1.Success);

            IDeviceProxy deviceProxy1 = GetMockDeviceProxy();
            await connectionManager.AddDeviceConnection(clientCredentials1.Identity, deviceProxy1);

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

            Assert.NotNull(tokenProvider);
            Task <string> tokenGetter = tokenProvider.GetTokenAsync(Option.None <TimeSpan>());

            Assert.False(tokenGetter.IsCompleted);

            ITokenCredentials clientCredentials2 = GetClientCredentials(TimeSpan.FromMinutes(2));
            Try <ICloudProxy> cloudProxyTry2     = await connectionManager.CreateCloudConnectionAsync(clientCredentials2);

            Assert.True(cloudProxyTry2.Success);

            IDeviceProxy deviceProxy2 = GetMockDeviceProxy();
            await connectionManager.AddDeviceConnection(clientCredentials2.Identity, deviceProxy2);

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

            Assert.False(tokenGetter.IsCompleted);

            ITokenCredentials clientCredentials3 = GetClientCredentials(TimeSpan.FromMinutes(10));
            Try <ICloudProxy> cloudProxyTry3     = await connectionManager.CreateCloudConnectionAsync(clientCredentials3);

            Assert.True(cloudProxyTry3.Success);

            IDeviceProxy deviceProxy3 = GetMockDeviceProxy();
            await connectionManager.AddDeviceConnection(clientCredentials3.Identity, deviceProxy3);

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

            Assert.True(tokenGetter.IsCompleted);
            Assert.Equal(tokenGetter.Result, clientCredentials3.Token);
        }
        public async Task CloudConnectionCallbackTest()
        {
            int receivedConnectedStatusCount = 0;
            ConnectionStatusChangesHandler connectionStatusChangesHandler = (_, __) => { };

            IClient GetMockedDeviceClient()
            {
                var deviceClient = new Mock <IClient>();

                deviceClient.SetupGet(dc => dc.IsActive).Returns(true);
                deviceClient.Setup(dc => dc.CloseAsync())
                .Callback(() => deviceClient.SetupGet(dc => dc.IsActive).Returns(false))
                .Returns(Task.FromResult(true));

                deviceClient.Setup(dc => dc.SetConnectionStatusChangedHandler(It.IsAny <ConnectionStatusChangesHandler>()))
                .Callback <ConnectionStatusChangesHandler>(c => connectionStatusChangesHandler = c);

                deviceClient.Setup(dc => dc.OpenAsync())
                .Callback(
                    () =>
                {
                    Assert.NotNull(connectionStatusChangesHandler);
                    connectionStatusChangesHandler.Invoke(ConnectionStatus.Connected, ConnectionStatusChangeReason.Connection_Ok);
                })
                .Returns(Task.CompletedTask);
                return(deviceClient.Object);
            }

            var deviceClientProvider = new Mock <IClientProvider>();

            deviceClientProvider.Setup(dc => dc.Create(It.IsAny <IIdentity>(), It.IsAny <ITokenProvider>(), It.IsAny <ITransportSettings[]>(), Option.None <string>()))
            .Returns(() => GetMockedDeviceClient());

            var transportSettings = new ITransportSettings[] { new AmqpTransportSettings(TransportType.Amqp_Tcp_Only) };

            void ConnectionStatusHandler(string id, CloudConnectionStatus status)
            {
                if (status == CloudConnectionStatus.ConnectionEstablished)
                {
                    receivedConnectedStatusCount++;
                }
            }

            var messageConverterProvider = new MessageConverterProvider(new Dictionary <Type, IMessageConverter> {
                [typeof(TwinCollection)] = Mock.Of <IMessageConverter>()
            });
            ITokenCredentials          clientCredentialsWithExpiringToken1 = GetMockClientCredentialsWithToken();
            ClientTokenCloudConnection cloudConnection = await ClientTokenCloudConnection.Create(
                clientCredentialsWithExpiringToken1,
                ConnectionStatusHandler,
                transportSettings,
                messageConverterProvider,
                deviceClientProvider.Object,
                Mock.Of <ICloudListener>(),
                TimeSpan.FromMinutes(60),
                true,
                TimeSpan.FromSeconds(20),
                DummyProductInfo,
                Option.None <string>());

            Assert.Equal(1, receivedConnectedStatusCount);
            Option <ICloudProxy> cloudProxy1 = cloudConnection.CloudProxy;

            Assert.True(cloudProxy1.HasValue);
            Assert.True(cloudProxy1.OrDefault().IsActive);

            Assert.NotNull(connectionStatusChangesHandler);
            connectionStatusChangesHandler.Invoke(ConnectionStatus.Connected, ConnectionStatusChangeReason.Connection_Ok);
            Assert.Equal(2, receivedConnectedStatusCount);

            ITokenCredentials clientCredentialsWithExpiringToken2 = GetMockClientCredentialsWithToken();
            ICloudProxy       cloudProxy2 = await cloudConnection.UpdateTokenAsync(clientCredentialsWithExpiringToken2);

            Assert.True(cloudProxy2.IsActive);
            Assert.Equal(cloudProxy2, cloudConnection.CloudProxy.OrDefault());
            Assert.Equal(2, receivedConnectedStatusCount);

            connectionStatusChangesHandler.Invoke(ConnectionStatus.Connected, ConnectionStatusChangeReason.Connection_Ok);
            Assert.Equal(3, receivedConnectedStatusCount);
        }
        public async Task ConnectivityChangeEventTest2()
        {
            // Arrange
            int connectedStatusChangedHandlerCount    = 0;
            int disconnectedStatusChangedHandlerCount = 0;

            void ConnectionStatusChangedHandler(ConnectionStatus status, ConnectionStatusChangeReason reason)
            {
                if (status == ConnectionStatus.Connected)
                {
                    Interlocked.Increment(ref connectedStatusChangedHandlerCount);
                }
                else
                {
                    Interlocked.Increment(ref disconnectedStatusChangedHandlerCount);
                }
            }

            var deviceConnectivityManager = new DeviceConnectivityManager();
            ConnectionStatusChangesHandler innerClientHandler = null;
            var client = new Mock <IClient>();

            client.Setup(c => c.SetConnectionStatusChangedHandler(It.IsAny <ConnectionStatusChangesHandler>()))
            .Callback <ConnectionStatusChangesHandler>(c => innerClientHandler = c);

            var connectivityAwareClient = new ConnectivityAwareClient(client.Object, deviceConnectivityManager, Mock.Of <IIdentity>(i => i.Id == "d1"));

            connectivityAwareClient.SetConnectionStatusChangedHandler(ConnectionStatusChangedHandler);

            // Act
            await connectivityAwareClient.OpenAsync();

            // Assert
            Assert.NotNull(innerClientHandler);

            // Act
            deviceConnectivityManager.InvokeDeviceConnected();

            // Assert
            Assert.Equal(1, connectedStatusChangedHandlerCount);
            Assert.Equal(0, disconnectedStatusChangedHandlerCount);

            // Act
            innerClientHandler.Invoke(ConnectionStatus.Connected, ConnectionStatusChangeReason.Connection_Ok);

            // Assert
            Assert.Equal(1, connectedStatusChangedHandlerCount);
            Assert.Equal(0, disconnectedStatusChangedHandlerCount);

            // Act
            deviceConnectivityManager.InvokeDeviceDisconnected();

            // Assert
            Assert.Equal(1, connectedStatusChangedHandlerCount);
            Assert.Equal(1, disconnectedStatusChangedHandlerCount);

            // Act
            innerClientHandler.Invoke(ConnectionStatus.Disconnected, ConnectionStatusChangeReason.Communication_Error);

            // Assert
            Assert.Equal(1, connectedStatusChangedHandlerCount);
            Assert.Equal(1, disconnectedStatusChangedHandlerCount);
        }