Пример #1
0
        public async Task ResetDeadline()
        {
            var clock        = new FakeClock(0);
            var scheduler    = new AdvanceFakeClockScheduler(clock);
            var callSettings = CallSettings.FromExpiration(Expiration.FromDeadline(new DateTime(TimeSpan.FromSeconds(7).Ticks, DateTimeKind.Utc)));
            var state        = new RetryState(clock, scheduler, s_retrySettings, callSettings);

            var retryInfo = new Rpc.RetryInfo {
                RetryDelay = Duration.FromTimeSpan(TimeSpan.FromSeconds(3))
            };
            Metadata trailers = new Metadata
            {
                { RetryState.RetryInfoKey, retryInfo.ToByteArray() }
            };
            var exception = new RpcException(new Status(StatusCode.Unavailable, "Bang"), trailers);

            Assert.True(state.CanRetry(exception));
            await state.WaitAsync(exception, default);

            Assert.True(state.CanRetry(exception));
            await state.WaitAsync(exception, default);

            // Reset does not change the absolute deadline of the call.
            // The next retry attempt will therefore fail.
            state.Reset();

            Assert.True(state.CanRetry(exception));
            await Assert.ThrowsAsync <RpcException>(() => state.WaitAsync(exception, default));

            Assert.Equal(TimeSpan.FromSeconds(6).Ticks, clock.GetCurrentDateTimeUtc().Ticks);
        }
Пример #2
0
        public async Task ConsecutiveErrors_FailsRetryWhenDeadlineExceeded()
        {
            var clock        = new FakeClock(0);
            var scheduler    = new AdvanceFakeClockScheduler(clock);
            var callSettings = CallSettings.FromExpiration(Expiration.FromDeadline(new DateTime(TimeSpan.FromSeconds(7).Ticks, DateTimeKind.Utc)));
            var state        = new RetryState(clock, scheduler, s_retrySettings, callSettings);

            var retryInfo = new Rpc.RetryInfo {
                RetryDelay = Duration.FromTimeSpan(TimeSpan.FromSeconds(3))
            };
            Metadata trailers = new Metadata
            {
                { RetryState.RetryInfoKey, retryInfo.ToByteArray() }
            };
            var exception = new RpcException(new Status(StatusCode.Unavailable, "Bang"), trailers);

            Assert.True(state.CanRetry(exception));
            await state.WaitAsync(exception, default);

            Assert.True(state.CanRetry(exception));
            await state.WaitAsync(exception, default);

            Assert.True(state.CanRetry(exception));
            await Assert.ThrowsAsync <RpcException>(() => state.WaitAsync(exception, default));

            // Verify that the clock has been advanced 6 seconds.
            Assert.Equal(TimeSpan.FromSeconds(6).Ticks, clock.GetCurrentDateTimeUtc().Ticks);
        }
Пример #3
0
        public async Task ErrorWithBackoffAfterDeadline_FailsRetry()
        {
            // Create a clock that starts at zero ticks.
            var clock        = new FakeClock(0);
            var scheduler    = new AdvanceFakeClockScheduler(clock);
            var callSettings = CallSettings.FromExpiration(Expiration.FromDeadline(new DateTime(TimeSpan.FromSeconds(10).Ticks, DateTimeKind.Utc)));
            var state        = new RetryState(clock, scheduler, s_retrySettings, callSettings);

            // The retry info contains a wait time that is past the deadline of the call.
            // The retry state will throw a DeadlineExceeded error without waiting.
            var retryInfo = new Rpc.RetryInfo {
                RetryDelay = Duration.FromTimeSpan(TimeSpan.FromSeconds(20))
            };
            Metadata trailers = new Metadata
            {
                { RetryState.RetryInfoKey, retryInfo.ToByteArray() }
            };
            var exception = new RpcException(new Status(StatusCode.Unavailable, "Bang"), trailers);

            Assert.True(state.CanRetry(exception));
            await Assert.ThrowsAsync <RpcException>(() => state.WaitAsync(exception, default));

            // Check that the clock has not been advanced to verify that the retry state did not wait 20 seconds
            // before throwing an exception.
            Assert.Equal(0, clock.GetCurrentDateTimeUtc().Ticks);
        }
