Exemple #1
0
        public async Task GetDeviceByDevEUIAsync_When_Api_Returns_Empty_Should_Return_Null()
        {
            var deviceApi = new Mock <LoRaDeviceAPIServiceBase>(MockBehavior.Strict);

            deviceApi.Setup(x => x.GetPrimaryKeyByEuiAsync(It.IsNotNull <DevEui>()))
            .ReturnsAsync((string)null);

            var deviceClient = new Mock <ILoRaDeviceClient>(MockBehavior.Strict);

            var deviceFactory = new TestLoRaDeviceFactory(deviceClient.Object, DeviceCache);

            using var deviceRegistry = new LoRaDeviceRegistry(
                      ServerConfiguration,
                      this.cache,
                      deviceApi.Object,
                      deviceFactory,
                      DeviceCache);

            var actual = await deviceRegistry.GetDeviceByDevEUIAsync(new DevEui(1));

            Assert.Null(actual);

            deviceApi.VerifyAll();
            deviceClient.VerifyAll();
        }
Exemple #2
0
        public async Task When_Device_Is_Assigned_To_Another_Gateway_Cache_Locally_And_Return_Null()
        {
            var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: "another-gateway"));

            var apiService       = new Mock <LoRaDeviceAPIServiceBase>(MockBehavior.Strict);
            var iotHubDeviceInfo = new IoTHubDeviceInfo(simulatedDevice.LoRaDevice.DevAddr, simulatedDevice.LoRaDevice.DevEui, "pk")
            {
                GatewayId = "another-gateway",
                NwkSKey   = simulatedDevice.NwkSKey.Value
            };

            apiService.Setup(x => x.SearchByDevAddrAsync(It.IsAny <DevAddr>()))
            .ReturnsAsync(new SearchDevicesResult(iotHubDeviceInfo.AsList()));

            var deviceFactory = new TestLoRaDeviceFactory(LoRaDeviceClient.Object, DeviceCache, ConnectionManager);

            using var target = new LoRaDeviceRegistry(ServerConfiguration, this.cache, apiService.Object, deviceFactory, DeviceCache);

            // request #1
            var payload1 = simulatedDevice.CreateUnconfirmedDataUpMessage("1", fcnt: 11);

            using var request1 = WaitableLoRaRequest.Create(payload1);
            target.GetLoRaRequestQueue(request1).Queue(request1);
            Assert.True(await request1.WaitCompleteAsync());
            Assert.True(request1.ProcessingFailed);
            Assert.Equal(LoRaDeviceRequestFailedReason.BelongsToAnotherGateway, request1.ProcessingFailedReason);

            // request #2
            var payload2 = simulatedDevice.CreateUnconfirmedDataUpMessage("2", fcnt: 12);

            using var request2 = WaitableLoRaRequest.Create(payload2);
            target.GetLoRaRequestQueue(request2).Queue(request2);
            Assert.True(await request2.WaitCompleteAsync());
            Assert.True(request2.ProcessingFailed);
            Assert.Equal(LoRaDeviceRequestFailedReason.BelongsToAnotherGateway, request2.ProcessingFailedReason);

            // Device was searched by DevAddr
            apiService.VerifyAll();
            apiService.Verify(x => x.SearchByDevAddrAsync(It.IsAny <DevAddr>()), Times.Once());

            // Device should not be connected
            LoRaDeviceClient.VerifyAll();
            LoRaDeviceClient.Verify(x => x.GetTwinAsync(CancellationToken.None), Times.Never());
            LoRaDeviceClient.Verify(x => x.Disconnect(), Times.Never());

            // device is in cache
            Assert.True(DeviceCache.TryGetForPayload(request1.Payload, out var loRaDevice));
            Assert.False(loRaDevice.IsOurDevice);
        }
        public async Task When_Device_Does_Not_Match_Gateway_Should_Fail_Request()
        {
            var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: "a_different_one"));
            var payload         = simulatedDevice.CreateUnconfirmedDataUpMessage("1234");

            var apiService       = new Mock <LoRaDeviceAPIServiceBase>();
            var iotHubDeviceInfo = new IoTHubDeviceInfo(simulatedDevice.LoRaDevice.DevAddr, simulatedDevice.LoRaDevice.DevEui, "pk")
            {
                GatewayId = "a_different_one",
                NwkSKey   = simulatedDevice.NwkSKey.Value
            };

            apiService.Setup(x => x.SearchByDevAddrAsync(It.IsAny <DevAddr>()))
            .ReturnsAsync(new SearchDevicesResult(iotHubDeviceInfo.AsList()));

            var loRaDeviceClient = new Mock <ILoRaDeviceClient>(MockBehavior.Loose);

            using var deviceCache = LoRaDeviceCacheDefault.CreateDefault();
            var deviceFactory = new TestLoRaDeviceFactory(loRaDeviceClient.Object, deviceCache, this.connectionManager);
            var target        = new DeviceLoaderSynchronizer(
                simulatedDevice.DevAddr.Value,
                apiService.Object,
                deviceFactory,
                new NetworkServerConfiguration(),
                deviceCache,
                null,
                NullLogger <DeviceLoaderSynchronizer> .Instance);

            _ = target.LoadAsync();

            using var request = WaitableLoRaRequest.Create(payload);
            target.Queue(request);
            Assert.True(await request.WaitCompleteAsync());
            Assert.True(request.ProcessingFailed);
            Assert.Equal(LoRaDeviceRequestFailedReason.BelongsToAnotherGateway, request.ProcessingFailedReason);

            // device should not be initialized, since it belongs to another gateway
            loRaDeviceClient.Verify(x => x.GetTwinAsync(CancellationToken.None), Times.Never());

            // device should not be disconnected (was never connected)
            loRaDeviceClient.Verify(x => x.Disconnect(), Times.Never());

            // Device was searched by DevAddr
            apiService.VerifyAll();

            // Device was created by factory
            loRaDeviceClient.VerifyAll();
        }
