public async Task SetDeviceReceiveMethodAsync(string methodName, string deviceResponseJson, string expectedServiceRequestJson)
        {
            await _deviceClient.SetMethodHandlerAsync(methodName,
                                                      (request, context) =>
            {
                try
                {
                    s_log.WriteLine($"{nameof(SetDeviceReceiveMethodAsync)}: DeviceClient callback method: {request.Name} {request.ResponseTimeout}.");
                    Assert.AreEqual(methodName, request.Name);
                    Assert.AreEqual(expectedServiceRequestJson, request.DataAsJson);

                    return(Task.FromResult(new MethodResponse(Encoding.UTF8.GetBytes(deviceResponseJson), 200)));
                }
                catch (Exception ex)
                {
                    s_log.WriteLine($"{nameof(SetDeviceReceiveMethodAsync)}: Error during DeviceClient callback method: {ex}.");

                    _methodExceptionDispatch = ExceptionDispatchInfo.Capture(ex);
                    return(Task.FromResult(new MethodResponse(500)));
                }
                finally
                {
                    // Always notify that we got the callback.
                    _methodCallbackSemaphore.Release();
                }
            },
                                                      null).ConfigureAwait(false);
        }
        public async Task DeviceClient_TokenConnectionDoubleRelease_Ok()
        {
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(DevicePrefix).ConfigureAwait(false);

            string 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
        }
Exemplo n.º 3
0
        private async Task <Task> SetTwinPropertyUpdateCallbackHandlerAsync(DeviceClient deviceClient, string expectedPropName, string expectedPropValue)
        {
            var    propertyUpdateReceived = new TaskCompletionSource <bool>();
            string userContext            = "myContext";

            await deviceClient.SetDesiredPropertyUpdateCallbackAsync(
                (patch, context) =>
            {
                _log.WriteLine($"{nameof(SetTwinPropertyUpdateCallbackHandlerAsync)}: DesiredProperty: {patch}, {context}");

                try
                {
                    Assert.AreEqual(expectedPropValue, patch[expectedPropName].ToString());
                    Assert.AreEqual(userContext, context, "Context");
                }
                catch (Exception e)
                {
                    propertyUpdateReceived.SetException(e);
                }
                finally
                {
                    propertyUpdateReceived.SetResult(true);
                }

                return(Task.FromResult <bool>(true));
            }, userContext).ConfigureAwait(false);

            return(propertyUpdateReceived.Task);
        }
Exemplo n.º 4
0
        private async Task Twin_DeviceSetsReportedPropertyAndGetsItBackPoolOverAmqp(
            TestDeviceType type,
            Client.TransportType transport,
            int poolSize,
            int devicesCount,
            ConnectionStringAuthScope authScope = ConnectionStringAuthScope.Device)
        {
            Func <DeviceClient, TestDevice, Task> testOperation = async(deviceClient, testDevice) =>
            {
                _log.WriteLine($"{nameof(TwinE2EPoolAmqpTests)}: Setting reported propery and verifying twin for device {testDevice.Id}");
                await TwinE2ETests.Twin_DeviceSetsReportedPropertyAndGetsItBack(deviceClient).ConfigureAwait(false);
            };

            Func <IList <DeviceClient>, Task> cleanupOperation = async(deviceClients) =>
            {
                foreach (DeviceClient deviceClient in deviceClients)
                {
                    deviceClient.Dispose();
                }
                await Task.FromResult <bool>(false).ConfigureAwait(false);
            };

            await PoolingOverAmqp.TestPoolAmqpAsync(
                DevicePrefix,
                transport,
                poolSize,
                devicesCount,
                (d, t) => { return(Task.FromResult(false)); },
                testOperation,
                cleanupOperation,
                authScope,
                true).ConfigureAwait(false);
        }
