Ejemplo n.º 1
0
        public async Task CannotAddToDispatchedBatch()
        {
            BatchAsyncBatcher  batchAsyncBatcher = new BatchAsyncBatcher(1, 1000, new CosmosJsonDotNetSerializer(), this.Executor, this.Retrier);
            ItemBatchOperation operation         = this.CreateItemBatchOperation();

            operation.AttachContext(new ItemBatchOperationContext(string.Empty));
            Assert.IsTrue(batchAsyncBatcher.TryAdd(operation));
            await batchAsyncBatcher.DispatchAsync();

            Assert.IsFalse(batchAsyncBatcher.TryAdd(this.CreateItemBatchOperation()));
        }
Ejemplo n.º 2
0
        public void TaskIsCreatedOnInitialization()
        {
            ItemBatchOperation        operation = new ItemBatchOperation(OperationType.Create, 0, Cosmos.PartitionKey.Null);
            ItemBatchOperationContext batchAsyncOperationContext = new ItemBatchOperationContext(string.Empty);

            operation.AttachContext(batchAsyncOperationContext);

            Assert.IsNotNull(batchAsyncOperationContext.OperationTask);
            Assert.AreEqual(batchAsyncOperationContext, operation.Context);
            Assert.AreEqual(TaskStatus.WaitingForActivation, batchAsyncOperationContext.OperationTask.Status);
        }
Ejemplo n.º 3
0
        private ItemBatchOperation CreateItemBatchOperation(bool withContext = false)
        {
            ItemBatchOperation operation = new ItemBatchOperation(OperationType.Create, 0, string.Empty, new MemoryStream(new byte[] { 0x41, 0x42 }, index: 0, count: 2, writable: false, publiclyVisible: true));

            if (withContext)
            {
                operation.AttachContext(new ItemBatchOperationContext(string.Empty));
            }

            return(operation);
        }
Ejemplo n.º 4
0
        public async Task CannotAddToDispatchedBatch()
        {
            BatchAsyncBatcher  batchAsyncBatcher = new BatchAsyncBatcher(1, 1000, MockCosmosUtil.Serializer, this.Executor, this.Retrier, BatchAsyncBatcherTests.MockClientContext());
            ItemBatchOperation operation         = this.CreateItemBatchOperation();

            operation.AttachContext(new ItemBatchOperationContext(string.Empty));
            Assert.IsTrue(batchAsyncBatcher.TryAdd(operation));
            await batchAsyncBatcher.DispatchAsync(metric);

            Assert.IsFalse(batchAsyncBatcher.TryAdd(this.CreateItemBatchOperation()));
        }
Ejemplo n.º 5
0
        public async Task ShouldRetry_WithPolicy_On429()
        {
            IDocumentClientRetryPolicy retryPolicy = new BulkPartitionKeyRangeGoneRetryPolicy(
                new ResourceThrottleRetryPolicy(1));
            TransactionalBatchOperationResult result = new TransactionalBatchOperationResult((HttpStatusCode)StatusCodes.TooManyRequests);
            ItemBatchOperation operation             = new ItemBatchOperation(OperationType.Create, 0, Cosmos.PartitionKey.Null);

            operation.AttachContext(new ItemBatchOperationContext(string.Empty, retryPolicy));
            ShouldRetryResult shouldRetryResult = await operation.Context.ShouldRetryAsync(result, default(CancellationToken));

            Assert.IsTrue(shouldRetryResult.ShouldRetry);
        }
