예제 #1
0
    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);
    }
예제 #2
0
        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);
        }
예제 #4
0
    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);
    }
예제 #5
0
        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);
        }
예제 #6
0
    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);
    }
예제 #7
0
    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);
    }
예제 #8
0
    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));
        }
예제 #11
0
    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);
    }
예제 #12
0
    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
    }
예제 #13
0
    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));
        }
예제 #15
0
        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;
 }
예제 #18
0
        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);
            });
        }