Пример #4
0
        public void ToCallOptions_CallTimingExpirationTimeout()
        {
            var          clock        = new FakeClock();
            var          timeout      = TimeSpan.FromSeconds(1);
            CallSettings callSettings = CallSettings.FromCallTiming(CallTiming.FromExpiration(Expiration.FromTimeout(timeout)));
            var          options      = callSettings.ToCallOptions(clock);

            // Value should be exact, as we control time precisely.
            Assert.Equal(options.Deadline.Value, clock.GetCurrentDateTimeUtc() + timeout);
        }
Пример #5
0
        public void WithEarlierDeadline_DeadlineIsLaterThanExistingTimeout()
        {
            // Use a cancellation token to emphasize that it's not just the timing.
            var          token    = new CancellationTokenSource().Token;
            CallSettings settings = CallSettings.FromCancellationToken(token)
                                    .WithTimeout(TimeSpan.FromTicks(100));
            var      clock    = new FakeClock();
            DateTime?deadline = clock.GetCurrentDateTimeUtc() + TimeSpan.FromTicks(200);

            Assert.Same(settings, settings.WithEarlierDeadline(deadline, clock));
        }
Пример #6
0
        public void WithEarlierDeadline_DeadlineIsEarlierThanExistingTimeout()
        {
            // Use a cancellation token to emphasize that it's not just the timing.
            var          token    = new CancellationTokenSource().Token;
            CallSettings settings = CallSettings.FromCancellationToken(token)
                                    .WithTimeout(TimeSpan.FromTicks(200));
            var          clock       = new FakeClock();
            DateTime?    deadline    = clock.GetCurrentDateTimeUtc() + TimeSpan.FromTicks(100);
            CallSettings newSettings = settings.WithEarlierDeadline(deadline, new FakeClock());

            // New timing has a deadline rather than a timeout
            Assert.Equal(deadline, newSettings.Expiration.Deadline);
            Assert.Equal(token, newSettings.CancellationToken);
        }
Пример #7
0
        public async Task LogEntriesLostSingleAppend_CheckTimestamps()
        {
            var fakeClock       = new FakeClock(new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Utc));
            var uploadedEntries = await RunTestWorkingServer(
                async appender =>
            {
                var logs = Enumerable.Range(0, 5).Select(i => CreateLog(Level.Info, $"Message{i}", i)).ToArray();
                appender.DoAppend(logs);
                Assert.True(await appender.FlushAsync(s_testTimeout));
            },
                clock : fakeClock,
                maxMemoryCount : 1);

            // Expect logs-loss warning, and the last log entry
            Assert.Equal(2, uploadedEntries.Count);
            // Check the "lost-entries" payload text and timestamp are correct
            Assert.Equal(string.Format(s_lostMsg, TimeOfs(0), TimeOfs(3)), uploadedEntries[0].TextPayload);
            Assert.Equal(fakeClock.GetCurrentDateTimeUtc(), uploadedEntries[0].Timestamp.ToDateTime());
            // Check the single successfully logged message is correct
            Assert.Equal("Message4", uploadedEntries[1].TextPayload.Trim());
        }
Пример #8
0
        public async Task ResetTimeout()
        {
            var clock        = new FakeClock(0);
            var scheduler    = new AdvanceFakeClockScheduler(clock);
            var callSettings = CallSettings.FromExpiration(Expiration.FromTimeout(TimeSpan.FromSeconds(7)));
            var state        = new RetryState(clock, scheduler, s_retrySettings, callSettings);

            var retryInfo = new Rpc.RetryInfo {
                RetryDelay = Duration.FromTimeSpan(TimeSpan.FromSeconds(3))
            };
            Metadata trailers = new Metadata
            {
                { RetryState.RetryInfoKey, retryInfo.ToByteArray() }
            };
            var exception = new RpcException(new Status(StatusCode.Unavailable, "Bang"), trailers);

            Assert.True(state.CanRetry(exception));
            await state.WaitAsync(exception, default);

            Assert.True(state.CanRetry(exception));
            await state.WaitAsync(exception, default);

            // Reset should set the deadline of the call to CurrentTime + Timeout.
            // That means that we can do two new retries without a timeout exception.
            state.Reset();

            Assert.True(state.CanRetry(exception));
            await state.WaitAsync(exception, default);

            Assert.True(state.CanRetry(exception));
            await state.WaitAsync(exception, default);

            Assert.True(state.CanRetry(exception));
            await Assert.ThrowsAsync <RpcException>(() => state.WaitAsync(exception, default));

            // Verify that the clock has been advanced 12 seconds.
            Assert.Equal(TimeSpan.FromSeconds(12).Ticks, clock.GetCurrentDateTimeUtc().Ticks);
        }