Ejemplo n.º 1
0
        public async Task CopyToAppliesStreamScheduling(int blocks, int blockSize)
        {
            var clock     = new ManualClock();
            var src       = new MemoryStream(Enumerable.Range(0, blockSize * blocks).Select(x => (byte)x).ToArray());
            var scheduler = new ShapeStreamAverage(BandwidthStreamCost.Default, blockSize,
                                                   averageSpan: TimeSpan.FromSeconds(1), clock: clock);
            var dst    = new MemoryStream();
            var bw     = new ReadMaxStream <Stream>(src.Shape(scheduler), blockSize);
            var cpTask = bw.CopyToAsync(dst, blockSize, CancellationToken);

            for (var i = 0; i < blocks; ++i)
            {
                await Waiter.TimesOut(cpTask.WaitAsync, cancellationToken : CancellationToken)
                .ConfigureAwait(false);

                dst.Length.Should().BeLessOrEqualTo((i + 1) * blockSize);
                await Task.WhenAll(clock.Advance(TimeSpan.FromSeconds(1))).ConfigureAwait(false);
            }

            await Waiter.WaitAsync(cpTask.WaitAsync, cancellationToken : CancellationToken)
            .ConfigureAwait(false);

            dst.Length.Should().Be(blocks * blockSize);
            dst.ToArray()
            .Should()
            .BeEquivalentTo(src.ToArray(), cfg => cfg.WithStrictOrdering());
        }
Ejemplo n.º 2
0
        public async Task ManualClockShouldSupportMultiplePendingOperationsAndSynchroneousOperations(int concurCount)
        {
            var clock = new ManualClock();
            var step  = TimeSpan.FromSeconds(1);

            Skip.If(concurCount < 4);
            var concurrent = Enumerable.Range(0, concurCount)
                             .Select(i =>
            {
                if (i % 2 == 0)     // Do async
                {
                    return new
                    {
                        i,
                        Task = clock.Delay(i <= 1 ? TimeSpan.Zero : step, CancellationToken).OnCompletion(i)
                    }
                }
                ;
                // Do blocking in separate thread
                var tcs    = new TaskCompletionSource <int>();
                var thread = new Thread(() =>
                {
                    clock.Sleep(i <= 1 ? TimeSpan.Zero : step);
                    tcs.SetResult(i);
                });
                thread.Start();
                return
                (new
                {
                    i,
                    tcs.Task
                });
            })
                             .ToDictionary(x => x.i, x => x.Task);

            // Only 0 should be able to run
            await Task.WhenAll(concurrent.Where(x => x.Key <= 1).Select(x => x.Value)).ConfigureAwait(false);

            concurrent.Where(x => x.Key > 1).Should().OnlyContain(x => !x.Value.IsCompleted);
            clock.PendingCount().Should().BeGreaterOrEqualTo(2).And.BeLessOrEqualTo(concurCount - 2);
            await Task.WhenAll(clock.Advance(step)).ConfigureAwait(false);

            clock.PendingCount().Should().Be(0);
            var done = await Task.WhenAll(concurrent.Values).ConfigureAwait(false);

            done.Should().BeEquivalentTo(concurrent.Keys);
        }
        public void sub_reporter_creates_sub_report_and_reports_to_it()
        {
            var subReporter = _statisticsReporter.CreateSubReporter("foo");

            _clock.Advance(2.5);
            subReporter.ReportEvent("bar");

            _statisticsReporter.DumpToReport(_report);

            var subReport = _report.GetSubReportAndRemove("foo");

            _report.ValidateNoMoreReports();

            subReport.ValidateReportedAndRemove("bar_COUNT", 1);
        }
