public void Matcher_Ignores_NonRouteEndpoint() { // Arrange var dataSource = new DynamicEndpointDataSource(); var lifetime = new DataSourceDependentMatcher.Lifetime(); var endpoint = new Endpoint(TestConstants.EmptyRequestDelegate, EndpointMetadataCollection.Empty, "test"); dataSource.AddEndpoint(endpoint); // Act var matcher = new DataSourceDependentMatcher(dataSource, lifetime, TestMatcherBuilder.Create); // Assert var inner = Assert.IsType <TestMatcher>(matcher.CurrentMatcher); Assert.Empty(inner.Endpoints); }
public void GetRoutePatternMatcher_CanCache() { // Arrange var endpoint1 = EndpointFactory.CreateRouteEndpoint("{controller}/{action}/{id}", metadata: new object[] { new IntMetadata(1), }); var dataSource = new DynamicEndpointDataSource(endpoint1); var parser = CreateLinkParser(dataSources: new[] { dataSource }); var expected = parser.GetMatcherState(endpoint1); // Act var actual = parser.GetMatcherState(endpoint1); // Assert Assert.Same(expected.Matcher, actual.Matcher); Assert.Same(expected.Constraints, actual.Constraints); }
public void ConsumerChangeToken_IsRefreshed_WhenDataSourceCallbackFires() { // Arrange1 var endpoint1 = CreateEndpoint("/a"); var dataSource1 = new DynamicEndpointDataSource(endpoint1); var compositeDataSource = new CompositeEndpointDataSource(new[] { dataSource1 }); // Act1 var endpoints = compositeDataSource.Endpoints; // Assert1 var changeToken1 = compositeDataSource.GetChangeToken(); var token = Assert.IsType <CancellationChangeToken>(changeToken1); Assert.False(token.HasChanged); // initial state // Arrange2 var endpoint2 = CreateEndpoint("/b"); // Act2 dataSource1.AddEndpoint(endpoint2); // Assert2 Assert.True(changeToken1.HasChanged); // old token is expected to be changed var changeToken2 = compositeDataSource.GetChangeToken(); // new token is in a unchanged state Assert.NotSame(changeToken2, changeToken1); token = Assert.IsType <CancellationChangeToken>(changeToken2); Assert.False(token.HasChanged); // Arrange3 var endpoint3 = CreateEndpoint("/c"); // Act2 dataSource1.AddEndpoint(endpoint3); // Assert2 Assert.True(changeToken2.HasChanged); // old token is expected to be changed var changeToken3 = compositeDataSource.GetChangeToken(); // new token is in a unchanged state Assert.NotSame(changeToken3, changeToken2); Assert.NotSame(changeToken3, changeToken1); token = Assert.IsType <CancellationChangeToken>(changeToken3); Assert.False(token.HasChanged); }
public void Cache_CanDispose_WhenUninitialized() { // Arrange var count = 0; var dataSource = new DynamicEndpointDataSource(); var cache = new DataSourceDependentCache <string>(dataSource, (endpoints) => { count++; return($"hello, {count}!"); }); // Act cache.Dispose(); // Assert dataSource.AddEndpoint(null); Assert.Null(cache.Value); }
public void GetTemplateBinder_CanClearCache() { // Arrange var endpoint1 = EndpointFactory.CreateRouteEndpoint("{controller}/{action}/{id}", metadata: new object[] { new IntMetadata(1), }); var dataSource = new DynamicEndpointDataSource(endpoint1); var linkGenerator = CreateLinkGenerator(dataSources: new[] { dataSource }); var original = linkGenerator.GetTemplateBinder(endpoint1); var endpoint2 = EndpointFactory.CreateRouteEndpoint("{controller}/{action}/{id}", metadata: new object[] { new IntMetadata(1), }); dataSource.AddEndpoint(endpoint2); // Act var actual = linkGenerator.GetTemplateBinder(endpoint1); // Assert Assert.NotSame(original, actual); }
public void Cache_DoesNotInitialize_WhenValueCalled() { // Arrange var called = false; var dataSource = new DynamicEndpointDataSource(); var cache = new DataSourceDependentCache <string>(dataSource, (endpoints) => { called = true; return("hello, world!"); }); // Act GC.KeepAlive(cache.Value); // Assert Assert.False(called); Assert.Null(cache.Value); }
public void Cache_Initializes_WhenEnsureInitializedCalled() { // Arrange var called = false; var dataSource = new DynamicEndpointDataSource(); var cache = new DataSourceDependentCache <string>(dataSource, (endpoints) => { called = true; return("hello, world!"); }); // Act cache.EnsureInitialized(); // Assert Assert.True(called); Assert.Equal("hello, world!", cache.Value); }
public void ConsumerChangeToken_IsRefreshed_WhenNewDataSourceCallbackFires() { var endpoint1 = CreateEndpoint("/a"); var dataSource1 = new DynamicEndpointDataSource(endpoint1); var observableCollection = new ObservableCollection <EndpointDataSource> { dataSource1 }; var compositeDataSource = new CompositeEndpointDataSource(observableCollection); var changeToken1 = compositeDataSource.GetChangeToken(); var token = Assert.IsType <CancellationChangeToken>(changeToken1); Assert.False(token.HasChanged); var endpoint2 = CreateEndpoint("/b"); // Update ObservableCollection with a new DynamicEndpointDataSource var dataSource2 = new DynamicEndpointDataSource(endpoint2); observableCollection.Add(dataSource2); Assert.True(changeToken1.HasChanged); var changeToken2 = compositeDataSource.GetChangeToken(); Assert.NotSame(changeToken2, changeToken1); token = Assert.IsType <CancellationChangeToken>(changeToken2); Assert.False(token.HasChanged); // Update the newly added DynamicEndpointDataSource var endpoint3 = CreateEndpoint("/c"); dataSource2.AddEndpoint(endpoint3); Assert.True(changeToken2.HasChanged); var changeToken3 = compositeDataSource.GetChangeToken(); Assert.NotSame(changeToken3, changeToken2); Assert.NotSame(changeToken3, changeToken1); token = Assert.IsType <CancellationChangeToken>(changeToken3); Assert.False(token.HasChanged); }
public void Matcher_Ignores_SuppressedEndpoint() { // Arrange var dataSource = new DynamicEndpointDataSource(); var endpoint = new RouteEndpoint( TestConstants.EmptyRequestDelegate, RoutePatternFactory.Parse("/"), 0, new EndpointMetadataCollection(new SuppressMatchingMetadata()), "test"); dataSource.AddEndpoint(endpoint); // Act var matcher = new DataSourceDependentMatcher(dataSource, TestMatcherBuilder.Create); // Assert var inner = Assert.IsType <TestMatcher>(matcher.CurrentMatcher); Assert.Empty(inner.Endpoints); }
public void DataSourceChanges_AreReflected_InEndpoints() { // Arrange1 var endpoint1 = CreateEndpoint("/a"); var dataSource1 = new DynamicEndpointDataSource(endpoint1); var compositeDataSource = new CompositeEndpointDataSource(new[] { dataSource1 }); // Act1 var endpoints = compositeDataSource.Endpoints; // Assert1 var endpoint = Assert.Single(endpoints); Assert.Same(endpoint1, endpoint); // Arrange2 var endpoint2 = CreateEndpoint("/b"); // Act2 dataSource1.AddEndpoint(endpoint2); // Assert2 Assert.Collection( compositeDataSource.Endpoints, (ep) => Assert.Same(endpoint1, ep), (ep) => Assert.Same(endpoint2, ep)); // Arrange3 var endpoint3 = CreateEndpoint("/c"); // Act2 dataSource1.AddEndpoint(endpoint3); // Assert2 Assert.Collection( compositeDataSource.Endpoints, (ep) => Assert.Same(endpoint1, ep), (ep) => Assert.Same(endpoint2, ep), (ep) => Assert.Same(endpoint3, ep)); }
public void Matcher_ThrowsOnDuplicateEndpointsFromMultipleSources() { // Arrange var expectedError = "Duplicate endpoint name 'Foo' found on '/foo2' and '/foo'. Endpoint names must be globally unique."; var dataSource = new DynamicEndpointDataSource(); var lifetime = new DataSourceDependentMatcher.Lifetime(); dataSource.AddEndpoint(new RouteEndpoint( TestConstants.EmptyRequestDelegate, RoutePatternFactory.Parse("/foo"), 0, new EndpointMetadataCollection(new EndpointNameMetadata("Foo")), "/foo" )); dataSource.AddEndpoint(new RouteEndpoint( TestConstants.EmptyRequestDelegate, RoutePatternFactory.Parse("/bar"), 0, new EndpointMetadataCollection(new EndpointNameMetadata("Bar")), "/bar" )); var anotherDataSource = new DynamicEndpointDataSource(); anotherDataSource.AddEndpoint(new RouteEndpoint( TestConstants.EmptyRequestDelegate, RoutePatternFactory.Parse("/foo2"), 0, new EndpointMetadataCollection(new EndpointNameMetadata("Foo")), "/foo2" )); var compositeDataSource = new CompositeEndpointDataSource(new[] { dataSource, anotherDataSource }); // Assert var exception = Assert.Throws <InvalidOperationException>( () => new DataSourceDependentMatcher(compositeDataSource, lifetime, TestMatcherBuilder.Create)); Assert.Equal(expectedError, exception.Message); }
public void Cache_CanDispose_WhenInitialized() { // Arrange var count = 0; var dataSource = new DynamicEndpointDataSource(); var cache = new DataSourceDependentCache <string>(dataSource, (endpoints) => { count++; return($"hello, {count}!"); }); cache.EnsureInitialized(); Assert.Equal("hello, 1!", cache.Value); // Act cache.Dispose(); // Assert dataSource.AddEndpoint(null); Assert.Equal("hello, 1!", cache.Value); // Ignores update }
public void Cache_Reinitializes_WhenDataSourceChanges() { // Arrange var count = 0; var dataSource = new DynamicEndpointDataSource(); var cache = new DataSourceDependentCache <string>(dataSource, (endpoints) => { count++; return($"hello, {count}!"); }); cache.EnsureInitialized(); Assert.Equal("hello, 1!", cache.Value); // Act dataSource.AddEndpoint(null); // Assert Assert.Equal(2, count); Assert.Equal("hello, 2!", cache.Value); }
public void Matcher_Reinitializes_WhenDataSourceChanges() { // Arrange var dataSource = new DynamicEndpointDataSource(); var matcher = new DataSourceDependentMatcher(dataSource, TestMatcherBuilder.Create); var endpoint = new RouteEndpoint( TestConstants.EmptyRequestDelegate, RoutePatternFactory.Parse("a/b/c"), 0, EndpointMetadataCollection.Empty, "test"); // Act dataSource.AddEndpoint(endpoint); // Assert var inner = Assert.IsType <TestMatcher>(matcher.CurrentMatcher); Assert.Collection( inner.Endpoints, e => Assert.Same(endpoint, e)); }
public void Matcher_IgnoresUpdate_WhenDisposed() { // Arrange var dataSource = new DynamicEndpointDataSource(); var lifetime = new DataSourceDependentMatcher.Lifetime(); var matcher = new DataSourceDependentMatcher(dataSource, lifetime, TestMatcherBuilder.Create); var endpoint = new RouteEndpoint( TestConstants.EmptyRequestDelegate, RoutePatternFactory.Parse("a/b/c"), 0, EndpointMetadataCollection.Empty, "test"); lifetime.Dispose(); // Act dataSource.AddEndpoint(endpoint); // Assert var inner = Assert.IsType <TestMatcher>(matcher.CurrentMatcher); Assert.Empty(inner.Endpoints); }
public void AddressScheme_UpdatesWhenDataSourceChanges() { var endpoint1 = EndpointFactory.CreateRouteEndpoint( "/a", metadata: new object[] { new EndpointNameMetadata("name1"), }); var dynamicDataSource = new DynamicEndpointDataSource(new[] { endpoint1 }); // Act 1 var addressScheme = CreateAddressScheme(dynamicDataSource); // Assert 1 var match = Assert.Single(addressScheme.Entries); Assert.Same(endpoint1, match.Value.Single()); // Arrange 2 var endpoint2 = EndpointFactory.CreateRouteEndpoint( "/b", metadata: new object[] { new EndpointNameMetadata("name2"), }); // Act 2 // Trigger change dynamicDataSource.AddEndpoint(endpoint2); // Assert 2 Assert.Collection( addressScheme.Entries.OrderBy(kvp => kvp.Key), (m) => { Assert.Same(endpoint1, m.Value.Single()); }, (m) => { Assert.Same(endpoint2, m.Value.Single()); }); }
public DynamicGrpcServiceRegistry(DynamicEndpointDataSource endpointDataSource, IServiceProvider serviceProvider) { _endpointDataSource = endpointDataSource; _serviceProvider = serviceProvider; }
public void EndpointDataSource_ChangeCallback_Refreshes_OutboundMatches() { // Arrange 1 var endpoint1 = CreateEndpoint("/a", metadataRequiredValues: new { }); var dynamicDataSource = new DynamicEndpointDataSource(new[] { endpoint1 }); // Act 1 var addressScheme = new CustomRouteValuesBasedAddressScheme(new CompositeEndpointDataSource(new[] { dynamicDataSource })); // Assert 1 Assert.NotNull(addressScheme.AllMatches); var match = Assert.Single(addressScheme.AllMatches); var actual = Assert.IsType <RouteEndpoint>(match.Entry.Data); Assert.Same(endpoint1, actual); // Arrange 2 var endpoint2 = CreateEndpoint("/b", metadataRequiredValues: new { }); // Act 2 // Trigger change dynamicDataSource.AddEndpoint(endpoint2); // Arrange 2 var endpoint3 = CreateEndpoint("/c", metadataRequiredValues: new { }); // Act 2 // Trigger change dynamicDataSource.AddEndpoint(endpoint3); // Arrange 3 var endpoint4 = CreateEndpoint("/d", metadataRequiredValues: new { }); // Act 3 // Trigger change dynamicDataSource.AddEndpoint(endpoint4); // Assert 3 Assert.NotNull(addressScheme.AllMatches); Assert.Collection( addressScheme.AllMatches, (m) => { actual = Assert.IsType <RouteEndpoint>(m.Entry.Data); Assert.Same(endpoint1, actual); }, (m) => { actual = Assert.IsType <RouteEndpoint>(m.Entry.Data); Assert.Same(endpoint2, actual); }, (m) => { actual = Assert.IsType <RouteEndpoint>(m.Entry.Data); Assert.Same(endpoint3, actual); }, (m) => { actual = Assert.IsType <RouteEndpoint>(m.Entry.Data); Assert.Same(endpoint4, actual); }); }
public void EndpointDataSource_ChangeCallback_Refreshes_OutboundMatches() { // Arrange 1 var endpoint1 = CreateEndpoint("/a"); var dynamicDataSource = new DynamicEndpointDataSource(new[] { endpoint1 }); var objectPoolProvider = new DefaultObjectPoolProvider(); var objectPool = objectPoolProvider.Create(new UriBuilderContextPooledObjectPolicy()); // Act 1 var finder = new CustomRouteValuesBasedEndpointFinder( new CompositeEndpointDataSource(new[] { dynamicDataSource }), objectPool); // Assert 1 Assert.NotNull(finder.AllMatches); var match = Assert.Single(finder.AllMatches); var actual = Assert.IsType <MatcherEndpoint>(match.Entry.Data); Assert.Same(endpoint1, actual); // Arrange 2 var endpoint2 = CreateEndpoint("/b"); // Act 2 // Trigger change dynamicDataSource.AddEndpoint(endpoint2); // Arrange 2 var endpoint3 = CreateEndpoint("/c"); // Act 2 // Trigger change dynamicDataSource.AddEndpoint(endpoint3); // Arrange 3 var endpoint4 = CreateEndpoint("/d"); // Act 3 // Trigger change dynamicDataSource.AddEndpoint(endpoint4); // Assert 3 Assert.NotNull(finder.AllMatches); Assert.Collection( finder.AllMatches, (m) => { actual = Assert.IsType <MatcherEndpoint>(m.Entry.Data); Assert.Same(endpoint1, actual); }, (m) => { actual = Assert.IsType <MatcherEndpoint>(m.Entry.Data); Assert.Same(endpoint2, actual); }, (m) => { actual = Assert.IsType <MatcherEndpoint>(m.Entry.Data); Assert.Same(endpoint3, actual); }, (m) => { actual = Assert.IsType <MatcherEndpoint>(m.Entry.Data); Assert.Same(endpoint4, actual); }); }
public void EndpointDataSource_ChangeCallback_Refreshes_OutboundMatches() { // Arrange 1 var endpoint1 = CreateEndpoint("/a", routeName: "a"); var dynamicDataSource = new DynamicEndpointDataSource(new[] { endpoint1 }); // Act 1 var addressScheme = new RouteValuesAddressScheme(new CompositeEndpointDataSource(new[] { dynamicDataSource })); // Assert 1 var state = addressScheme.State; Assert.NotNull(state.AllMatches); var match = Assert.Single(state.AllMatches); var actual = Assert.IsType <RouteEndpoint>(match.Entry.Data); Assert.Same(endpoint1, actual); // Arrange 2 var endpoint2 = CreateEndpoint("/b", routeName: "b"); // Act 2 // Trigger change dynamicDataSource.AddEndpoint(endpoint2); // Assert 2 Assert.NotSame(state, addressScheme.State); state = addressScheme.State; // Arrange 3 var endpoint3 = CreateEndpoint("/c", routeName: "c"); // Act 3 // Trigger change dynamicDataSource.AddEndpoint(endpoint3); // Assert 3 Assert.NotSame(state, addressScheme.State); state = addressScheme.State; // Arrange 4 var endpoint4 = CreateEndpoint("/d", routeName: "d"); // Act 4 // Trigger change dynamicDataSource.AddEndpoint(endpoint4); // Assert 4 Assert.NotSame(state, addressScheme.State); state = addressScheme.State; Assert.NotNull(state.AllMatches); Assert.Collection( state.AllMatches, (m) => { actual = Assert.IsType <RouteEndpoint>(m.Entry.Data); Assert.Same(endpoint1, actual); }, (m) => { actual = Assert.IsType <RouteEndpoint>(m.Entry.Data); Assert.Same(endpoint2, actual); }, (m) => { actual = Assert.IsType <RouteEndpoint>(m.Entry.Data); Assert.Same(endpoint3, actual); }, (m) => { actual = Assert.IsType <RouteEndpoint>(m.Entry.Data); Assert.Same(endpoint4, actual); }); }