public async Task DeviceClient_TokenConnectionDoubleRelease_Ok()
        {
            using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false);

            string deviceConnectionString = testDevice.ConnectionString;

            var    config   = new TestConfiguration.IoTHub.ConnectionStringParser(deviceConnectionString);
            string iotHub   = config.IotHubHostName;
            string deviceId = config.DeviceID;
            string key      = config.SharedAccessKey;

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

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

            using var deviceClient = DeviceClient.Create(iotHub, auth, Client.TransportType.Amqp_Tcp_Only);
            Logger.Trace($"{deviceId}: Created {nameof(DeviceClient)} ID={TestLogger.IdOf(deviceClient)}");

            Logger.Trace($"{deviceId}: DeviceClient OpenAsync.");
            await deviceClient.OpenAsync().ConfigureAwait(false);

            Logger.Trace($"{deviceId}: DeviceClient SendEventAsync.");
            using var testMessage = new Client.Message(Encoding.UTF8.GetBytes("TestMessage"));
            await deviceClient.SendEventAsync(testMessage).ConfigureAwait(false);

            Logger.Trace($"{deviceId}: DeviceClient CloseAsync.");
            await deviceClient.CloseAsync().ConfigureAwait(false);
        }
        public async Task DeviceClient_Not_Exist_AMQP()
        {
            using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false);

            var config = new TestConfiguration.IoTHub.ConnectionStringParser(testDevice.ConnectionString);

            using (var deviceClient = DeviceClient.CreateFromConnectionString($"HostName={config.IotHubHostName};DeviceId=device_id_not_exist;SharedAccessKey={config.SharedAccessKey}", Client.TransportType.Amqp_Tcp_Only))
            {
                await deviceClient.OpenAsync().ConfigureAwait(false);
            }
        }
        public async Task DeviceClient_Bad_Credentials_AMQP()
        {
            using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false);

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

            using (var deviceClient = DeviceClient.CreateFromConnectionString($"HostName={config.IotHubHostName};DeviceId={config.DeviceID};SharedAccessKey={invalidKey}", Client.TransportType.Amqp_Tcp_Only))
            {
                await deviceClient.OpenAsync().ConfigureAwait(false);
            }
        }
        private async Task DeviceClient_Gives_ConnectionStatus_DeviceDisabled_Base(
            Client.TransportType protocol, Func <RegistryManager, string, Task> registryManagerOperation)
        {
            using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix + $"_{Guid.NewGuid()}").ConfigureAwait(false);

            string deviceConnectionString = testDevice.ConnectionString;

            var    config   = new TestConfiguration.IoTHub.ConnectionStringParser(deviceConnectionString);
            string deviceId = config.DeviceID;

            ConnectionStatus?            status             = null;
            ConnectionStatusChangeReason?statusChangeReason = null;
            int deviceDisabledReceivedCount = 0;

            using (var deviceClient = DeviceClient.CreateFromConnectionString(deviceConnectionString, protocol))
            {
                ConnectionStatusChangesHandler statusChangeHandler = (s, r) =>
                {
                    if (r == ConnectionStatusChangeReason.Device_Disabled)
                    {
                        status             = s;
                        statusChangeReason = r;
                        deviceDisabledReceivedCount++;
                    }
                };

                deviceClient.SetConnectionStatusChangesHandler(statusChangeHandler);
                Logger.Trace($"{nameof(DeviceClient_Gives_ConnectionStatus_DeviceDisabled_Base)}: Created {nameof(DeviceClient)} with device Id={testDevice.Id}");

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

                // Receiving the module twin should succeed right now.
                Logger.Trace($"{nameof(DeviceClient_Gives_ConnectionStatus_DeviceDisabled_Base)}: DeviceClient GetTwinAsync.");
                Shared.Twin twin = await deviceClient.GetTwinAsync().ConfigureAwait(false);

                Assert.IsNotNull(twin);

                // Delete/disable the device in IoT hub. This should trigger the ConnectionStatusChangesHandler.
                using (var registryManager = RegistryManager.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString))
                {
                    await registryManagerOperation(registryManager, deviceId).ConfigureAwait(false);
                }

                Logger.Trace($"{nameof(DeviceClient_Gives_ConnectionStatus_DeviceDisabled_Base)}: Completed RegistryManager operation.");

                // Artificial sleep waiting for the connection status change handler to get triggered.
                int sleepCount = 50;
                for (int i = 0; i < sleepCount; i++)
                {
                    await Task.Delay(TimeSpan.FromSeconds(10)).ConfigureAwait(false);

                    if (deviceDisabledReceivedCount == 1)
                    {
                        break;
                    }
                }

                Logger.Trace($"{nameof(DeviceClient_Gives_ConnectionStatus_DeviceDisabled_Base)}: Asserting connection status change.");

                Assert.AreEqual(1, deviceDisabledReceivedCount);
                Assert.AreEqual(ConnectionStatus.Disconnected, status);
                Assert.AreEqual(ConnectionStatusChangeReason.Device_Disabled, statusChangeReason);
            }
        }