Exemplo n.º 5
0
        private async Task SendMessagePoolOverAmqp(
            TestDeviceType type,
            Client.TransportType transport,
            int poolSize,
            int devicesCount,
            ConnectionStringAuthScope authScope = ConnectionStringAuthScope.Device)
        {
            Func <DeviceClient, TestDevice, Task> testOperation = async(deviceClient, testDevice) =>
            {
                s_log.WriteLine($"{nameof(MessageSendE2EPoolAmqpTests)}: Preparing to send message for device {testDevice.Id}");
                await deviceClient.OpenAsync().ConfigureAwait(false);

                (Client.Message testMessage, string messageId, string payload, string p1Value) = MessageSendE2ETests.ComposeD2cTestMessage();
                s_log.WriteLine($"{nameof(MessageSendE2EPoolAmqpTests)}.{testDevice.Id}: messageId='{messageId}' payload='{payload}' p1Value='{p1Value}'");
                await deviceClient.SendEventAsync(testMessage).ConfigureAwait(false);

                bool isReceived = EventHubTestListener.VerifyIfMessageIsReceived(testDevice.Id, payload, p1Value);
                Assert.IsTrue(isReceived, "Message is not received.");
            };

            await PoolingOverAmqp
            .TestPoolAmqpAsync(
                _devicePrefix,
                transport,
                poolSize,
                devicesCount,
                null,
                testOperation,
                null,
                authScope,
                true)
            .ConfigureAwait(false);
        }
        // verify required message is present in the dictionary
        public static bool VerifyIfMessageIsReceived(string deviceId, string payload, string p1Value, TimeSpan?maxWaitTime = null)
        {
            if (!maxWaitTime.HasValue)
            {
                maxWaitTime = MaximumWaitTime;
            }

            s_log.WriteLine($"Expected payload: deviceId={deviceId}; payload={payload}; property1={p1Value}");

            bool isReceived = false;

            var sw = new Stopwatch();

            sw.Start();

            while (!isReceived && sw.Elapsed < maxWaitTime)
            {
                events.TryRemove(payload, out EventData eventData);
                if (eventData == null)
                {
                    continue;
                }

                isReceived = VerifyTestMessage(eventData, deviceId, p1Value);
            }

            sw.Stop();

            return(isReceived);
        }
Exemplo n.º 7
0
        private async Task SendMessagePoolOverAmqp(
            TestDeviceType type,
            Client.TransportType transport,
            int poolSize,
            int devicesCount,
            ConnectionStringAuthScope authScope = ConnectionStringAuthScope.Device)
        {
            Dictionary <string, EventHubTestListener> eventHubListeners = new Dictionary <string, EventHubTestListener>();

            Func <DeviceClient, TestDevice, Task> initOperation = async(deviceClient, testDevice) =>
            {
                EventHubTestListener testListener = await EventHubTestListener.CreateListener(testDevice.Id).ConfigureAwait(false);

                eventHubListeners.Add(testDevice.Id, testListener);
            };

            Func <DeviceClient, TestDevice, Task> testOperation = async(deviceClient, testDevice) =>
            {
                _log.WriteLine($"{nameof(MessageSendE2EPoolAmqpTests)}: Preparing to send message for device {testDevice.Id}");
                await deviceClient.OpenAsync().ConfigureAwait(false);

                (Client.Message testMessage, string messageId, string payload, string p1Value) = MessageSendE2ETests.ComposeD2CTestMessage();
                _log.WriteLine($"{nameof(MessageSendE2EPoolAmqpTests)}.{testDevice.Id}: messageId='{messageId}' payload='{payload}' p1Value='{p1Value}'");
                await deviceClient.SendEventAsync(testMessage).ConfigureAwait(false);

                EventHubTestListener testListener = eventHubListeners[testDevice.Id];
                bool isReceived = await testListener.WaitForMessage(testDevice.Id, payload, p1Value).ConfigureAwait(false);

                Assert.IsTrue(isReceived, "Message is not received.");
            };

            Func <IList <DeviceClient>, Task> cleanupOperation = async(deviceClients) =>
            {
                foreach (var listener in eventHubListeners)
                {
                    await listener.Value.CloseAsync().ConfigureAwait(false);
                }

                foreach (DeviceClient deviceClient in deviceClients)
                {
                    deviceClient.Dispose();
                }

                eventHubListeners.Clear();
            };

            await PoolingOverAmqp.TestPoolAmqpAsync(
                DevicePrefix,
                transport,
                poolSize,
                devicesCount,
                initOperation,
                testOperation,
                cleanupOperation,
                authScope).ConfigureAwait(false);
        }
