コード例 #1
0
        /* Commented multi gateway tests as they make C2D tests flaky for now
         * [RetryFact]
         * public Task Test_OTAA_Unconfirmed_Receives_Confirmed_C2D_Message_MultiGw()
         * {
         *  var device = TestFixtureCi.GetDeviceByPropertyName(nameof(TestFixtureCi.Device14_OTAA_MultiGw));
         *  LogTestStart(device);
         *  return Test_OTAA_Unconfirmed_Receives_Confirmed_C2D_Message(device);
         * }
         */

        // Ensures that C2D messages are received when working with unconfirmed messages
        // Uses Device10_OTAA
        private async Task Test_OTAA_Unconfirmed_Receives_Confirmed_C2D_Message(TestDeviceInfo device)
        {
            const int messagesToSend     = 10;
            const int warmUpMessageCount = 2;

            await ArduinoDevice.setDeviceModeAsync(LoRaArduinoSerial._device_mode_t.LWOTAA);

            await ArduinoDevice.setIdAsync(device.DevAddr, device.DeviceID, device.AppEui);

            await ArduinoDevice.setKeyAsync(device.NwkSKey, device.AppSKey, device.AppKey);

            await ArduinoDevice.SetupLora(TestFixtureCi.Configuration);

            await TestFixture.CleanupC2DDeviceQueueAsync(device.DeviceID);

            var joinSucceeded = await ArduinoDevice.setOTAAJoinAsyncWithRetry(LoRaArduinoSerial._otaa_join_cmd_t.JOIN, 20000, 5);

            Assert.True(joinSucceeded, "Join failed");

            // wait 1 second after joined
            await Task.Delay(Constants.DELAY_FOR_SERIAL_AFTER_JOIN);

            if (device.IsMultiGw)
            {
                await TestFixtureCi.WaitForTwinSyncAfterJoinAsync(ArduinoDevice.SerialLogs, device.DevEui);
            }

            // Sends 2x unconfirmed messages
            for (var i = 1; i <= warmUpMessageCount; ++i)
            {
                var msg = PayloadGenerator.Next().ToString(CultureInfo.InvariantCulture);
                Log($"{device.DeviceID}: Sending unconfirmed '{msg}' {i}/{messagesToSend}");

                await ArduinoDevice.transferPacketAsync(msg, 10);

                await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES);

                await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", ArduinoDevice.SerialLogs);

                TestFixtureCi.ClearLogs();
            }

            // sends C2D - between 10 and 99
            var c2dMessageBody = (100 + random.Next(90)).ToString(CultureInfo.InvariantCulture);
            var msgId          = Guid.NewGuid().ToString();
            var c2dMessage     = new LoRaCloudToDeviceMessage()
            {
                Payload   = c2dMessageBody,
                Fport     = FramePorts.App1,
                MessageId = msgId,
                Confirmed = true,
            };

            await TestFixtureCi.SendCloudToDeviceMessageAsync(device.DeviceID, c2dMessage);

            Log($"Message {c2dMessageBody} sent to device, need to check if it receives");

            var foundC2DMessageCount    = 0;
            var foundReceivePacketCount = 0;
            var expectedRxSerial        = $"+MSG: PORT: 1; RX: \"{ToHexString(c2dMessageBody)}\"";
            var expectedTcpMessageV1    = $"{device.DevAddr}: ConfirmedDataDown";
            var expectedTcpMessageV2    = $"{device.DeviceID}: cloud to device message: {ToHexString(c2dMessageBody)}, id: {msgId}, fport: 1, confirmed: True";

            Log($"Expected C2D received log is: {expectedRxSerial}");
            Log($"Expected TCP log starting with: {expectedTcpMessageV1} or {expectedTcpMessageV2}");

            // Sends 8x unconfirmed messages, stopping if C2D message is found
            for (var i = warmUpMessageCount + 1; i <= messagesToSend; ++i)
            {
                var msg = PayloadGenerator.Next().ToString(CultureInfo.InvariantCulture);
                Log($"{device.DeviceID}: Sending unconfirmed '{msg}' {i}/{messagesToSend}");
                await ArduinoDevice.transferPacketAsync(msg, 10);

                await Task.Delay(Constants.DELAY_FOR_SERIAL_AFTER_SENDING_PACKET);

                await AssertUtils.ContainsWithRetriesAsync("+MSG: Done", ArduinoDevice.SerialLogs);

                // check if c2d message was found
                var searchResults = await TestFixtureCi.SearchNetworkServerModuleAsync(
                    (messageBody) =>
                {
                    return(messageBody.StartsWith(expectedTcpMessageV1, StringComparison.OrdinalIgnoreCase) || messageBody.StartsWith(expectedTcpMessageV2, StringComparison.OrdinalIgnoreCase));
                },
                    new SearchLogOptions($"{expectedTcpMessageV1} or {expectedTcpMessageV2}")
                {
                    MaxAttempts = 1
                });

                // We should only receive the message once
                if (searchResults.Found)
                {
                    foundC2DMessageCount++;
                    Log($"{device.DeviceID}: Found C2D message in log (after sending {i}/{messagesToSend}) {foundC2DMessageCount} times");
                    EnsureNotSeenTooManyTimes(foundC2DMessageCount);
                }

                var localFoundCloudToDeviceInSerial = ArduinoDevice.SerialLogs.Contains(expectedRxSerial);
                if (localFoundCloudToDeviceInSerial)
                {
                    foundReceivePacketCount++;
                    Log($"{device.DeviceID}: Found C2D message in serial logs (after sending {i}/{messagesToSend}) {foundReceivePacketCount} times");
                    EnsureNotSeenTooManyTimes(foundReceivePacketCount);
                }

                TestFixtureCi.ClearLogs();

                await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES);
            }

            Assert.True(foundC2DMessageCount > 0, $"Did not find {expectedTcpMessageV1} or {expectedTcpMessageV2} in logs");

            // checks if log arrived
            if (foundReceivePacketCount == 0)
            {
                if (ArduinoDevice.SerialLogs.Contains(expectedRxSerial))
                {
                    foundReceivePacketCount++;
                }
            }

            Assert.True(foundReceivePacketCount > 0, $"Could not find lora receiving message '{expectedRxSerial}'");
        }
