コード例 #1
0
        // verifies that outgoing messages from a hub call:
        // - use the same primary service connection the hub call was made from
        // - pick and stick to the same secondary connection(s)
        public async Task OutgoingMessagesUseSameServiceConnection()
        {
            var builder = WebHost.CreateDefaultBuilder()
                          .ConfigureServices((IServiceCollection services) => {})
                          .ConfigureLogging(logging => logging.AddXunit(_output))
                          .UseStartup <IntegrationTestStartup <MockServiceMessageOrderTestParams, UseSameServiceConnectionHub> >();

            using var server = new AspNetTestServer(builder);
            var mockSvc = (server.Host.Services.GetRequiredService <ServiceHubDispatcher <UseSameServiceConnectionHub> >()
                           as MockServiceHubDispatcher <UseSameServiceConnectionHub>).MockService;
            await mockSvc.AllConnectionsEstablished();

            List <MockServiceSideConnection> allSvcConns = mockSvc.ServiceSideConnections;

            // A few extra checks (just for this initial test to verify more invariants)
            // Each ServiceEndpoint will have ConnectionCount connections
            Assert.Equal(
                MockServiceMessageOrderTestParams.ConnectionCount * MockServiceMessageOrderTestParams.ServiceEndpoints.Length,
                allSvcConns.Count);
            int endpointCount = allSvcConns.Distinct(new MockServiceSideConnectionEndpointComparer()).Count();

            Assert.Equal(MockServiceMessageOrderTestParams.ServiceEndpoints.Length, endpointCount);

            // specify invocation binder before making calls
            mockSvc.CurrentInvocationBinder = new TestHubBroadcastNCallsInvocationBinder();

            // pick a random primary svc connection to make a client connection
            var priList = allSvcConns.Where(i => i.Endpoint.EndpointType == EndpointType.Primary).ToList();

            await using var primarySvc0 = priList[StaticRandom.Next(priList.Count)];
            var client0 = await primarySvc0.ConnectClientAsync();

            const int MsgNum = 10;
            await client0.SendMessage("BroadcastNumCalls", new object[] { MsgNum });

            var counts = await DrainBroadcastMessages(endpointCount, MsgNum, mockSvc);

            // Did we got the expected number of calls and all of them stick to exactly one primary?
            var primary = counts.Where(c => c.Key.Endpoint.EndpointType == EndpointType.Primary);

            Assert.Single(primary);

            // the primary is the one we used to send client message
            Assert.Equal(primarySvc0, primary.FirstOrDefault().Key);

            // the primary received MsgNum messages
            Assert.Equal(MsgNum, primary.FirstOrDefault().Value);

            // for every secondary that received the messages verify that
            // - their number equals to the number of seconary endpoints
            // - each received N messages
            var secondary          = counts.Where(c => c.Key.Endpoint.EndpointType == EndpointType.Secondary);
            var secondaryEndpoints = MockServiceMessageOrderTestParams.ServiceEndpoints.Where(ep => ep.EndpointType == EndpointType.Secondary);

            Assert.Equal(secondaryEndpoints.Count(), secondary.Count());
            foreach (var conn in secondary)
            {
                Assert.Equal(MsgNum, conn.Value);
            }
        }
コード例 #2
0
        public async Task PreviouslyUsedServiceConnectionsNotLeakedAfterHotReload2()
        {
            var builder = WebHost.CreateDefaultBuilder()
                          .ConfigureServices((IServiceCollection services) => { })
                          .ConfigureLogging(logging => logging.AddXunit(_output))
                          .UseStartup <HotReloadIntegrationTestStartup <HotReloadMessageOrderTestParams, HotReloadTestHub> >();

            using var server = new AspNetTestServer(builder);
            var wrList = await BroadcastAndHotReloadAllEndpoints(server);

            // here we assume that 2 GCs and 1 finalizer are enough
            await Task.Delay(3300);

            GC.Collect();
            GC.WaitForPendingFinalizers();
            await Task.Delay(3300);

            GC.Collect();

            foreach (var wr in wrList)
            {
                object o = wr.Target;
                Assert.Null(o);
            }
        }
コード例 #3
0
        public void Launch()
        {
            var builder = new WebHostBuilder();

            builder.UseContentRoot(GetContentRootPath())
            .UseEnvironment(_environment)
            .ConfigureLogging(factory =>
            {
                factory.AddConsole();
            })
            .UseAutofac()
            .UseConfiguration(_configBuilder.Invoke(_environment, builder.GetSetting(WebHostDefaults.ContentRootKey)))
            .UseStartup <T>()
            .ConfigureServices(services =>
            {
                services.AddAntiforgery(options => {
                    options.CookieName    = AntiForgeryCookieName;
                    options.FormFieldName = AntiForgeryFieldName;
                });

                //Test Server Fix
                //https://github.com/aspnet/Hosting/issues/954
                //https://github.com/Microsoft/vstest/issues/428
                var assembly = typeof(T).GetTypeInfo().Assembly;
                services.ConfigureRazorViewEngineForTestServer(assembly, _netVersion);
            });

            _testServer = new Microsoft.AspNetCore.TestHost.TestServer(builder);

            Client = _testServer.CreateClient();
        }
