private async Task UploadFileDisconnectTransport(
            Client.TransportType transport,
            string filename,
            string faultType,
            string reason,
            int delayInSec,
            int durationInSec           = 0,
            int retryDurationInMilliSec = FaultInjection.RecoveryTimeMilliseconds)
        {
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false);

            using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport);

            deviceClient.OperationTimeoutInMilliseconds = (uint)retryDurationInMilliSec;

            using (var fileStreamSource = new FileStream(filename, FileMode.Open, FileAccess.Read))
            {
                // UploadToBlobAsync is obsolete, added [Obsolete] attribute to suppress CS0618 message
                Task fileUploadTask     = deviceClient.UploadToBlobAsync(filename, fileStreamSource);
                Task errorInjectionTask = SendErrorInjectionMessageAsync(deviceClient, faultType, reason, delayInSec, durationInSec);
                await Task.WhenAll(fileUploadTask, errorInjectionTask).ConfigureAwait(false);
            }

            try
            {
                await deviceClient.CloseAsync().ConfigureAwait(false);
            }
            catch
            {
                // catch and ignore exceptions resulted incase device client close failed while offline
            }
        }
        private async Task Twin_DeviceReportedPropertiesRecovery(Client.TransportType transport, string faultType, string reason, int delayInSec)
        {
            var propName   = Guid.NewGuid().ToString();
            var propValue1 = Guid.NewGuid().ToString();

            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(DevicePrefix).ConfigureAwait(false);

            var            deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport);
            TwinCollection props        = new TwinCollection();

            props[propName] = propValue1;
            await deviceClient.UpdateReportedPropertiesAsync(props).ConfigureAwait(false);

            var deviceTwin = await deviceClient.GetTwinAsync().ConfigureAwait(false);

            Assert.AreEqual <String>(deviceTwin.Properties.Reported[propName].ToString(), propValue1);

            // send error command
            await deviceClient.SendEventAsync(FaultInjection.ComposeErrorInjectionProperties(faultType, reason, delayInSec)).ConfigureAwait(false);

            deviceTwin = await deviceClient.GetTwinAsync().ConfigureAwait(false);

            Assert.AreEqual <String>(deviceTwin.Properties.Reported[propName].ToString(), propValue1);

            var propValue2 = Guid.NewGuid().ToString();

            props[propName] = propValue2;
            await deviceClient.UpdateReportedPropertiesAsync(props).ConfigureAwait(false);

            deviceTwin = await deviceClient.GetTwinAsync().ConfigureAwait(false);

            Assert.AreEqual <String>(deviceTwin.Properties.Reported[propName].ToString(), propValue2);

            await deviceClient.CloseAsync().ConfigureAwait(false);
        }