コード例 #2
0
        public async Task Test_OTAA_Confirmed_Receives_C2D_Message_With_RX_Delay_2()
        {
            const int messagesToSend     = 10;
            const int warmUpMessageCount = 2;
            var       device             = TestFixtureCi.Device9_OTAA;

            LogTestStart(device);

            await ArduinoDevice.setDeviceModeAsync(LoRaArduinoSerial._device_mode_t.LWOTAA);

            await ArduinoDevice.setIdAsync(device.DevAddr, device.DeviceID, device.AppEui);

            await ArduinoDevice.setKeyAsync(device.NwkSKey, device.AppSKey, device.AppKey);

            await ArduinoDevice.SetupLora(TestFixtureCi.Configuration);

            await TestFixture.CleanupC2DDeviceQueueAsync(device.DeviceID);

            var joinSucceeded = await ArduinoDevice.setOTAAJoinAsyncWithRetry(LoRaArduinoSerial._otaa_join_cmd_t.JOIN, 20000, 5);

            Assert.True(joinSucceeded, "Join failed");

            // find the gateway that accepted the join
            const string expectedLog = "JoinAccept";
            var          joinAccept  = await TestFixtureCi.SearchNetworkServerModuleAsync((s) => s.IndexOf(expectedLog, StringComparison.OrdinalIgnoreCase) != -1, new SearchLogOptions(expectedLog));

            Assert.NotNull(joinAccept);
            Assert.NotNull(joinAccept.MatchedEvent);

            var targetGw = joinAccept.MatchedEvent.SourceId;

            Assert.Equal(device.GatewayID, targetGw);

            // wait 1 second after joined
            await Task.Delay(Constants.DELAY_FOR_SERIAL_AFTER_JOIN);

            // Sends 2x confirmed messages
            for (var i = 1; i <= warmUpMessageCount; ++i)
            {
                var msg = PayloadGenerator.Next().ToString(CultureInfo.InvariantCulture);
                Log($"{device.DeviceID}: Sending confirmed '{msg}' {i}/{messagesToSend}");

                await ArduinoDevice.transferPacketWithConfirmedAsync(msg, 10);

                await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES);

                // +CMSG: ACK Received
                await AssertUtils.ContainsWithRetriesAsync("+CMSG: ACK Received", ArduinoDevice.SerialLogs);

                TestFixtureCi.ClearLogs();
            }

            // sends C2D - between 10 and 99
            var c2dMessageBody = (100 + random.Next(90)).ToString(CultureInfo.InvariantCulture);
            var c2dMessage     = new LoRaCloudToDeviceMessage()
            {
                Payload   = c2dMessageBody,
                Fport     = FramePorts.App1,
                MessageId = Guid.NewGuid().ToString(),
            };

            await TestFixtureCi.SendCloudToDeviceMessageAsync(device.DeviceID, c2dMessage);

            Log($"Message {c2dMessageBody} sent to device, need to check if it receives");

            var foundC2DMessageCount    = 0;
            var foundReceivePacketCount = 0;
            var expectedRxSerial        = $"+CMSG: PORT: 1; RX: \"{ToHexString(c2dMessageBody)}\"";

            Log($"Expected C2D received log is: {expectedRxSerial}");

            var c2dLogMessage = $"{device.DeviceID}: done completing cloud to device message, id: {c2dMessage.MessageId}";

            Log($"Expected C2D network server log is: {expectedRxSerial}");

            // Sends 8x confirmed messages, stopping if C2D message is found
            for (var i = warmUpMessageCount + 1; i <= messagesToSend; ++i)
            {
                var msg = PayloadGenerator.Next().ToString(CultureInfo.InvariantCulture);
                Log($"{device.DeviceID}: Sending confirmed '{msg}' {i}/{messagesToSend}");
                await ArduinoDevice.transferPacketWithConfirmedAsync(msg, 10);

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

                // After transferPacketWithConfirmed: Expectation from serial
                // +CMSG: ACK Received
                await AssertUtils.ContainsWithRetriesAsync("+CMSG: ACK Received", ArduinoDevice.SerialLogs);

                // Check that RXDelay was correctly used
                await TestFixtureCi.CheckAnswerTimingAsync(device.RXDelay, device.GatewayID);

                // check if c2d message was found
                // 0000000000000009: C2D message: 58
                var searchResults = await TestFixtureCi.SearchNetworkServerModuleAsync(
                    (messageBody) =>
                {
                    return(messageBody.StartsWith(c2dLogMessage, StringComparison.OrdinalIgnoreCase));
                },
                    new SearchLogOptions(c2dLogMessage)
                {
                    MaxAttempts = 1
                });

                // We should only receive the message once
                if (searchResults.Found)
                {
                    foundC2DMessageCount++;
                    Log($"{device.DeviceID}: Found C2D message in log (after sending {i}/{messagesToSend}) {foundC2DMessageCount} times");
                    EnsureNotSeenTooManyTimes(foundC2DMessageCount);
                }

                var localFoundCloudToDeviceInSerial = ArduinoDevice.SerialLogs.Contains(expectedRxSerial);
                if (localFoundCloudToDeviceInSerial)
                {
                    foundReceivePacketCount++;
                    Log($"{device.DeviceID}: Found C2D message in serial logs (after sending {i}/{messagesToSend}) {foundReceivePacketCount} times");
                    EnsureNotSeenTooManyTimes(foundReceivePacketCount);
                }

                TestFixtureCi.ClearLogs();

                await Task.Delay(Constants.DELAY_BETWEEN_MESSAGES);
            }

            Assert.True(foundC2DMessageCount > 0, $"Did not find '{device.DeviceID}: C2D message: {c2dMessageBody}' in logs");

            // checks if log arrived
            if (foundReceivePacketCount == 0)
            {
                if (ArduinoDevice.SerialLogs.Contains(expectedRxSerial))
                {
                    foundReceivePacketCount++;
                }
            }

            Assert.True(foundReceivePacketCount > 0, $"Could not find lora receiving message '{expectedRxSerial}'");
        }