Exemple #4
0
        public async Task When_Device_Is_Assigned_To_Another_Gateway_After_No_Connection_Should_Be_Established()
        {
            const string gatewayId       = "another-gateway";
            var          simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: gatewayId));

            var apiService       = new Mock <LoRaDeviceAPIServiceBase>(MockBehavior.Strict);
            var iotHubDeviceInfo = new IoTHubDeviceInfo(simulatedDevice.LoRaDevice.DevAddr, simulatedDevice.LoRaDevice.DevEui, "pk")
            {
                NwkSKey = simulatedDevice.NwkSKey.Value, GatewayId = gatewayId
            };

            apiService.Setup(x => x.SearchByDevAddrAsync(It.IsAny <DevAddr>()))
            .ReturnsAsync(new SearchDevicesResult(iotHubDeviceInfo.AsList()));

            var deviceFactory = new TestLoRaDeviceFactory(LoRaDeviceClient.Object, DeviceCache, ConnectionManager);

            using var target = new LoRaDeviceRegistry(ServerConfiguration, this.cache, apiService.Object, deviceFactory, DeviceCache);

            // setup 2 requests - ensure the cache is validated before fetching from the function
            var requests = Enumerable.Range(1, 2).Select((n) =>
            {
                var payload = simulatedDevice.CreateUnconfirmedDataUpMessage(n.ToString(CultureInfo.InvariantCulture), fcnt: (uint)n + 10);
                var request = WaitableLoRaRequest.Create(payload);
                target.GetLoRaRequestQueue(request).Queue(request);
                return(request);
            }
                                                         ).ToList();

            foreach (var request in requests)
            {
                Assert.True(await request.WaitCompleteAsync());
                Assert.True(request.ProcessingFailed);
                Assert.Equal(LoRaDeviceRequestFailedReason.BelongsToAnotherGateway, request.ProcessingFailedReason);
            }

            // Device was searched by DevAddr
            apiService.VerifyAll();
            apiService.Verify(x => x.SearchByDevAddrAsync(It.IsAny <DevAddr>()), Times.Once());

            LoRaDeviceClient.Verify(x => x.GetTwinAsync(CancellationToken.None), Times.Never());

            // device is in cache
            Assert.True(DeviceCache.TryGetForPayload(requests.First().Payload, out var cachedLoRaDevice));
            Assert.False(cachedLoRaDevice.IsOurDevice);
        }