コード例 #4
0
        // OnConnectedAsync and regular hub method calls should have the same connection selection for the same client connection
        // This test verifies this by sending messages from both and verifying the message order.
        public async Task OutgoingMessagesMultipleContexts()
        {
            var builder = WebHost.CreateDefaultBuilder()
                          .ConfigureServices((IServiceCollection services) => { })
                          .ConfigureLogging(logging => logging.AddXunit(_output))
                          .UseStartup <IntegrationTestStartup <MockServiceMessageOrderTestParams, MultipleContextsHub> >();

            using var server = new AspNetTestServer(builder);
            var mockSvc = (server.Host.Services.GetRequiredService <ServiceHubDispatcher <MultipleContextsHub> >() as MockServiceHubDispatcher <MultipleContextsHub>).MockService;
            await mockSvc.AllConnectionsEstablished();

            List <MockServiceSideConnection> allSvcConns = mockSvc.ServiceSideConnections;

            mockSvc.CurrentInvocationBinder = new TestHubBroadcastNCallsInvocationBinder();
            var priList = allSvcConns.Where(i => i.Endpoint.EndpointType == EndpointType.Primary).ToList();

            await using var primarySvc0 = priList[StaticRandom.Next(priList.Count)];
            var client0 = await primarySvc0.ConnectClientAsync();

            int       epCount = allSvcConns.Distinct(new MockServiceSideConnectionEndpointComparer()).Count();
            const int MsgNum  = 10;
            await client0.SendMessage("BroadcastNumCallsMultipleContexts", new object[] { MsgNum });

            var counts = await DrainBroadcastMessages(epCount, MsgNum, mockSvc);

            Assert.Equal(counts.Count(), MockServiceMessageOrderTestParams.ServiceEndpoints.Count());
            foreach (var conn in counts)
            {
                Assert.Equal(MsgNum, conn.Value);
            }
        }
コード例 #5
0
        public async Task Get_get_all_catalogitems_and_response_ok_status_code()
        {
            using (Microsoft.AspNetCore.TestHost.TestServer server = CreateServer())
            {
                System.Net.Http.HttpResponseMessage response = await server.CreateClient()
                                                               .GetAsync(Get.Items());

                response.EnsureSuccessStatusCode();
            }
        }
コード例 #6
0
 public TestServer()
 {
     Server = new Microsoft.AspNetCore.TestHost.TestServer(WebHost.CreateDefaultBuilder()
                                                           .UseStartup <Startup>()
                                                           .UseEnvironment("Development"))
     {
         BaseAddress = new Uri("http://dpaapi.azurewebsites.net")
     };
     Client = Server.CreateClient();
 }
コード例 #7
0
        private async System.Threading.Tasks.Task <System.Net.Http.Headers.HttpResponseHeaders> GetHeaders(Action <Microsoft.AspNetCore.Builder.IApplicationBuilder> app)
        {
            var webHostBuilder = GetNewHostBuilder(app);

            using (var server = new Microsoft.AspNetCore.TestHost.TestServer(webHostBuilder))
            {
                var response = await server.CreateRequest("/").GetAsync();

                return(response.Headers);
            }
        }
コード例 #8
0
        /// <summary>Argument constructor.</summary>
        protected TestIntegrationBase(string projectParentFolderName = "src")
        {
            var startupAssembly = typeof(TStartup).GetTypeInfo().Assembly;
            var contentRoot     = TestBase.GetProjectFolderPath(SolutionFileName, projectParentFolderName, startupAssembly);

            _server = new Microsoft.AspNetCore.TestHost.TestServer(new WebHostBuilder()
                                                                   .UseContentRoot(contentRoot)
                                                                   .UseEnvironment(EnvironmentName.Development)
                                                                   .UseStartup(typeof(TStartup))
                                                                   );
            _client = _server.CreateClient();
        }
コード例 #9
0
        public async Task GetArticles_ApiRequest_ReturnsArticles()
        {
            var server = new Microsoft.AspNetCore.TestHost.TestServer(new WebHostBuilder().UseStartup <Startup>());
            var client = server.CreateClient();


            var response = await client.GetAsync("/articles");

            response.EnsureSuccessStatusCode();
            var responseString = await response.Content.ReadAsStringAsync();

            // Assert
            Assert.Equal("Hello World!", responseString);
        }