예제 #3
0
        public async Task DeviceClient_TokenConnectionDoubleRelease_Ok()
        {
            string     deviceConnectionString = null;
            TestDevice testDevice             = await TestDevice.GetTestDeviceAsync(DevicePrefix).ConfigureAwait(false);

            deviceConnectionString = testDevice.ConnectionString;

            var    config   = new Configuration.IoTHub.DeviceConnectionStringParser(deviceConnectionString);
            string iotHub   = config.IoTHub;
            string deviceId = config.DeviceID;
            string key      = config.SharedAccessKey;

            SharedAccessSignatureBuilder builder = new SharedAccessSignatureBuilder()
            {
                Key        = key,
                TimeToLive = new TimeSpan(0, 10, 0),
                Target     = $"{iotHub}/devices/{WebUtility.UrlEncode(deviceId)}",
            };

            DeviceAuthenticationWithToken auth = new DeviceAuthenticationWithToken(deviceId, builder.ToSignature());

            using (DeviceClient deviceClient = DeviceClient.Create(iotHub, auth, Client.TransportType.Amqp_Tcp_Only))
            {
                _log.WriteLine($"Created {nameof(DeviceClient)} ID={TestLogging.IdOf(deviceClient)}");

                Console.WriteLine("DeviceClient OpenAsync.");
                await deviceClient.OpenAsync().ConfigureAwait(false);

                Console.WriteLine("DeviceClient SendEventAsync.");
                await deviceClient.SendEventAsync(new Client.Message(Encoding.UTF8.GetBytes("TestMessage"))).ConfigureAwait(false);

                Console.WriteLine("DeviceClient CloseAsync.");
                await deviceClient.CloseAsync().ConfigureAwait(false);   // First release
            } // Second release
        }
        public async Task Twin_ClientSetsReportedPropertyWithoutDesiredPropertyCallback(Client.TransportType transportType)
        {
            // arrange

            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(_devicePrefix).ConfigureAwait(false);

            using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transportType);

            await Twin_DeviceSetsReportedPropertyAndGetsItBackAsync(deviceClient, Guid.NewGuid().ToString()).ConfigureAwait(false);

            int connectionStatusChangeCount = 0;
            ConnectionStatusChangesHandler connectionStatusChangesHandler = (ConnectionStatus status, ConnectionStatusChangeReason reason) =>
            {
                Interlocked.Increment(ref connectionStatusChangeCount);
            };

            string propName  = Guid.NewGuid().ToString();
            string propValue = Guid.NewGuid().ToString();

            s_log.WriteLine($"{nameof(Twin_ServiceSetsDesiredPropertyAndDeviceReceivesEventAsync)}: name={propName}, value={propValue}");

            // act
            await RegistryManagerUpdateDesiredPropertyAsync(testDevice.Id, propName, propValue).ConfigureAwait(false);

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

            // assert
            Assert.AreEqual(0, connectionStatusChangeCount, "AMQP should not be disconnected.");
        }
        private async Task Twin_ClientHandlesRejectionInvalidPropertyNameAsync(Client.TransportType transport)
        {
            var propName1 = "$" + Guid.NewGuid().ToString();
            var propName2 = Guid.NewGuid().ToString();

            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(_devicePrefix).ConfigureAwait(false);

            using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString);
            using var deviceClient    = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport);

            var exceptionThrown = false;

            try
            {
                await deviceClient
                .UpdateReportedPropertiesAsync(
                    new TwinCollection
                {
                    [propName1] = 123,
                    [propName2] = "abcd"
                })
                .ConfigureAwait(false);
            }
            catch (Exception)
            {
                exceptionThrown = true;
            }

            Assert.IsTrue(exceptionThrown, "Exception was expected, but not thrown.");

            Twin serviceTwin = await registryManager.GetTwinAsync(testDevice.Id).ConfigureAwait(false);

            Assert.IsFalse(serviceTwin.Properties.Reported.Contains(propName1));
        }
        private async Task ReceiveSingleMessageWithCancellationToken(TestDeviceType type, Client.TransportType transport)
        {
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(DevicePrefix, type).ConfigureAwait(false);

            using (DeviceClient deviceClient = testDevice.CreateDeviceClient(transport))
                using (ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString))
                {
                    await deviceClient.OpenAsync().ConfigureAwait(false);

                    if (transport == Client.TransportType.Mqtt_Tcp_Only ||
                        transport == Client.TransportType.Mqtt_WebSocket_Only)
                    {
                        // Dummy ReceiveAsync to ensure mqtt subscription registration before SendAsync() is called on service client.
                        await deviceClient.ReceiveAsync(TIMESPAN_FIVE_SECONDS).ConfigureAwait(false);
                    }

                    await serviceClient.OpenAsync().ConfigureAwait(false);

                    (Message msg, string messageId, string payload, string p1Value) = ComposeC2DTestMessage();
                    await serviceClient.SendAsync(testDevice.Id, msg).ConfigureAwait(false);
                    await VerifyReceivedC2DMessageWithCancellationTokenAsync(transport, deviceClient, testDevice.Id, payload, p1Value).ConfigureAwait(false);

                    await deviceClient.CloseAsync().ConfigureAwait(false);

                    await serviceClient.CloseAsync().ConfigureAwait(false);
                }
        }
        private async Task GetSasUriAsync(Client.TransportType transport, string blobName, bool x509auth = false)
        {
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(
                Logger,
                _devicePrefix,
                x509auth?TestDeviceType.X509 : TestDeviceType.Sasl).ConfigureAwait(false);

            DeviceClient deviceClient;

            if (x509auth)
            {
                X509Certificate2 cert = Configuration.IoTHub.GetCertificateWithPrivateKey();

                var auth = new DeviceAuthenticationWithX509Certificate(testDevice.Id, cert);
                deviceClient = DeviceClient.Create(testDevice.IoTHubHostName, auth, transport);
            }
            else
            {
                deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport);
            }

            using (deviceClient)
            {
                FileUploadSasUriResponse sasUriResponse = await deviceClient.GetFileUploadSasUriAsync(new FileUploadSasUriRequest { BlobName = blobName });

                await deviceClient.CloseAsync().ConfigureAwait(false);
            }
        }
        private async Task ReceiveSingleMessage(TestDeviceType type, Client.TransportType transport)
        {
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(DevicePrefix, type).ConfigureAwait(false);

            using (DeviceClient deviceClient = testDevice.CreateDeviceClient(transport))
                using (ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString))
                {
                    await deviceClient.OpenAsync().ConfigureAwait(false);

                    if (transport == Client.TransportType.Mqtt_Tcp_Only ||
                        transport == Client.TransportType.Mqtt_WebSocket_Only)
                    {
                        _log.WriteLine("Dummy ReceiveAsync to ensure mqtt subscription registration before SendAsync() is called on service client.");
                        await deviceClient.ReceiveAsync(TimeSpan.FromSeconds(2)).ConfigureAwait(false);
                    }

                    string payload, messageId, p1Value;
                    await serviceClient.OpenAsync().ConfigureAwait(false);

                    Message msg = ComposeC2DTestMessage(out payload, out messageId, out p1Value);
                    await serviceClient.SendAsync(testDevice.Id, msg).ConfigureAwait(false);

                    await VerifyReceivedC2DMessage(transport, deviceClient, payload, p1Value).ConfigureAwait(false);

                    await deviceClient.CloseAsync().ConfigureAwait(false);

                    await serviceClient.CloseAsync().ConfigureAwait(false);
                }
        }
