public async Task BlobPartitionManagerCanListCheckpoints()
        {
            await using (StorageScope storageScope = await StorageScope.CreateAsync())
            {
                var storageConnectionString = StorageTestEnvironment.StorageConnectionString;
                var containerClient         = new BlobContainerClient(storageConnectionString, storageScope.ContainerName);

                var partitionManager = new Processor.BlobsCheckpointStore(containerClient);

                Assert.That(async() => await partitionManager.ListCheckpointsAsync("namespace", "eventHubName", "consumerGroup"), Throws.Nothing);
            }
        }
        public async Task CheckpointUpdateFailsWhenContainerDoesNotExist()
        {
            await using (StorageScope storageScope = await StorageScope.CreateAsync())
            {
                var storageConnectionString = StorageTestEnvironment.StorageConnectionString;
                var containerClient         = new BlobContainerClient(storageConnectionString, $"test-container-{Guid.NewGuid()}");

                var partitionManager = new Processor.BlobsCheckpointStore(containerClient);

                Assert.That(async() => await partitionManager.UpdateCheckpointAsync(new MockCheckpoint
                                                                                        ("namespace", "eventHubName", "consumerGroup", "partitionId", offset: 10, sequenceNumber: 20)), Throws.InstanceOf <RequestFailedException>());
            }
        }
        public async Task ListCheckpointAsyncReturnsEmptyIEnumerableWhenThereAreNoCheckpoints()
        {
            await using (StorageScope storageScope = await StorageScope.CreateAsync())
            {
                var storageConnectionString = StorageTestEnvironment.StorageConnectionString;
                var containerClient         = new BlobContainerClient(storageConnectionString, storageScope.ContainerName);

                var partitionManager = new Processor.BlobsCheckpointStore(containerClient);
                IEnumerable <Checkpoint> checkpoints = await partitionManager.ListCheckpointsAsync("namespace", "eventHubName", "consumerGroup");

                Assert.That(checkpoints, Is.Not.Null.And.Empty);
            }
        }
        public async Task OwnershipClaimDoesNotInterfereWithOtherNamespaces()
        {
            await using (var storageScope = await StorageScope.CreateAsync())
            {
                var storageConnectionString = StorageTestEnvironment.StorageConnectionString;
                var containerClient         = new BlobContainerClient(storageConnectionString, storageScope.ContainerName);

                var partitionManager = new Processor.BlobsCheckpointStore(containerClient);
                var ownershipList    = new List <PartitionOwnership>();
                var firstOwnership   =
                    new MockPartitionOwnership
                    (
                        "namespace1",
                        "eventHubName",
                        "consumerGroup",
                        "ownerIdentifier",
                        "partitionId"
                    );

                ownershipList.Add(firstOwnership);

                await partitionManager.ClaimOwnershipAsync(ownershipList);

                // ETag must have been set by the partition manager.

                var eTag = firstOwnership.ETag;

                ownershipList.Clear();

                var secondOwnership =
                    new MockPartitionOwnership
                    (
                        "namespace2",
                        "eventHubName",
                        "consumerGroup",
                        "ownerIdentifier",
                        "partitionId",
                        eTag: eTag
                    );

                ownershipList.Add(secondOwnership);

                await partitionManager.ClaimOwnershipAsync(ownershipList);

                var storedOwnershipList = await partitionManager.ListOwnershipAsync("namespace1", "eventHubName", "consumerGroup");

                Assert.That(storedOwnershipList, Is.Not.Null);
                Assert.That(storedOwnershipList.Count, Is.EqualTo(1));
                Assert.That(storedOwnershipList.Single().IsEquivalentTo(firstOwnership), Is.True);
            }
        }
        public async Task OwnershipClaimFailsWhenETagIsInvalid(string eTag)
        {
            await using (StorageScope storageScope = await StorageScope.CreateAsync())
            {
                var storageConnectionString = StorageTestEnvironment.StorageConnectionString;
                var containerClient         = new BlobContainerClient(storageConnectionString, storageScope.ContainerName);

                var partitionManager = new Processor.BlobsCheckpointStore(containerClient);
                var ownershipList    = new List <PartitionOwnership>();
                var firstOwnership   =
                    new MockPartitionOwnership
                    (
                        "namespace",
                        "eventHubName",
                        "consumerGroup",
                        "ownerIdentifier",
                        "partitionId"
                    );

                ownershipList.Add(firstOwnership);

                await partitionManager.ClaimOwnershipAsync(ownershipList);

                ownershipList.Clear();

                var secondOwnership =
                    new MockPartitionOwnership
                    (
                        "namespace",
                        "eventHubName",
                        "consumerGroup",
                        "ownerIdentifier",
                        "partitionId",
                        eTag: eTag
                    );

                ownershipList.Add(secondOwnership);

                await partitionManager.ClaimOwnershipAsync(ownershipList);

                IEnumerable <PartitionOwnership> storedOwnershipList = await partitionManager.ListOwnershipAsync("namespace", "eventHubName", "consumerGroup");

                Assert.That(storedOwnershipList, Is.Not.Null);
                Assert.That(storedOwnershipList.Count, Is.EqualTo(1));
                Assert.That(storedOwnershipList.Single().IsEquivalentTo(firstOwnership), Is.True);
            }
        }
        public async Task ClaimOwnershipAsyncCanClaimMultipleOwnership()
        {
            await using (StorageScope storageScope = await StorageScope.CreateAsync())
            {
                var storageConnectionString = StorageTestEnvironment.StorageConnectionString;
                var containerClient         = new BlobContainerClient(storageConnectionString, storageScope.ContainerName);

                var partitionManager = new Processor.BlobsCheckpointStore(containerClient);
                var ownershipList    = new List <PartitionOwnership>();
                var ownershipCount   = 5;

                for (int i = 0; i < ownershipCount; i++)
                {
                    ownershipList.Add(
                        new MockPartitionOwnership
                        (
                            "namespace",
                            "eventHubName",
                            "consumerGroup",
                            "ownerIdentifier",
                            $"partitionId { i }"
                        ));
                }

                await partitionManager.ClaimOwnershipAsync(ownershipList);

                IEnumerable <PartitionOwnership> storedOwnershipList = await partitionManager.ListOwnershipAsync("namespace", "eventHubName", "consumerGroup");

                Assert.That(storedOwnershipList, Is.Not.Null);
                Assert.That(storedOwnershipList.Count, Is.EqualTo(ownershipCount));

                var index = 0;

                foreach (PartitionOwnership ownership in storedOwnershipList.OrderBy(ownership => ownership.PartitionId))
                {
                    Assert.That(ownership.IsEquivalentTo(ownershipList[index]), Is.True, $"Ownership of partition '{ ownership.PartitionId }' should be equivalent.");
                    ++index;
                }
            }
        }
        public async Task ClaimOwnershipAsyncReturnsOnlyTheSuccessfullyClaimedOwnership()
        {
            await using (StorageScope storageScope = await StorageScope.CreateAsync())
            {
                var storageConnectionString = StorageTestEnvironment.StorageConnectionString;
                var containerClient         = new BlobContainerClient(storageConnectionString, storageScope.ContainerName);

                var partitionManager = new Processor.BlobsCheckpointStore(containerClient);
                var ownershipList    = new List <PartitionOwnership>();
                var ownershipCount   = 5;

                for (int i = 0; i < ownershipCount; i++)
                {
                    ownershipList.Add(
                        new MockPartitionOwnership
                        (
                            "namespace",
                            "eventHubName",
                            "consumerGroup",
                            "ownerIdentifier",
                            partitionId: $"{i}"
                        ));
                }

                await partitionManager.ClaimOwnershipAsync(ownershipList);

                // The ETags must have been set by the partition manager.

                var eTags = ownershipList.Select(ownership => ownership.ETag).ToList();

                ownershipList.Clear();

                // Use a valid eTag when 'i' is odd.  This way, we can expect 'ownershipCount / 2' successful
                // claims (rounded down).

                var expectedClaimedCount = ownershipCount / 2;

                for (int i = 0; i < ownershipCount; i++)
                {
                    ownershipList.Add(
                        new MockPartitionOwnership
                        (
                            "namespace",
                            "eventHubName",
                            "consumerGroup",
                            "ownerIdentifier",
                            partitionId: $"{i}",
                            eTag: i % 2 == 1 ? eTags[i] : null
                        ));
                }

                IEnumerable <PartitionOwnership> claimedOwnershipList = await partitionManager.ClaimOwnershipAsync(ownershipList);

                IEnumerable <PartitionOwnership> expectedOwnership = ownershipList.Where(ownership => int.Parse(ownership.PartitionId) % 2 == 1);

                Assert.That(claimedOwnershipList, Is.Not.Null);
                Assert.That(claimedOwnershipList.Count, Is.EqualTo(expectedClaimedCount));

                var index = 0;

                foreach (PartitionOwnership ownership in claimedOwnershipList.OrderBy(ownership => ownership.PartitionId))
                {
                    Assert.That(ownership.IsEquivalentTo(expectedOwnership.ElementAt(index)), Is.True, $"Ownership of partition '{ ownership.PartitionId }' should be equivalent.");
                    ++index;
                }
            }
        }