コード例 #10
0
        public static TestClientFactory GetTestClientFactory(Type startupType)
        {
            if (_testServer == null)
            {
                var hostBuilder = new WebHostBuilder();
                hostBuilder.UseStartup(startupType);
                _testServer = new Microsoft.AspNetCore.TestHost.TestServer(hostBuilder);
            }

            var testClient = MintClient();
            var testServerHttpClientFactory = new TestClientFactory(testClient);

            return(testServerHttpClientFactory);
        }
コード例 #11
0
        private void CreateClient <T>()
            where T : class
        {
            var builder = new Microsoft.AspNetCore.Hosting.WebHostBuilder()
                          .UseStartup <T>();
            var server = new Microsoft.AspNetCore.TestHost.TestServer(builder);

            Client = server.CreateClient();

            if (_useDatabaseSeed)
            {
                var host = server.Host;
                SeedData(host);
            }
        }
コード例 #12
0
        private async void DiscoverPatientCareContexts_ReturnsExpectedStatusCode_WhenRequestIsSentWithParameters(
            HttpStatusCode expectedStatusCode, params string[] missingRequestParameters)
        {
            var _server = new Microsoft.AspNetCore.TestHost.TestServer(new WebHostBuilder().UseStartup <TestStartup>());
            var _client = _server.CreateClient();

            _client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Test");
            var requestContent = new DiscoveryRequestPayloadBuilder()
                                 .WithMissingParameters(missingRequestParameters)
                                 .BuildSerializedFormat();

            var response =
                await _client.PostAsync(
                    "/v0.5/care-contexts/discover",
                    requestContent);

            response.StatusCode.Should().Be(expectedStatusCode);
        }
コード例 #13
0
        public void BeforeTest(ITest test)
        {
            if (!(test.Fixture is IRequireTestEndpoint requireTestEndpoint))
            {
                throw new Exception(
                          $"Test should implement interface '{typeof(IRequireTestEndpoint)}'"
                          + $" instead of using the attribute '{GetType()}'");
            }

            var hostConfig     = test.Fixture as IRequireTestEndpointHostBuilder;
            var appConfig      = test.Fixture as IRequireTestEndpointApplicationBuilder;
            var servicesConfig = test.Fixture as IRequireTestEndpointServices;
            var overrideConfig = test.Fixture as IRequireTestEndpointOverride;

            var hostBuilder = new WebHostBuilder();

            hostConfig?.Configure(hostBuilder);
            hostBuilder.Configure(x => appConfig?.Configure(x));

            if (servicesConfig != null)
            {
                hostBuilder.ConfigureServices(servicesConfig.Configure);
            }

            if (overrideConfig != null)
            {
                hostBuilder.Configure(x => x.Run(overrideConfig.ServerRun));
            }

            var startupDefinition = test.Fixture.GetType()
                                    .GetInterfaces()
                                    .SingleOrDefault(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IRequireTestEndpointStartup <>));

            if (startupDefinition != null)
            {
                var startupType = startupDefinition.GetGenericArguments()[0];
                hostBuilder.UseStartup(startupType);
            }

            testServer = requireTestEndpoint.Endpoint =
                new Microsoft.AspNetCore.TestHost.TestServer(hostBuilder);
        }
コード例 #14
0
        public TestServerFixture()
        {
            //const string connectionString = "server=192.168.35.155,1433;initial catalog=KiSS_Standard_R41016_MIKA_DEV;user id=sa;password=123456a@";
            //const string connectionString = "server=192.168.35.205,1433;initial catalog=KiSS_Ivos_TestDB_R4929_1;user id=testKiss";
            const string connectionString = "server=CMC-DUNGNT31;initial catalog=KiSS_Standard_R41016_MIKA;user id=sa;password=123456";

            DockerStarter.TryStartDbContainer(connectionString);
            DateTime = new TestDateTimeProvider();

            var builderIdentityServer = WebHost.CreateDefaultBuilder()
                                        .ConfigureAppConfiguration(o => o.AddInMemoryCollection(new[]
            {
                new KeyValuePair <string, string>("ConnectionStrings:DefaultConnection", connectionString),
                new KeyValuePair <string, string>("Authentication:Authority", Authority),
            }))
                                        .UseStartup <IdentityServer.Startup>();

            TestIdentityServer = new Microsoft.AspNetCore.TestHost.TestServer(builderIdentityServer);

            var builderKiss4Web = WebHost.CreateDefaultBuilder()
                                  .ConfigureAppConfiguration(o => o.AddInMemoryCollection(new[]
            {
                new KeyValuePair <string, string>("ConnectionStrings:DefaultConnection", connectionString),
                new KeyValuePair <string, string>("Authentication:Authority", Authority),
            }))
                                  .ConfigureServices(c =>
            {
                c.AddSingleton <IDateTimeProvider>(DateTime);
                c.AddSingleton(TestIdentityServer.CreateHandler());
            })
                                  .UseStartup <Startup>();

            TestServer = new Microsoft.AspNetCore.TestHost.TestServer(builderKiss4Web);

            Container = TestServer.Host.Services.GetService <Container>();

            _testData = new TestDataInserter(Container);

            // connection string might have been modified (different IP in VSTS), so update it
            ConnectionString = Container.GetInstance <ConnectionString>();
        }