예제 #9
0
        public async Task BulkOperations_UpdateTwins2DevicePatch_Ok()
        {
            var tagName  = Guid.NewGuid().ToString();
            var tagValue = Guid.NewGuid().ToString();

            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(DevicePrefix).ConfigureAwait(false);

            using (RegistryManager registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString))
            {
                Twin twin = new Twin();
                twin.DeviceId      = testDevice.Id;
                twin.Tags          = new TwinCollection();
                twin.Tags[tagName] = tagValue;

                var result = await registryManager.UpdateTwins2Async(new List <Twin> {
                    twin
                }, true).ConfigureAwait(false);

                Assert.IsTrue(result.IsSuccessful, $"UpdateTwins2Async error:\n{ResultErrorsToString(result)}");

                Twin twinUpd = await registryManager.GetTwinAsync(testDevice.Id).ConfigureAwait(false);

                Assert.AreEqual(twin.DeviceId, twinUpd.DeviceId, "Device ID changed");
                Assert.IsNotNull(twinUpd.Tags, "Twin.Tags is null");
                Assert.IsTrue(twinUpd.Tags.Contains(tagName), "Twin doesn't contain the tag");
                Assert.AreEqual((string)twin.Tags[tagName], (string)twinUpd.Tags[tagName], "Tag value changed");

                await registryManager.CloseAsync().ConfigureAwait(false);
            }
        }