Exemple #5
0
        public async Task When_Loading_Device_By_DevEUI_Should_Be_Able_To_Load_By_DevAddr()
        {
            var simDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1));

            var deviceApi = new Mock <LoRaDeviceAPIServiceBase>(MockBehavior.Strict);

            deviceApi.Setup(x => x.GetPrimaryKeyByEuiAsync(simDevice.DevEUI))
            .ReturnsAsync("123");

            var deviceClient = new Mock <ILoRaDeviceClient>(MockBehavior.Loose);

            deviceClient.Setup(x => x.GetTwinAsync(CancellationToken.None))
            .ReturnsAsync(simDevice.CreateABPTwin());

            var handlerImplementation = new Mock <ILoRaDataRequestHandler>(MockBehavior.Strict);

            handlerImplementation.Setup(x => x.ProcessRequestAsync(It.IsNotNull <LoRaRequest>(), It.IsNotNull <LoRaDevice>()))
            .Returns <LoRaRequest, LoRaDevice>((req, device) =>
            {
                return(Task.FromResult(new LoRaDeviceRequestProcessResult(device, req)));
            });

            var deviceFactory = new TestLoRaDeviceFactory(deviceClient.Object, handlerImplementation.Object, DeviceCache, ConnectionManager);

            using var deviceRegistry = new LoRaDeviceRegistry(
                      ServerConfiguration,
                      this.cache,
                      deviceApi.Object,
                      deviceFactory,
                      DeviceCache);

            Assert.NotNull(await deviceRegistry.GetDeviceByDevEUIAsync(simDevice.DevEUI));

            var payload = simDevice.CreateUnconfirmedDataUpMessage("1");

            using var request = WaitableLoRaRequest.Create(payload);

            deviceRegistry.GetLoRaRequestQueue(request).Queue(request);
            Assert.True(await request.WaitCompleteAsync());

            handlerImplementation.VerifyAll();
            deviceApi.VerifyAll();
            deviceClient.Verify(x => x.GetTwinAsync(CancellationToken.None), Times.Once());
        }