コード例 #15
0
        public void Setup()
        {
            IWebHostBuilder webHostBuilder = new WebHostBuilder()
                                             .Configure(builder => builder.UseMvc())
                                             .ConfigureServices((context, serviceCollection) =>
            {
                serviceCollection
                .AddDbContext <TestDbContext>(opts => opts.UseInMemoryDatabase("test"))
                .UseAutoPagination(context.Configuration)
                .AddPaged <IRepository, Repository>()
                .AddMvc();
            });
            var testServer = new Microsoft.AspNetCore.TestHost.TestServer(webHostBuilder);

            _serviceProvider = testServer.Host.Services;
            var dbContext = _serviceProvider.GetService <TestDbContext>();

            _users = new Fixture().CreateMany <User>(100);
            dbContext.Users.AddRange(_users);
            dbContext.SaveChanges();
            _httpClient = testServer.CreateClient();
        }
コード例 #16
0
        public async Task MockServiceConnectionHandshake()
        {
            var builder = WebHost.CreateDefaultBuilder()
                          .ConfigureServices((IServiceCollection services) => {})
                          .ConfigureLogging(logging => logging.AddXunit(_output))
                          .UseStartup <IntegrationTestStartup>();

            var server = new AspNetTestServer(builder);
            var host   = server.Host;

            try
            {
                await host.StartAsync();

                var  mockSvc = host.Services.GetRequiredService <ServiceHubDispatcher <TestHub> >() as MockServiceHubDispatcher <TestHub>;
                bool result  = await mockSvc.MockService.CompletedServiceConnectionHandshake.Task;
                Assert.True(result);
            }
            finally
            {
                await host.StopAsync();
            }
        }
コード例 #17
0
 void SetupClient()
 {
     _server = new Microsoft.AspNetCore.TestHost.TestServer(new WebHostBuilder().UseStartup <Backend.Startup>());
     Client  = _server.CreateClient();
 }
コード例 #18
0
 public RequestBuilder(Microsoft.AspNetCore.TestHost.TestServer server, string path)
 {
 }
コード例 #19
0
 public SwaggerGenTest()
 {
     server = TestEndpointServerFactory.CreateEndpointServer();
 }