예제 #10
0
        private async Task ReceiveMessageInOperationTimeout(TestDeviceType type, Client.TransportType transport)
        {
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(DevicePrefix, type).ConfigureAwait(false);

            using (DeviceClient deviceClient = testDevice.CreateDeviceClient(transport))
            {
                await deviceClient.OpenAsync().ConfigureAwait(false);

                if (transport == Client.TransportType.Mqtt_Tcp_Only ||
                    transport == Client.TransportType.Mqtt_WebSocket_Only)
                {
                    // Dummy ReceiveAsync to ensure mqtt subscription registration before SendAsync() is called on service client.
                    await deviceClient.ReceiveAsync(TIMESPAN_FIVE_SECONDS).ConfigureAwait(false);
                }

                try
                {
                    deviceClient.OperationTimeoutInMilliseconds = Convert.ToUInt32(TIMESPAN_ONE_MINUTE.TotalMilliseconds);
                    if (transport == Client.TransportType.Amqp || transport == Client.TransportType.Amqp_Tcp_Only || transport == Client.TransportType.Amqp_WebSocket_Only)
                    {
                        // For AMQP because of static 1 min interval check the cancellation token, in worst case it will block upto extra 1 min to return
                        await ReceiveMessageWithoutTimeoutCheck(deviceClient, TIMESPAN_ONE_MINUTE).ConfigureAwait(false);
                    }
                    else
                    {
                        await ReceiveMessageWithoutTimeoutCheck(deviceClient, TIMESPAN_FIVE_SECONDS).ConfigureAwait(false);
                    }
                }
                finally
                {
                    deviceClient.OperationTimeoutInMilliseconds = DeviceClient.DefaultOperationTimeoutInMilliseconds;
                    await deviceClient.CloseAsync().ConfigureAwait(false);
                }
            }
        }
        private async Task ReuseAuthenticationMethod_SingleDevice(Client.TransportType transport)
        {
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false);

            var authenticationMethod = new DeviceAuthenticationSasToken(testDevice.ConnectionString, disposeWithClient: false);

            // Create an instance of the device client, send a test message and then close and dispose it.
            DeviceClient deviceClient = DeviceClient.Create(testDevice.IoTHubHostName, authenticationMethod, transport);

            using var message1 = new Client.Message();
            await deviceClient.SendEventAsync(message1).ConfigureAwait(false);

            await deviceClient.CloseAsync();

            deviceClient.Dispose();
            Logger.Trace("Test with instance 1 completed");

            // Perform the same steps again, reusing the previously created authentication method instance to ensure
            // that the sdk did not dispose the user supplied authentication method instance.
            DeviceClient deviceClient2 = DeviceClient.Create(testDevice.IoTHubHostName, authenticationMethod, transport);

            using var message2 = new Client.Message();
            await deviceClient2.SendEventAsync(message2).ConfigureAwait(false);

            await deviceClient2.CloseAsync();

            deviceClient2.Dispose();
            Logger.Trace("Test with instance 2 completed, reused the previously created authentication method instance for the device client.");

            authenticationMethod.Dispose();
        }
        private async Task AuthenticationMethodDisposesTokenRefresher(Client.TransportType transport)
        {
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false);

            var authenticationMethod = new DeviceAuthenticationSasToken(testDevice.ConnectionString, disposeWithClient: true);

            // Create an instance of the device client, send a test message and then close and dispose it.
            DeviceClient deviceClient = DeviceClient.Create(testDevice.IoTHubHostName, authenticationMethod, transport);

            using var message1 = new Client.Message();
            await deviceClient.SendEventAsync(message1).ConfigureAwait(false);

            await deviceClient.CloseAsync();

            deviceClient.Dispose();
            Logger.Trace("Test with instance 1 completed");

            // Perform the same steps again, reusing the previously created authentication method instance.
            // Since the default behavior is to dispose AuthenticationWithTokenRefresh authentication method on DeviceClient disposal,
            // this should now throw an ObjectDisposedException.
            DeviceClient deviceClient2 = DeviceClient.Create(testDevice.IoTHubHostName, authenticationMethod, transport);

            using var message2 = new Client.Message();

            Func <Task> act = async() => await deviceClient2.SendEventAsync(message2).ConfigureAwait(false);

            await act.Should().ThrowAsync <ObjectDisposedException>();
        }
        private async Task UploadFileAsync(Client.TransportType transport, string filename, bool x509auth = false)
        {
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(
                Logger,
                _devicePrefix,
                x509auth?TestDeviceType.X509 : TestDeviceType.Sasl).ConfigureAwait(false);

            DeviceClient deviceClient;

            if (x509auth)
            {
                X509Certificate2 cert = Configuration.IoTHub.GetCertificateWithPrivateKey();

                var auth = new DeviceAuthenticationWithX509Certificate(testDevice.Id, cert);
                deviceClient = DeviceClient.Create(testDevice.IoTHubHostName, auth, transport);
            }
            else
            {
                deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport);
            }

            using (deviceClient)
            {
                using (var fileStreamSource = new FileStream(filename, FileMode.Open, FileAccess.Read))
                {
                    await deviceClient.UploadToBlobAsync(filename, fileStreamSource).ConfigureAwait(false);
                }

                await deviceClient.CloseAsync().ConfigureAwait(false);
            }
        }
예제 #14
0
        private async Task Twin_ServiceDoesNotCreateNullPropertyInCollectionAsync(Client.TransportType transport)
        {
            var propName1      = Guid.NewGuid().ToString();
            var propName2      = Guid.NewGuid().ToString();
            var propEmptyValue = "{}";

            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(_devicePrefix).ConfigureAwait(false);

            using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString);
            using var deviceClient    = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport);

            await deviceClient
            .UpdateReportedPropertiesAsync(
                new TwinCollection
            {
                [propName1] = null
            })
            .ConfigureAwait(false);

            Twin serviceTwin = await registryManager.GetTwinAsync(testDevice.Id).ConfigureAwait(false);

            Assert.IsFalse(serviceTwin.Properties.Reported.Contains(propName1));

            await deviceClient
            .UpdateReportedPropertiesAsync(
                new TwinCollection
            {
                [propName1] = new TwinCollection
                {
                    [propName2] = null
                }
            })
            .ConfigureAwait(false);

            serviceTwin = await registryManager.GetTwinAsync(testDevice.Id).ConfigureAwait(false);

            Assert.IsTrue(serviceTwin.Properties.Reported.Contains(propName1));
            string value1 = serviceTwin.Properties.Reported[propName1].ToString();

            Assert.AreEqual(value1, propEmptyValue);

            await deviceClient
            .UpdateReportedPropertiesAsync(
                new TwinCollection
            {
                [propName1] = new TwinCollection
                {
                    [propName2] = null
                }
            })
            .ConfigureAwait(false);

            serviceTwin = await registryManager.GetTwinAsync(testDevice.Id).ConfigureAwait(false);

            Assert.IsTrue(serviceTwin.Properties.Reported.Contains(propName1));
            string value2 = serviceTwin.Properties.Reported[propName1].ToString();

            Assert.AreEqual(value2, propEmptyValue);
        }
        private async Task FastTimeout()
        {
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(DevicePrefixTimeout).ConfigureAwait(false);
            ServiceClient sender = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString);

            var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, Client.TransportType.Amqp);
            await sender.SendAsync(testDevice.Id, new Message(Encoding.ASCII.GetBytes("Dummy Message")), TimeSpan.FromTicks(1)).ConfigureAwait(false);
        }