Ejemplo n.º 4
0
        public async Task StreamShedulingIsAppliedAccordingToClockAndSchedulers()
        {
            var clock     = new ManualClock(new DateTime(2000, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc));
            var stream    = new MemoryStream();
            var scheduler = new ShapeStreamAverage(BandwidthStreamCost.Default, 1000, 2000, 10,
                                                   averageSpan: TimeSpan.FromSeconds(5), clock: clock);
            var bw = stream.Shape(scheduler);

            // Writing (2000b/s over 5s = 10kb/5s)
            await WriteAsync(bw, 1, 9000).ConfigureAwait(false);

            stream.Length.Should().Be(9000);

            await WriteAsync(bw, 2, 1000).ConfigureAwait(false);

            stream.Length.Should().Be(10000);

            await Task.WhenAll(clock.Advance(TimeSpan.FromSeconds(4), CancellationToken)).ConfigureAwait(false);

            // Exceed the shaping: will timeout and not get invoked
            await Waiter.TimesOut(ct => WriteAsync(bw, 3, 2000, ct), cancellationToken : CancellationToken).ConfigureAwait(false);

            stream.Length.Should().Be(10000);

            // Try writing again
            var wtask = WriteAsync(bw, 4, 2000);
            // That won't run immediately
            await Waiter.TimesOut(wtask.WaitAsync, cancellationToken : CancellationToken).ConfigureAwait(false);

            // And one second is not enough, as we are accounted the 2000 from time timed out write
            await Task.WhenAll(clock.Advance(TimeSpan.FromSeconds(1), CancellationToken)).ConfigureAwait(false);

            await Waiter.TimesOut(wtask.WaitAsync, cancellationToken : CancellationToken).ConfigureAwait(false);

            // So we need another second
            await Task.WhenAll(clock.Advance(TimeSpan.FromSeconds(1), CancellationToken));

            // Now, It will be completed (pretty quickly)
            await Waiter.WaitAsync(wtask.WaitAsync, cancellationToken : CancellationToken);

            // And now have the required state
            stream.Length.Should().Be(12000);

            stream.Position = 0;
            var streamBytes = stream.ToArray();
            IList <IList <byte> > readParts = new List <IList <byte> >();

            // ReSharper disable once ImplicitlyCapturedClosure - bw, this captured
            void AssertReadCorrect()
            => readParts.Aggregate(0, (offset, part) =>
            {
                part.Should().BeEquivalentTo(streamBytes.Skip(offset).Take(part.Count));
                return(offset + part.Count);
            });

            // Reading (1000b/s over 5s = 50kb/5s)
            readParts.Add(await ReadAsync(bw, 4999, CancellationToken).ConfigureAwait(false));
            AssertReadCorrect();
            readParts.Add(await ReadAsync(bw, 1).ConfigureAwait(false));
            AssertReadCorrect();

            // Exceed the shaping: will timeout and not get invoked
            // ReSharper disable once ImplicitlyCapturedClosure -- streamBytes captured
            await Waiter.TimesOut(async ct => readParts.Add(await ReadAsync(bw, 1, ct).ConfigureAwait(false)), cancellationToken : CancellationToken).ConfigureAwait(false);

            AssertReadCorrect();

            // Try reading again
            var rtask = ReadAsync(bw, 6000);
            // That won't run immediately
            await Waiter.TimesOut(rtask.WaitAsync, cancellationToken : CancellationToken).ConfigureAwait(false);

            // And 6 seconds is not enough, as we are exceeding average in the read itself and pay for the extra 1 failing byte
            await Task.WhenAll(clock.Advance(TimeSpan.FromSeconds(6), CancellationToken)).ConfigureAwait(false);

            await Waiter.TimesOut(rtask.WaitAsync, cancellationToken : CancellationToken).ConfigureAwait(false);

            // But a little more is
            await Task.WhenAll(clock.Advance(TimeSpan.FromSeconds(.1), CancellationToken)).ConfigureAwait(false);

            // Now, It will be completed (pretty quickly)
            readParts.Add(await Waiter.WaitAsync(rtask.WaitAsync, cancellationToken: CancellationToken));
            AssertReadCorrect();
            readParts.Sum(x => x.Count).Should().Be(4999 + 1 + 6000);
        }