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); }
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); } }
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); } }
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); } }
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); }
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); }
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); }
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); }
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}."); } }
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); }
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}."); }
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); } }
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; } }