public void AllMetrics_SampleData_Recorded()
        {
            const int NumberOfItems = 42;
            var       errors        = new KeyValuePair <string, Exception>[]
            {
                new KeyValuePair <string, Exception>("1", new Exception()),
                new KeyValuePair <string, Exception>("2", new ArgumentException()),
                new KeyValuePair <string, Exception>("3", new KeyNotFoundException())
            };

            var statistics = new ThreadSafeTransferStatistics();

            statistics.Start();

            for (var index = 0; index < NumberOfItems; ++index)
            {
                statistics.AddTransferred();
            }

            foreach (var error in errors)
            {
                statistics.AddError(error.Key, error.Value);
            }

            statistics.Stop();

            var result = statistics.GetSnapshot();

            Assert.IsNotNull(result, TestResources.NullStatisticsSnapshot);
            Assert.AreNotEqual(TimeSpan.Zero, result.ElapsedTime, TestResources.StatisticsElapsedTimeIsEmpty);
            Assert.AreEqual(NumberOfItems, result.Transferred, TestResources.StatisticsInvalidTransferredCount);
            CollectionAssert.AreEquivalent(errors, result.GetErrors().ToArray(), TestResources.StatisticsInvalidErrors);
        }
        public async Task ExecuteAsync_SampleData_NonFatalReadExceptionsSkipped()
        {
            const int NumberOfItems = 10;
            const int ThrowAfter    = 5;

            var action = new DataTransferAction();

            var sourceData = SampleData.GetSimpleDataItems(NumberOfItems);

            var transferredCount = 0;
            var sourceMock       = new DataSourceAdapterMock(sourceData, i =>
            {
                if (ThrowAfter <= ++transferredCount && transferredCount < NumberOfItems)
                {
                    throw new NonFatalReadException();
                }
            });
            var sinkMock = new DataSinkAdapterMock();

            var statistics = new ThreadSafeTransferStatistics();

            using (var source = sourceMock)
                using (var sink = sinkMock)
                    await action.ExecuteAsync(source, sink, statistics, CancellationToken.None);

            var receivedData = sinkMock.ReceivedData;

            Assert.IsNotNull(receivedData, TestResources.NullDataInSink);
            Assert.AreEqual(ThrowAfter, receivedData.Count(), TestResources.InvalidNumberOfDataItems);

            var resultStatistics = statistics.GetSnapshot();

            Assert.AreEqual(ThrowAfter, resultStatistics.Transferred, TestResources.StatisticsInvalidTransferredCount);
            Assert.AreNotEqual(TimeSpan.Zero, resultStatistics.ElapsedTime, TestResources.StatisticsElapsedTimeIsEmpty);

            var resultExceptions = resultStatistics.GetErrors();

            Assert.IsNotNull(resultExceptions, TestResources.NullTransferExceptions);
            Assert.AreEqual(NumberOfItems - ThrowAfter, resultExceptions.Count, TestResources.InvalidNumberOfTransferExceptions);
        }