コード例 #20
0
        // verifies the outgoing messages from the hub call:
        // * are using the same primary service connection the hub call was made from
        // * pick and stick to the same secondary connection
        public async Task OutgoingMessagesUseSameServiceConnection()
        {
            var builder = WebHost.CreateDefaultBuilder()
                          .ConfigureServices((IServiceCollection services) => {})
                          .ConfigureLogging(logging => logging.AddXunit(_output))
                          .UseStartup <IntegrationTestStartup <RealMockServiceE2ETestParams, TestHub> >();

            using (var server = new AspNetTestServer(builder))
            {
                var mockSvc = (server.Host.Services.GetRequiredService <ServiceHubDispatcher <TestHub> >() as MockServiceHubDispatcher <TestHub>).MockService;
                await mockSvc.AllConnectionsEstablished();

                List <MockServiceSideConnection> allSvcConns = mockSvc.ServiceSideConnections;

                // A few extra checks (just for this initial test to verify more invariants)
                // Each ServiceEndpoints will have ConnectionCount connections
                Assert.Equal(allSvcConns.Count, RealMockServiceE2ETestParams.ConnectionCount * RealMockServiceE2ETestParams.ServiceEndpoints.Length);
                int endpointCount = allSvcConns.Distinct(new MockServiceSideConnectionEndpointComparer()).Count();
                Assert.Equal(endpointCount, RealMockServiceE2ETestParams.ServiceEndpoints.Length);

                // specify invocation binder before making calls
                // todo: maybe there is a better way?
                mockSvc.CurrentInvocationBinder = new TestHubBroadcastNCallsInvocationBinder();

                // use the first primary to make a client connection
                var primarySvc0 = allSvcConns.Where(i => i.Endpoint.EndpointType == EndpointType.Primary).FirstOrDefault();
                var client0     = await primarySvc0.ConnectClientAsync();

                const int MsgNum = 10;
                await client0.SendMessage("BroadcastNumCalls", new object[] { MsgNum });

                // The mock service does not route messages to client connections as there are no actual clients connected
                // So we just ask for raw messages received by the mock service and count them per service connection
                // Each endpoint will get the broadcast message so we should receive endpointCount * MsgNum messages
                var counts = new ConcurrentDictionary <MockServiceSideConnection, int>();

                for (int ep = 0; ep < endpointCount * MsgNum; ep++)
                {
                    // todo: extension method?
                    var receivedMessage = await Task.WhenAny(allSvcConns.Select(async c =>
                    {
                        bool moreData = await c.WaitToDequeueMessageAsync <BroadcastDataMessage>();
                        return(c, moreData);
                    }));

                    Assert.True(receivedMessage.Result.moreData);
                    var conn   = receivedMessage.Result.c;
                    var newMsg = await conn.DequeueMessageAsync <BroadcastDataMessage>();

                    int msgCount = counts.GetOrAdd(conn, 0);
                    counts[conn] = ++msgCount;

                    // parse each BroadcastDataMessage and verify this is the correct message
                    var hubMessage = ParseBroadcastDataMessageJson(newMsg, mockSvc.CurrentInvocationBinder);
                    Assert.True(hubMessage is InvocationMessage);
                    var invMsg = hubMessage as InvocationMessage;
                    Assert.Equal("Callback", invMsg.Target);

                    // finally, get ready to verify the order of messages
                    int actualCallbackNum = (int)invMsg.Arguments[0];

                    if (MessageOrderFixed)
                    {
                        // this check works for both primary and secondary connections
                        Assert.Equal(actualCallbackNum, msgCount);
                    }
                }

                // todo: verify we received no extra BroadcastDataMessage - need TryPeek method (async with timeout?)

                if (MessageOrderFixed)
                {
                    // Did we got the expected number of calls and all of them stick to exactly one primary and one secondary?
                    var primary = counts.Where(c => c.Key.Endpoint.EndpointType == EndpointType.Primary);

                    Assert.Single(primary);

                    // and the primary is the one we used to send client message
                    Assert.Equal(primary.FirstOrDefault().Key, primarySvc0);

                    // and it received N messages
                    Assert.Equal(primary.FirstOrDefault().Value, MsgNum);

                    // for every secondary verify that
                    // - their number equals to the number of seconary endpoints
                    // - each received N messages
                    var secondary = counts.Where(c => c.Key.Endpoint.EndpointType == EndpointType.Secondary);
                    Assert.Single(secondary);
                    Assert.Equal(secondary.FirstOrDefault().Value, MsgNum);
                }
            }
        }
コード例 #21
0
        // App server may continue sending messages after both the hub call is finished and the client connection is closed.
        // This test verifies the following strong guarantees:
        // - outgoing messages continue to use the same service connection
        // - the order of messages is preserved
        // This test also verifies that all hub calls over the same client connection
        // stick to the same primary and secondary service connections
        public async Task OutgoingMessagesOnSameServiceConnectionAfterClientConnectionClosed()
        {
            // step 0: initialize
            var builder = WebHost.CreateDefaultBuilder()
                          .ConfigureServices((IServiceCollection services) => { })
                          .ConfigureLogging(logging => logging.AddXunit(_output))
                          .UseStartup <IntegrationTestStartup <MockServiceMessageOrderTestParams, SameSvcConnAfterClientConnectionClosedHub> >();

            using var server = new AspNetTestServer(builder);
            var mockSvc = (server.Host.Services.GetRequiredService <ServiceHubDispatcher <SameSvcConnAfterClientConnectionClosedHub> >() as MockServiceHubDispatcher <SameSvcConnAfterClientConnectionClosedHub>).MockService;
            var epCount = MockServiceMessageOrderTestParams.ServiceEndpoints.Length;

            mockSvc.CurrentInvocationBinder = new TestHubBroadcastNCallsInvocationBinder();
            await mockSvc.AllConnectionsEstablished();

            List <MockServiceSideConnection> allSvcConns = mockSvc.ServiceSideConnections;

            await using var primarySvc0 = allSvcConns.Where(i => i.Endpoint.EndpointType == EndpointType.Primary).FirstOrDefault();
            var client0 = await primarySvc0.ConnectClientAsync();

            // step 1: make sure we know initial connection selections before disconnecting the client
            // make 2 calls to also verify that subsequent calls stick to previous selections
            await client0.SendMessage("BroadcastNumCalls", new object[] { /*numCalls*/ 1, /*countOffset*/ 0 });

            await client0.SendMessage("BroadcastNumCalls", new object[] { /*numCalls*/ 1, /*countOffset*/ 1 });

            var counts = await DrainBroadcastMessages(epCount, 2, mockSvc);

            // step 2: call hub and drop the client connection
            const int MsgNum      = 10;
            const int countOffset = 2; // account for 2 extra messages sent before we disconnected the client
            await client0.SendMessage("BroadcastNumCallsAfterDisconnected", new object[] { MsgNum, countOffset });

            await client0.CloseConnection();

            // step 3: receive and count messages sent as the result of the call to BroadcastNumCallsAfterDisconnected
            await DrainBroadcastMessages(epCount, MsgNum, mockSvc, counts);

            // step 4: verify the connections that received messages
            var primary = counts.Where(c => c.Key.Endpoint.EndpointType == EndpointType.Primary);

            Assert.Single(primary);
            // the primary is the one we used to send client message
            Assert.Equal(primarySvc0, primary.FirstOrDefault().Key);
            // and it received N + 2 messages
            Assert.Equal(MsgNum + countOffset, primary.FirstOrDefault().Value);

            // for every secondary verify that
            // - their number equals to the number of seconary endpoints
            // - each received N + 2 messages
            // - each of the secondary ones is the same as the original selection
            var secondary          = counts.Where(c => c.Key.Endpoint.EndpointType == EndpointType.Secondary);
            var secondaryEndpoints = MockServiceMessageOrderTestParams.ServiceEndpoints.Where(ep => ep.EndpointType == EndpointType.Secondary);

            Assert.Equal(secondaryEndpoints.Count(), secondary.Count());
            foreach (var secCon in secondary)
            {
                // each of the new secondary connections received MsgNum + 2 (including initial 2 calls) messages
                Assert.Equal(MsgNum + countOffset, secCon.Value);
            }
        }
