public async Task When_Fcnt_Down_Fails_Should_Stop_And_Not_Update_Device_Twin(uint initialFcntDown, uint initialFcntUp, uint payloadFcnt) { var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: null)); simulatedDevice.FrmCntDown = initialFcntDown; simulatedDevice.FrmCntUp = initialFcntUp; var devEUI = simulatedDevice.LoRaDevice.DeviceID; var devAddr = simulatedDevice.LoRaDevice.DevAddr; this.LoRaDeviceApi.Setup(x => x.ExecuteFunctionBundlerAsync(devEUI, It.IsAny <FunctionBundlerRequest>())).ReturnsAsync(() => new FunctionBundlerResult { AdrResult = new LoRaTools.ADR.LoRaADRResult { CanConfirmToDevice = true, FCntDown = 0 }, NextFCntDown = 0 }); this.LoRaDeviceApi.Setup(x => x.ABPFcntCacheResetAsync(devEUI, It.IsAny <uint>(), It.IsNotNull <string>())) .ReturnsAsync(true); var memoryCache = new MemoryCache(new MemoryCacheOptions()); var device = this.CreateLoRaDevice(simulatedDevice); var dicForDevAddr = new DevEUIToLoRaDeviceDictionary(); dicForDevAddr.TryAdd(devEUI, device); memoryCache.Set(devAddr, dicForDevAddr); var deviceRegistry = new LoRaDeviceRegistry(this.ServerConfiguration, memoryCache, this.LoRaDeviceApi.Object, this.LoRaDeviceFactory); // Send to message processor var messageDispatcher = new MessageDispatcher( this.ServerConfiguration, deviceRegistry, this.FrameCounterUpdateStrategyProvider); // sends unconfirmed message var unconfirmedMessagePayload = simulatedDevice.CreateConfirmedDataUpMessage("hello", fcnt: payloadFcnt); var rxpk = unconfirmedMessagePayload.SerializeUplink(simulatedDevice.AppSKey, simulatedDevice.NwkSKey).Rxpk[0]; var request = this.CreateWaitableRequest(rxpk); messageDispatcher.DispatchRequest(request); Assert.True(await request.WaitCompleteAsync()); Assert.Null(request.ResponseDownlink); // verify that the device in device registry has correct properties and frame counters var devicesForDevAddr = deviceRegistry.InternalGetCachedDevicesForDevAddr(devAddr); Assert.Single(devicesForDevAddr); Assert.True(devicesForDevAddr.TryGetValue(devEUI, out var loRaDevice)); Assert.Equal(devAddr, loRaDevice.DevAddr); Assert.Equal(devEUI, loRaDevice.DevEUI); Assert.True(loRaDevice.IsABP); Assert.Equal(initialFcntUp, loRaDevice.FCntUp); Assert.Equal(initialFcntDown, loRaDevice.FCntDown); Assert.False(loRaDevice.HasFrameCountChanges); this.LoRaDeviceClient.VerifyAll(); this.LoRaDeviceApi.VerifyAll(); }
public async Task When_Devices_From_Another_Gateway_Is_Cached_Return_Null() { var simulatedDevice1 = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: "another-gateway")); var loraDevice1 = TestUtils.CreateFromSimulatedDevice(simulatedDevice1, null); loraDevice1.IsOurDevice = false; var existingCache = new DevEUIToLoRaDeviceDictionary(); this.cache.Set<DevEUIToLoRaDeviceDictionary>(simulatedDevice1.LoRaDevice.DevAddr, existingCache); existingCache.TryAdd(loraDevice1.DevEUI, loraDevice1); var payload = simulatedDevice1.CreateUnconfirmedDataUpMessage("1234"); payload.SerializeUplink(simulatedDevice1.AppSKey, simulatedDevice1.NwkSKey); var apiService = new Mock<LoRaDeviceAPIServiceBase>(MockBehavior.Strict); var target = new LoRaDeviceRegistry(this.serverConfiguration, this.cache, apiService.Object, this.loraDeviceFactoryMock.Object); var request = new WaitableLoRaRequest(payload); var queue = target.GetLoRaRequestQueue(request); queue.Queue(request); Assert.IsType<ExternalGatewayLoRaRequestQueue>(queue); Assert.True(await request.WaitCompleteAsync()); Assert.True(request.ProcessingFailed); Assert.Equal(LoRaDeviceRequestFailedReason.BelongsToAnotherGateway, request.ProcessingFailedReason); // Device was searched by DevAddr apiService.VerifyAll(); // Device was created by factory this.loraDeviceFactoryMock.VerifyAll(); }
public async Task When_Device_Api_Throws_Error_Should_Not_Create_Any_Device() { const string devAddr = "039090"; var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1)); var payload = simulatedDevice.CreateUnconfirmedDataUpMessage("1234"); payload.SerializeUplink(simulatedDevice.AppSKey, simulatedDevice.NwkSKey); var apiService = new Mock <LoRaDeviceAPIServiceBase>(MockBehavior.Strict); apiService.Setup(x => x.SearchByDevAddrAsync(It.IsNotNull <string>())) .Throws(new Exception()); var deviceFactory = new Mock <ILoRaDeviceFactory>(MockBehavior.Strict); var destinationDictionary = new DevEUIToLoRaDeviceDictionary(); var finished = new SemaphoreSlim(0); var target = new DeviceLoaderSynchronizer( devAddr, apiService.Object, deviceFactory.Object, destinationDictionary, null, this.serverConfiguration, (_, l) => { finished.Release(); }, (d) => { destinationDictionary.TryAdd(d.DevEUI, d); }); await finished.WaitAsync(); Assert.Empty(destinationDictionary); // Device was searched by DevAddr apiService.VerifyAll(); }
public async Task When_Devices_From_Another_Gateway_Is_Cached_Return_Null() { var simulatedDevice1 = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: "another-gateway")); var loraDevice1 = TestUtils.CreateFromSimulatedDevice(simulatedDevice1, null); loraDevice1.IsOurDevice = false; var existingCache = new DevEUIToLoRaDeviceDictionary(); this.cache.Set <DevEUIToLoRaDeviceDictionary>(simulatedDevice1.LoRaDevice.DevAddr, existingCache); existingCache.TryAdd(loraDevice1.DevEUI, loraDevice1); var payload = simulatedDevice1.CreateUnconfirmedDataUpMessage("1234"); payload.SerializeUplink(simulatedDevice1.AppSKey, simulatedDevice1.NwkSKey); var apiService = new Mock <LoRaDeviceAPIServiceBase>(MockBehavior.Strict); var target = new LoRaDeviceRegistry(this.serverConfiguration, this.cache, apiService.Object, this.loraDeviceFactoryMock.Object); var actual = await target.GetDeviceForPayloadAsync(payload); Assert.Null(actual); // Device was searched by DevAddr apiService.VerifyAll(); // Device was created by factory this.loraDeviceFactoryMock.VerifyAll(); }
public async Task When_Fcnt_Down_Fails_Should_Stop_And_Not_Update_Device_Twin(int initialFcntDown, int initialFcntUp, int payloadFcnt) { var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: null)); simulatedDevice.FrmCntDown = initialFcntDown; simulatedDevice.FrmCntUp = initialFcntUp; var loRaDeviceClient = new Mock <ILoRaDeviceClient>(MockBehavior.Strict); var devEUI = simulatedDevice.LoRaDevice.DeviceID; var devAddr = simulatedDevice.LoRaDevice.DevAddr; // Lora device api var loRaDeviceApi = new Mock <LoRaDeviceAPIServiceBase>(MockBehavior.Strict); loRaDeviceApi.Setup(x => x.NextFCntDownAsync(devEUI, initialFcntDown, payloadFcnt, ServerGatewayID)).ReturnsAsync((ushort)0); // using factory to create mock of var loRaDeviceFactory = new TestLoRaDeviceFactory(loRaDeviceClient.Object); var memoryCache = new MemoryCache(new MemoryCacheOptions()); var device = TestUtils.CreateFromSimulatedDevice(simulatedDevice, loRaDeviceClient.Object); var dicForDevAddr = new DevEUIToLoRaDeviceDictionary(); dicForDevAddr.TryAdd(devEUI, device); memoryCache.Set(devAddr, dicForDevAddr); var deviceRegistry = new LoRaDeviceRegistry(this.ServerConfiguration, memoryCache, loRaDeviceApi.Object, loRaDeviceFactory); var frameCounterUpdateStrategyFactory = new LoRaDeviceFrameCounterUpdateStrategyFactory(this.ServerConfiguration.GatewayID, loRaDeviceApi.Object); // Send to message processor var messageProcessor = new MessageProcessor( this.ServerConfiguration, deviceRegistry, frameCounterUpdateStrategyFactory, new LoRaPayloadDecoder()); // sends unconfirmed message var unconfirmedMessagePayload = simulatedDevice.CreateConfirmedDataUpMessage("hello", fcnt: payloadFcnt); var rxpk = unconfirmedMessagePayload.SerializeUplink(simulatedDevice.AppSKey, simulatedDevice.NwkSKey).Rxpk[0]; var unconfirmedMessageResult = await messageProcessor.ProcessMessageAsync(rxpk); Assert.Null(unconfirmedMessageResult); // verify that the device in device registry has correct properties and frame counters var devicesForDevAddr = deviceRegistry.InternalGetCachedDevicesForDevAddr(devAddr); Assert.Single(devicesForDevAddr); Assert.True(devicesForDevAddr.TryGetValue(devEUI, out var loRaDevice)); Assert.Equal(devAddr, loRaDevice.DevAddr); Assert.Equal(devEUI, loRaDevice.DevEUI); Assert.True(loRaDevice.IsABP); Assert.Equal(initialFcntUp, loRaDevice.FCntUp); Assert.Equal(initialFcntDown, loRaDevice.FCntDown); Assert.False(loRaDevice.HasFrameCountChanges); loRaDeviceClient.VerifyAll(); loRaDeviceApi.VerifyAll(); }
public async Task When_Device_With_Downlink_Disabled_Received_Confirmed_Data_Should_Not_Check_For_C2D(string deviceGatewayID) { const int payloadFcnt = 10; var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: deviceGatewayID)); var devEUI = simulatedDevice.LoRaDevice.DeviceID; var devAddr = simulatedDevice.LoRaDevice.DevAddr; // message will be sent var loRaDeviceClient = new Mock <ILoRaDeviceClient>(MockBehavior.Strict); loRaDeviceClient.Setup(x => x.SendEventAsync(It.IsNotNull <LoRaDeviceTelemetry>(), null)) .ReturnsAsync(true); // Lora device api var loRaDeviceApi = new Mock <LoRaDeviceAPIServiceBase>(MockBehavior.Strict); // multi gateway will ask for next fcnt down if (string.IsNullOrEmpty(deviceGatewayID)) { loRaDeviceApi.Setup(x => x.NextFCntDownAsync(devEUI, simulatedDevice.FrmCntDown, payloadFcnt, this.ServerConfiguration.GatewayID)) .ReturnsAsync((ushort)(simulatedDevice.FrmCntDown + 1)); } // using factory to create mock of var loRaDeviceFactory = new TestLoRaDeviceFactory(loRaDeviceClient.Object); var memoryCache = new MemoryCache(new MemoryCacheOptions()); var cachedDevice = TestUtils.CreateFromSimulatedDevice(simulatedDevice, loRaDeviceClient.Object); cachedDevice.DownlinkEnabled = false; var devEUIDeviceDict = new DevEUIToLoRaDeviceDictionary(); devEUIDeviceDict.TryAdd(devEUI, cachedDevice); memoryCache.Set(devAddr, devEUIDeviceDict); var deviceRegistry = new LoRaDeviceRegistry(this.ServerConfiguration, memoryCache, loRaDeviceApi.Object, loRaDeviceFactory); var frameCounterUpdateStrategyFactory = new LoRaDeviceFrameCounterUpdateStrategyFactory(this.ServerConfiguration.GatewayID, loRaDeviceApi.Object); // Send to message processor var messageProcessor = new MessageProcessor( this.ServerConfiguration, deviceRegistry, frameCounterUpdateStrategyFactory, new LoRaPayloadDecoder()); // sends confirmed message var rxpk = simulatedDevice.CreateConfirmedMessageUplink("1234", fcnt: payloadFcnt).Rxpk[0]; var confirmedMessageResult = await messageProcessor.ProcessMessageAsync(rxpk); Assert.NotNull(confirmedMessageResult); loRaDeviceClient.Verify(x => x.ReceiveAsync(It.IsAny <TimeSpan>()), Times.Never()); loRaDeviceClient.VerifyAll(); loRaDeviceApi.VerifyAll(); }
public async Task When_Multiple_Devices_With_Same_DevAddr_Are_Cached_Should_Find_Matching_By_Mic(string deviceGatewayID) { var simulatedDevice1 = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: deviceGatewayID)); var loraDevice1 = TestUtils.CreateFromSimulatedDevice(simulatedDevice1, null); var simulatedDevice2 = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: this.serverConfiguration.GatewayID)); simulatedDevice2.LoRaDevice.DeviceID = "00000002"; simulatedDevice2.LoRaDevice.NwkSKey = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"; var loraDevice2 = TestUtils.CreateFromSimulatedDevice(simulatedDevice2, null); var existingCache = new DevEUIToLoRaDeviceDictionary(); this.cache.Set <DevEUIToLoRaDeviceDictionary>(simulatedDevice1.LoRaDevice.DevAddr, existingCache); existingCache.TryAdd(loraDevice1.DevEUI, loraDevice1); existingCache.TryAdd(loraDevice2.DevEUI, loraDevice2); var payload = simulatedDevice1.CreateUnconfirmedDataUpMessage("1234"); payload.SerializeUplink(simulatedDevice1.AppSKey, simulatedDevice1.NwkSKey); var apiService = new Mock <LoRaDeviceAPIServiceBase>(); var request = new WaitableLoRaRequest(payload); var requestHandler = new Mock <ILoRaDataRequestHandler>(MockBehavior.Strict); requestHandler.Setup(x => x.ProcessRequestAsync(request, loraDevice1)) .ReturnsAsync(new LoRaDeviceRequestProcessResult(loraDevice1, request)); loraDevice1.SetRequestHandler(requestHandler.Object); var target = new LoRaDeviceRegistry(this.serverConfiguration, this.cache, apiService.Object, this.loraDeviceFactoryMock.Object); target.GetLoRaRequestQueue(request).Queue(request); Assert.True(await request.WaitCompleteAsync()); Assert.True(request.ProcessingSucceeded); // Device was searched by DevAddr apiService.VerifyAll(); // Device was created by factory this.loraDeviceFactoryMock.VerifyAll(); requestHandler.VerifyAll(); }
public async Task When_Device_Does_Not_Exist_Should_Complete_Requests_As_Failed(int loadDevicesDurationInMs) { var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1)); var devAddr = simulatedDevice.DevAddr; var payload1 = simulatedDevice.CreateUnconfirmedDataUpMessage("1"); payload1.SerializeUplink(simulatedDevice.AppSKey, simulatedDevice.NwkSKey); var apiService = new Mock <LoRaDeviceAPIServiceBase>(); var searchMock = apiService.Setup(x => x.SearchByDevAddrAsync(devAddr)); if (loadDevicesDurationInMs > 0) { searchMock.ReturnsAsync(new SearchDevicesResult(), TimeSpan.FromMilliseconds(loadDevicesDurationInMs)); } else { searchMock.ReturnsAsync(new SearchDevicesResult()); } var deviceFactory = new Mock <ILoRaDeviceFactory>(MockBehavior.Strict); var destinationDictionary = new DevEUIToLoRaDeviceDictionary(); var finished = new SemaphoreSlim(0); var target = new DeviceLoaderSynchronizer( devAddr, apiService.Object, deviceFactory.Object, destinationDictionary, null, this.serverConfiguration, (_, l) => { finished.Release(); }, (d) => destinationDictionary.TryAdd(d.DevEUI, d)); var req1 = new WaitableLoRaRequest(payload1); target.Queue(req1); await finished.WaitAsync(); Assert.True(await req1.WaitCompleteAsync()); Assert.Equal(LoRaDeviceRequestFailedReason.NotMatchingDeviceByDevAddr, req1.ProcessingFailedReason); var payload2 = simulatedDevice.CreateUnconfirmedDataUpMessage("2"); payload2.SerializeUplink(simulatedDevice.AppSKey, simulatedDevice.NwkSKey); var req2 = new WaitableLoRaRequest(payload2); target.Queue(req2); Assert.True(await req2.WaitCompleteAsync()); Assert.Equal(LoRaDeviceRequestFailedReason.NotMatchingDeviceByDevAddr, req2.ProcessingFailedReason); // Device was searched by DevAddr apiService.VerifyAll(); }
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"); payload.SerializeUplink(simulatedDevice.AppSKey, simulatedDevice.NwkSKey); var apiService = new Mock <LoRaDeviceAPIServiceBase>(); var iotHubDeviceInfo = new IoTHubDeviceInfo(simulatedDevice.LoRaDevice.DevAddr, simulatedDevice.LoRaDevice.DeviceID, string.Empty) { GatewayId = "a_different_one", }; apiService.Setup(x => x.SearchByDevAddrAsync(It.IsNotNull <string>())) .ReturnsAsync(new SearchDevicesResult(iotHubDeviceInfo.AsList())); var loRaDeviceClient = new Mock <ILoRaDeviceClient>(MockBehavior.Strict); var deviceFactory = new TestLoRaDeviceFactory(loRaDeviceClient.Object); var destinationDictionary = new DevEUIToLoRaDeviceDictionary(); var finished = new SemaphoreSlim(0); var target = new DeviceLoaderSynchronizer( simulatedDevice.DevAddr, apiService.Object, deviceFactory, destinationDictionary, null, this.serverConfiguration, (_, l) => { finished.Release(); }, (d) => destinationDictionary.TryAdd(d.DevEUI, d)); var request = new WaitableLoRaRequest(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(), 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(); }
public async Task When_Multiple_Devices_With_Same_DevAddr_Are_Cached_Should_Find_Matching_By_Mic(string deviceGatewayID) { var simulatedDevice1 = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: deviceGatewayID)); var loraDevice1 = TestUtils.CreateFromSimulatedDevice(simulatedDevice1, null); var simulatedDevice2 = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: this.serverConfiguration.GatewayID)); simulatedDevice2.LoRaDevice.DeviceID = "00000002"; simulatedDevice2.LoRaDevice.NwkSKey = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"; var loraDevice2 = TestUtils.CreateFromSimulatedDevice(simulatedDevice2, null); var existingCache = new DevEUIToLoRaDeviceDictionary(); this.cache.Set <DevEUIToLoRaDeviceDictionary>(simulatedDevice1.LoRaDevice.DevAddr, existingCache); existingCache.TryAdd(loraDevice1.DevEUI, loraDevice1); existingCache.TryAdd(loraDevice2.DevEUI, loraDevice2); var payload = simulatedDevice1.CreateUnconfirmedDataUpMessage("1234"); payload.SerializeUplink(simulatedDevice1.AppSKey, simulatedDevice1.NwkSKey); var apiService = new Mock <LoRaDeviceAPIServiceBase>(); var target = new LoRaDeviceRegistry(this.serverConfiguration, this.cache, apiService.Object, this.loraDeviceFactoryMock.Object); var actual = await target.GetDeviceForPayloadAsync(payload); Assert.NotNull(actual); Assert.Same(loraDevice1, actual); Assert.True(actual.IsOurDevice); // Device was searched by DevAddr apiService.VerifyAll(); // Device was created by factory this.loraDeviceFactoryMock.VerifyAll(); }
/// <summary> /// Creates a <see cref="IMemoryCache"/> containing the <paramref name="loRaDevice"/> already available. /// </summary> public IMemoryCache NewNonEmptyCache(LoRaDevice loRaDevice) { var cache = new MemoryCache(new MemoryCacheOptions()); // add by dev addr var dictionary = new DevEUIToLoRaDeviceDictionary(); dictionary.TryAdd(loRaDevice.DevEUI, loRaDevice); cache.Set(loRaDevice.DevAddr, dictionary); // add device by deveui cache.Set(LoRaDeviceRegistry.CacheKeyForDevEUIDevice(loRaDevice.DevEUI), loRaDevice); return(cache); }
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.DeviceID, string.Empty); apiService.Setup(x => x.SearchByDevAddrAsync(It.IsNotNull <string>())) .ReturnsAsync(new SearchDevicesResult(iotHubDeviceInfo.AsList())); // Will get device twin var loRaDeviceClient = new Mock <ILoRaDeviceClient>(MockBehavior.Strict); loRaDeviceClient.Setup(x => x.GetTwinAsync()) .ReturnsAsync(TestUtils.CreateABPTwin(simulatedDevice)); var deviceFactory = new TestLoRaDeviceFactory(loRaDeviceClient.Object); var destinationDictionary = new DevEUIToLoRaDeviceDictionary(); var finished = new SemaphoreSlim(0); var target = new DeviceLoaderSynchronizer( simulatedDevice.DevAddr, apiService.Object, deviceFactory, destinationDictionary, null, this.serverConfiguration, (_, l) => { finished.Release(); }, (d) => destinationDictionary.TryAdd(d.DevEUI, d)); var payload = simulatedDevice.CreateUnconfirmedDataUpMessage("1234"); payload.SerializeUplink(simulatedDevice.AppSKey, "00000000000000000000000000EEAAFF"); var request = new WaitableLoRaRequest(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(); }
public async Task When_Getting_C2D_Message_Fails_To_Resolve_Fcnt_Down_Should_Drop_Message_And_Return_Null() { const int initialFcntDown = 5; const int initialFcntUp = 21; const int payloadFcnt = 23; var simulatedDevice = new SimulatedDevice(TestDeviceInfo.CreateABPDevice(1, gatewayID: null)); simulatedDevice.FrmCntUp = initialFcntUp; simulatedDevice.FrmCntDown = initialFcntDown; var devEUI = simulatedDevice.LoRaDevice.DeviceID; var devAddr = simulatedDevice.LoRaDevice.DevAddr; // message will be sent var loRaDeviceClient = new Mock <ILoRaDeviceClient>(MockBehavior.Strict); loRaDeviceClient.Setup(x => x.SendEventAsync(It.IsNotNull <LoRaDeviceTelemetry>(), null)) .ReturnsAsync(true); var cloudToDeviceMessage = new Message(); cloudToDeviceMessage.Properties.Add("fport", "1"); // C2D message will be retrieved loRaDeviceClient.Setup(x => x.ReceiveAsync(It.IsAny <TimeSpan>())) .ReturnsAsync(cloudToDeviceMessage); // C2D message will be abandonned loRaDeviceClient.Setup(x => x.AbandonAsync(cloudToDeviceMessage)) .ReturnsAsync(true); // Lora device api var loRaDeviceApi = new Mock <LoRaDeviceAPIServiceBase>(MockBehavior.Strict); // getting the fcnt down will return 0! loRaDeviceApi.Setup(x => x.NextFCntDownAsync(devEUI, initialFcntDown, payloadFcnt, this.ServerConfiguration.GatewayID)) .ReturnsAsync((ushort)0); // using factory to create mock of var loRaDeviceFactory = new TestLoRaDeviceFactory(loRaDeviceClient.Object); var memoryCache = new MemoryCache(new MemoryCacheOptions()); var cachedDevice = TestUtils.CreateFromSimulatedDevice(simulatedDevice, loRaDeviceClient.Object); var devEUIDeviceDict = new DevEUIToLoRaDeviceDictionary(); devEUIDeviceDict.TryAdd(devEUI, cachedDevice); memoryCache.Set(devAddr, devEUIDeviceDict); var deviceRegistry = new LoRaDeviceRegistry(this.ServerConfiguration, memoryCache, loRaDeviceApi.Object, loRaDeviceFactory); var frameCounterUpdateStrategyFactory = new LoRaDeviceFrameCounterUpdateStrategyFactory(this.ServerConfiguration.GatewayID, loRaDeviceApi.Object); // Send to message processor var messageProcessor = new MessageProcessor( this.ServerConfiguration, deviceRegistry, frameCounterUpdateStrategyFactory, new LoRaPayloadDecoder()); // sends unconfirmed message var unconfirmedMessagePayload = simulatedDevice.CreateUnconfirmedDataUpMessage("hello", fcnt: payloadFcnt); var rxpk = unconfirmedMessagePayload.SerializeUplink(simulatedDevice.AppSKey, simulatedDevice.NwkSKey).Rxpk[0]; var unconfirmedMessageResult = await messageProcessor.ProcessMessageAsync(rxpk); Assert.Null(unconfirmedMessageResult); var cachedDevices = deviceRegistry.InternalGetCachedDevicesForDevAddr(simulatedDevice.DevAddr); Assert.True(cachedDevices.TryGetValue(devEUI, out var loRaDevice)); // fcnt down did not change Assert.Equal(initialFcntDown, loRaDevice.FCntDown); // fcnt up changed Assert.Equal(unconfirmedMessagePayload.GetFcnt(), loRaDevice.FCntUp); loRaDeviceClient.Verify(x => x.ReceiveAsync(It.IsAny <TimeSpan>()), Times.Once()); loRaDeviceClient.Verify(x => x.AbandonAsync(It.IsAny <Message>()), Times.Once()); loRaDeviceClient.VerifyAll(); loRaDeviceApi.VerifyAll(); }