Ejemplo n.º 6
0
        public async Task ShouldRetry_WithPolicy_OnSuccess()
        {
            IDocumentClientRetryPolicy retryPolicy = new BulkPartitionKeyRangeGoneRetryPolicy(
                new ResourceThrottleRetryPolicy(1));
            BatchOperationResult result    = new BatchOperationResult(HttpStatusCode.OK);
            ItemBatchOperation   operation = new ItemBatchOperation(OperationType.Create, 0);

            operation.AttachContext(new ItemBatchOperationContext(string.Empty, retryPolicy));
            ShouldRetryResult shouldRetryResult = await operation.Context.ShouldRetryAsync(result, default(CancellationToken));

            Assert.IsFalse(shouldRetryResult.ShouldRetry);
        }
        public async Task DispatchWithLessResponses()
        {
            BatchAsyncBatcher         batchAsyncBatcher  = new BatchAsyncBatcher(10, 1000, MockCosmosUtil.Serializer, this.ExecutorWithLessResponses, this.Retrier, BatchAsyncBatcherTests.MockClientContext());
            BatchAsyncBatcher         secondAsyncBatcher = new BatchAsyncBatcher(10, 1000, MockCosmosUtil.Serializer, this.Executor, this.Retrier, BatchAsyncBatcherTests.MockClientContext());
            List <ItemBatchOperation> operations         = new List <ItemBatchOperation>(10);

            for (int i = 0; i < 10; i++)
            {
                ItemBatchOperation        operation = new ItemBatchOperation(OperationType.Create, i, Cosmos.PartitionKey.Null, i.ToString());
                ItemBatchOperationContext context   = new ItemBatchOperationContext(string.Empty, NoOpTrace.Singleton);
                operation.AttachContext(context);
                operations.Add(operation);
                Assert.IsTrue(batchAsyncBatcher.TryAdd(operation));
            }

            await batchAsyncBatcher.DispatchAsync(metric);

            // Responses 1 and 10 should be missing
            for (int i = 0; i < 10; i++)
            {
                ItemBatchOperation operation = operations[i];
                // Some tasks should not be resolved
                if (i == 0 || i == 9)
                {
                    Assert.IsTrue(operation.Context.OperationTask.Status == TaskStatus.WaitingForActivation);
                }
                else
                {
                    Assert.IsTrue(operation.Context.OperationTask.Status == TaskStatus.RanToCompletion);
                }
                if (operation.Context.OperationTask.Status == TaskStatus.RanToCompletion)
                {
                    TransactionalBatchOperationResult result = await operation.Context.OperationTask;
                    Assert.AreEqual(i.ToString(), result.ETag);
                }
                else
                {
                    // Pass the pending one to another batcher
                    Assert.IsTrue(secondAsyncBatcher.TryAdd(operation));
                }
            }

            await secondAsyncBatcher.DispatchAsync(metric);

            // All tasks should be completed
            for (int i = 0; i < 10; i++)
            {
                ItemBatchOperation operation = operations[i];
                Assert.AreEqual(TaskStatus.RanToCompletion, operation.Context.OperationTask.Status);
                TransactionalBatchOperationResult result = await operation.Context.OperationTask;
                Assert.AreEqual(i.ToString(), result.ETag);
            }
        }
Ejemplo n.º 8
0
        public void PartitionKeyRangeIdIsSetOnInitialization()
        {
            string                    expectedPkRangeId          = Guid.NewGuid().ToString();
            ItemBatchOperation        operation                  = new ItemBatchOperation(OperationType.Create, 0);
            ItemBatchOperationContext batchAsyncOperationContext = new ItemBatchOperationContext(expectedPkRangeId);

            operation.AttachContext(batchAsyncOperationContext);

            Assert.IsNotNull(batchAsyncOperationContext.OperationTask);
            Assert.AreEqual(batchAsyncOperationContext, operation.Context);
            Assert.AreEqual(expectedPkRangeId, batchAsyncOperationContext.PartitionKeyRangeId);
            Assert.AreEqual(TaskStatus.WaitingForActivation, batchAsyncOperationContext.OperationTask.Status);
        }
        public async Task ShouldRetry_WithPolicy_OnSuccess()
        {
            IDocumentClientRetryPolicy retryPolicy = new BulkPartitionKeyRangeGoneRetryPolicy(
                Mock.Of <ContainerInternal>(),
                new ResourceThrottleRetryPolicy(1));
            TransactionalBatchOperationResult result = new TransactionalBatchOperationResult(HttpStatusCode.OK);
            ItemBatchOperation operation             = new ItemBatchOperation(OperationType.Create, 0, Cosmos.PartitionKey.Null);

            operation.AttachContext(new ItemBatchOperationContext(string.Empty, retryPolicy));
            ShouldRetryResult shouldRetryResult = await operation.Context.ShouldRetryAsync(result, default);

            Assert.IsFalse(shouldRetryResult.ShouldRetry);
        }