예제 #16
0
        private async Task SendSingleMessage(TestDeviceType type, ITransportSettings[] transportSettings)
        {
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(DevicePrefix).ConfigureAwait(false);

            DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transportSettings);

            await SendSingleMessage(deviceClient, testDevice.Id).ConfigureAwait(false);
        }
예제 #17
0
        private async Task Twin_DeviceSetsReportedPropertyAndGetsItBackSingleDeviceAsync(Client.TransportType transport)
        {
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(_devicePrefix).ConfigureAwait(false);

            using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport);

            await Twin_DeviceSetsReportedPropertyAndGetsItBackAsync(deviceClient).ConfigureAwait(false);
        }
예제 #18
0
        private async Task SendSingleMessage(TestDeviceType type, Client.TransportType transport)
        {
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(DevicePrefix, type).ConfigureAwait(false);

            DeviceClient deviceClient = testDevice.CreateDeviceClient(transport);

            await SendSingleMessage(deviceClient, testDevice.Id).ConfigureAwait(false);
        }
예제 #19
0
        public async Task Duplicated_NoPingpong()
        {
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(DevicePrefix, TestDeviceType.Sasl).ConfigureAwait(false);

            _log.WriteLine($"{nameof(Duplicated_NoPingpong)}: 2 device client instances with the same deviceId={testDevice.Id}.");

            using (DeviceClient deviceClient1 = testDevice.CreateDeviceClient(Client.TransportType.Amqp_Tcp_Only), deviceClient2 = testDevice.CreateDeviceClient(Client.TransportType.Amqp_Tcp_Only))
            {
                _log.WriteLine($"{nameof(Duplicated_NoPingpong)}: set device client instance 1 to no retry.");
                deviceClient1.SetRetryPolicy(new NoRetry());

                ConnectionStatus?lastConnectionStatus = null;
                Dictionary <ConnectionStatus, int> connectionStatusChanges = new Dictionary <ConnectionStatus, int>();
                deviceClient1.SetConnectionStatusChangesHandler((status, reason) =>
                {
                    connectionStatusChanges.TryGetValue(status, out int count);
                    count++;
                    connectionStatusChanges[status] = count;
                    lastConnectionStatus            = status;
                });

                _log.WriteLine($"{nameof(FaultInjection_NoRecovery)}: device client instance 1 calling OpenAsync...");
                await deviceClient1.OpenAsync().ConfigureAwait(false);

                await deviceClient1.SetMethodHandlerAsync(
                    "dummy_method",
                    (methodRequest, userContext) => Task.FromResult(new MethodResponse(200)),
                    deviceClient1
                    ).ConfigureAwait(false);

                _log.WriteLine($"{nameof(FaultInjection_NoRecovery)}: device client instance 2 calling OpenAsync...");
                await deviceClient2.OpenAsync().ConfigureAwait(false);

                await deviceClient2.SetMethodHandlerAsync(
                    "dummy_method",
                    (methodRequest, userContext) => Task.FromResult(new MethodResponse(200)),
                    deviceClient2
                    ).ConfigureAwait(false);

                _log.WriteLine($"{nameof(Duplicated_NoPingpong)}: waiting device client instance 1 to be kicked off...");
                for (int i = 0; i < FaultInjection.LatencyTimeBufferInSec; i++)
                {
                    if (connectionStatusChanges.ContainsKey(ConnectionStatus.Disconnected))
                    {
                        break;
                    }
                    await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false);
                }

                Assert.AreEqual(ConnectionStatus.Disconnected, lastConnectionStatus, $"Excepeted device to be {ConnectionStatus.Disconnected} but was {lastConnectionStatus}.");
                Assert.IsFalse(connectionStatusChanges.ContainsKey(ConnectionStatus.Disconnected_Retrying), $"Shouldn't get {ConnectionStatus.Disconnected_Retrying} status change.");
                int connected = connectionStatusChanges[ConnectionStatus.Connected];
                Assert.AreEqual(1, connected, $"Should get {ConnectionStatus.Connected} once but was {connected}.");
                int disconnected = connectionStatusChanges[ConnectionStatus.Disconnected];
                Assert.AreEqual(1, disconnected, $"Should get {ConnectionStatus.Disconnected} once but was {disconnected}.");
            }
        }