コード例 #22
0
        // verifies that when original outboud service connection associated with the hub call is closed:
        // - a new service connection for each endpoint is selected
        // - all subsequent messages use newly selected service connections
        // Note 1: this test is for a scenario which already has much weaker message order guarantees
        // because switching from one connection to another may lead to out of order messages.
        // However there are valid scenarios when the outboud messages are only sent after the original connection is closed.
        // In this case all the messages will be sent over a new connection and the order will be preserved.
        // Note 2: there are multiple ways to close service connection. In this test we ask the mock service to close the pipe.
        // There are several other cases when SDK initiates disconnect which we didn't test here.
        // In either case we need to wait for the connection to be "fully closed" before sending messages.
        public async Task OutgoingMessagesSwitchOverToNewServiceConnection()
        {
            // step 0: create initial connections
            var builder = WebHost.CreateDefaultBuilder()
                          .ConfigureServices((IServiceCollection services) => { })
                          .ConfigureLogging(logging => logging.AddXunit(_output))
                          .UseStartup <IntegrationTestStartup <MockServiceMessageOrderTestParams, SwitchOverToNewServiceConnectionHub> >();

            using var server = new AspNetTestServer(builder);
            var mockSvc = (server.Host.Services.GetRequiredService <ServiceHubDispatcher <SwitchOverToNewServiceConnectionHub> >()
                           as MockServiceHubDispatcher <SwitchOverToNewServiceConnectionHub>).MockService;

            mockSvc.CurrentInvocationBinder = new TestHubBroadcastNCallsInvocationBinder();
            await mockSvc.AllConnectionsEstablished();

            var allSvcConns = mockSvc.ServiceSideConnections;
            var primarySvc0 = allSvcConns.Where(i => i.Endpoint.EndpointType == EndpointType.Primary).FirstOrDefault();
            var client0     = await primarySvc0.ConnectClientAsync();

            // step 1: broadcast a message to figure out secondary connection selections
            // we already know the primary connection (primarySvc0) but not the secondary one(s)
            // which will only be selected at the first outgoing message to the service
            await client0.SendMessage("BroadcastNumCalls", new object[] { 1 });

            var epCount        = MockServiceMessageOrderTestParams.ServiceEndpoints.Length;
            var connSelections = new ConcurrentBag <MockServiceSideConnection>();

            for (int ep = 0; ep < epCount; ep++)
            {
                var connReceivedMessage = await Task.WhenAny(allSvcConns.Select(async c =>
                {
                    await c.WaitToDequeueMessageAsync <BroadcastDataMessage>();
                    return(c);
                }));

                connSelections.Add(connReceivedMessage.Result);
                await connReceivedMessage.Result.DequeueMessageAsync <BroadcastDataMessage>();
            }

            // sanity checks
            Assert.Equal(primarySvc0, connSelections.Where(c => c.Endpoint.EndpointType == EndpointType.Primary).FirstOrDefault());
            var secondaryEpCount       = MockServiceMessageOrderTestParams.ServiceEndpoints.Where(ep => ep.EndpointType == EndpointType.Secondary).Count();
            var secondaryReceivedCount = connSelections.Where(c => c.Endpoint.EndpointType == EndpointType.Secondary).Count();

            Assert.Equal(secondaryEpCount, secondaryReceivedCount);

            // step 2: call hub and drop all the connections associated with the current client
            const int MsgNum = 10;
            await client0.SendMessage("BroadcastNumCallsAfterDisconnected", new object[] { MsgNum });

            foreach (var secConnUsed in connSelections.Where(c => c.Endpoint.EndpointType == EndpointType.Secondary))
            {
                await secConnUsed.StopAsync();
            }
            await primarySvc0.StopAsync();

            // step 3: drain and count messages sent as the result of the call to BroadcastNumCallsAfterDisconnected
            await mockSvc.AllConnectionsEstablished();

            var counts = await DrainBroadcastMessages(epCount, MsgNum, mockSvc);

            // step 4: verify the connections that received messages
            var primary = counts.Where(c => c.Key.Endpoint.EndpointType == EndpointType.Primary);

            Assert.Single(primary);
            // the primary is NOT the one we used to send client message
            Assert.NotEqual(primary.FirstOrDefault().Key, primarySvc0);
            // and it received MsgNum messages
            Assert.Equal(MsgNum, primary.FirstOrDefault().Value);

            // for every secondary verify that
            // - their number equals to the number of seconary endpoints
            // - each received MsgNum messages
            // - each of the secondary ones is not the same as the original selection
            var secondary          = counts.Where(c => c.Key.Endpoint.EndpointType == EndpointType.Secondary);
            var secondaryEndpoints = MockServiceMessageOrderTestParams.ServiceEndpoints.Where(ep => ep.EndpointType == EndpointType.Secondary);

            Assert.Equal(secondaryEndpoints.Count(), secondary.Count());
            foreach (var newSecCon in secondary)
            {
                // none of the new secondary connections are the same as the ones initially used
                foreach (var oldSecCon in connSelections.Where(c => c.Endpoint.EndpointType == EndpointType.Secondary))
                {
                    Assert.NotEqual(newSecCon.Key, oldSecCon);
                }
                // each of the new secondary connections received MsgNum messages
                Assert.Equal(MsgNum, newSecCon.Value);
            }
        }