Ejemplo n.º 10
0
        public async Task ShouldRetry_WithPolicy_On413_OnRead()
        {
            IDocumentClientRetryPolicy retryPolicy = new BulkExecutionRetryPolicy(
                Mock.Of <ContainerInternal>(),
                OperationType.Read,
                new ResourceThrottleRetryPolicy(1));
            TransactionalBatchOperationResult result = new TransactionalBatchOperationResult(HttpStatusCode.RequestEntityTooLarge);
            ItemBatchOperation operation             = new ItemBatchOperation(OperationType.Create, 0, Cosmos.PartitionKey.Null);

            operation.AttachContext(new ItemBatchOperationContext(string.Empty, retryPolicy));
            ShouldRetryResult shouldRetryResult = await operation.Context.ShouldRetryAsync(result, default);

            Assert.IsTrue(shouldRetryResult.ShouldRetry);
        }
Ejemplo n.º 11
0
        public async Task TaskResultIsSetOnCompleteAsync()
        {
            ItemBatchOperation        operation = new ItemBatchOperation(OperationType.Create, 0, Cosmos.PartitionKey.Null);
            ItemBatchOperationContext batchAsyncOperationContext = new ItemBatchOperationContext(string.Empty, NoOpTrace.Singleton);

            operation.AttachContext(batchAsyncOperationContext);

            TransactionalBatchOperationResult expected = new TransactionalBatchOperationResult(HttpStatusCode.OK);

            batchAsyncOperationContext.Complete(null, expected);

            Assert.AreEqual(expected, await batchAsyncOperationContext.OperationTask);
            Assert.AreEqual(TaskStatus.RanToCompletion, batchAsyncOperationContext.OperationTask.Status);
        }
Ejemplo n.º 12
0
        public async Task TaskResultIsSetOnCompleteAsync()
        {
            ItemBatchOperation        operation = new ItemBatchOperation(OperationType.Create, 0);
            ItemBatchOperationContext batchAsyncOperationContext = new ItemBatchOperationContext(string.Empty);

            operation.AttachContext(batchAsyncOperationContext);

            BatchOperationResult expected = new BatchOperationResult(HttpStatusCode.OK);

            batchAsyncOperationContext.Complete(null, expected);

            Assert.AreEqual(expected, await batchAsyncOperationContext.OperationTask);
            Assert.AreEqual(TaskStatus.RanToCompletion, batchAsyncOperationContext.OperationTask.Status);
        }
Ejemplo n.º 13
0
        public async Task ExceptionIsSetOnFailAsync()
        {
            Exception                 failure   = new Exception("It failed");
            ItemBatchOperation        operation = new ItemBatchOperation(OperationType.Create, 0);
            ItemBatchOperationContext batchAsyncOperationContext = new ItemBatchOperationContext(string.Empty);

            operation.AttachContext(batchAsyncOperationContext);

            batchAsyncOperationContext.Fail(null, failure);

            Exception capturedException = await Assert.ThrowsExceptionAsync <Exception>(() => batchAsyncOperationContext.OperationTask);

            Assert.AreEqual(failure, capturedException);
            Assert.AreEqual(TaskStatus.Faulted, batchAsyncOperationContext.OperationTask.Status);
        }
Ejemplo n.º 14
0
        public async Task ShouldRetry_WithPolicy_OnCompletingPartitionMigration()
        {
            IDocumentClientRetryPolicy retryPolicy = new BulkPartitionKeyRangeGoneRetryPolicy(
                new ResourceThrottleRetryPolicy(1));
            TransactionalBatchOperationResult result = new TransactionalBatchOperationResult(HttpStatusCode.Gone)
            {
                SubStatusCode = SubStatusCodes.CompletingPartitionMigration
            };
            ItemBatchOperation operation = new ItemBatchOperation(OperationType.Create, 0, Cosmos.PartitionKey.Null);

            operation.AttachContext(new ItemBatchOperationContext(string.Empty, retryPolicy));
            ShouldRetryResult shouldRetryResult = await operation.Context.ShouldRetryAsync(result, default);

            Assert.IsTrue(shouldRetryResult.ShouldRetry);
        }
        private ItemBatchOperation CreateItemBatchOperation(bool withContext = false)
        {
            ItemBatchOperation operation = new ItemBatchOperation(
                operationType: OperationType.Create,
                operationIndex: 0,
                partitionKey: Cosmos.PartitionKey.Null,
                id: string.Empty,
                resourceStream: new MemoryStream(new byte[] { 0x41, 0x42 }, index: 0, count: 2, writable: false, publiclyVisible: true));

            if (withContext)
            {
                operation.AttachContext(new ItemBatchOperationContext(string.Empty, NoOpTrace.Singleton));
            }

            return(operation);
        }