コード例 #3
0
        private async Task Test_Deduplication_Strategies(string devicePropertyName, string strategy)
        {
            var device = TestFixtureCi.GetDeviceByPropertyName(devicePropertyName);

            LogTestStart(device);

            await ArduinoDevice.setDeviceModeAsync(LoRaArduinoSerial._device_mode_t.LWABP);

            await ArduinoDevice.setIdAsync(device.DevAddr, device.DeviceID, null);

            await ArduinoDevice.setKeyAsync(device.NwkSKey, device.AppSKey, null);

            await ArduinoDevice.SetupLora(TestFixtureCi.Configuration);

            for (var i = 0; i < 10; i++)
            {
                var msg = PayloadGenerator.Next().ToString(CultureInfo.InvariantCulture);
                await ArduinoDevice.transferPacketWithConfirmedAsync(msg, 10);

                await Task.Delay(Constants.DELAY_FOR_SERIAL_AFTER_SENDING_PACKET);

                // After transferPacket: Expectation from serial
                // +CMSG: ACK Received
                await AssertUtils.ContainsWithRetriesAsync("+CMSG: ACK Received", ArduinoDevice.SerialLogs);

                var allGwGotIt = await TestFixtureCi.ValidateMultiGatewaySources((log) => log.IndexOf($"deduplication Strategy: {strategy}", StringComparison.OrdinalIgnoreCase) != -1);

                if (allGwGotIt)
                {
                    var notDuplicate = "\"IsDuplicate\":false";
                    var isDuplicate  = "\"IsDuplicate\":true";

                    var notDuplicateResult = await TestFixtureCi.SearchNetworkServerModuleAsync((s) => s.IndexOf(notDuplicate, StringComparison.Ordinal) != -1, new SearchLogOptions(notDuplicate));

                    var duplicateResult = await TestFixtureCi.SearchNetworkServerModuleAsync((s) => s.IndexOf(isDuplicate, StringComparison.Ordinal) != -1, new SearchLogOptions(isDuplicate));

                    Assert.NotNull(notDuplicateResult.MatchedEvent);
                    Assert.NotNull(duplicateResult.MatchedEvent);

                    Assert.NotEqual(duplicateResult.MatchedEvent.SourceId, notDuplicateResult.MatchedEvent.SourceId);

                    switch (strategy)
                    {
                    case "Mark":
                        var expectedProperty = "dupmsg";
                        await TestFixture.AssertIoTHubDeviceMessageExistsAsync(device.DeviceID, expectedProperty, "true", new SearchLogOptions(expectedProperty) { SourceIdFilter = duplicateResult.MatchedEvent.SourceId, TreatAsError = true });

                        await TestFixture.AssertIoTHubDeviceMessageExistsAsync(device.DeviceID, expectedProperty, "true", new SearchLogOptions(expectedProperty) { SourceIdFilter = notDuplicateResult.MatchedEvent.SourceId, TreatAsError = true });

                        break;

                    case "Drop":
                        var logMsg     = $"{device.DeviceID}: duplication strategy indicated to not process message";
                        var droppedLog = await TestFixtureCi.SearchNetworkServerModuleAsync((log) => log.StartsWith(logMsg, StringComparison.Ordinal), new SearchLogOptions(logMsg) { SourceIdFilter = duplicateResult.MatchedEvent.SourceId });

                        Assert.NotNull(droppedLog.MatchedEvent);

                        var expectedPayload = $"{{\"value\":{msg}}}";
                        await TestFixtureCi.AssertIoTHubDeviceMessageExistsAsync(device.DeviceID, expectedPayload, new SearchLogOptions(expectedPayload) { TreatAsError = true });

                        break;

                    default:
                        throw new SwitchExpressionException();
                    }
                }

                TestFixtureCi.ClearLogs();
            }
        }