Beispiel #1
0
        public async Task When_Disposed_While_Refreshing_We_Shutdown_Gracefully()
        {
            using var cache = new TestDeviceCache(this.quickRefreshOptions, true);
            var deviceMock = CreateMockDevice();

            deviceMock.Setup(x => x.InitializeAsync(It.IsAny <NetworkServerConfiguration>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync((NetworkServerConfiguration config, CancellationToken token) =>
            {
                token.WaitHandle.WaitOne();
                throw new LoRaProcessingException("Refresh failed.", LoRaProcessingErrorCode.DeviceInitializationFailed);
            });

            var device = deviceMock.Object;

            cache.Register(device);

            while (!deviceMock.Invocations.Any(x => x.Method.Name == nameof(LoRaDevice.InitializeAsync)))
            {
                await Task.Delay(5);
            }

            cache.Dispose();
            var count = cache.DeviceRefreshCount;
            await Task.Delay(this.quickRefreshOptions.ValidationInterval * 2);

            Assert.Equal(count, cache.DeviceRefreshCount);
        }
Beispiel #2
0
        public async Task When_Device_Is_Fresh_No_Refresh_Is_Triggered()
        {
            using var cache   = new TestDeviceCache(this.quickRefreshOptions);
            using var device  = CreateTestDevice();
            device.LastUpdate = DateTime.UtcNow + TimeSpan.FromMinutes(1);

            cache.Register(device);
            using var cts = new CancellationTokenSource(this.quickRefreshOptions.ValidationInterval * 2);
            await Assert.ThrowsAsync <OperationCanceledException>(() => cache.WaitForRefreshAsync(cts.Token));
        }
Beispiel #3
0
        public async Task When_Refresh_Fails_It_Is_Retried()
        {
            using var cache = new TestDeviceCache(this.quickRefreshOptions, true);
            var deviceMock = CreateMockDevice();

            deviceMock.SetupSequence(x => x.InitializeAsync(It.IsAny <NetworkServerConfiguration>(), It.IsAny <CancellationToken>()))
            .ThrowsAsync(new LoRaProcessingException("Refresh failed.", LoRaProcessingErrorCode.DeviceInitializationFailed))
            .ReturnsAsync(true);

            var device = deviceMock.Object;

            cache.Register(device);

            await cache.WaitForRefreshCallsAsync(3);

            deviceMock.Verify(x => x.InitializeAsync(It.IsAny <NetworkServerConfiguration>(), It.IsAny <CancellationToken>()), Times.AtLeast(2));
        }
Beispiel #4
0
        public void Mic_Validation_Is_Used_To_Validate_Items(bool isValid)
        {
            using var device = CreateTestDevice();
            using var cache  = new TestDeviceCache(this.noRefreshOptions, (_, _) => isValid);

            cache.Register(device);

            var payload = new LoRaPayloadData(device.DevAddr.Value, new MacHeader(MacMessageType.UnconfirmedDataUp),
                                              FrameControlFlags.None, 1, string.Empty, "payload", FramePort.AppMin,
                                              mic: null, NullLogger.Instance);

            Assert.Equal(isValid, cache.TryGetForPayload(payload, out _));

            var stats = cache.CalculateStatistics();

            Assert.Equal(isValid ? 1 : 0, stats.Hit);
            Assert.Equal(isValid ? 0 : 1, stats.Miss);
        }
Beispiel #5
0
        public async Task When_Device_Expires_It_Is_Refreshed()
        {
            var moqCallback = new Mock <Action <LoRaDevice> >();

            using var cache = new TestDeviceCache(moqCallback.Object, this.quickRefreshOptions, true);
            var deviceMock     = CreateMockDevice();
            var disposableMock = new Mock <IDisposable>();

            deviceMock.Setup(x => x.BeginDeviceClientConnectionActivity())
            .Returns(disposableMock.Object);
            var device = deviceMock.Object;

            cache.Register(device);
            await cache.WaitForRefreshAsync(CancellationToken.None);

            moqCallback.Verify(x => x.Invoke(device));
            disposableMock.Verify(x => x.Dispose(), Times.Once);
        }
Beispiel #6
0
        public async Task When_Device_Inactive_It_Is_Removed()
        {
            var options = this.quickRefreshOptions with
            {
                MaxUnobservedLifetime = TimeSpan.FromMilliseconds(1)
            };

            using var cache = new TestDeviceCache(options);

            var connectionManager = new Mock <ILoRaDeviceClientConnectionManager>();

            using var device = new LoRaDevice(new DevAddr(0xabc), new DevEui(0x123), connectionManager.Object)
                  {
                      LastSeen = DateTime.UtcNow
                  };

            cache.Register(device);
            using var cts = new CancellationTokenSource(this.quickRefreshOptions.ValidationInterval * 2);
            await cache.WaitForRemoveAsync(cts.Token);

            Assert.False(cache.TryGetByDevEui(device.DevEUI, out _));
            connectionManager.Verify(x => x.Release(device), Times.Once);
        }
Beispiel #7
0
        public void Last_Seen_Is_Updated_Depending_On_Cache_Hit(bool cacheHit)
        {
            using var device = CreateTestDevice();
            using var cache  = new TestDeviceCache(this.noRefreshOptions, (_, _) => cacheHit);

            cache.Register(device);

            var payload = new LoRaPayloadData(device.DevAddr.Value, new MacHeader(MacMessageType.UnconfirmedDataUp),
                                              FrameControlFlags.None, 1, string.Empty, "payload", FramePort.AppMin,
                                              mic: null, NullLogger.Instance);

            var lastSeen = device.LastSeen;

            cache.TryGetForPayload(payload, out _);

            if (cacheHit)
            {
                Assert.True(device.LastSeen > lastSeen);
            }
            else
            {
                Assert.Equal(device.LastSeen, lastSeen);
            }
        }