Exemplo n.º 8
0
        // Fault timings:
        // --------------------------------------------------------------------------------------------------------------------------------------------------------------------
        //  --- device in normal operation --- | FaultRequested | --- <delayInSec> --- | --- Device in fault mode for <durationInSec> --- | --- device in normal operation ---
        // --------------------------------------------------------------------------------------------------------------------------------------------------------------------
        public static async Task ActivateFaultInjection(Client.TransportType transport, string faultType, string reason, int delayInSec, int durationInSec, DeviceClient deviceClient)
        {
            s_log.WriteLine($"{nameof(ActivateFaultInjection)}: Requesting fault injection type={faultType} reason={reason}, delay={delayInSec}s, duration={FaultInjection.DefaultDurationInSec}s");

            uint oldTimeout = deviceClient.OperationTimeoutInMilliseconds;

            try
            {
                // For MQTT FaultInjection will terminate the connection prior to a PUBACK
                // which leads to an infinite loop trying to resend the FaultInjection message.
                if (transport == Client.TransportType.Mqtt ||
                    transport == Client.TransportType.Mqtt_Tcp_Only ||
                    transport == Client.TransportType.Mqtt_WebSocket_Only)
                {
                    deviceClient.OperationTimeoutInMilliseconds = (uint)delayInSec * 2000;
                }

                await deviceClient.SendEventAsync(
                    FaultInjection.ComposeErrorInjectionProperties(
                        faultType,
                        reason,
                        delayInSec,
                        durationInSec)).ConfigureAwait(false);
            }
            catch (TimeoutException ex)
            {
                s_log.WriteLine($"{nameof(ActivateFaultInjection)}: {ex}");
            }
            finally
            {
                deviceClient.OperationTimeoutInMilliseconds = oldTimeout;
                s_log.WriteLine($"{nameof(ActivateFaultInjection)}: Fault injection requested.");
            }
        }
        public static async Task InitAsync()
        {
            bool gained = await s_lock.WaitAsync(s_interval).ConfigureAwait(false);

            if (gained)
            {
                try
                {
                    if (!s_receiving)
                    {
                        s_log.WriteLine("Initializing FileNotificationReceiver...");
                        ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString);
                        s_fileNotificationReceiver = serviceClient.GetFileNotificationReceiver();
                        s_log.WriteLine("Receiving once to connect FileNotificationReceiver...");
                        await s_fileNotificationReceiver.ReceiveAsync(TimeSpan.FromSeconds(1)).ConfigureAwait(false);

                        s_log.WriteLine("FileNotificationReceiver connected.");
                        _           = StartReceivingLoopAsync().ConfigureAwait(false);
                        s_receiving = true;
                    }
                }
                finally
                {
                    s_lock.Release();
                }
            }
        }
Exemplo n.º 10
0
        private Client.Message ComposeD2CTestMessage(out string payload, out string p1Value)
        {
            payload = Guid.NewGuid().ToString();
            p1Value = Guid.NewGuid().ToString();

            _log.WriteLine($"{nameof(ComposeD2CTestMessage)}: payload='{payload}' p1Value='{p1Value}'");

            return(new Client.Message(Encoding.UTF8.GetBytes(payload))
            {
                Properties = { ["property1"] = p1Value }
            });
        }
