public async Task TestInitialConfigUpdate_WaitForInit() { // Arrange string id = "id"; string iotHub = "foo.azure-devices.net"; var routerConfig = new RouterConfig(Enumerable.Empty<Route>()); var messageStore = new Mock<IMessageStore>(); messageStore.Setup(m => m.SetTimeToLive(It.IsAny<TimeSpan>())); TimeSpan updateFrequency = TimeSpan.FromSeconds(10); Endpoint GetEndpoint() => new ModuleEndpoint("id", Guid.NewGuid().ToString(), "in1", Mock.Of<IConnectionManager>(), Mock.Of<Core.IMessageConverter<IMessage>>()); var endpointFactory = new Mock<IEndpointFactory>(); endpointFactory.Setup(e => e.CreateSystemEndpoint($"$upstream")).Returns(GetEndpoint); var routeFactory = new EdgeRouteFactory(endpointFactory.Object); var endpointExecutorFactory = new Mock<IEndpointExecutorFactory>(); endpointExecutorFactory.Setup(e => e.CreateAsync(It.IsAny<Endpoint>())) .Returns<Endpoint>(endpoint => Task.FromResult(Mock.Of<IEndpointExecutor>(e => e.Endpoint == endpoint))); Router router = await Router.CreateAsync(id, iotHub, routerConfig, endpointExecutorFactory.Object); var routes1 = Routes.Take(2) .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value))); var storeAndForwardConfiguration1 = new StoreAndForwardConfiguration(7200); var edgeHubConfig1 = new EdgeHubConfig("1.0", routes1, storeAndForwardConfiguration1); var configProvider = new Mock<IConfigSource>(); configProvider.SetupSequence(c => c.GetConfig()) .Returns(async () => { await Task.Delay(5000); return Option.Some(edgeHubConfig1); }); configProvider.Setup(c => c.SetConfigUpdatedCallback(It.IsAny<Func<EdgeHubConfig, Task>>())); // Act var configUpdater = new ConfigUpdater(router, messageStore.Object, updateFrequency, Option.None<IConfigSource>()); await configUpdater.Init(configProvider.Object); // Assert Assert.Equal(2, router.Routes.Count); // After 6 seconds no updates await Task.Delay(TimeSpan.FromSeconds(6)); Assert.Equal(2, router.Routes.Count); }
static async Task <(IEdgeHub, IConnectionManager)> SetupEdgeHub(IEnumerable <string> routes, IoTHub iotHub, string edgeDeviceId) { string iotHubName = "testHub"; Routing.UserMetricLogger = NullRoutingUserMetricLogger.Instance; Routing.PerfCounter = NullRoutingPerfCounter.Instance; Routing.UserAnalyticsLogger = NullUserAnalyticsLogger.Instance; RetryStrategy defaultRetryStrategy = new FixedInterval(0, TimeSpan.FromSeconds(1)); TimeSpan defaultRevivePeriod = TimeSpan.FromHours(1); TimeSpan defaultTimeout = TimeSpan.FromSeconds(60); var endpointExecutorConfig = new EndpointExecutorConfig(defaultTimeout, defaultRetryStrategy, defaultRevivePeriod, true); var cloudProxy = new Mock <ICloudProxy>(); cloudProxy.Setup(c => c.SendMessageAsync(It.IsAny <IMessage>())).Callback <IMessage>(m => iotHub.ReceivedMessages.Add(m)).Returns(Task.CompletedTask); cloudProxy.Setup(c => c.SendMessageBatchAsync(It.IsAny <IEnumerable <IMessage> >())).Callback <IEnumerable <IMessage> >(m => iotHub.ReceivedMessages.AddRange(m)).Returns(Task.CompletedTask); cloudProxy.Setup(c => c.UpdateReportedPropertiesAsync(It.IsAny <IMessage>())).Callback <IMessage>(m => iotHub.ReceivedMessages.Add(m)).Returns(Task.CompletedTask); cloudProxy.SetupGet(c => c.IsActive).Returns(true); var cloudConnection = Mock.Of <ICloudConnection>(c => c.IsActive && c.CloudProxy == Option.Some(cloudProxy.Object)); var cloudConnectionProvider = new Mock <ICloudConnectionProvider>(); cloudConnectionProvider.Setup(c => c.Connect(It.IsAny <IClientCredentials>(), It.IsAny <Action <string, CloudConnectionStatus> >())).ReturnsAsync(Try.Success(cloudConnection)); var deviceConnectivityManager = Mock.Of <IDeviceConnectivityManager>(); IConnectionManager connectionManager = new ConnectionManager(cloudConnectionProvider.Object, Mock.Of <ICredentialsCache>(), new IdentityProvider(iotHubName), deviceConnectivityManager); var routingMessageConverter = new RoutingMessageConverter(); RouteFactory routeFactory = new EdgeRouteFactory(new EndpointFactory(connectionManager, routingMessageConverter, edgeDeviceId, 10, 10)); IEnumerable <Route> routesList = routeFactory.Create(routes).ToList(); IEnumerable <Endpoint> endpoints = routesList.Select(r => r.Endpoint); var routerConfig = new RouterConfig(endpoints, routesList); IDbStoreProvider dbStoreProvider = new InMemoryDbStoreProvider(); IStoreProvider storeProvider = new StoreProvider(dbStoreProvider); IMessageStore messageStore = new MessageStore(storeProvider, CheckpointStore.Create(storeProvider), TimeSpan.MaxValue); IEndpointExecutorFactory endpointExecutorFactory = new StoringAsyncEndpointExecutorFactory(endpointExecutorConfig, new AsyncEndpointExecutorOptions(1, TimeSpan.FromMilliseconds(10)), messageStore); Router router = await Router.CreateAsync(Guid.NewGuid().ToString(), iotHubName, routerConfig, endpointExecutorFactory); ITwinManager twinManager = new TwinManager(connectionManager, new TwinCollectionMessageConverter(), new TwinMessageConverter(), Option.None <IEntityStore <string, TwinInfo> >()); var invokeMethodHandler = Mock.Of <IInvokeMethodHandler>(); var subscriptionProcessor = new SubscriptionProcessor(connectionManager, invokeMethodHandler, deviceConnectivityManager); IEdgeHub edgeHub = new RoutingEdgeHub(router, routingMessageConverter, connectionManager, twinManager, edgeDeviceId, invokeMethodHandler, subscriptionProcessor); return(edgeHub, connectionManager); }
async Task <(IMessageConsumer, IMessageConsumer, NullBrokerConnector)> SetupEnvironment() { Routing.UserMetricLogger = NullRoutingUserMetricLogger.Instance; Routing.PerfCounter = NullRoutingPerfCounter.Instance; Routing.UserAnalyticsLogger = NullUserAnalyticsLogger.Instance; var defaultRetryStrategy = new FixedInterval(5, TimeSpan.FromSeconds(5)); var defaultRevivePeriod = TimeSpan.FromHours(1); var defaultTimeout = TimeSpan.FromSeconds(60); var endpointExecutorConfig = new EndpointExecutorConfig(defaultTimeout, defaultRetryStrategy, defaultRevivePeriod, true); var cloudProxyDispatcher = new BrokeredCloudProxyDispatcher(); var cloudConnectionProvider = new BrokeredCloudConnectionProvider(cloudProxyDispatcher); var identityProvider = new IdentityProvider(iotHubName); var deviceConnectivityManager = new BrokeredDeviceConnectivityManager(cloudProxyDispatcher); var connectionManager = new ConnectionManager(cloudConnectionProvider, Mock.Of <ICredentialsCache>(), new IdentityProvider(iotHubName), deviceConnectivityManager); var routingMessageConverter = new RoutingMessageConverter(); var routeFactory = new EdgeRouteFactory(new EndpointFactory(connectionManager, routingMessageConverter, edgeDeviceId, 10, 10)); var routesList = new[] { routeFactory.Create("FROM /messages INTO $upstream") }; var endpoints = routesList.Select(r => r.Endpoint); var routerConfig = new RouterConfig(endpoints, routesList); var dbStoreProvider = new InMemoryDbStoreProvider(); var storeProvider = new StoreProvider(dbStoreProvider); var messageStore = new MessageStore(storeProvider, CheckpointStore.Create(storeProvider), TimeSpan.MaxValue, false, 1800); var endpointExecutorFactory = new StoringAsyncEndpointExecutorFactory(endpointExecutorConfig, new AsyncEndpointExecutorOptions(1, TimeSpan.FromMilliseconds(10)), messageStore); var router = await Router.CreateAsync(Guid.NewGuid().ToString(), iotHubName, routerConfig, endpointExecutorFactory); var messageConverterProvider = new MessageConverterProvider( new Dictionary <Type, IMessageConverter>() { { typeof(Twin), new TwinMessageConverter() }, { typeof(TwinCollection), new TwinCollectionMessageConverter() } }); var twinManager = TwinManager.CreateTwinManager(connectionManager, messageConverterProvider, Option.None <IStoreProvider>()); var invokeMethodHandler = Mock.Of <IInvokeMethodHandler>(); var subscriptionProcessor = new SubscriptionProcessor(connectionManager, invokeMethodHandler, deviceConnectivityManager); var edgeHub = new RoutingEdgeHub(router, routingMessageConverter, connectionManager, twinManager, edgeDeviceId, edgeModuleName, invokeMethodHandler, subscriptionProcessor, Mock.Of <IDeviceScopeIdentitiesCache>()); var brokerConnector = new NullBrokerConnector(cloudProxyDispatcher); cloudProxyDispatcher.SetConnector(brokerConnector); cloudProxyDispatcher.BindEdgeHub(edgeHub); var connectionProvider = new ConnectionProvider(connectionManager, edgeHub, TimeSpan.FromSeconds(30)); var authenticator = new NullAuthenticator(); var edgeHubIdentity = new ModuleIdentity(iotHubName, edgeDeviceId, edgeModuleName); var tokenCredentials = new TokenCredentials(edgeHubIdentity, "qwerty", "test-product", Option.Some("test-model"), Option.None <string>(), false); var systemComponentProvider = new SystemComponentIdProvider(tokenCredentials); var connectionHandler = default(ConnectionHandler); connectionHandler = new ConnectionHandler( Task.FromResult <IConnectionProvider>(connectionProvider), Task.FromResult <IAuthenticator>(authenticator), identityProvider, systemComponentProvider, DeviceProxyFactory); DeviceProxy DeviceProxyFactory(IIdentity identity, bool isDirectClient) { return(new DeviceProxy(identity, isDirectClient, connectionHandler, Mock.Of <ITwinHandler>(), Mock.Of <IModuleToModuleMessageHandler>(), Mock.Of <ICloud2DeviceMessageHandler>(), Mock.Of <IDirectMethodHandler>())); } var cloud2DeviceMessageHandler = new Cloud2DeviceMessageHandler(connectionHandler); var moduleToModuleMessageHandler = new ModuleToModuleMessageHandler(connectionHandler, identityProvider, new ModuleToModuleResponseTimeout(TimeSpan.FromSeconds(10))); var directMethodHandler = new DirectMethodHandler(connectionHandler, identityProvider); var twinHandler = new TwinHandler(connectionHandler, identityProvider); var subscriptionChangeHandler = new SubscriptionChangeHandler( cloud2DeviceMessageHandler, moduleToModuleMessageHandler, directMethodHandler, twinHandler, connectionHandler, identityProvider); return(subscriptionChangeHandler, cloudProxyDispatcher, brokerConnector); }
public async Task TestPeriodicConfigUpdate() { // Arrange string id = "id"; string iotHub = "foo.azure-devices.net"; var routerConfig = new RouterConfig(Enumerable.Empty <Route>()); var messageStore = new Mock <IMessageStore>(); messageStore.Setup(m => m.SetTimeToLive(It.IsAny <TimeSpan>())); TimeSpan updateFrequency = TimeSpan.FromSeconds(10); Endpoint GetEndpoint() => new ModuleEndpoint("id", Guid.NewGuid().ToString(), "in1", Mock.Of <IConnectionManager>(), Mock.Of <Core.IMessageConverter <IMessage> >()); var endpointFactory = new Mock <IEndpointFactory>(); endpointFactory.Setup(e => e.CreateSystemEndpoint($"$upstream")).Returns(GetEndpoint); var routeFactory = new EdgeRouteFactory(endpointFactory.Object); var endpointExecutorFactory = new Mock <IEndpointExecutorFactory>(); endpointExecutorFactory.Setup(e => e.CreateAsync(It.IsAny <Endpoint>())) .Returns <Endpoint>(endpoint => Task.FromResult(Mock.Of <IEndpointExecutor>(e => e.Endpoint == endpoint))); Router router = await Router.CreateAsync(id, iotHub, routerConfig, endpointExecutorFactory.Object); var routes1 = Routes.Take(2) .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value))); var storeAndForwardConfiguration1 = new StoreAndForwardConfiguration(7200); var edgeHubConfig1 = new EdgeHubConfig("1.0", routes1, storeAndForwardConfiguration1); var routes2 = Routes.Take(2) .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value))); var storeAndForwardConfiguration2 = new StoreAndForwardConfiguration(7200); var edgeHubConfig2 = new EdgeHubConfig("1.0", routes2, storeAndForwardConfiguration2); var routes3 = Routes.Take(2) .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value))); var storeAndForwardConfiguration3 = new StoreAndForwardConfiguration(7200); var edgeHubConfig3 = new EdgeHubConfig("1.0", routes3, storeAndForwardConfiguration3); var routes4 = Routes.Skip(2) .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value))); var storeAndForwardConfiguration4 = new StoreAndForwardConfiguration(7200); var edgeHubConfig4 = new EdgeHubConfig("1.0", routes4, storeAndForwardConfiguration4); var routes5 = Routes .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value))); var storeAndForwardConfiguration5 = new StoreAndForwardConfiguration(7200); var edgeHubConfig5 = new EdgeHubConfig("1.0", routes5, storeAndForwardConfiguration5); var routes6 = Routes .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value))); var storeAndForwardConfiguration6 = new StoreAndForwardConfiguration(3600); var edgeHubConfig6 = new EdgeHubConfig("1.0", routes6, storeAndForwardConfiguration6); var configProvider = new Mock <IConfigSource>(); configProvider.SetupSequence(c => c.GetConfig()) .ReturnsAsync(Option.Some(edgeHubConfig1)) .ReturnsAsync(Option.Some(edgeHubConfig2)) .ReturnsAsync(Option.Some(edgeHubConfig3)) .ReturnsAsync(Option.Some(edgeHubConfig4)) .ReturnsAsync(Option.Some(edgeHubConfig5)) .ReturnsAsync(Option.Some(edgeHubConfig6)); configProvider.Setup(c => c.SetConfigUpdatedCallback(It.IsAny <Func <EdgeHubConfig, Task> >())); // Act var configUpdater = new ConfigUpdater(router, messageStore.Object, updateFrequency); configUpdater.Init(configProvider.Object); // Assert await Task.Delay(TimeSpan.FromSeconds(8)); configProvider.Verify(c => c.GetConfig(), Times.Once); endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>()), Times.Once); messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Once); await Task.Delay(TimeSpan.FromSeconds(20)); configProvider.Verify(c => c.GetConfig(), Times.Exactly(3)); endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>()), Times.Once); messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Once); await Task.Delay(TimeSpan.FromSeconds(10)); configProvider.Verify(c => c.GetConfig(), Times.Exactly(4)); endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>()), Times.Once); messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Exactly(2)); await Task.Delay(TimeSpan.FromSeconds(10)); configProvider.Verify(c => c.GetConfig(), Times.Exactly(5)); endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>()), Times.Once); messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Exactly(3)); await Task.Delay(TimeSpan.FromSeconds(10)); configProvider.Verify(c => c.GetConfig(), Times.Exactly(6)); endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>()), Times.Once); messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Exactly(4)); }
public async Task TestPeriodicAndCallbackConfigUpdate() { // Arrange string id = "id"; string iotHub = "foo.azure-devices.net"; var routerConfig = new RouterConfig(Enumerable.Empty <Route>()); var messageStore = new Mock <IMessageStore>(); messageStore.Setup(m => m.SetTimeToLive(It.IsAny <TimeSpan>())); var storageSpaceChecker = new Mock <IStorageSpaceChecker>(); storageSpaceChecker.Setup(m => m.SetMaxSizeBytes(It.IsAny <Option <long> >())); TimeSpan updateFrequency = TimeSpan.FromSeconds(10); Endpoint GetEndpoint() => new ModuleEndpoint("id", Guid.NewGuid().ToString(), "in1", Mock.Of <IConnectionManager>(), Mock.Of <Core.IMessageConverter <IMessage> >()); var endpointFactory = new Mock <IEndpointFactory>(); endpointFactory.Setup(e => e.CreateSystemEndpoint($"$upstream")).Returns(GetEndpoint); var routeFactory = new EdgeRouteFactory(endpointFactory.Object); var endpointExecutorFactory = new Mock <IEndpointExecutorFactory>(); endpointExecutorFactory.Setup(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >())) .Returns <Endpoint, IList <uint> >((endpoint, priorities) => Task.FromResult(Mock.Of <IEndpointExecutor>(e => e.Endpoint == endpoint))); Router router = await Router.CreateAsync(id, iotHub, routerConfig, endpointExecutorFactory.Object); var routes1 = Routes.Take(2) .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value))); var storeAndForwardConfiguration1 = new StoreAndForwardConfiguration(7200); var edgeHubConfig1 = new EdgeHubConfig("1.0", routes1, storeAndForwardConfiguration1); var routes2 = Routes.Take(3) .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value))); var storeAndForwardConfiguration2 = new StoreAndForwardConfiguration(7200); var edgeHubConfig2 = new EdgeHubConfig("1.0", routes2, storeAndForwardConfiguration2); var routes3 = Routes.Take(4) .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value))); var storeAndForwardConfiguration3 = new StoreAndForwardConfiguration(7200); var edgeHubConfig3 = new EdgeHubConfig("1.0", routes3, storeAndForwardConfiguration3); Func <EdgeHubConfig, Task> updateCallback = null; var configProvider = new Mock <IConfigSource>(); configProvider.SetupSequence(c => c.GetConfig()) .ReturnsAsync(Option.Some(edgeHubConfig1)) .ReturnsAsync(Option.Some(edgeHubConfig2)) .ReturnsAsync(Option.Some(edgeHubConfig3)); configProvider.Setup(c => c.SetConfigUpdatedCallback(It.IsAny <Func <EdgeHubConfig, Task> >())) .Callback <Func <EdgeHubConfig, Task> >(callback => { updateCallback = callback; }); configProvider.Setup(c => c.GetCachedConfig()) .Returns(() => Task.FromResult(Option.None <EdgeHubConfig>())); // Act var configUpdater = new ConfigUpdater(router, messageStore.Object, updateFrequency, storageSpaceChecker.Object); await configUpdater.Init(configProvider.Object); // Assert configProvider.Verify(c => c.GetConfig(), Times.Once); endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >()), Times.Once); messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Once); storageSpaceChecker.Verify(m => m.SetMaxSizeBytes(It.Is <Option <long> >(x => x.Equals(Option.None <long>()))), Times.Once); // call update with no changes await updateCallback(edgeHubConfig1); configProvider.Verify(c => c.GetConfig(), Times.Exactly(1)); endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >()), Times.Once); messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Once); storageSpaceChecker.Verify(m => m.SetMaxSizeBytes(It.Is <Option <long> >(x => x.Equals(Option.None <long>()))), Times.Once); await Task.Delay(TimeSpan.FromSeconds(12)); configProvider.Verify(c => c.GetConfig(), Times.Exactly(2)); endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >()), Times.Once); messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Exactly(2)); storageSpaceChecker.Verify(m => m.SetMaxSizeBytes(It.Is <Option <long> >(x => x.Equals(Option.None <long>()))), Times.Exactly(2)); // call update with changes await updateCallback(edgeHubConfig3); configProvider.Verify(c => c.GetConfig(), Times.Exactly(2)); endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >()), Times.Once); messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Exactly(3)); storageSpaceChecker.Verify(m => m.SetMaxSizeBytes(It.Is <Option <long> >(x => x.Equals(Option.None <long>()))), Times.Exactly(3)); await Task.Delay(TimeSpan.FromSeconds(10)); configProvider.Verify(c => c.GetConfig(), Times.Exactly(3)); endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >()), Times.Once); messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Exactly(3)); storageSpaceChecker.Verify(m => m.SetMaxSizeBytes(It.Is <Option <long> >(x => x.Equals(Option.None <long>()))), Times.Exactly(3)); }
public async Task TestInitialConfigUpdate_NoWaitForInit() { // Arrange string id = "id"; string iotHub = "foo.azure-devices.net"; var routerConfig = new RouterConfig(Enumerable.Empty <Route>()); var messageStore = new Mock <IMessageStore>(); messageStore.Setup(m => m.SetTimeToLive(It.IsAny <TimeSpan>())); var storageSpaceChecker = new Mock <IStorageSpaceChecker>(); storageSpaceChecker.Setup(m => m.SetMaxSizeBytes(It.IsAny <Option <long> >())); TimeSpan updateFrequency = TimeSpan.FromMinutes(10); Endpoint GetEndpoint() => new ModuleEndpoint("id", Guid.NewGuid().ToString(), "in1", Mock.Of <IConnectionManager>(), Mock.Of <Core.IMessageConverter <IMessage> >()); var endpointFactory = new Mock <IEndpointFactory>(); endpointFactory.Setup(e => e.CreateSystemEndpoint($"$upstream")).Returns(GetEndpoint); var routeFactory = new EdgeRouteFactory(endpointFactory.Object); var endpointExecutorFactory = new Mock <IEndpointExecutorFactory>(); endpointExecutorFactory.Setup(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >(), It.IsAny <ICheckpointerFactory>())) .Returns <Endpoint, IList <uint>, ICheckpointerFactory>((endpoint, priorities, checkpointerFactory) => Task.FromResult(Mock.Of <IEndpointExecutor>(e => e.Endpoint == endpoint))); Router router = await Router.CreateAsync(id, iotHub, routerConfig, endpointExecutorFactory.Object); var routes1 = Routes.Take(2) .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value))); var storeAndForwardConfiguration1 = new StoreAndForwardConfiguration(7200); var edgeHubConfig1 = new EdgeHubConfig("1.0", routes1, storeAndForwardConfiguration1, Option.None <BrokerConfig>(), Option.None <ManifestIntegrity>()); var routes2 = Routes.Take(3) .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value))); var storeAndForwardConfiguration2 = new StoreAndForwardConfiguration(7200); var edgeHubConfig2 = new EdgeHubConfig("1.0", routes2, storeAndForwardConfiguration2, Option.None <BrokerConfig>(), Option.None <ManifestIntegrity>()); var configProvider = new Mock <IConfigSource>(); configProvider.SetupSequence(c => c.GetConfig()) .Returns(async() => { await Task.Delay(5000); return(Option.Some(edgeHubConfig2)); }); configProvider.Setup(c => c.GetCachedConfig()) .Returns(() => Task.FromResult(Option.Some(edgeHubConfig1))); // Act var configUpdater = new ConfigUpdater(router, messageStore.Object, updateFrequency, storageSpaceChecker.Object); await configUpdater.Init(configProvider.Object); // Assert // First only has updated from prefeched config Assert.Equal(2, router.Routes.Count); // After 6 seconds updates from init received await Task.Delay(TimeSpan.FromSeconds(6)); Assert.Equal(3, router.Routes.Count); }
public async Task TestPeriodicConfigUpdate() { // Arrange string id = "id"; string iotHub = "foo.azure-devices.net"; var routerConfig = new RouterConfig(Enumerable.Empty <Route>()); var messageStore = new Mock <IMessageStore>(); messageStore.Setup(m => m.SetTimeToLive(It.IsAny <TimeSpan>())); var storageSpaceChecker = new Mock <IStorageSpaceChecker>(); storageSpaceChecker.Setup(m => m.SetMaxSizeBytes(It.IsAny <Option <long> >())); TimeSpan updateFrequency = TimeSpan.FromSeconds(10); Endpoint GetEndpoint() => new ModuleEndpoint("id", Guid.NewGuid().ToString(), "in1", Mock.Of <IConnectionManager>(), Mock.Of <Core.IMessageConverter <IMessage> >()); var endpointFactory = new Mock <IEndpointFactory>(); endpointFactory.Setup(e => e.CreateSystemEndpoint($"$upstream")).Returns(GetEndpoint); var routeFactory = new EdgeRouteFactory(endpointFactory.Object); var endpointExecutorFactory = new Mock <IEndpointExecutorFactory>(); endpointExecutorFactory.Setup(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >(), It.IsAny <ICheckpointerFactory>())) .Returns <Endpoint, IList <uint>, ICheckpointerFactory>((endpoint, priorities, checkpointerFactory) => Task.FromResult(Mock.Of <IEndpointExecutor>(e => e.Endpoint == endpoint))); Router router = await Router.CreateAsync(id, iotHub, routerConfig, endpointExecutorFactory.Object); var routes1 = Routes.Take(2) .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value))); var storeAndForwardConfiguration1 = new StoreAndForwardConfiguration(7200); var edgeHubConfig1 = new EdgeHubConfig("1.0", routes1, storeAndForwardConfiguration1, Option.None <BrokerConfig>(), Option.None <ManifestIntegrity>()); var routes2 = Routes.Take(2) .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value))); var storeAndForwardConfiguration2 = new StoreAndForwardConfiguration(7200); var edgeHubConfig2 = new EdgeHubConfig("1.0", routes2, storeAndForwardConfiguration2, Option.None <BrokerConfig>(), Option.None <ManifestIntegrity>()); var routes3 = Routes.Take(2) .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value))); var storeAndForwardConfiguration3 = new StoreAndForwardConfiguration(7200); var edgeHubConfig3 = new EdgeHubConfig("1.0", routes3, storeAndForwardConfiguration3, Option.None <BrokerConfig>(), Option.None <ManifestIntegrity>()); var routes4 = Routes.Skip(2) .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value))); var storeAndForwardConfiguration4 = new StoreAndForwardConfiguration(7200); var edgeHubConfig4 = new EdgeHubConfig("1.0", routes4, storeAndForwardConfiguration4, Option.None <BrokerConfig>(), Option.None <ManifestIntegrity>()); var routes5 = Routes .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value))); var storeAndForwardConfiguration5 = new StoreAndForwardConfiguration(7200); var edgeHubConfig5 = new EdgeHubConfig("1.0", routes5, storeAndForwardConfiguration5, Option.None <BrokerConfig>(), Option.None <ManifestIntegrity>()); var routes6 = Routes .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value))); var storeAndForwardConfiguration6 = new StoreAndForwardConfiguration(3600); var edgeHubConfig6 = new EdgeHubConfig("1.0", routes6, storeAndForwardConfiguration6, Option.None <BrokerConfig>(), Option.None <ManifestIntegrity>()); var routes7 = Routes .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value))); var storeAndForwardConfiguration7 = new StoreAndForwardConfiguration(3600, new StoreLimits(10L)); var edgeHubConfig7 = new EdgeHubConfig("1.0", routes7, storeAndForwardConfiguration7, Option.None <BrokerConfig>(), Option.None <ManifestIntegrity>()); var routes8 = Routes .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value))); var storeAndForwardConfiguration8 = new StoreAndForwardConfiguration(3600, new StoreLimits(20L)); var edgeHubConfig8 = new EdgeHubConfig("1.0", routes8, storeAndForwardConfiguration8, Option.None <BrokerConfig>(), Option.None <ManifestIntegrity>()); var configProvider = new Mock <IConfigSource>(); configProvider.SetupSequence(c => c.GetConfig()) .ReturnsAsync(Option.Some(edgeHubConfig1)) .ReturnsAsync(Option.Some(edgeHubConfig2)) .ReturnsAsync(Option.Some(edgeHubConfig3)) .ReturnsAsync(Option.Some(edgeHubConfig4)) .ReturnsAsync(Option.Some(edgeHubConfig5)) .ReturnsAsync(Option.Some(edgeHubConfig6)) .ReturnsAsync(Option.Some(edgeHubConfig7)) .ReturnsAsync(Option.Some(edgeHubConfig8)) .ReturnsAsync(Option.Some(edgeHubConfig8)); configProvider.Setup(c => c.GetCachedConfig()) .Returns(() => Task.FromResult(Option.None <EdgeHubConfig>())); // Act var configUpdater = new ConfigUpdater(router, messageStore.Object, updateFrequency, storageSpaceChecker.Object); await configUpdater.Init(configProvider.Object); // Assert configProvider.Verify(c => c.GetConfig(), Times.Once); endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >(), It.IsAny <ICheckpointerFactory>()), Times.Once); messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Once); storageSpaceChecker.Verify(m => m.SetMaxSizeBytes(It.Is <Option <long> >(x => x.Equals(Option.None <long>()))), Times.Once); // After 5 seconds, the periodic task should not have run. await Task.Delay(TimeSpan.FromSeconds(5)); configProvider.Verify(c => c.GetConfig(), Times.Once); endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >(), It.IsAny <ICheckpointerFactory>()), Times.Once); messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Once); storageSpaceChecker.Verify(m => m.SetMaxSizeBytes(It.Is <Option <long> >(x => x.Equals(Option.None <long>()))), Times.Once); await Task.Delay(TimeSpan.FromSeconds(20)); configProvider.Verify(c => c.GetConfig(), Times.Exactly(3)); endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >(), It.IsAny <ICheckpointerFactory>()), Times.Once); messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Exactly(3)); storageSpaceChecker.Verify(m => m.SetMaxSizeBytes(It.Is <Option <long> >(x => x.Equals(Option.None <long>()))), Times.Exactly(3)); await Task.Delay(TimeSpan.FromSeconds(10)); configProvider.Verify(c => c.GetConfig(), Times.Exactly(4)); endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >(), It.IsAny <ICheckpointerFactory>()), Times.Once); messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Exactly(4)); storageSpaceChecker.Verify(m => m.SetMaxSizeBytes(It.Is <Option <long> >(x => x.Equals(Option.None <long>()))), Times.Exactly(4)); await Task.Delay(TimeSpan.FromSeconds(10)); configProvider.Verify(c => c.GetConfig(), Times.Exactly(5)); endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >(), It.IsAny <ICheckpointerFactory>()), Times.Once); messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Exactly(5)); storageSpaceChecker.Verify(m => m.SetMaxSizeBytes(It.Is <Option <long> >(x => x.Equals(Option.None <long>()))), Times.Exactly(5)); await Task.Delay(TimeSpan.FromSeconds(10)); configProvider.Verify(c => c.GetConfig(), Times.Exactly(6)); endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >(), It.IsAny <ICheckpointerFactory>()), Times.Once); messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Exactly(6)); storageSpaceChecker.Verify(m => m.SetMaxSizeBytes(It.Is <Option <long> >(x => x.Equals(Option.None <long>()))), Times.Exactly(6)); await Task.Delay(TimeSpan.FromSeconds(10)); configProvider.Verify(c => c.GetConfig(), Times.Exactly(7)); endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >(), It.IsAny <ICheckpointerFactory>()), Times.Once); messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Exactly(7)); storageSpaceChecker.Verify(m => m.SetMaxSizeBytes(It.Is <Option <long> >(x => !x.Equals(Option.None <long>()))), Times.Exactly(1)); await Task.Delay(TimeSpan.FromSeconds(10)); configProvider.Verify(c => c.GetConfig(), Times.Exactly(8)); endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >(), It.IsAny <ICheckpointerFactory>()), Times.Once); messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Exactly(8)); storageSpaceChecker.Verify(m => m.SetMaxSizeBytes(It.Is <Option <long> >(x => !x.Equals(Option.None <long>()))), Times.Exactly(2)); await Task.Delay(TimeSpan.FromSeconds(10)); configProvider.Verify(c => c.GetConfig(), Times.Exactly(9)); endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >(), It.IsAny <ICheckpointerFactory>()), Times.Once); messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Exactly(8)); storageSpaceChecker.Verify(m => m.SetMaxSizeBytes(It.Is <Option <long> >(x => !x.Equals(Option.None <long>()))), Times.Exactly(2)); }