Exemple #6
0
        public DefaultClassCDevicesMessageSenderTest()
        {
            this.serverConfiguration = new NetworkServerConfiguration()
            {
                GatewayID = ServerGatewayID,
            };

            this.loRaRegion = RegionManager.EU868;

            this.downstreamMessageSender = new Mock <IDownstreamMessageSender>(MockBehavior.Strict);
            this.deviceApi    = new Mock <LoRaDeviceAPIServiceBase>(MockBehavior.Strict);
            this.deviceClient = new Mock <ILoRaDeviceClient>(MockBehavior.Loose);

            this.cache = new MemoryCache(new MemoryCacheOptions());
#pragma warning disable CA2000 // Dispose objects before losing scope
            this.loRaDeviceFactory = new TestLoRaDeviceFactory(this.deviceClient.Object, this.deviceCache, new LoRaDeviceClientConnectionManager(this.cache, NullLogger <LoRaDeviceClientConnectionManager> .Instance));
#pragma warning restore CA2000 // Dispose objects before losing scope
            this.loRaDeviceRegistry           = new LoRaDeviceRegistry(this.serverConfiguration, this.cache, this.deviceApi.Object, this.loRaDeviceFactory, this.deviceCache);
            this.frameCounterStrategyProvider = new LoRaDeviceFrameCounterUpdateStrategyProvider(this.serverConfiguration, this.deviceApi.Object);
        }
        public ClassCCloudToDeviceMessageSizeLimitTests(ITestOutputHelper testOutputHelper)
        {
            this.serverConfiguration = new NetworkServerConfiguration()
            {
                GatewayID = ServerGatewayID,
            };

            this.loRaRegion              = RegionManager.EU868;
            DownstreamMessageSender      = new TestDownstreamMessageSender();
            this.deviceApi               = new Mock <LoRaDeviceAPIServiceBase>(MockBehavior.Strict);
            this.deviceClient            = new Mock <ILoRaDeviceClient>(MockBehavior.Loose);
            this.testOutputLoggerFactory = new TestOutputLoggerFactory(testOutputHelper);

            this.cache             = new MemoryCache(new MemoryCacheOptions());
            this.connectionManager = new LoRaDeviceClientConnectionManager(this.cache, testOutputLoggerFactory.CreateLogger <LoRaDeviceClientConnectionManager>());
            this.loRaDeviceFactory = new TestLoRaDeviceFactory(this.deviceClient.Object, this.deviceCache, this.connectionManager);

            this.loRaDeviceRegistry           = new LoRaDeviceRegistry(this.serverConfiguration, this.cache, this.deviceApi.Object, this.loRaDeviceFactory, this.deviceCache);
            this.frameCounterStrategyProvider = new LoRaDeviceFrameCounterUpdateStrategyProvider(this.serverConfiguration, this.deviceApi.Object);
        }
        public async Task When_Device_Is_Not_In_Cache_And_Found_In_Api_Does_Not_Match_Mic_Should_Fail_Request(string deviceGatewayID)
        {
            var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: deviceGatewayID));

            var apiService       = new Mock <LoRaDeviceAPIServiceBase>();
            var iotHubDeviceInfo = new IoTHubDeviceInfo(simulatedDevice.LoRaDevice.DevAddr, simulatedDevice.LoRaDevice.DevEui, "pk");

            apiService.Setup(x => x.SearchByDevAddrAsync(It.IsAny <DevAddr>()))
            .ReturnsAsync(new SearchDevicesResult(iotHubDeviceInfo.AsList()));

            // Will get device twin
            var loRaDeviceClient = new Mock <ILoRaDeviceClient>(MockBehavior.Loose);

            loRaDeviceClient.Setup(x => x.GetTwinAsync(CancellationToken.None))
            .ReturnsAsync(TestUtils.CreateABPTwin(simulatedDevice));

            using var deviceCache = LoRaDeviceCacheDefault.CreateDefault();
            var deviceFactory = new TestLoRaDeviceFactory(loRaDeviceClient.Object, deviceCache, this.connectionManager);
            var target        = new DeviceLoaderSynchronizer(
                simulatedDevice.DevAddr.Value,
                apiService.Object,
                deviceFactory,
                new NetworkServerConfiguration(),
                deviceCache,
                null,
                NullLogger <DeviceLoaderSynchronizer> .Instance);

            _ = target.LoadAsync();

            var payload = simulatedDevice.CreateUnconfirmedDataUpMessage("1234", appSKey: simulatedDevice.AppSKey, nwkSKey: TestKeys.CreateNetworkSessionKey(0xEEAAFF));

            using var request = WaitableLoRaRequest.Create(payload);
            target.Queue(request);
            Assert.True(await request.WaitCompleteAsync());
            Assert.True(request.ProcessingFailed);
            Assert.Equal(LoRaDeviceRequestFailedReason.NotMatchingDeviceByMicCheck, request.ProcessingFailedReason);

            // Device was searched by DevAddr
            apiService.VerifyAll();
            loRaDeviceClient.VerifyAll();
        }
Exemple #9
0
        public async Task When_Device_Is_Not_In_Cache_And_Found_In_Api_Should_Cache_And_Process_Request(string deviceGatewayID)
        {
            var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: deviceGatewayID));
            var payload         = simulatedDevice.CreateUnconfirmedDataUpMessage("1234");

            var apiService       = new Mock <LoRaDeviceAPIServiceBase>();
            var iotHubDeviceInfo = new IoTHubDeviceInfo(simulatedDevice.LoRaDevice.DevAddr, simulatedDevice.LoRaDevice.DevEui, "pk")
            {
                GatewayId = deviceGatewayID
            };

            apiService.Setup(x => x.SearchByDevAddrAsync(It.IsAny <DevAddr>()))
            .ReturnsAsync(new SearchDevicesResult(iotHubDeviceInfo.AsList()));

            // device will be initialized
            LoRaDeviceClient.Setup(x => x.GetTwinAsync(CancellationToken.None))
            .ReturnsAsync(simulatedDevice.CreateABPTwin());

            using var request = WaitableLoRaRequest.Create(payload);
            var requestHandler = new Mock <ILoRaDataRequestHandler>(MockBehavior.Strict);

            requestHandler.Setup(x => x.ProcessRequestAsync(request, It.IsNotNull <LoRaDevice>()))
            .ReturnsAsync(new LoRaDeviceRequestProcessResult(null, request));

            var deviceFactory = new TestLoRaDeviceFactory(LoRaDeviceClient.Object, requestHandler.Object, DeviceCache, ConnectionManager);

            using var target = new LoRaDeviceRegistry(ServerConfiguration, this.cache, apiService.Object, deviceFactory, DeviceCache);
            target.GetLoRaRequestQueue(request).Queue(request);

            Assert.True(await request.WaitCompleteAsync());
            Assert.True(request.ProcessingSucceeded);

            // Device was searched by DevAddr
            apiService.VerifyAll();

            // ensure device is in cache
            Assert.True(DeviceCache.TryGetForPayload(request.Payload, out var actualCachedLoRaDevice));

            // request was handled
            requestHandler.VerifyAll();
        }