Exemplo n.º 11
0
        public async Task FaultInjection_NoRecovery()
        {
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(DevicePrefix, TestDeviceType.Sasl).ConfigureAwait(false);

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

            _log.WriteLine($"{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;
            });

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

            _log.WriteLine($"{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)
            .ConfigureAwait(false);

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

            _log.WriteLine($"{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}.");
        }
        public static Message ComposeC2DTestMessage(out string payload, out string messageId, out string p1Value)
        {
            payload   = Guid.NewGuid().ToString();
            messageId = Guid.NewGuid().ToString();
            p1Value   = Guid.NewGuid().ToString();

            s_log.WriteLine($"{nameof(ComposeC2DTestMessage)}: payload='{payload}' messageId='{messageId}' p1Value='{p1Value}'");

            return(new Message(Encoding.UTF8.GetBytes(payload))
            {
                MessageId = messageId,
                Properties = { ["property1"] = p1Value }
            });
        }
        public static (Message message, string messageId, string payload, string p1Value) ComposeC2DTestMessage()
        {
            var payload   = Guid.NewGuid().ToString();
            var messageId = Guid.NewGuid().ToString();
            var p1Value   = Guid.NewGuid().ToString();

            _log.WriteLine($"{nameof(ComposeC2DTestMessage)}: messageId='{messageId}' payload='{payload}' p1Value='{p1Value}'");
            var message = new Message(Encoding.UTF8.GetBytes(payload))
            {
                MessageId  = messageId,
                Properties = { ["property1"] = p1Value }
            };

            return(message, messageId, payload, p1Value);
        }
Exemplo n.º 14
0
        private async Task ServiceSendMethodAndVerifyResponse(string deviceName, string methodName, string respJson, string reqJson)
        {
            ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString);

            _log.WriteLine($"{nameof(ServiceSendMethodAndVerifyResponse)}: Invoke method {methodName}.");
            CloudToDeviceMethodResult response =
                await serviceClient.InvokeDeviceMethodAsync(
                    deviceName,
                    new CloudToDeviceMethod(methodName, TimeSpan.FromMinutes(5)).SetPayloadJson(reqJson)).ConfigureAwait(false);

            _log.WriteLine($"{nameof(ServiceSendMethodAndVerifyResponse)}: Method status: {response.Status}.");
            Assert.AreEqual(200, response.Status);
            Assert.AreEqual(respJson, response.GetPayloadAsJson());

            await serviceClient.CloseAsync().ConfigureAwait(false);
        }