コード例 #23
0
        public void Initialize(bool mockedServices = false)
        {
            SyncTest.WaitOne(); // tests must not run in parallel since each test first deletes database
            try
            {
                // setup call back server
                serverCallback = CallbackServer.GetTestServer(Callback.Url, Callback);
                clientCallback = serverCallback.CreateClient();

                //setup server
                server = TestServerBase.CreateServer(mockedServices, serverCallback, dbConnectionString);
                client = server.CreateClient();

                // setup repositories
                NodeRepository       = server.Services.GetRequiredService <INodeRepository>() as NodeRepositoryPostgres;
                TxRepositoryPostgres = server.Services.GetRequiredService <ITxRepository>() as TxRepositoryPostgres;
                FeeQuoteRepository   = server.Services.GetRequiredService <IFeeQuoteRepository>() as FeeQuoteRepositoryPostgres;

                BlockChainInfo = server.Services.GetRequiredService <IBlockChainInfo>();
                MinerId        = server.Services.GetRequiredService <IMinerId>();

                // setup common services
                loggerFactory = server.Services.GetRequiredService <ILoggerFactory>();
                loggerTest    = loggerFactory.CreateLogger(LOG_CATEGORY);

                Nodes          = server.Services.GetRequiredService <INodes>();
                blockChainInfo = server.Services.GetRequiredService <IBlockChainInfo>();
                rpcMultiClient = server.Services.GetRequiredService <IRpcMultiClient>();

                eventBus = server.Services.GetRequiredService <IEventBus>();

                rpcClientFactoryMock   = server.Services.GetRequiredService <IRpcClientFactory>() as RpcClientFactoryMock;
                feeQuoteRepositoryMock = server.Services.GetRequiredService <IFeeQuoteRepository>() as FeeQuoteRepositoryMock;
                FeeQuoteRepositoryMock.quoteExpiryMinutes = quoteExpiryMinutes;

                if (rpcClientFactoryMock != null)
                {
                    rpcClientFactoryMock.SetUpTransaction(
                        txC3Hex,
                        txC2Hex,
                        txZeroFeeHex,
                        txZeroFeeInput1Hex,
                        txZeroFeeInput2Hex,
                        tx2Hex,
                        tx2Input1Hex,
                        tx2Input2Hex);

                    rpcClientFactoryMock.AddKnownBlock(0, HelperTools.HexStringToByteArray(genesisBlock));

                    rpcClientFactoryMock.Reset(); // remove calls that are used to test node connection when adding a new node
                }
                loggerTest.LogInformation($"Path: {Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)}");
                loggerTest.LogInformation($"ConnString: {dbConnectionString}");
            }
            catch
            {
                SyncTest.Reset();
                // If there was error during initialization, let the other tests run (although they will probably also fail)
                throw;
            }
        }
