public void ConvertedMessageHasAnEnqueuedTimeProperty() { IMessage actualMessage = new TwinMessageConverter().ToMessage(new Twin()); Assert.InRange( DateTime.Parse(actualMessage.SystemProperties[SystemProperties.EnqueuedTime], null, DateTimeStyles.RoundtripKind), DateTime.UtcNow.Subtract(new TimeSpan(0, 1, 0)), DateTime.UtcNow); }
public async Task UpdateReportedPropertiesTest() { string id = "d1"; var reported1 = new TwinCollection { ["p1"] = "vp1", ["p3"] = "v3" }; TwinCollection receivedTwinPatch = null; var twinStore = new Mock <ITwinStore>(MockBehavior.Strict); twinStore.Setup(c => c.UpdateReportedProperties(id, It.IsAny <TwinCollection>())) .Callback <string, TwinCollection>((s, t) => receivedTwinPatch = t) .Returns(Task.CompletedTask); TwinCollection receivedTwinPatch2 = null; var reportedPropertiesStore = new Mock <IReportedPropertiesStore>(MockBehavior.Strict); reportedPropertiesStore.Setup(r => r.InitSyncToCloud(id)); reportedPropertiesStore.Setup(r => r.Update(id, It.IsAny <TwinCollection>())) .Callback <string, TwinCollection>((s, t) => receivedTwinPatch2 = t) .Returns(Task.CompletedTask); var cloudSync = Mock.Of <ICloudSync>(); var twinMessageConverter = new TwinMessageConverter(); var connectionManager = Mock.Of <IConnectionManager>(); var twinCollectionConverter = new TwinCollectionMessageConverter(); var reportedPropertiesValidator = Mock.Of <IValidator <TwinCollection> >(); var deviceConnectivityManager = Mock.Of <IDeviceConnectivityManager>(); var twinManager = new StoringTwinManager( connectionManager, twinCollectionConverter, twinMessageConverter, reportedPropertiesValidator, twinStore.Object, reportedPropertiesStore.Object, cloudSync, deviceConnectivityManager, TimeSpan.FromMinutes(10)); IMessage reportedPropertiesMessage = twinCollectionConverter.ToMessage(reported1); // Act await twinManager.UpdateReportedPropertiesAsync(id, reportedPropertiesMessage); // Assert twinStore.VerifyAll(); reportedPropertiesStore.VerifyAll(); Assert.NotNull(receivedTwinPatch); Assert.NotNull(receivedTwinPatch2); Assert.Equal(reported1.ToJson(), receivedTwinPatch.ToJson()); Assert.Equal(reported1.ToJson(), receivedTwinPatch2.ToJson()); }
public void CheckVersionConvertion() { var messageConverter = new TwinMessageConverter(); var twin = new Twin("d1") { Version = 10 }; IMessage message = messageConverter.ToMessage(twin); Twin convertedTwin = messageConverter.FromMessage(message); Assert.Equal(twin.Version, convertedTwin.Version); }
public async Task DeviceConnectionNoSubscriptionTest() { string id = "d1"; var identity = Mock.Of <IIdentity>(i => i.Id == id); var twinStore = new Mock <ITwinStore>(MockBehavior.Strict); twinStore.Setup(c => c.Get(id)) .ReturnsAsync(Option.None <Twin>()); var reportedPropertiesStore = new Mock <IReportedPropertiesStore>(MockBehavior.Strict); reportedPropertiesStore.Setup(r => r.SyncToCloud(id)) .Returns(Task.CompletedTask); var deviceProxy = new Mock <IDeviceProxy>(MockBehavior.Strict); var cloudSync = new Mock <ICloudSync>(MockBehavior.Strict); var twinMessageConverter = new TwinMessageConverter(); var twinCollectionConverter = new TwinCollectionMessageConverter(); var reportedPropertiesValidator = Mock.Of <IValidator <TwinCollection> >(); var connectionManager = Mock.Of <IConnectionManager>( c => c.CheckClientSubscription(id, DeviceSubscription.DesiredPropertyUpdates) == false && c.GetConnectedClients() == new[] { identity }); var deviceConnectivityManager = new Mock <IDeviceConnectivityManager>(); var twinManager = new StoringTwinManager( connectionManager, twinCollectionConverter, twinMessageConverter, reportedPropertiesValidator, twinStore.Object, reportedPropertiesStore.Object, cloudSync.Object, deviceConnectivityManager.Object, TimeSpan.FromMinutes(10)); // Act deviceConnectivityManager.Raise(d => d.DeviceConnected += null, this, new EventArgs()); // Assert await Task.Delay(TimeSpan.FromSeconds(3)); twinStore.VerifyAll(); reportedPropertiesStore.VerifyAll(); Mock.Get(connectionManager).VerifyAll(); cloudSync.VerifyAll(); deviceProxy.VerifyAll(); }
public void ConvertsTwinMessagesToMqttMessages(Twin twin, string expectedJson) { EdgeMessage expectedMessage = new EdgeMessage.Builder(expectedJson.ToBody()) .SetSystemProperties(new Dictionary <string, string>() { [SystemProperties.EnqueuedTime] = "" }) .Build(); IMessage actualMessage = new TwinMessageConverter().ToMessage(twin); Assert.Equal(expectedMessage.Body, actualMessage.Body); Assert.Equal(expectedMessage.Properties, actualMessage.Properties); Assert.Equal(expectedMessage.SystemProperties.Keys, actualMessage.SystemProperties.Keys); }
public static async Task <EdgeHubConnection> GetEdgeHubConnection() { var connectionManager = new ConnectionManager(Mock.Of <ICloudConnectionProvider>(), Mock.Of <ICredentialsCache>(), Mock.Of <IIdentityProvider>(), Mock.Of <IDeviceConnectivityManager>()); var endpointFactory = new EndpointFactory(connectionManager, new RoutingMessageConverter(), "testHubEdgeDevice1", 10, 10, false); var routeFactory = new EdgeRouteFactory(endpointFactory); var twinCollectionMessageConverter = new TwinCollectionMessageConverter(); var twinMessageConverter = new TwinMessageConverter(); var dbStoreProvider = new InMemoryDbStoreProvider(); IStoreProvider storeProvider = new StoreProvider(dbStoreProvider); IEntityStore <string, TwinInfo> twinStore = storeProvider.GetEntityStore <string, TwinInfo>("twins"); var twinManager = new TwinManager(connectionManager, twinCollectionMessageConverter, twinMessageConverter, Option.Some(twinStore)); var versionInfo = new VersionInfo(string.Empty, string.Empty, string.Empty); return(await EdgeHubConnection.Create( Mock.Of <IIdentity>(i => i.Id == "someid"), Mock.Of <IEdgeHub>(), twinManager, Mock.Of <IConnectionManager>(), routeFactory, twinCollectionMessageConverter, versionInfo, new NullDeviceScopeIdentitiesCache())); }
public async Task TestEdgeHubConnection() { const string EdgeDeviceId = "testHubEdgeDevice1"; var twinMessageConverter = new TwinMessageConverter(); var twinCollectionMessageConverter = new TwinCollectionMessageConverter(); var messageConverterProvider = new MessageConverterProvider( new Dictionary <Type, IMessageConverter>() { { typeof(Message), new DeviceClientMessageConverter() }, { typeof(Twin), twinMessageConverter }, { typeof(TwinCollection), twinCollectionMessageConverter } }); string iotHubConnectionString = await SecretsHelper.GetSecretFromConfigKey("iotHubConnStrKey"); IotHubConnectionStringBuilder iotHubConnectionStringBuilder = IotHubConnectionStringBuilder.Create(iotHubConnectionString); RegistryManager registryManager = RegistryManager.CreateFromConnectionString(iotHubConnectionString); await registryManager.OpenAsync(); string iothubHostName = iotHubConnectionStringBuilder.HostName; var identityProvider = new IdentityProvider(iothubHostName); var identityFactory = new ClientCredentialsFactory(identityProvider); (string edgeDeviceId, string deviceConnStr) = await RegistryManagerHelper.CreateDevice(EdgeDeviceId, iotHubConnectionString, registryManager, true, false); string edgeHubConnectionString = $"{deviceConnStr};ModuleId={EdgeHubModuleId}"; IClientCredentials edgeHubCredentials = identityFactory.GetWithConnectionString(edgeHubConnectionString); string sasKey = ConnectionStringHelper.GetSharedAccessKey(deviceConnStr); var signatureProvider = new SharedAccessKeySignatureProvider(sasKey); var credentialsCache = Mock.Of <ICredentialsCache>(); var metadataStore = new Mock <IMetadataStore>(); metadataStore.Setup(m => m.GetMetadata(It.IsAny <string>())).ReturnsAsync(new ConnectionMetadata("dummyValue")); var cloudConnectionProvider = new CloudConnectionProvider( messageConverterProvider, 1, new ClientProvider(), Option.None <UpstreamProtocol>(), new ClientTokenProvider(signatureProvider, iothubHostName, edgeDeviceId, TimeSpan.FromMinutes(60)), Mock.Of <IDeviceScopeIdentitiesCache>(), credentialsCache, edgeHubCredentials.Identity, TimeSpan.FromMinutes(60), true, TimeSpan.FromSeconds(20), false, Option.None <IWebProxy>(), metadataStore.Object); var deviceConnectivityManager = Mock.Of <IDeviceConnectivityManager>(); var connectionManager = new ConnectionManager(cloudConnectionProvider, Mock.Of <ICredentialsCache>(), identityProvider, deviceConnectivityManager); try { Mock.Get(credentialsCache) .Setup(c => c.Get(edgeHubCredentials.Identity)) .ReturnsAsync(Option.Some(edgeHubCredentials)); Assert.NotNull(edgeHubCredentials); Assert.NotNull(edgeHubCredentials.Identity); // Set Edge hub desired properties await this.SetDesiredProperties(registryManager, edgeDeviceId); var endpointFactory = new EndpointFactory(connectionManager, new RoutingMessageConverter(), edgeDeviceId, 10, 10); var routeFactory = new EdgeRouteFactory(endpointFactory); var dbStoreProvider = new InMemoryDbStoreProvider(); IStoreProvider storeProvider = new StoreProvider(dbStoreProvider); IEntityStore <string, TwinInfo> twinStore = storeProvider.GetEntityStore <string, TwinInfo>("twins"); var twinManager = new TwinManager(connectionManager, twinCollectionMessageConverter, twinMessageConverter, Option.Some(twinStore)); var routerConfig = new RouterConfig(Enumerable.Empty <Route>()); TimeSpan defaultTimeout = TimeSpan.FromSeconds(60); var endpointExecutorFactory = new SyncEndpointExecutorFactory(new EndpointExecutorConfig(defaultTimeout, new FixedInterval(0, TimeSpan.FromSeconds(1)), defaultTimeout, true)); Router router = await Router.CreateAsync(Guid.NewGuid().ToString(), iothubHostName, routerConfig, endpointExecutorFactory); IInvokeMethodHandler invokeMethodHandler = new InvokeMethodHandler(connectionManager); var subscriptionProcessor = new SubscriptionProcessor(connectionManager, invokeMethodHandler, deviceConnectivityManager); IEdgeHub edgeHub = new RoutingEdgeHub(router, new RoutingMessageConverter(), connectionManager, twinManager, edgeDeviceId, invokeMethodHandler, subscriptionProcessor); cloudConnectionProvider.BindEdgeHub(edgeHub); var versionInfo = new VersionInfo("v1", "b1", "c1"); // Create Edge Hub connection EdgeHubConnection edgeHubConnection = await EdgeHubConnection.Create( edgeHubCredentials.Identity, edgeHub, twinManager, connectionManager, routeFactory, twinCollectionMessageConverter, versionInfo, new NullDeviceScopeIdentitiesCache()); await Task.Delay(TimeSpan.FromMinutes(1)); TwinConfigSource configSource = new TwinConfigSource(edgeHubConnection, edgeHubCredentials.Identity.Id, versionInfo, twinManager, twinMessageConverter, twinCollectionMessageConverter, routeFactory); // Get and Validate EdgeHubConfig Option <EdgeHubConfig> edgeHubConfigOption = await configSource.GetConfig(); Assert.True(edgeHubConfigOption.HasValue); EdgeHubConfig edgeHubConfig = edgeHubConfigOption.OrDefault(); Assert.Equal("1.0", edgeHubConfig.SchemaVersion); Assert.NotNull(edgeHubConfig.Routes); Assert.NotNull(edgeHubConfig.StoreAndForwardConfiguration); Assert.Equal(20, edgeHubConfig.StoreAndForwardConfiguration.TimeToLiveSecs); IReadOnlyDictionary <string, RouteConfig> routes = edgeHubConfig.Routes; Assert.Equal(4, routes.Count); RouteConfig route1 = routes["route1"]; Assert.True(route1.Route.Endpoint.GetType() == typeof(CloudEndpoint)); Assert.Equal("route1", route1.Name); Assert.Equal("from /* INTO $upstream", route1.Value); RouteConfig route2 = routes["route2"]; Endpoint endpoint = route2.Route.Endpoint; Assert.True(endpoint.GetType() == typeof(ModuleEndpoint)); Assert.Equal($"{edgeDeviceId}/module2/input1", endpoint.Id); Assert.Equal("route2", route2.Name); Assert.Equal("from /modules/module1 INTO BrokeredEndpoint(\"/modules/module2/inputs/input1\")", route2.Value); RouteConfig route3 = routes["route3"]; endpoint = route3.Route.Endpoint; Assert.True(endpoint.GetType() == typeof(ModuleEndpoint)); Assert.Equal($"{edgeDeviceId}/module3/input1", endpoint.Id); Assert.Equal("route3", route3.Name); Assert.Equal("from /modules/module2 INTO BrokeredEndpoint(\"/modules/module3/inputs/input1\")", route3.Value); RouteConfig route4 = routes["route4"]; endpoint = route4.Route.Endpoint; Assert.True(endpoint.GetType() == typeof(ModuleEndpoint)); Assert.Equal($"{edgeDeviceId}/module4/input1", endpoint.Id); Assert.Equal("route4", route4.Name); Assert.Equal("from /modules/module3 INTO BrokeredEndpoint(\"/modules/module4/inputs/input1\")", route4.Value); // Make sure reported properties were updated appropriately EdgeHubConnection.ReportedProperties reportedProperties = await this.GetReportedProperties(registryManager, edgeDeviceId); Assert.Equal(200, reportedProperties.LastDesiredStatus.Code); Assert.NotNull(reportedProperties.Clients); Assert.Equal(0, reportedProperties.Clients.Count); Assert.Equal("1.0", reportedProperties.SchemaVersion); Assert.Equal(versionInfo, reportedProperties.VersionInfo); // Simulate a module and a downstream device that connects to Edge Hub. string moduleId = "module1"; string sasToken = TokenHelper.CreateSasToken($"{iothubHostName}/devices/{edgeDeviceId}/modules/{moduleId}"); string moduleConnectionstring = $"HostName={iothubHostName};DeviceId={edgeDeviceId};ModuleId={moduleId};SharedAccessSignature={sasToken}"; IClientCredentials moduleClientCredentials = identityFactory.GetWithConnectionString(moduleConnectionstring); var moduleProxy = Mock.Of <IDeviceProxy>(d => d.IsActive); string downstreamDeviceId = "device1"; sasToken = TokenHelper.CreateSasToken($"{iothubHostName}/devices/{downstreamDeviceId}"); string downstreamDeviceConnectionstring = $"HostName={iothubHostName};DeviceId={downstreamDeviceId};SharedAccessSignature={sasToken}"; IClientCredentials downstreamDeviceCredentials = identityFactory.GetWithConnectionString(downstreamDeviceConnectionstring); var downstreamDeviceProxy = Mock.Of <IDeviceProxy>(d => d.IsActive); // Connect the module and downstream device and make sure the reported properties are updated as expected. await connectionManager.AddDeviceConnection(moduleClientCredentials.Identity, moduleProxy); await connectionManager.AddDeviceConnection(downstreamDeviceCredentials.Identity, downstreamDeviceProxy); string moduleIdKey = $"{edgeDeviceId}/{moduleId}"; await Task.Delay(TimeSpan.FromSeconds(10)); reportedProperties = await this.GetReportedProperties(registryManager, edgeDeviceId); Assert.Equal(2, reportedProperties.Clients.Count); Assert.Equal(ConnectionStatus.Connected, reportedProperties.Clients[moduleIdKey].Status); Assert.NotNull(reportedProperties.Clients[moduleIdKey].LastConnectedTimeUtc); Assert.Null(reportedProperties.Clients[moduleIdKey].LastDisconnectTimeUtc); Assert.Equal(ConnectionStatus.Connected, reportedProperties.Clients[downstreamDeviceId].Status); Assert.NotNull(reportedProperties.Clients[downstreamDeviceId].LastConnectedTimeUtc); Assert.Null(reportedProperties.Clients[downstreamDeviceId].LastDisconnectTimeUtc); Assert.Equal(200, reportedProperties.LastDesiredStatus.Code); Assert.Equal("1.0", reportedProperties.SchemaVersion); Assert.Equal(versionInfo, reportedProperties.VersionInfo); // Update desired propertied and make sure callback is called with valid values bool callbackCalled = false; Task ConfigUpdatedCallback(EdgeHubConfig updatedConfig) { Assert.NotNull(updatedConfig); Assert.NotNull(updatedConfig.StoreAndForwardConfiguration); Assert.NotNull(updatedConfig.Routes); routes = updatedConfig.Routes; Assert.Equal(4, routes.Count); route1 = routes["route1"]; Assert.True(route1.Route.Endpoint.GetType() == typeof(CloudEndpoint)); Assert.Equal("route1", route1.Name); Assert.Equal("from /* INTO $upstream", route1.Value); route2 = routes["route2"]; endpoint = route2.Route.Endpoint; Assert.True(endpoint.GetType() == typeof(ModuleEndpoint)); Assert.Equal($"{edgeDeviceId}/module2/input1", endpoint.Id); Assert.Equal("route2", route2.Name); Assert.Equal("from /modules/module1 INTO BrokeredEndpoint(\"/modules/module2/inputs/input1\")", route2.Value); route3 = routes["route4"]; endpoint = route3.Route.Endpoint; Assert.True(endpoint.GetType() == typeof(ModuleEndpoint)); Assert.Equal($"{edgeDeviceId}/module5/input1", endpoint.Id); Assert.Equal("route4", route3.Name); Assert.Equal("from /modules/module3 INTO BrokeredEndpoint(\"/modules/module5/inputs/input1\")", route3.Value); route4 = routes["route5"]; endpoint = route4.Route.Endpoint; Assert.True(endpoint.GetType() == typeof(ModuleEndpoint)); Assert.Equal($"{edgeDeviceId}/module6/input1", endpoint.Id); Assert.Equal("route5", route4.Name); Assert.Equal("from /modules/module5 INTO BrokeredEndpoint(\"/modules/module6/inputs/input1\")", route4.Value); callbackCalled = true; return(Task.CompletedTask); } configSource.SetConfigUpdatedCallback(ConfigUpdatedCallback); await this.UpdateDesiredProperties(registryManager, edgeDeviceId); await Task.Delay(TimeSpan.FromSeconds(5)); Assert.True(callbackCalled); reportedProperties = await this.GetReportedProperties(registryManager, edgeDeviceId); Assert.Equal(200, reportedProperties.LastDesiredStatus.Code); Assert.NotNull(reportedProperties.Clients); Assert.Equal(2, reportedProperties.Clients.Count); Assert.Equal("1.0", reportedProperties.SchemaVersion); Assert.Equal(versionInfo, reportedProperties.VersionInfo); // Disconnect the downstream device and make sure the reported properties are updated as expected. await connectionManager.RemoveDeviceConnection(moduleIdKey); await connectionManager.RemoveDeviceConnection(downstreamDeviceId); await Task.Delay(TimeSpan.FromSeconds(10)); reportedProperties = await this.GetReportedProperties(registryManager, edgeDeviceId); Assert.Equal(1, reportedProperties.Clients.Count); Assert.True(reportedProperties.Clients.ContainsKey(moduleIdKey)); Assert.False(reportedProperties.Clients.ContainsKey(downstreamDeviceId)); Assert.Equal(ConnectionStatus.Disconnected, reportedProperties.Clients[moduleIdKey].Status); Assert.NotNull(reportedProperties.Clients[moduleIdKey].LastConnectedTimeUtc); Assert.NotNull(reportedProperties.Clients[moduleIdKey].LastDisconnectTimeUtc); Assert.Equal(200, reportedProperties.LastDesiredStatus.Code); Assert.Equal("1.0", reportedProperties.SchemaVersion); Assert.Equal(versionInfo, reportedProperties.VersionInfo); // If the edge hub restarts, clear out the connected devices in the reported properties. await EdgeHubConnection.Create( edgeHubCredentials.Identity, edgeHub, twinManager, connectionManager, routeFactory, twinCollectionMessageConverter, versionInfo, new NullDeviceScopeIdentitiesCache()); await Task.Delay(TimeSpan.FromMinutes(1)); reportedProperties = await this.GetReportedProperties(registryManager, edgeDeviceId); Assert.Null(reportedProperties.Clients); Assert.Equal("1.0", reportedProperties.SchemaVersion); Assert.Equal(versionInfo, reportedProperties.VersionInfo); } finally { try { await RegistryManagerHelper.RemoveDevice(edgeDeviceId, registryManager); } catch (Exception) { // ignored } } }
public async Task TestSendMessages() { // Arrange const string Id = "id1"; var identity = Mock.Of <IIdentity>(i => i.Id == Id); var twinMessageConverter = new TwinMessageConverter(); var twinCollectionMessageConverter = new TwinCollectionMessageConverter(); var messageConverterProvider = new MessageConverterProvider( new Dictionary <Type, IMessageConverter>() { { typeof(Message), new DeviceClientMessageConverter() }, { typeof(Shared.Twin), twinMessageConverter }, { typeof(TwinCollection), twinCollectionMessageConverter } }); var edgeHubTokenProvider = new Mock <ITokenProvider>(); var clientWatcher = new ClientWatcher(); var clientProvider = new Mock <IClientProvider>(); clientProvider.Setup(c => c.Create(identity, edgeHubTokenProvider.Object, It.IsAny <ITransportSettings[]>(), Option.None <string>())) .Returns(() => new ThrowingClient(clientWatcher, 3)); var deviceScopeIdentitiesCache = new Mock <IDeviceScopeIdentitiesCache>(); deviceScopeIdentitiesCache.Setup(d => d.GetServiceIdentity(Id)) .ReturnsAsync( Option.Some( new ServiceIdentity( Id, "dummy", new List <string>(), new ServiceAuthentication(new SymmetricKeyAuthentication("foo", "bar")), ServiceIdentityStatus.Enabled))); deviceScopeIdentitiesCache.Setup(d => d.GetAuthChain(It.Is <string>(i => i == Id))) .ReturnsAsync(Option.Some(Id)); var edgeHubIdentity = Mock.Of <IIdentity>(); ConnectionMetadata connectionMetadata = new ConnectionMetadata("edgeProdInfo"); var metadataStore = new Mock <IMetadataStore>(); metadataStore.Setup(p => p.GetMetadata(Id)) .ReturnsAsync(connectionMetadata); var identityProvider = new Mock <IIdentityProvider>(); identityProvider.Setup(i => i.Create(Id)).Returns(identity); var credentialsCache = new Mock <ICredentialsCache>(); var edgeHub = new Mock <IEdgeHub>(); var connectionProvider = new CloudConnectionProvider( messageConverterProvider, 1, clientProvider.Object, Option.None <UpstreamProtocol>(), edgeHubTokenProvider.Object, deviceScopeIdentitiesCache.Object, credentialsCache.Object, edgeHubIdentity, TimeSpan.FromMinutes(10), false, TimeSpan.FromMinutes(10), false, Option.None <IWebProxy>(), metadataStore.Object, scopeAuthenticationOnly: true, trackDeviceState: true, true); connectionProvider.BindEdgeHub(edgeHub.Object); var deviceConnectivityManager = Mock.Of <IDeviceConnectivityManager>(); var connectionManager = new ConnectionManager(connectionProvider, credentialsCache.Object, identityProvider.Object, deviceConnectivityManager); var messagesToSend = new List <IMessage>(); for (int i = 0; i < 10; i++) { var message = new EdgeMessage.Builder(new byte[i]) .SetSystemProperties( new Dictionary <string, string>() { [SystemProperties.MessageId] = i.ToString() }) .Build(); messagesToSend.Add(message); } // Act Option <ICloudProxy> cloudProxyOption = await connectionManager.GetCloudConnection(Id); // Assert Assert.True(cloudProxyOption.HasValue); ICloudProxy cloudProxy = cloudProxyOption.OrDefault(); Assert.True(cloudProxy.IsActive); // Act await RunSendMessages(cloudProxy, messagesToSend); // Assert Assert.Equal(messagesToSend.Count, clientWatcher.ReceivedMessages.Count()); Assert.Equal(5, clientWatcher.OpenAsyncCount); Assert.True(cloudProxy.IsActive); IEnumerable <string> expectedMessageIds = messagesToSend.Select(m => m.SystemProperties[SystemProperties.MessageId]); IEnumerable <string> receivedMessageIds = clientWatcher.ReceivedMessages.Select(m => m.MessageId); Assert.Equal(expectedMessageIds, receivedMessageIds); }
public async Task TestGetTwin() { // Arrange const string Id = "id1"; var identity = Mock.Of <IIdentity>(i => i.Id == Id); var twinMessageConverter = new TwinMessageConverter(); var twinCollectionMessageConverter = new TwinCollectionMessageConverter(); var messageConverterProvider = new MessageConverterProvider( new Dictionary <Type, IMessageConverter>() { { typeof(Message), new DeviceClientMessageConverter() }, { typeof(Shared.Twin), twinMessageConverter }, { typeof(TwinCollection), twinCollectionMessageConverter } }); var edgeHubTokenProvider = new Mock <ITokenProvider>(); var clientWatcher = new ClientWatcher(); var clientProvider = new Mock <IClientProvider>(); clientProvider.Setup(c => c.Create(identity, edgeHubTokenProvider.Object, It.IsAny <ITransportSettings[]>(), Option.None <string>())) .Returns(() => new ThrowingClient(clientWatcher, 3)); var deviceScopeIdentitiesCache = new Mock <IDeviceScopeIdentitiesCache>(); deviceScopeIdentitiesCache.Setup(d => d.GetServiceIdentity(Id)) .ReturnsAsync( Option.Some( new ServiceIdentity( Id, "dummy", new List <string>(), new ServiceAuthentication(new SymmetricKeyAuthentication("foo", "bar")), ServiceIdentityStatus.Enabled))); deviceScopeIdentitiesCache.Setup(d => d.GetAuthChain(It.Is <string>(i => i == Id))) .ReturnsAsync(Option.Some(Id)); var edgeHubIdentity = Mock.Of <IIdentity>(); ConnectionMetadata connectionMetadata = new ConnectionMetadata("edgeProdInfo"); var metadataStore = new Mock <IMetadataStore>(); metadataStore.Setup(p => p.GetMetadata(Id)) .ReturnsAsync(connectionMetadata); var identityProvider = new Mock <IIdentityProvider>(); identityProvider.Setup(i => i.Create(Id)).Returns(identity); var credentialsCache = new Mock <ICredentialsCache>(); var edgeHub = new Mock <IEdgeHub>(); var connectionProvider = new CloudConnectionProvider( messageConverterProvider, 1, clientProvider.Object, Option.None <UpstreamProtocol>(), edgeHubTokenProvider.Object, deviceScopeIdentitiesCache.Object, credentialsCache.Object, edgeHubIdentity, TimeSpan.FromMinutes(10), false, TimeSpan.FromMinutes(10), false, Option.None <IWebProxy>(), metadataStore.Object, true); connectionProvider.BindEdgeHub(edgeHub.Object); var deviceConnectivityManager = Mock.Of <IDeviceConnectivityManager>(); var connectionManager = new ConnectionManager(connectionProvider, credentialsCache.Object, identityProvider.Object, deviceConnectivityManager); // Act Option <ICloudProxy> cloudProxyOption = await connectionManager.GetCloudConnection(Id); // Assert Assert.True(cloudProxyOption.HasValue); ICloudProxy cloudProxy = cloudProxyOption.OrDefault(); Assert.True(cloudProxy.IsActive); // Act await RunGetTwin(cloudProxy, 10); // Assert Assert.Equal(5, clientWatcher.OpenAsyncCount); Assert.True(cloudProxy.IsActive); Assert.Equal(10, clientWatcher.GetTwinCount); }
public async Task TestMultipleOperations() { // Arrange const string Id = "id1"; var identity = Mock.Of <IIdentity>(i => i.Id == Id); var twinMessageConverter = new TwinMessageConverter(); var twinCollectionMessageConverter = new TwinCollectionMessageConverter(); var messageConverterProvider = new MessageConverterProvider( new Dictionary <Type, IMessageConverter> { { typeof(Message), new DeviceClientMessageConverter() }, { typeof(Shared.Twin), twinMessageConverter }, { typeof(TwinCollection), twinCollectionMessageConverter } }); var edgeHubTokenProvider = new Mock <ITokenProvider>(); var clientWatcher = new ClientWatcher(); var clientProvider = new Mock <IClientProvider>(); clientProvider.Setup(c => c.Create(identity, edgeHubTokenProvider.Object, It.IsAny <ITransportSettings[]>())) .Returns(() => new ThrowingClient(clientWatcher, 15)); var deviceScopeIdentitiesCache = new Mock <IDeviceScopeIdentitiesCache>(); deviceScopeIdentitiesCache.Setup(d => d.GetServiceIdentity(Id, false)) .ReturnsAsync( Option.Some( new ServiceIdentity( Id, "dummy", new List <string>(), new ServiceAuthentication(new SymmetricKeyAuthentication("foo", "bar")), ServiceIdentityStatus.Enabled))); var edgeHubIdentity = Mock.Of <IIdentity>(); var productInfoStore = new Mock <IProductInfoStore>(); productInfoStore.Setup(p => p.GetEdgeProductInfo(Id)) .ReturnsAsync("ProdInfo1"); var identityProvider = new Mock <IIdentityProvider>(); identityProvider.Setup(i => i.Create(Id)).Returns(identity); var credentialsCache = new Mock <ICredentialsCache>(); var edgeHub = new Mock <IEdgeHub>(); var connectionProvider = new CloudConnectionProvider( messageConverterProvider, 1, clientProvider.Object, Option.None <UpstreamProtocol>(), edgeHubTokenProvider.Object, deviceScopeIdentitiesCache.Object, credentialsCache.Object, edgeHubIdentity, TimeSpan.FromMinutes(10), false, TimeSpan.FromMinutes(10), Option.None <IWebProxy>(), productInfoStore.Object); connectionProvider.BindEdgeHub(edgeHub.Object); var connectionManager = new ConnectionManager(connectionProvider, credentialsCache.Object, identityProvider.Object); async Task <ICloudProxy> GetCloudProxy(IConnectionManager cm) { // Act Option <ICloudProxy> cloudProxyOption = await cm.GetCloudConnection(Id); // Assert Assert.True(cloudProxyOption.HasValue); ICloudProxy cloudProxy = cloudProxyOption.OrDefault(); Assert.True(cloudProxy.IsActive); return(cloudProxy); } var messagesToSend = new List <IMessage>(); for (int i = 0; i < 60; i++) { var message = new EdgeMessage.Builder(new byte[i]) .SetSystemProperties( new Dictionary <string, string>() { [SystemProperties.MessageId] = i.ToString() }) .Build(); messagesToSend.Add(message); } // Act ICloudProxy cloudProxy1 = await GetCloudProxy(connectionManager); ICloudProxy cloudProxy2 = await GetCloudProxy(connectionManager); ICloudProxy cloudProxy3 = await GetCloudProxy(connectionManager); // Act var tasks = new[] { RunGetTwin(cloudProxy1, 10), RunGetTwin(cloudProxy2, 30), RunGetTwin(cloudProxy3, 10), RunSendMessages(cloudProxy1, messagesToSend.Take(20), 2), RunSendMessages(cloudProxy2, messagesToSend.Skip(20).Take(10)), RunSendMessages(cloudProxy3, messagesToSend.Skip(30).Take(30), 3) }; await Task.WhenAll(tasks); // Assert Assert.Equal(50, clientWatcher.GetTwinCount); List <string> expectedMessageIds = messagesToSend .Select(m => m.SystemProperties[SystemProperties.MessageId]) .OrderBy(s => s) .ToList(); List <string> receivedMessageIds = clientWatcher.ReceivedMessages .Select(m => m.MessageId) .OrderBy(s => s) .ToList(); Assert.Equal(expectedMessageIds.Count, receivedMessageIds.Count); Assert.Equal(expectedMessageIds, receivedMessageIds); }
public async Task DeviceConnectionSyncPeriodTest() { string id = "d1"; var identity = Mock.Of <IIdentity>(i => i.Id == id); var desired2 = new TwinCollection { ["p1"] = "vp1", ["p2"] = "v2", ["p3"] = "v3", ["$version"] = 2 }; var reported2 = new TwinCollection { ["p2"] = "vp2", ["$version"] = 2 }; var twin2 = new Twin { Properties = new TwinProperties { Reported = reported2, Desired = desired2 } }; var twinStore = new Mock <ITwinStore>(MockBehavior.Strict); twinStore.Setup(c => c.Get(id)) .ReturnsAsync(Option.Some(twin2)); Twin storedTwin = null; twinStore.Setup(c => c.Update(id, It.IsAny <Twin>())) .Callback <string, Twin>((s, t) => storedTwin = t) .Returns(Task.CompletedTask); var reportedPropertiesStore = new Mock <IReportedPropertiesStore>(MockBehavior.Strict); reportedPropertiesStore.Setup(r => r.SyncToCloud(id)) .Returns(Task.CompletedTask); var deviceProxy = new Mock <IDeviceProxy>(MockBehavior.Strict); var cloudSync = new Mock <ICloudSync>(MockBehavior.Strict); cloudSync.Setup(c => c.GetTwin(id)) .ReturnsAsync(Option.Some(twin2)); var twinMessageConverter = new TwinMessageConverter(); var twinCollectionConverter = new TwinCollectionMessageConverter(); var reportedPropertiesValidator = Mock.Of <IValidator <TwinCollection> >(); var connectionManager = Mock.Of <IConnectionManager>( c => c.CheckClientSubscription(id, DeviceSubscription.DesiredPropertyUpdates) && c.GetDeviceConnection(id) == Option.Some(deviceProxy.Object) && c.GetConnectedClients() == new[] { identity }); var deviceConnectivityManager = new Mock <IDeviceConnectivityManager>(); var twinManager = new StoringTwinManager( connectionManager, twinCollectionConverter, twinMessageConverter, reportedPropertiesValidator, twinStore.Object, reportedPropertiesStore.Object, cloudSync.Object, deviceConnectivityManager.Object, TimeSpan.FromMinutes(10)); // Act IMessage getTwinMessage = await twinManager.GetTwinAsync(id); // Assert Assert.NotNull(getTwinMessage); Twin getTwin = twinMessageConverter.FromMessage(getTwinMessage); Assert.NotNull(getTwin); Assert.Equal(twin2.ToJson(), getTwin.ToJson()); // Act deviceConnectivityManager.Raise(d => d.DeviceConnected += null, this, new EventArgs()); // Assert await Task.Delay(TimeSpan.FromSeconds(3)); twinStore.VerifyAll(); reportedPropertiesStore.VerifyAll(); deviceProxy.VerifyAll(); cloudSync.Verify(c => c.GetTwin(id), Times.AtMostOnce); Assert.NotNull(storedTwin); Assert.Equal(twin2.ToJson(), storedTwin.ToJson()); }
public async Task UpdateDesiredPropertiesWithIncorrectPatchTest() { string id = "d1"; var desired0 = new TwinCollection { ["p0"] = "vp0", ["$version"] = 0 }; var reported0 = new TwinCollection { ["p0"] = "vp0", ["$version"] = 0 }; var twinBase = new Twin { Properties = new TwinProperties { Reported = reported0, Desired = desired0 } }; var desired2 = new TwinCollection { ["p1"] = "vp1", ["p2"] = "v2", ["p3"] = "v3", ["$version"] = 2 }; var reported2 = new TwinCollection { ["p2"] = "vp2", ["$version"] = 2 }; var twin2 = new Twin { Properties = new TwinProperties { Reported = reported2, Desired = desired2 } }; var desired2Patch = new TwinCollection { ["p1"] = "vp1", ["$version"] = 2 }; var twinStore = new Mock <ITwinStore>(MockBehavior.Strict); twinStore.Setup(c => c.Get(id)) .ReturnsAsync(Option.Some(twinBase)); Twin storedTwin = null; twinStore.Setup(c => c.Update(id, It.IsAny <Twin>())) .Callback <string, Twin>((s, t) => storedTwin = t) .Returns(Task.CompletedTask); var reportedPropertiesStore = new Mock <IReportedPropertiesStore>(MockBehavior.Strict); IMessage receivedTwinPatchMessage = null; var deviceProxy = new Mock <IDeviceProxy>(); deviceProxy.Setup(d => d.OnDesiredPropertyUpdates(It.IsAny <IMessage>())) .Callback <IMessage>(m => receivedTwinPatchMessage = m) .Returns(Task.CompletedTask); var cloudSync = Mock.Of <ICloudSync>(c => c.GetTwin(id) == Task.FromResult(Option.Some(twin2))); var twinMessageConverter = new TwinMessageConverter(); var twinCollectionConverter = new TwinCollectionMessageConverter(); var reportedPropertiesValidator = Mock.Of <IValidator <TwinCollection> >(); var deviceConnectivityManager = Mock.Of <IDeviceConnectivityManager>(); var connectionManager = Mock.Of <IConnectionManager>( c => c.CheckClientSubscription(id, DeviceSubscription.DesiredPropertyUpdates) && c.GetDeviceConnection(id) == Option.Some(deviceProxy.Object)); var twinManager = new StoringTwinManager( connectionManager, twinCollectionConverter, twinMessageConverter, reportedPropertiesValidator, twinStore.Object, reportedPropertiesStore.Object, cloudSync, deviceConnectivityManager, TimeSpan.FromMinutes(10)); IMessage desiredPropertiesMessage = twinCollectionConverter.ToMessage(desired2Patch); // Act await twinManager.UpdateDesiredPropertiesAsync(id, desiredPropertiesMessage); // Assert twinStore.VerifyAll(); reportedPropertiesStore.VerifyAll(); Assert.NotNull(storedTwin); Assert.NotNull(receivedTwinPatchMessage); Assert.Equal(twin2.ToJson(), storedTwin.ToJson()); TwinCollection receivedTwinPatch2 = twinCollectionConverter.FromMessage(receivedTwinPatchMessage); Assert.Equal("{\"p0\":null,\"$version\":2,\"p1\":\"vp1\",\"p2\":\"v2\",\"p3\":\"v3\"}", receivedTwinPatch2.ToJson()); }
public async Task GetTwinTest() { // Arrange string id = "d1"; var desired1 = new TwinCollection { ["p1"] = "vp1", ["p3"] = "v3", ["$version"] = 1 }; var reported1 = new TwinCollection { ["p1"] = "vp1", ["p3"] = "v3", ["$version"] = 1 }; var twin1 = new Twin { Properties = new TwinProperties { Desired = desired1, Reported = reported1 } }; var cloudSync = new Mock <ICloudSync>(); cloudSync.SetupSequence(c => c.GetTwin(id)) .ReturnsAsync(Option.None <Twin>()) .ReturnsAsync(Option.Some(twin1)) .ReturnsAsync(Option.None <Twin>()); Twin receivedTwin = null; var twinStore = new Mock <ITwinStore>(); twinStore.Setup(c => c.Update(id, It.IsAny <Twin>())) .Callback <string, Twin>((s, t) => receivedTwin = t) .Returns(Task.CompletedTask); twinStore.Setup(c => c.Get(id)) .ReturnsAsync(() => Option.Maybe(receivedTwin)); var twinMessageConverter = new TwinMessageConverter(); var connectionManager = Mock.Of <IConnectionManager>(); var twinCollectionConverter = Mock.Of <IMessageConverter <TwinCollection> >(); var reportedPropertiesValidator = Mock.Of <IValidator <TwinCollection> >(); var reportedPropertiesStore = Mock.Of <IReportedPropertiesStore>(); var deviceConnectivityManager = Mock.Of <IDeviceConnectivityManager>(); var twinManager = new StoringTwinManager( connectionManager, twinCollectionConverter, twinMessageConverter, reportedPropertiesValidator, twinStore.Object, reportedPropertiesStore, cloudSync.Object, deviceConnectivityManager, TimeSpan.FromMinutes(10)); // Act IMessage twinMessage = await twinManager.GetTwinAsync(id); // Assert Assert.NotNull(twinMessage); Twin twin = twinMessageConverter.FromMessage(twinMessage); Assert.NotNull(twin); Assert.Equal("{\"deviceId\":null,\"etag\":null,\"version\":null,\"properties\":{\"desired\":{},\"reported\":{}}}", twin.ToJson()); // Act twinMessage = await twinManager.GetTwinAsync(id); // Assert Assert.NotNull(twinMessage); twin = twinMessageConverter.FromMessage(twinMessage); Assert.NotNull(twin); Assert.NotNull(receivedTwin); Assert.Equal(receivedTwin.ToJson(), twin.ToJson()); Assert.Equal(twin1.ToJson(), twin.ToJson()); // Act twinMessage = await twinManager.GetTwinAsync(id); // Assert Assert.NotNull(twinMessage); twin = twinMessageConverter.FromMessage(twinMessage); Assert.NotNull(twin); Assert.NotNull(receivedTwin); Assert.Equal(receivedTwin.ToJson(), twin.ToJson()); Assert.Equal(twin1.ToJson(), twin.ToJson()); }