Exemplo n.º 15
0
        public static async Task Twin_DeviceSetsReportedPropertyAndGetsItBack(DeviceClient deviceClient)
        {
            var propName  = Guid.NewGuid().ToString();
            var propValue = Guid.NewGuid().ToString();

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

            TwinCollection props = new TwinCollection();

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

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

            Assert.AreEqual <String>(deviceTwin.Properties.Reported[propName].ToString(), propValue);
        }
        private async Task ServiceSendMethodAndVerifyResponseAsync(string deviceName, string methodName, string respJson, string reqJson)
        {
            var sw = new Stopwatch();

            sw.Start();
            bool done = false;
            ExceptionDispatchInfo exceptionDispatchInfo = null;
            int attempt = 0;

            while (!done && sw.ElapsedMilliseconds < FaultInjection.RecoveryTimeMilliseconds)
            {
                attempt++;
                try
                {
                    using ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString);

                    s_log.WriteLine($"{nameof(ServiceSendMethodAndVerifyResponseAsync)}: Invoke method {methodName}.");
                    CloudToDeviceMethodResult response =
                        await serviceClient
                        .InvokeDeviceMethodAsync(
                            deviceName,
                            new CloudToDeviceMethod(methodName, TimeSpan.FromMinutes(5)).SetPayloadJson(reqJson))
                        .ConfigureAwait(false);

                    s_log.WriteLine($"{nameof(ServiceSendMethodAndVerifyResponseAsync)}: Method status: {response.Status}.");

                    Assert.AreEqual(200, response.Status, $"The expected respose status should be 200 but was {response.Status}");
                    string payload = response.GetPayloadAsJson();
                    Assert.AreEqual(respJson, payload, $"The expected respose payload should be {respJson} but was {payload}");

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

                    done = true;
                }
                catch (DeviceNotFoundException ex)
                {
                    exceptionDispatchInfo = ExceptionDispatchInfo.Capture(ex);
                    s_log.WriteLine($"{nameof(ServiceSendMethodAndVerifyResponseAsync)}: [Tried {attempt} time(s)] ServiceClient exception caught: {ex}.");
                    await Task.Delay(1000).ConfigureAwait(false);
                }
            }

            if (!done && (exceptionDispatchInfo != null))
            {
                exceptionDispatchInfo.Throw();
            }
        }
        private async Task Twin_DeviceDesiredPropertyUpdateRecoveryAsync(
            Client.TransportType transport,
            string faultType,
            string reason,
            int delayInSec)
        {
            TestDeviceCallbackHandler testDeviceCallbackHandler = null;
            var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString);

            using var cts = new CancellationTokenSource(FaultInjection.RecoveryTimeMilliseconds);

            var propName = Guid.NewGuid().ToString();
            var props    = new TwinCollection();

            // Configure the callback and start accepting twin changes.
            Func <DeviceClient, TestDevice, Task> initOperation = async(deviceClient, testDevice) =>
            {
                testDeviceCallbackHandler = new TestDeviceCallbackHandler(deviceClient);
                await testDeviceCallbackHandler.SetTwinPropertyUpdateCallbackHandlerAsync(propName).ConfigureAwait(false);
            };

            // Change the twin from the service side and verify the device received it.
            Func <DeviceClient, TestDevice, Task> testOperation = async(deviceClient, testDevice) =>
            {
                var propValue = Guid.NewGuid().ToString();
                testDeviceCallbackHandler.ExpectedTwinPropertyValue = propValue;

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

                Task serviceSendTask  = RegistryManagerUpdateDesiredPropertyAsync(testDevice.Id, propName, propValue);
                Task twinReceivedTask = testDeviceCallbackHandler.WaitForTwinCallbackAsync(cts.Token);

                var tasks = new List <Task>()
                {
                    serviceSendTask, twinReceivedTask
                };
                while (tasks.Count > 0)
                {
                    Task completedTask = await Task.WhenAny(tasks).ConfigureAwait(false);

                    completedTask.GetAwaiter().GetResult();
                    tasks.Remove(completedTask);
                }
            };

            await FaultInjection
            .TestErrorInjectionAsync(
                s_devicePrefix,
                TestDeviceType.Sasl,
                transport,
                faultType,
                reason,
                delayInSec,
                FaultInjection.DefaultDurationInSec,
                initOperation,
                testOperation,
                () => { return(Task.FromResult(false)); })
            .ConfigureAwait(false);
        }
        private async Task ServiceSendMethodAndVerifyResponse(string deviceName, string methodName, string respJson, string reqJson)
        {
            var sw = new Stopwatch();

            sw.Start();
            bool done = false;
            ExceptionDispatchInfo exceptionDispatchInfo = null;

            while (!done && sw.ElapsedMilliseconds < FaultInjection.RecoveryTimeMilliseconds)
            {
                try
                {
                    using (ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString))
                    {
                        s_log.WriteLine($"{nameof(ServiceSendMethodAndVerifyResponse)}: Invoke method {methodName}.");
                        CloudToDeviceMethodResult response =
                            await serviceClient.InvokeDeviceMethodAsync(
                                deviceName,
                                new CloudToDeviceMethod(methodName, TimeSpan.FromMinutes(5)).SetPayloadJson(reqJson)).ConfigureAwait(false);

                        s_log.WriteLine($"{nameof(ServiceSendMethodAndVerifyResponse)}: Method status: {response.Status}.");

                        // This is a simple hack to ensure that we're still exercising these tests while we address the race conditions causing the following issues:
                        // [Ignore] // TODO: #571
                        // [Ignore] // TODO: #558
                        //Assert.AreEqual(200, response.Status);
                        //Assert.AreEqual(respJson, response.GetPayloadAsJson());

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

                        done = true;
                    }
                }
                catch (DeviceNotFoundException ex)
                {
                    exceptionDispatchInfo = ExceptionDispatchInfo.Capture(ex);
                    s_log.WriteLine($"{nameof(ServiceSendMethodAndVerifyResponse)}: ServiceClient exception caught: {ex}.");
                    await Task.Delay(1000).ConfigureAwait(false);
                }
            }

            if (exceptionDispatchInfo != null)
            {
                exceptionDispatchInfo.Throw();
            }
        }
        public static (Client.Message message, string messageId, string payload, string p1Value) ComposeD2cTestMessage()
        {
            string messageId = Guid.NewGuid().ToString();
            string payload   = Guid.NewGuid().ToString();
            string p1Value   = Guid.NewGuid().ToString();

            _log.WriteLine($"{nameof(ComposeD2cTestMessage)}: messageId='{messageId}' payload='{payload}' p1Value='{p1Value}'");
            var message = new Client.Message(Encoding.UTF8.GetBytes(payload))
            {
                MessageId = messageId,
            };

            message.Properties.Add("property1", p1Value);
            message.Properties.Add("property2", null);

            return(message, messageId, payload, p1Value);
        }
        private async Task ReceiveMessagePoolOverAmqp(
            Client.TransportType transport,
            int poolSize,
            int devicesCount,
            ConnectionStringAuthScope authScope = ConnectionStringAuthScope.Device)
        {
            Dictionary <string, List <string> > messagesSent = new Dictionary <string, List <string> >();

            // Initialize the service client
            ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString);

            Func <DeviceClient, TestDevice, Task> initOperation = async(deviceClient, testDevice) =>
            {
                (Message msg, string messageId, string payload, string p1Value) = MessageReceiveE2ETests.ComposeC2DTestMessage();
                messagesSent.Add(testDevice.Id, new List <string> {
                    payload, p1Value
                });

                await serviceClient.SendAsync(testDevice.Id, msg).ConfigureAwait(false);
            };

            Func <DeviceClient, TestDevice, Task> testOperation = async(deviceClient, testDevice) =>
            {
                _log.WriteLine($"{nameof(MessageReceiveE2EPoolAmqpTests)}: Preparing to receive message for device {testDevice.Id}");
                await deviceClient.OpenAsync().ConfigureAwait(false);

                List <string> msgSent = messagesSent[testDevice.Id];
                string        payload = msgSent[0];
                string        p1Value = msgSent[1];

                await MessageReceiveE2ETests.VerifyReceivedC2DMessageAsync(transport, deviceClient, testDevice.Id, payload, p1Value).ConfigureAwait(false);
            };

            Func <IList <DeviceClient>, Task> cleanupOperation = async(deviceClients) =>
            {
                await serviceClient.CloseAsync().ConfigureAwait(false);

                serviceClient.Dispose();

                foreach (DeviceClient deviceClient in deviceClients)
                {
                    deviceClient.Dispose();
                }

                messagesSent.Clear();
            };

            await PoolingOverAmqp.TestPoolAmqpAsync(
                DevicePrefix,
                transport,
                poolSize,
                devicesCount,
                initOperation,
                testOperation,
                cleanupOperation,
                authScope,
                true).ConfigureAwait(false);
        }
        public static async Task ServiceSendMethodAndVerifyResponse(string deviceName, string methodName, string respJson, string reqJson)
        {
            using (ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString))
            {
                _log.WriteLine($"{nameof(ServiceSendMethodAndVerifyResponse)}: Invoke method {methodName}.");
                CloudToDeviceMethodResult response =
                    await serviceClient.InvokeDeviceMethodAsync(
                        deviceName,
                        new CloudToDeviceMethod(methodName, TimeSpan.FromMinutes(5)).SetPayloadJson(reqJson)).ConfigureAwait(false);

                _log.WriteLine($"{nameof(ServiceSendMethodAndVerifyResponse)}: Method status: {response.Status}.");
                Assert.AreEqual(200, response.Status, $"The expected respose status should be 200 but was {response.Status}");
                string payload = response.GetPayloadAsJson();
                Assert.AreEqual(respJson, payload, $"The expected respose payload should be {respJson} but was {payload}");

                await serviceClient.CloseAsync().ConfigureAwait(false);
            }
        }
        private async Task ReceiveAsync()
        {
            IEnumerable <EventData> eventDatas = await _receiver.ReceiveAsync(int.MaxValue, TimeSpan.FromSeconds(OperationTimeoutInSeconds)).ConfigureAwait(false);

            if (eventDatas == null)
            {
                s_log.WriteLine($"{nameof(EventHubTestListener)}.{nameof(VerifyTestMessage)}: no events received.");
            }
            else
            {
                s_log.WriteLine($"{nameof(EventHubTestListener)}.{nameof(VerifyTestMessage)}: {eventDatas.Count()} events received.");
                foreach (EventData eventData in eventDatas)
                {
                    string body = GetEventDataBody(eventData);
                    events[body] = eventData;
                }
            }
        }
        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);
            }
        }