예제 #20
0
        private async Task DeviceClient_TokenIsRefreshed_Internal(Client.TransportType transport)
        {
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(DevicePrefix).ConfigureAwait(false);

            int ttl    = 6;
            int buffer = 50;

            Device device = testDevice.Identity;

            var refresher = new TestTokenRefresher(
                device.Id,
                device.Authentication.SymmetricKey.PrimaryKey,
                ttl,
                buffer);

            DeviceClient deviceClient =
                DeviceClient.Create(testDevice.IoTHubHostName, refresher, transport);

            var message = new Client.Message(Encoding.UTF8.GetBytes("Hello"));

            // Create the first Token.
            Console.WriteLine($"[{DateTime.UtcNow}] OpenAsync");
            await deviceClient.OpenAsync().ConfigureAwait(false);

            Console.WriteLine($"[{DateTime.UtcNow}] SendEventAsync (1)");
            await deviceClient.SendEventAsync(message).ConfigureAwait(false);

            int countAfterOpenAndFirstSend = refresher.SafeCreateNewTokenCallCount;

            Assert.IsTrue(countAfterOpenAndFirstSend >= 1, $"[{DateTime.UtcNow}] Token should have been refreshed at least once.");

            Console.WriteLine($"[{DateTime.UtcNow}] Waiting {ttl} seconds.");

            // Wait for the Token to expire.
            await Task.Delay(ttl * 1000).ConfigureAwait(false);

            Console.WriteLine($"[{DateTime.UtcNow}] SendEventAsync (2)");
            await deviceClient.SendEventAsync(message).ConfigureAwait(false);

            // Ensure that the token was refreshed.
            if (transport == Client.TransportType.Mqtt)
            {
                // This is not currently supported for MQTT unless the connection is dropped and re-established.
                Assert.IsTrue(
                    refresher.SafeCreateNewTokenCallCount >= countAfterOpenAndFirstSend,
                    $"[{DateTime.UtcNow}] Token should have been refreshed after TTL expired.");
            }
            else
            {
                Assert.IsTrue(
                    refresher.SafeCreateNewTokenCallCount >= countAfterOpenAndFirstSend + 1,
                    $"[{DateTime.UtcNow}] Token should have been refreshed after TTL expired.");
            }

            Console.WriteLine($"[{DateTime.UtcNow}] CloseAsync");
            await deviceClient.CloseAsync().ConfigureAwait(false);
        }
        private async Task DeviceClient_TokenIsRefreshed_Internal(Client.TransportType transport, int ttl = 6)
        {
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(DevicePrefix).ConfigureAwait(false);

            int buffer = 50;

            Device device = testDevice.Identity;

            var refresher = new TestTokenRefresher(
                device.Id,
                device.Authentication.SymmetricKey.PrimaryKey,
                ttl,
                buffer,
                transport);

            DeviceClient deviceClient =
                DeviceClient.Create(testDevice.IoTHubHostName, refresher, transport);

            if (transport == Client.TransportType.Mqtt)
            {
                deviceClient.SetConnectionStatusChangesHandler((ConnectionStatus status, ConnectionStatusChangeReason reason) =>
                {
                    _log.WriteLine($"{nameof(ConnectionStatusChangesHandler)}: {status}; {reason}");
                });
            }


            var message = new Client.Message(Encoding.UTF8.GetBytes("Hello"));

            // Create the first Token.
            Console.WriteLine($"[{DateTime.UtcNow}] OpenAsync");
            await deviceClient.OpenAsync().ConfigureAwait(false);

            Console.WriteLine($"[{DateTime.UtcNow}] SendEventAsync (1)");
            await deviceClient.SendEventAsync(message).ConfigureAwait(false);

            int countAfterOpenAndFirstSend = refresher.SafeCreateNewTokenCallCount;

            Assert.IsTrue(countAfterOpenAndFirstSend >= 1, $"[{DateTime.UtcNow}] Token should have been refreshed at least once.");

            Console.WriteLine($"[{DateTime.UtcNow}] Waiting {ttl} seconds.");

            // Wait for the Token to expire.
            await Task.Delay(ttl * 1000).ConfigureAwait(false);

            Console.WriteLine($"[{DateTime.UtcNow}] SendEventAsync (2)");
            await deviceClient.SendEventAsync(message).ConfigureAwait(false);

            // Ensure that the token was refreshed.
            Assert.IsTrue(
                refresher.SafeCreateNewTokenCallCount >= countAfterOpenAndFirstSend + 1,
                $"[{DateTime.UtcNow}] Token should have been refreshed after TTL expired.");

            Console.WriteLine($"[{DateTime.UtcNow}] CloseAsync");
            await deviceClient.CloseAsync().ConfigureAwait(false);
        }