Ejemplo n.º 16
0
        public async Task ShouldRetry_WithPolicy_OnCompletingSplit()
        {
            IDocumentClientRetryPolicy retryPolicy = new BulkExecutionRetryPolicy(
                GetSplitEnabledContainer(),
                OperationType.Read,
                new ResourceThrottleRetryPolicy(1));
            TransactionalBatchOperationResult result = new TransactionalBatchOperationResult(HttpStatusCode.Gone)
            {
                SubStatusCode = SubStatusCodes.CompletingSplit
            };
            ItemBatchOperation operation = new ItemBatchOperation(OperationType.Create, 0, Cosmos.PartitionKey.Null);

            operation.AttachContext(new ItemBatchOperationContext(string.Empty, NoOpTrace.Singleton, retryPolicy));
            ShouldRetryResult shouldRetryResult = await operation.Context.ShouldRetryAsync(result, default);

            Assert.IsTrue(shouldRetryResult.ShouldRetry);
        }
        public async Task ExceptionsFailOperationsAsync()
        {
            BatchAsyncBatcher         batchAsyncBatcher = new BatchAsyncBatcher(2, 1000, MockCosmosUtil.Serializer, this.ExecutorWithFailure, this.Retrier, BatchAsyncBatcherTests.MockClientContext());
            ItemBatchOperation        operation1        = this.CreateItemBatchOperation();
            ItemBatchOperation        operation2        = this.CreateItemBatchOperation();
            ItemBatchOperationContext context1          = new ItemBatchOperationContext(string.Empty, NoOpTrace.Singleton);

            operation1.AttachContext(context1);
            ItemBatchOperationContext context2 = new ItemBatchOperationContext(string.Empty, NoOpTrace.Singleton);

            operation2.AttachContext(context2);
            batchAsyncBatcher.TryAdd(operation1);
            batchAsyncBatcher.TryAdd(operation2);
            await batchAsyncBatcher.DispatchAsync(metric);

            Assert.AreEqual(TaskStatus.Faulted, context1.OperationTask.Status);
            Assert.AreEqual(TaskStatus.Faulted, context2.OperationTask.Status);
            Assert.AreEqual(expectedException, context1.OperationTask.Exception.InnerException);
            Assert.AreEqual(expectedException, context2.OperationTask.Exception.InnerException);
        }
        public async Task ExceptionsFailOperationsAsync()
        {
            BatchAsyncBatcher         batchAsyncBatcher = new BatchAsyncBatcher(2, 1000, new CosmosJsonDotNetSerializer(), this.ExecutorWithFailure, this.Retrier);
            ItemBatchOperation        operation1        = this.CreateItemBatchOperation();
            ItemBatchOperation        operation2        = this.CreateItemBatchOperation();
            ItemBatchOperationContext context1          = new ItemBatchOperationContext(string.Empty);

            operation1.AttachContext(context1);
            ItemBatchOperationContext context2 = new ItemBatchOperationContext(string.Empty);

            operation2.AttachContext(context2);
            batchAsyncBatcher.TryAdd(operation1);
            batchAsyncBatcher.TryAdd(operation2);
            await batchAsyncBatcher.DispatchAsync();

            Assert.AreEqual(TaskStatus.Faulted, context1.OperationTask.Status);
            Assert.AreEqual(TaskStatus.Faulted, context2.OperationTask.Status);
            Assert.AreEqual(expectedException, context1.OperationTask.Exception.InnerException);
            Assert.AreEqual(expectedException, context2.OperationTask.Exception.InnerException);
        }