Exemplo n.º 24
0
        private async Task TestTimeout(TimeSpan?timeout)
        {
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(DevicePrefix).ConfigureAwait(false);

            using (ServiceClient sender = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString))
            {
                Stopwatch sw = new Stopwatch();
                sw.Start();

                _log.WriteLine($"Testing ServiceClient SendAsync() timeout in ticks={timeout?.Ticks}");
                try
                {
                    await sender.SendAsync(testDevice.Id, new Message(Encoding.ASCII.GetBytes("Dummy Message")), timeout).ConfigureAwait(false);
                }
                finally
                {
                    sw.Stop();
                    _log.WriteLine($"Testing ServiceClient SendAsync(): exiting test after time={sw.Elapsed}; ticks={sw.ElapsedTicks}");
                }
            }
        }
Exemplo n.º 25
0
        private async Task SendMethodAndRespondPoolOverAmqp(
            Client.TransportType transport,
            int poolSize,
            int devicesCount,
            Func <DeviceClient, string, Task <Task> > setDeviceReceiveMethod,
            ConnectionStringAuthScope authScope = ConnectionStringAuthScope.Device)
        {
            Func <DeviceClient, TestDevice, Task> initOperation = async(deviceClient, testDevice) =>
            {
                _log.WriteLine($"{nameof(MethodE2EPoolAmqpTests)}: Setting method for device {testDevice.Id}");
                Task methodReceivedTask = await setDeviceReceiveMethod(deviceClient, MethodName).ConfigureAwait(false);
            };

            Func <DeviceClient, TestDevice, Task> testOperation = async(deviceClient, testDevice) =>
            {
                _log.WriteLine($"{nameof(MethodE2EPoolAmqpTests)}: Preparing to receive method for device {testDevice.Id}");
                await MethodE2ETests.ServiceSendMethodAndVerifyResponse(
                    testDevice.Id, MethodName, MethodE2ETests.DeviceResponseJson, MethodE2ETests.ServiceRequestJson).ConfigureAwait(false);
            };

            Func <IList <DeviceClient>, Task> cleanupOperation = async(deviceClients) =>
            {
                foreach (DeviceClient deviceClient in deviceClients)
                {
                    deviceClient.Dispose();
                }
                await Task.FromResult <bool>(false).ConfigureAwait(false);
            };

            await PoolingOverAmqp.TestPoolAmqpAsync(
                DevicePrefix,
                transport,
                poolSize,
                devicesCount,
                initOperation,
                testOperation,
                cleanupOperation,
                authScope,
                true).ConfigureAwait(false);
        }