コード例 #24
0
        public async Task <List <WeakReference> > BroadcastAndHotReloadAllEndpoints(AspNetTestServer server)
        {
            // Part1: broadcast messages over initial set of endpoints
            var mockSvc = (server.Host.Services.GetRequiredService <ServiceHubDispatcher <HotReloadTestHub> >() as MockServiceHubDispatcher <HotReloadTestHub>).MockService;
            await mockSvc.AllConnectionsEstablished();

            List <MockServiceSideConnection> allSvcConns0 = mockSvc.ServiceSideConnections;

            mockSvc.CurrentInvocationBinder = new TestHubBroadcastNCallsInvocationBinder();

            var priList     = allSvcConns0.Where(i => i.Endpoint.EndpointType == EndpointType.Primary).ToList();
            var primarySvc0 = priList[0];
            var client0     = await primarySvc0.ConnectClientAsync();

            const int MsgNum = 10;
            await client0.SendMessage("BroadcastNumCalls", new object[] { MsgNum });

            // Todo: properly drain messages from this hub call before hot reload
            // (otherwise they appear on the new endpoints)
            await Task.Delay(3333); // a small delay will normally be enough

            // check and save the refs to the old connections before hot reload
            var wrList = new List <WeakReference>();

            foreach (var svcConn in allSvcConns0)
            {
                Assert.NotNull(svcConn.SDKSideServiceConnection);
                wrList.Add(new WeakReference(svcConn.SDKSideServiceConnection));

                Assert.NotNull(svcConn.SDKSideServiceConnection.MyMockServiceConnetion);
                wrList.Add(new WeakReference(svcConn.SDKSideServiceConnection.MyMockServiceConnetion));

                Assert.NotNull(svcConn.SDKSideServiceConnection.MyMockServiceConnetion.InnerServiceConnection);
                wrList.Add(new WeakReference(svcConn.SDKSideServiceConnection.MyMockServiceConnetion.InnerServiceConnection));

                Assert.NotNull(svcConn.Endpoint);
                wrList.Add(new WeakReference(svcConn.Endpoint));
            }

            // Part2: hot reload and until the old connections are all gone
            mockSvc.RemoveUnregisteredConnections = true;
            HotReloadIntegrationTestStartup <HotReloadMessageOrderTestParams, HotReloadTestHub> .ReloadConfig(index : 1);

            List <MockServiceSideConnection> allSvcConnsNew = null;
            bool allNew = false;

            do
            {
                await Task.Delay(TimeSpan.FromSeconds(3));

                await mockSvc.AllConnectionsEstablished();

                allSvcConnsNew = mockSvc.ServiceSideConnections;
                var newEndpoints = HotReloadMessageOrderTestParams.AllEndpoints[1];
                if (allSvcConnsNew.Count != newEndpoints.Length)
                {
                    continue;
                }

                foreach (var ep in HotReloadMessageOrderTestParams.AllEndpoints[1])
                {
                    allNew = true;
                    bool foundEp = false;
                    foreach (var conn in allSvcConnsNew)
                    {
                        if (conn.Endpoint.ConnectionString == ep.Value)
                        {
                            foundEp = true;
                            break;
                        }
                    }
                    if (!foundEp)
                    {
                        allNew = false;
                        break;
                    }
                }
            } while (!allNew);

            // Part3: send message over the new set of endpoints and verify that only the new endpoints are used
            var primarySvc1   = allSvcConnsNew.Where(i => i.Endpoint.EndpointType == EndpointType.Primary).FirstOrDefault();
            int endpointCount = allSvcConnsNew.Distinct(new MockServiceSideConnectionEndpointComparer()).Count();
            var client1       = await primarySvc1.ConnectClientAsync();

            await client1.SendMessage("BroadcastNumCalls", new object[] { MsgNum });

            var counts = await DrainBroadcastMessages(endpointCount, MsgNum, mockSvc);

            Assert.Equal(HotReloadMessageOrderTestParams.AllEndpoints[1].Count(), counts.Count());
            foreach (var conn in counts)
            {
                Assert.Equal(MsgNum, conn.Value);
            }
            return(wrList);
        }