Ejemplo n.º 19
0
        public async Task RetrierGetsCalledOnSplit()
        {
            ItemBatchOperation operation1 = this.CreateItemBatchOperation();
            ItemBatchOperation operation2 = this.CreateItemBatchOperation();

            operation1.AttachContext(new ItemBatchOperationContext(string.Empty));
            operation2.AttachContext(new ItemBatchOperationContext(string.Empty));

            Mock <BatchAsyncBatcherRetryDelegate> retryDelegate = new Mock <BatchAsyncBatcherRetryDelegate>();

            BatchAsyncBatcher batchAsyncBatcher = new BatchAsyncBatcher(2, 1000, new CosmosJsonDotNetSerializer(), this.ExecutorWithSplit, retryDelegate.Object);

            Assert.IsTrue(batchAsyncBatcher.TryAdd(operation1));
            Assert.IsTrue(batchAsyncBatcher.TryAdd(operation2));
            await batchAsyncBatcher.DispatchAsync();

            retryDelegate.Verify(a => a(It.Is <ItemBatchOperation>(o => o == operation1), It.IsAny <CancellationToken>()), Times.Once);
            retryDelegate.Verify(a => a(It.Is <ItemBatchOperation>(o => o == operation2), It.IsAny <CancellationToken>()), Times.Once);
            retryDelegate.Verify(a => a(It.IsAny <ItemBatchOperation>(), It.IsAny <CancellationToken>()), Times.Exactly(2));
        }