Exemplo n.º 26
0
        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).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.");
        }
Exemplo n.º 27
0
        /// <summary>
        /// Factory method.
        /// </summary>
        /// <param name="namePrefix"></param>
        /// <param name="type"></param>
        public static async Task <TestDevice> GetTestDeviceAsync(string namePrefix, TestDeviceType type = TestDeviceType.Sasl)
        {
            string prefix = namePrefix + type + "_";

            try
            {
                await s_semaphore.WaitAsync().ConfigureAwait(false);

                TestDevice ret = await CreateDeviceAsync(type, prefix).ConfigureAwait(false);

                s_log.WriteLine($"{nameof(GetTestDeviceAsync)}: Using device {ret.Id}.");
                return(ret);
            }
            finally
            {
                s_semaphore.Release();
            }
        }
        private async Task Twin_DeviceSetsReportedPropertyAndGetsItBackPoolOverAmqp(
            TestDeviceType type,
            Client.TransportType transport,
            int poolSize,
            int devicesCount,
            ConnectionStringAuthScope authScope = ConnectionStringAuthScope.Device)
        {
            Func <DeviceClient, TestDevice, Task> testOperation = async(deviceClient, testDevice) =>
            {
                s_log.WriteLine($"{nameof(TwinE2EPoolAmqpTests)}: Setting reported propery and verifying twin for device {testDevice.Id}");
                await TwinE2ETests.Twin_DeviceSetsReportedPropertyAndGetsItBackAsync(deviceClient, Guid.NewGuid().ToString()).ConfigureAwait(false);
            };

            await PoolingOverAmqp.TestPoolAmqpAsync(
                _devicePrefix,
                transport,
                poolSize,
                devicesCount,
                null,
                testOperation,
                null,
                authScope,
                true).ConfigureAwait(false);
        }
