public async Task GetCursor()
        {
            // Arrange
            string manifestPath = "idx/segments/2020/03/25/0200/meta.json";

            Mock <BlobContainerClient> containerClient = new Mock <BlobContainerClient>(MockBehavior.Strict);
            Mock <BlobClient>          blobClient      = new Mock <BlobClient>(MockBehavior.Strict);
            Mock <ShardFactory>        shardFactory    = new Mock <ShardFactory>(MockBehavior.Strict);

            List <Mock <Shard> > shards = new List <Mock <Shard> >();
            int shardCount = 3;

            for (int i = 0; i < shardCount; i++)
            {
                shards.Add(new Mock <Shard>(MockBehavior.Strict));
            }

            DateTimeOffset dateTime         = new DateTimeOffset(2020, 3, 25, 2, 0, 0, TimeSpan.Zero);
            string         segmentPath      = "idx/segments/2020/03/25/0200/meta.json";
            string         currentShardPath = "log/00/2020/03/25/0200/";

            List <ShardCursor> shardCursors = new List <ShardCursor>
            {
                new ShardCursor("log/00/2020/03/25/0200/chunk1", 2, 3),
                new ShardCursor("log/01/2020/03/25/0200/chunk4", 5, 6),
                new ShardCursor("log/02/2020/03/25/0200/chunk7", 8, 9)
            };

            SegmentCursor expectedCursor = new SegmentCursor(
                segmentPath,
                shardCursors,
                currentShardPath);

            containerClient.Setup(r => r.GetBlobClient(It.IsAny <string>())).Returns(blobClient.Object);

            using FileStream stream = File.OpenRead(
                      $"{Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)}{Path.DirectorySeparatorChar}Resources{Path.DirectorySeparatorChar}{"SegmentManifest.json"}");
            BlobDownloadStreamingResult            blobDownloadStreamingResult = BlobsModelFactory.BlobDownloadStreamingResult(content: stream);
            Response <BlobDownloadStreamingResult> downloadResponse            = Response.FromValue(blobDownloadStreamingResult, new MockResponse(200));

            if (IsAsync)
            {
                blobClient.Setup(r => r.DownloadStreamingAsync(default, default, default, default)).ReturnsAsync(downloadResponse);
        public async Task GetCursor()
        {
            // Arrange
            string manifestPath = "idx/segments/2020/03/25/0200/meta.json";

            Mock <BlobContainerClient> containerClient = new Mock <BlobContainerClient>(MockBehavior.Strict);
            Mock <BlobClient>          blobClient      = new Mock <BlobClient>(MockBehavior.Strict);
            Mock <ShardFactory>        shardFactory    = new Mock <ShardFactory>(MockBehavior.Strict);

            List <Mock <Shard> > shards = new List <Mock <Shard> >();
            int shardCount = 3;

            for (int i = 0; i < shardCount; i++)
            {
                shards.Add(new Mock <Shard>(MockBehavior.Strict));
            }

            List <ShardCursor> shardCursors = new List <ShardCursor>
            {
                new ShardCursor(1, 2, 3),
                new ShardCursor(4, 5, 6),
                new ShardCursor(7, 8, 9)
            };

            DateTimeOffset dateTime   = new DateTimeOffset(2020, 3, 25, 2, 0, 0, TimeSpan.Zero);
            int            shardIndex = 1;

            SegmentCursor expectedCursor = new SegmentCursor(
                dateTime,
                shardCursors,
                shardIndex);

            containerClient.Setup(r => r.GetBlobClient(It.IsAny <string>())).Returns(blobClient.Object);

            using FileStream stream = File.OpenRead(
                      $"{Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)}{Path.DirectorySeparatorChar}Resources{Path.DirectorySeparatorChar}{"SegmentManifest.json"}");
            BlobDownloadInfo            blobDownloadInfo = BlobsModelFactory.BlobDownloadInfo(content: stream);
            Response <BlobDownloadInfo> downloadResponse = Response.FromValue(blobDownloadInfo, new MockResponse(200));

            if (IsAsync)
            {
                blobClient.Setup(r => r.DownloadAsync()).ReturnsAsync(downloadResponse);
            }
            else
            {
                blobClient.Setup(r => r.Download()).Returns(downloadResponse);
            }

            shardFactory.SetupSequence(r => r.BuildShard(
                                           It.IsAny <bool>(),
                                           It.IsAny <string>(),
                                           It.IsAny <ShardCursor>()))
            .ReturnsAsync(shards[0].Object)
            .ReturnsAsync(shards[1].Object)
            .ReturnsAsync(shards[2].Object);

            for (int i = 0; i < shardCount; i++)
            {
                shards[i].Setup(r => r.GetCursor()).Returns(shardCursors[i]);
            }

            SegmentFactory segmentFactory = new SegmentFactory(
                containerClient.Object,
                shardFactory.Object);
            Segment segment = await segmentFactory.BuildSegment(
                IsAsync,
                manifestPath,
                expectedCursor);

            // Act
            SegmentCursor cursor = segment.GetCursor();

            // Assert
            Assert.AreEqual(expectedCursor.SegmentTime, cursor.SegmentTime);
            Assert.AreEqual(expectedCursor.ShardCursors.Count, cursor.ShardCursors.Count);
            for (int i = 0; i < shardCount; i++)
            {
                Assert.AreEqual(expectedCursor.ShardCursors[i].BlockOffset, cursor.ShardCursors[i].BlockOffset);
                Assert.AreEqual(expectedCursor.ShardCursors[i].ChunkIndex, cursor.ShardCursors[i].ChunkIndex);
                Assert.AreEqual(expectedCursor.ShardCursors[i].EventIndex, cursor.ShardCursors[i].EventIndex);
            }
            Assert.AreEqual(shardIndex, cursor.ShardIndex);

            containerClient.Verify(r => r.GetBlobClient(manifestPath));

            if (IsAsync)
            {
                blobClient.Verify(r => r.DownloadAsync());
            }
            else
            {
                blobClient.Verify(r => r.Download());
            }

            for (int i = 0; i < shards.Count; i++)
            {
                shardFactory.Verify(r => r.BuildShard(
                                        IsAsync,
                                        $"log/0{i}/2020/03/25/0200/",
                                        shardCursors[i]));
            }
        }