예제 #22
0
        public async Task FaultInjection_NoRecovery()
        {
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix, TestDeviceType.Sasl).ConfigureAwait(false);

            using DeviceClient deviceClient = testDevice.CreateDeviceClient(Client.TransportType.Amqp_Tcp_Only);

            Logger.Trace($"{nameof(FaultInjection_NoRecovery)}: deviceId={testDevice.Id}");
            deviceClient.SetRetryPolicy(new NoRetry());

            ConnectionStatus?lastConnectionStatus = null;
            Dictionary <ConnectionStatus, int> connectionStatusChanges = new Dictionary <ConnectionStatus, int>();

            deviceClient.SetConnectionStatusChangesHandler((status, reason) =>
            {
                connectionStatusChanges.TryGetValue(status, out int count);
                count++;
                connectionStatusChanges[status] = count;
                lastConnectionStatus            = status;
            });

            Logger.Trace($"{nameof(FaultInjection_NoRecovery)}: calling OpenAsync...");
            await deviceClient.OpenAsync().ConfigureAwait(false);

            Logger.Trace($"{nameof(FaultInjection_NoRecovery)}: injecting fault {FaultInjection.FaultType_Tcp}...");
            await FaultInjection
            .ActivateFaultInjectionAsync(
                Client.TransportType.Amqp_Tcp_Only,
                FaultInjection.FaultType_Tcp,
                FaultInjection.FaultCloseReason_Boom,
                FaultInjection.DefaultDelayInSec,
                FaultInjection.DefaultDurationInSec,
                deviceClient,
                Logger)
            .ConfigureAwait(false);

            await Task.Delay(FaultInjection.DefaultDelayInSec).ConfigureAwait(false);

            Logger.Trace($"{nameof(FaultInjection_NoRecovery)}: waiting fault injection occurs...");
            for (int i = 0; i < FaultInjection.LatencyTimeBufferInSec; i++)
            {
                if (connectionStatusChanges.ContainsKey(ConnectionStatus.Disconnected))
                {
                    break;
                }
                await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false);
            }

            Assert.AreEqual(ConnectionStatus.Disconnected, lastConnectionStatus, $"Excepeted device to be {ConnectionStatus.Disconnected} but was {lastConnectionStatus}.");
            Assert.IsFalse(connectionStatusChanges.ContainsKey(ConnectionStatus.Disconnected_Retrying), $"Shouldn't get {ConnectionStatus.Disconnected_Retrying} status change.");
            int connected = connectionStatusChanges[ConnectionStatus.Connected];

            Assert.AreEqual(1, connected, $"Should get {ConnectionStatus.Connected} once but was {connected}.");
            int disconnected = connectionStatusChanges[ConnectionStatus.Disconnected];

            Assert.AreEqual(1, disconnected, $"Should get {ConnectionStatus.Disconnected} once but was {disconnected}.");
        }
예제 #23
0
        private async Task TestTimeout(TimeSpan?timeout)
        {
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(DevicePrefix).ConfigureAwait(false);

            using (ServiceClient sender = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString))
                using (DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, Client.TransportType.Amqp))
                {
                    await sender.SendAsync(testDevice.Id, new Message(Encoding.ASCII.GetBytes("Dummy Message")), timeout).ConfigureAwait(false);
                }
        }
        private async Task TestTimeout(TimeSpan?timeout)
        {
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(DevicePrefix).ConfigureAwait(false);

            using (ServiceClient sender = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString))
            {
                _log.WriteLine($"Testing ServiceClient SendAsync() timeout={timeout}");
                await sender.SendAsync(testDevice.Id, new Message(Encoding.ASCII.GetBytes("Dummy Message")), timeout).ConfigureAwait(false);
            }
        }
        public async Task DeviceClient_Not_Exist_AMQP()
        {
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(DevicePrefix).ConfigureAwait(false);

            var config = new Configuration.IoTHub.DeviceConnectionStringParser(testDevice.ConnectionString);

            using (DeviceClient deviceClient = DeviceClient.CreateFromConnectionString($"HostName={config.IoTHub};DeviceId=device_id_not_exist;SharedAccessKey={config.SharedAccessKey}", Client.TransportType.Amqp_Tcp_Only))
            {
                await deviceClient.OpenAsync().ConfigureAwait(false);
            }
        }
        private async Task SendMessageTest(ITransportSettings transportSetting)
        {
            using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, s_devicePrefix, TestDeviceType.X509).ConfigureAwait(false);

            using DeviceClient deviceClient = testDevice.CreateDeviceClient(new[] { transportSetting });
            await deviceClient.OpenAsync().ConfigureAwait(false);

            await MessageSendE2ETests.SendSingleMessageAsync(deviceClient, testDevice.Id, Logger).ConfigureAwait(false);

            await deviceClient.CloseAsync().ConfigureAwait(false);
        }
        public async Task Message_TimeOutReachedResponse()
        {
            TimeSpan?  timeout    = TimeSpan.FromTicks(1);
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(DevicePrefix).ConfigureAwait(false);

            using (ServiceClient sender = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString))
                using (DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, Client.TransportType.Amqp))
                {
                    await sender.SendAsync(testDevice.Id, new Message(Encoding.ASCII.GetBytes($"TestTimeout {timeout?.ToString()}")), timeout).ConfigureAwait(false);
                }
        }
        public async Task DeviceClient_Bad_Credentials_AMQP()
        {
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(DevicePrefix).ConfigureAwait(false);

            var    config     = new Configuration.IoTHub.DeviceConnectionStringParser(testDevice.ConnectionString);
            string invalidKey = Convert.ToBase64String(Encoding.UTF8.GetBytes("invalid_key"));

            using (DeviceClient deviceClient = DeviceClient.CreateFromConnectionString($"HostName={config.IoTHub};DeviceId={config.DeviceID};SharedAccessKey={invalidKey}", Client.TransportType.Amqp_Tcp_Only))
            {
                await deviceClient.OpenAsync().ConfigureAwait(false);
            }
        }