Exemplo n.º 29
0
        private async Task UploadFile(Client.TransportType transport, string filename, bool x509auth = false)
        {
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(
                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 (ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString))
                {
                    FileNotificationReceiver <FileNotification> notificationReceiver = serviceClient.GetFileNotificationReceiver();
                    using (FileStream fileStreamSource = new FileStream(filename, FileMode.Open, FileAccess.Read))
                    {
                        await deviceClient.UploadToBlobAsync(filename, fileStreamSource).ConfigureAwait(false);
                    }

                    FileNotification fileNotification = await VerifyFileNotification(notificationReceiver, testDevice.Id).ConfigureAwait(false);

                    // The following checks allow running these tests multiple times in parallel.
                    // Notifications for one of the test-run instances may be received by the other test-run.

                    Assert.IsNotNull(fileNotification, "FileNotification is not received.");
                    _log.WriteLine($"TestDevice: '{testDevice.Id}', blobName: '{fileNotification.BlobName}', size: {fileNotification.BlobSizeInBytes}");
                    Assert.IsFalse(string.IsNullOrEmpty(fileNotification.BlobUri), "File notification blob uri is null or empty");
                    await deviceClient.CloseAsync().ConfigureAwait(false);

                    await serviceClient.CloseAsync().ConfigureAwait(false);
                }
        }
Exemplo n.º 30
0
        /// <summary>
        /// Factory method.
        /// IMPORTANT: Not thread safe!
        /// </summary>
        /// <param name="namePrefix"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public static async Task <TestDevice> GetTestDeviceAsync(string namePrefix, TestDeviceType type = TestDeviceType.Sasl)
        {
            string prefix = namePrefix + type + "_";

            if (!s_deviceCache.TryGetValue(prefix, out TestDevice testDevice))
            {
                string deviceName = prefix + Guid.NewGuid();
                s_log.WriteLine($"{nameof(GetTestDeviceAsync)}: Device with prefix {prefix} not found. Removing old devices.");

                // Delete existing devices named this way and create a new one.
                RegistryManager rm = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString);

                s_log.WriteLine($"{nameof(GetTestDeviceAsync)}: Creating device {deviceName} with type {type}.");

                Client.IAuthenticationMethod auth = null;

                Device requestDevice = new Device(deviceName);
                if (type == TestDeviceType.X509)
                {
                    requestDevice.Authentication = new AuthenticationMechanism()
                    {
                        X509Thumbprint = new X509Thumbprint()
                        {
                            PrimaryThumbprint = Configuration.IoTHub.GetCertificateWithPrivateKey().Thumbprint
                        }
                    };

                    auth = new DeviceAuthenticationWithX509Certificate(deviceName, Configuration.IoTHub.GetCertificateWithPrivateKey());
                }

                Device device = await rm.AddDeviceAsync(requestDevice).ConfigureAwait(false);

                s_log.WriteLine($"{nameof(GetTestDeviceAsync)}: Pausing for {DelayAfterDeviceCreationSeconds}s after device was created.");
                await Task.Delay(DelayAfterDeviceCreationSeconds * 1000).ConfigureAwait(false);

                s_deviceCache[prefix] = new TestDevice(device, auth);

                await rm.CloseAsync().ConfigureAwait(false);
            }

            TestDevice ret = s_deviceCache[prefix];

            s_log.WriteLine($"{nameof(GetTestDeviceAsync)}: Using device {ret.Id}.");
            return(ret);
        }