public async Task InjectTotalLatency_Should_AddLatencyOnceForSendMethod() { var transport = Substitute.For <ITransport>(); var clusterProvider = Substitute.For <IClusterProvider>(); transport.Capabilities.Returns(TransportCapabilities.None); transport .SendAsync(Arg.Any <Request>(), Arg.Any <TimeSpan?>(), Arg.Any <TimeSpan>(), Arg.Any <CancellationToken>()) .Returns(Task.FromResult(new Response(ResponseCode.Ok))); clusterProvider.GetCluster().Returns(new List <Uri> { new Uri("http://localhost1") }); var delay = TimeSpan.FromMilliseconds(200); var latencyPerformer = new MockLatencyPerformer(); var clusterClient = new Vostok.Clusterclient.Core.ClusterClient(null, configuration => { configuration.Transport = transport; configuration.ClusterProvider = clusterProvider; configuration.DefaultRequestStrategy = new SingleReplicaRequestStrategy(); configuration.InjectTotalLatency(latencyPerformer, () => delay, () => 1); }); var request = new Request("GET", new Uri("/fakemethod", UriKind.Relative)); await clusterClient.SendAsync(request); latencyPerformer.TotalAddedLatency.Should().Be(delay); }
public async Task TimeExpiredReturn_WhenRequestedLatencyLessThanBudget() { var latency = TimeSpan.FromSeconds(2); var budget = TimeSpan.FromSeconds(1); var latencyPerformer = new MockLatencyPerformer(); var context = Substitute.For <IRequestContext>(); context.Budget.Remaining.Returns(budget); var module = new LatencyModule(latencyPerformer, new RateManager(), () => latency, () => 1); var result = await module.ExecuteAsync(context, defaultNext); nextExecuted.Should().BeFalse(); result.Status.Should().Be(ClusterResultStatus.TimeExpired); latencyPerformer.TotalAddedLatency.Should().Be(budget); }
public async Task TestRequestTimeoutReducedWithDelay(TimeSpan latency, TimeSpan callTimeout, TimeSpan expectedTimeout, TimeSpan expectedPerformedDelay) { var baseSender = Substitute.For <IRequestSender>(); var request = new Request("GET", new Uri("/fakemethod", UriKind.Relative)); var replica = new Uri("http://localhost"); var cancellationToken = new CancellationToken(); baseSender .SendToReplicaAsync(replica, request, null, expectedTimeout, cancellationToken) .Returns(Task.FromResult <ReplicaResult>(null)); var latencyPerformer = new MockLatencyPerformer(); var latencySender = new LatencyRequestSender(baseSender, latencyPerformer, new RateManager(), latency, 1); await latencySender.SendToReplicaAsync(replica, request, null, callTimeout, cancellationToken); baseSender.Received() .SendToReplicaAsync(replica, request, null, expectedTimeout, cancellationToken); latencyPerformer.TotalAddedLatency.Should().Be(expectedPerformedDelay); }
public async Task InjectLatencyOnEveryRetry_Should_AddLatencyOnEveryRetryCall() { var transport = Substitute.For <ITransport>(); var clusterProvider = Substitute.For <IClusterProvider>(); var callsCount = 0; transport.Capabilities.Returns(TransportCapabilities.None); transport .SendAsync(Arg.Any <Request>(), Arg.Any <TimeSpan?>(), Arg.Any <TimeSpan>(), Arg.Any <CancellationToken>()) .Returns(Task.FromResult(new Response(ResponseCode.TooManyRequests))) .AndDoes(_ => callsCount++); clusterProvider.GetCluster().Returns(new List <Uri> { new Uri("http://localhost1"), new Uri("http://localhost2"), new Uri("http://localhost3") }); var latency = TimeSpan.FromMilliseconds(200); var latencyPerformer = new MockLatencyPerformer(); var clusterClient = new Vostok.Clusterclient.Core.ClusterClient(null, configuration => { configuration.Transport = transport; configuration.ClusterProvider = clusterProvider; configuration.RetryPolicy = new AdHocRetryPolicy((_, __, ___) => callsCount < 3); configuration.RetryStrategy = new ImmediateRetryStrategy(3); configuration.DefaultRequestStrategy = new SingleReplicaRequestStrategy(); configuration.InjectLatencyOnEveryRetry(latencyPerformer, () => latency, () => 1); }); var request = new Request("GET", new Uri("/fakemethod", UriKind.Relative)); await clusterClient.SendAsync(request); callsCount.Should().Be(3); latencyPerformer.TotalAddedLatency.Should().Be(latency * 3); }