예제 #29
0
        private async Task SendSingleMessage(TestDeviceType type, ITransportSettings[] transportSettings)
        {
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(DevicePrefix, type).ConfigureAwait(false);

            using (DeviceClient deviceClient = testDevice.CreateDeviceClient(transportSettings))
            {
                await deviceClient.OpenAsync().ConfigureAwait(false);
                await SendSingleMessageAndVerifyAsync(deviceClient, testDevice.Id).ConfigureAwait(false);

                await deviceClient.CloseAsync().ConfigureAwait(false);
            }
        }
        public async Task DeviceClient_CreateFromConnectionString_TokenIsRefreshed_Mqtt()
        {
            var sasTokenTimeToLive    = TimeSpan.FromSeconds(10);
            int sasTokenRenewalBuffer = 50;

            using var deviceDisconnected = new SemaphoreSlim(0);

            int operationTimeoutInMilliseconds = (int)sasTokenTimeToLive.TotalMilliseconds * 2;

            // Service allows a buffer time of upto 10mins before dropping connections that are authenticated with an expired sas tokens.
            using var tokenRefreshCts = new CancellationTokenSource((int)(sasTokenTimeToLive.TotalMilliseconds * 2 + TimeSpan.FromMinutes(10).TotalMilliseconds));

            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false);

            var options = new ClientOptions
            {
                SasTokenTimeToLive    = sasTokenTimeToLive,
                SasTokenRenewalBuffer = sasTokenRenewalBuffer,
            };

            using DeviceClient deviceClient = testDevice.CreateDeviceClient(Client.TransportType.Mqtt, options);
            Logger.Trace($"Created {nameof(DeviceClient)} instance for {testDevice.Id}.");

            deviceClient.SetConnectionStatusChangesHandler((ConnectionStatus status, ConnectionStatusChangeReason reason) =>
            {
                Logger.Trace($"{nameof(ConnectionStatusChangesHandler)}: {status}; {reason}");
                if (status == ConnectionStatus.Disconnected_Retrying || status == ConnectionStatus.Disconnected)
                {
                    deviceDisconnected.Release();
                }
            });
            deviceClient.OperationTimeoutInMilliseconds = (uint)operationTimeoutInMilliseconds;

            var message = new Client.Message(Encoding.UTF8.GetBytes("Hello"));

            Logger.Trace($"[{testDevice.Id}]: SendEventAsync (1)");
            await deviceClient.SendEventAsync(message).ConfigureAwait(false);

            // Wait for the Token to expire.
            Logger.Trace($"[{testDevice.Id}]: Waiting for device disconnect.");
            await deviceDisconnected.WaitAsync(tokenRefreshCts.Token).ConfigureAwait(false);

            try
            {
                Logger.Trace($"[{testDevice.Id}]: SendEventAsync (2)");
                await deviceClient.SendEventAsync(message).ConfigureAwait(false);
            }
            catch (OperationCanceledException ex)
            {
                Assert.Fail($"{testDevice.Id} did not refresh token after expected ttl of {sasTokenTimeToLive}: {ex}");
                throw;
            }
        }