Ejemplo n.º 20
0
        public async Task TraceIsJoinedOnCompletionWithRetry()
        {
            IDocumentClientRetryPolicy retryPolicy = new BulkExecutionRetryPolicy(
                Mock.Of <ContainerInternal>(),
                OperationType.Read,
                new ResourceThrottleRetryPolicy(1));

            Trace rootTrace = Trace.GetRootTrace(name: "RootTrace");

            ItemBatchOperation operation = new ItemBatchOperation(OperationType.Create, 0, Cosmos.PartitionKey.Null);

            // Start with the base trace
            ItemBatchOperationContext batchAsyncOperationContext = new ItemBatchOperationContext(Guid.NewGuid().ToString(), rootTrace, retryPolicy);

            operation.AttachContext(batchAsyncOperationContext);

            // Simulate a retry scenario that should append to the context traces
            Trace retryTrace = Trace.GetRootTrace(name: "TransportTrace");
            TransactionalBatchOperationResult retryResult = new TransactionalBatchOperationResult(HttpStatusCode.TooManyRequests)
            {
                Trace = retryTrace
            };
            ShouldRetryResult shouldRetryResult = await batchAsyncOperationContext.ShouldRetryAsync(retryResult, default);

            Assert.IsTrue(shouldRetryResult.ShouldRetry);

            // Simulate the completion that should append to the context traces
            Trace transportTrace = Trace.GetRootTrace(name: "TransportTrace");
            TransactionalBatchOperationResult result = new TransactionalBatchOperationResult(HttpStatusCode.OK)
            {
                Trace = transportTrace
            };

            batchAsyncOperationContext.Complete(null, result);

            Assert.AreEqual(result, await batchAsyncOperationContext.OperationTask);
            Assert.AreEqual(2, result.Trace.Children.Count, "The final trace should have the initial trace, plus the retries, plus the final trace");
            Assert.AreEqual(rootTrace, result.Trace, "The first trace child should be the initial root");
            Assert.AreEqual(retryTrace, result.Trace.Children[0], "The second trace child should be the one from the retry");
            Assert.AreEqual(transportTrace, result.Trace.Children[1], "The third trace child should be the one from the final result");
        }
        public async Task RetrierGetsCalledOnOverFlow()
        {
            ItemBatchOperation operation1 = this.CreateItemBatchOperation();
            ItemBatchOperation operation2 = this.CreateItemBatchOperation();

            operation1.AttachContext(new ItemBatchOperationContext(string.Empty, NoOpTrace.Singleton));
            operation2.AttachContext(new ItemBatchOperationContext(string.Empty, NoOpTrace.Singleton));

            Mock <BatchAsyncBatcherRetryDelegate>   retryDelegate   = new Mock <BatchAsyncBatcherRetryDelegate>();
            Mock <BatchAsyncBatcherExecuteDelegate> executeDelegate = new Mock <BatchAsyncBatcherExecuteDelegate>();

            BatchAsyncBatcherThatOverflows batchAsyncBatcher = new BatchAsyncBatcherThatOverflows(2, 1000, MockCosmosUtil.Serializer, executeDelegate.Object, retryDelegate.Object);

            Assert.IsTrue(batchAsyncBatcher.TryAdd(operation1));
            Assert.IsTrue(batchAsyncBatcher.TryAdd(operation2));
            await batchAsyncBatcher.DispatchAsync(metric);

            retryDelegate.Verify(a => a(It.Is <ItemBatchOperation>(o => o == operation1), It.IsAny <CancellationToken>()), Times.Never);
            retryDelegate.Verify(a => a(It.Is <ItemBatchOperation>(o => o == operation2), It.IsAny <CancellationToken>()), Times.Once);
            retryDelegate.Verify(a => a(It.IsAny <ItemBatchOperation>(), It.IsAny <CancellationToken>()), Times.Once);
        }
        public async Task RetrierGetsCalledOn413_NoSubstatus()
        {
            IDocumentClientRetryPolicy retryPolicy1 = new BulkExecutionRetryPolicy(
                GetSplitEnabledContainer(),
                OperationType.Read,
                new ResourceThrottleRetryPolicy(1));

            IDocumentClientRetryPolicy retryPolicy2 = new BulkExecutionRetryPolicy(
                GetSplitEnabledContainer(),
                OperationType.Read,
                new ResourceThrottleRetryPolicy(1));

            IDocumentClientRetryPolicy retryPolicy3 = new BulkExecutionRetryPolicy(
                GetSplitEnabledContainer(),
                OperationType.Create,
                new ResourceThrottleRetryPolicy(1));

            ItemBatchOperation operation1 = this.CreateItemBatchOperation();
            ItemBatchOperation operation2 = this.CreateItemBatchOperation();
            ItemBatchOperation operation3 = this.CreateItemBatchOperation();

            operation1.AttachContext(new ItemBatchOperationContext(string.Empty, NoOpTrace.Singleton, retryPolicy1));
            operation2.AttachContext(new ItemBatchOperationContext(string.Empty, NoOpTrace.Singleton, retryPolicy2));
            operation3.AttachContext(new ItemBatchOperationContext(string.Empty, NoOpTrace.Singleton, retryPolicy3));

            Mock <BatchAsyncBatcherRetryDelegate> retryDelegate = new Mock <BatchAsyncBatcherRetryDelegate>();

            BatchAsyncBatcher batchAsyncBatcher = new BatchAsyncBatcher(3, 1000, MockCosmosUtil.Serializer, this.ExecutorWith413, retryDelegate.Object, BatchAsyncBatcherTests.MockClientContext());

            Assert.IsTrue(batchAsyncBatcher.TryAdd(operation1));
            Assert.IsTrue(batchAsyncBatcher.TryAdd(operation2));
            Assert.IsTrue(batchAsyncBatcher.TryAdd(operation3));
            await batchAsyncBatcher.DispatchAsync(metric);

            retryDelegate.Verify(a => a(It.Is <ItemBatchOperation>(o => o == operation1), It.IsAny <CancellationToken>()), Times.Never);
            retryDelegate.Verify(a => a(It.Is <ItemBatchOperation>(o => o == operation2), It.IsAny <CancellationToken>()), Times.Never);
            retryDelegate.Verify(a => a(It.Is <ItemBatchOperation>(o => o == operation3), It.IsAny <CancellationToken>()), Times.Never);
            retryDelegate.Verify(a => a(It.IsAny <ItemBatchOperation>(), It.IsAny <CancellationToken>()), Times.Never);
        }
Ejemplo n.º 23
0
        public async Task DispatchProcessInOrderAsync()
        {
            BatchAsyncBatcher batchAsyncBatcher       = new BatchAsyncBatcher(10, 1000, new CosmosJsonDotNetSerializer(), this.Executor, this.Retrier);
            List <ItemBatchOperationContext> contexts = new List <ItemBatchOperationContext>(10);

            for (int i = 0; i < 10; i++)
            {
                ItemBatchOperation        operation = new ItemBatchOperation(OperationType.Create, i, i.ToString());
                ItemBatchOperationContext context   = new ItemBatchOperationContext(string.Empty);
                operation.AttachContext(context);
                contexts.Add(context);
                Assert.IsTrue(batchAsyncBatcher.TryAdd(operation));
            }

            await batchAsyncBatcher.DispatchAsync();

            for (int i = 0; i < 10; i++)
            {
                ItemBatchOperationContext context = contexts[i];
                Assert.AreEqual(TaskStatus.RanToCompletion, context.OperationTask.Status);
                BatchOperationResult result = await context.OperationTask;
                Assert.AreEqual(i.ToString(), result.ETag);
            }
        }