Exemple #10
0
        public async Task When_Loading_Device_By_DevAddr_Should_Be_Able_To_Load_By_DevEUI()
        {
            var simDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1));

            var deviceApi = new Mock <LoRaDeviceAPIServiceBase>(MockBehavior.Strict);

            deviceApi.Setup(x => x.SearchByDevAddrAsync(simDevice.DevAddr.Value))
            .ReturnsAsync(new SearchDevicesResult(new IoTHubDeviceInfo(simDevice.DevAddr, simDevice.DevEUI, "123").AsList()));

            var deviceClient = new Mock <ILoRaDeviceClient>(MockBehavior.Loose);

            deviceClient.Setup(x => x.GetTwinAsync(CancellationToken.None))
            .ReturnsAsync(simDevice.CreateABPTwin());

            var handlerImplementation = new Mock <ILoRaDataRequestHandler>(MockBehavior.Strict);
            var deviceFactory         = new TestLoRaDeviceFactory(deviceClient.Object, handlerImplementation.Object, DeviceCache, ConnectionManager);

            using var deviceRegistry = new LoRaDeviceRegistry(
                      ServerConfiguration,
                      this.cache,
                      deviceApi.Object,
                      deviceFactory,
                      DeviceCache);

            var payload = simDevice.CreateUnconfirmedDataUpMessage("1");

            using var request = WaitableLoRaRequest.Create(payload);

            deviceRegistry.GetLoRaRequestQueue(request).Queue(request);
            Assert.True(await request.WaitCompleteAsync());
            await Task.Delay(50);

            Assert.NotNull(await deviceRegistry.GetDeviceByDevEUIAsync(simDevice.DevEUI));

            handlerImplementation.VerifyAll();
            deviceApi.VerifyAll();
            deviceClient.VerifyAll();
            deviceClient.Verify(x => x.GetTwinAsync(CancellationToken.None), Times.Once());
        }
Exemple #11
0
        public void When_Cache_Clear_Is_Called_Should_Removed_Cached_Devices(string deviceGatewayID)
        {
            LoRaDeviceClient.Setup(ldc => ldc.Dispose());
            const int deviceCount = 10;
            var       deviceList  = new HashSet <LoRaDevice>();

            var apiService    = new Mock <LoRaDeviceAPIServiceBase>();
            var deviceFactory = new TestLoRaDeviceFactory(LoRaDeviceClient.Object, DeviceCache);

            using var target            = new LoRaDeviceRegistry(ServerConfiguration, this.cache, apiService.Object, deviceFactory, DeviceCache);
            using var connectionManager = new SingleDeviceConnectionManager(LoRaDeviceClient.Object);

            for (var deviceID = 1; deviceID <= deviceCount; ++deviceID)
            {
                var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice((uint)deviceID, gatewayID: deviceGatewayID));
#pragma warning disable CA2000 // Dispose objects before losing scope - transfer ownership
                var device = TestUtils.CreateFromSimulatedDevice(simulatedDevice, connectionManager);
#pragma warning restore CA2000 // Dispose objects before losing scope
                DeviceCache.Register(device);
                deviceList.Add(device);
            }

            Assert.Equal(deviceCount, DeviceCache.CalculateStatistics().Count);

            // Device was searched by DevAddr
            apiService.VerifyAll();

            // Device was created by factory
            this.loraDeviceFactoryMock.VerifyAll();

            // ensure all devices are in cache
            Assert.Equal(deviceCount, deviceList.Count(x => DeviceCache.TryGetByDevEui(x.DevEUI, out _)));

            target.ResetDeviceCache();
            Assert.False(deviceList.Any(x => DeviceCache.TryGetByDevEui(x.DevEUI, out _)), "Should not find devices again");
        }