public async Task QueryRequestRateTest(bool directMode) { string firstItemIdAndPk = "BasicQueryItem" + Guid.NewGuid(); // Prevent the test from changing the static client { CosmosClient client = directMode ? DirectCosmosClient : GatewayCosmosClient; Container container = client.GetContainer(DatabaseId, ContainerId); List <string> createdIds = new List <string>() { firstItemIdAndPk, "BasicQueryItem2" + Guid.NewGuid(), "BasicQueryItem3" + Guid.NewGuid() }; foreach (string id in createdIds) { dynamic item = new { id = id, pk = id, }; await container.CreateItemAsync <dynamic>(item : item); } } CosmosClient clientWithThrottle; if (directMode) { clientWithThrottle = TestCommon.CreateCosmosClient(); } else { clientWithThrottle = TestCommon.CreateCosmosClient((builder) => builder.WithConnectionModeGateway()); } Container containerWithThrottle = clientWithThrottle.GetContainer(DatabaseId, ContainerId); // Do a read to warm up all the caches to prevent them from getting the throttle errors using (await containerWithThrottle.ReadItemStreamAsync(firstItemIdAndPk, new PartitionKey(firstItemIdAndPk))) { } Documents.IStoreModel storeModel = clientWithThrottle.ClientContext.DocumentClient.StoreModel; Mock <Documents.IStoreModel> mockStore = new Mock <Documents.IStoreModel>(); clientWithThrottle.ClientContext.DocumentClient.StoreModel = mockStore.Object; // Cause 429 after the first call int callCount = 0; string activityId = null; string errorMessage = "QueryRequestRateTest Resource Not Found"; mockStore.Setup(x => x.ProcessMessageAsync(It.IsAny <Documents.DocumentServiceRequest>(), It.IsAny <CancellationToken>())) .Returns <Documents.DocumentServiceRequest, CancellationToken>((dsr, token) => { callCount++; if (callCount > 1) { INameValueCollection headers = new StoreRequestNameValueCollection(); headers.Add(Documents.HttpConstants.HttpHeaders.RetryAfterInMilliseconds, "42"); activityId = Guid.NewGuid().ToString(); headers.Add(Documents.HttpConstants.HttpHeaders.ActivityId, activityId); Documents.DocumentServiceResponse response = new Documents.DocumentServiceResponse( body: TestCommon.GenerateStreamFromString(@"{""Errors"":[""" + errorMessage + @"""]}"), headers: headers, statusCode: (HttpStatusCode)429, clientSideRequestStatistics: dsr.RequestContext.ClientRequestStatistics); return(Task.FromResult(response)); } return(storeModel.ProcessMessageAsync(dsr, token)); }); List <dynamic> results = new List <dynamic>(); try { using (FeedIterator <dynamic> feedIterator = containerWithThrottle.GetItemQueryIterator <dynamic>( "select * from T where STARTSWITH(T.id, \"BasicQueryItem\")", requestOptions: new QueryRequestOptions() { MaxItemCount = 1, MaxConcurrency = 1 })) { while (feedIterator.HasMoreResults) { FeedResponse <dynamic> response = await feedIterator.ReadNextAsync(); Assert.IsTrue(response.Count <= 1); Assert.IsTrue(response.Resource.Count() <= 1); results.AddRange(response); } } Assert.Fail("Should throw 429 exception after the first page."); } catch (CosmosException ce) { Assert.IsTrue(ce.RetryAfter.HasValue); Assert.AreEqual(42, ce.RetryAfter.Value.TotalMilliseconds); Assert.AreEqual(activityId, ce.ActivityId); Assert.IsNotNull(ce.DiagnosticsContext); Assert.IsTrue(ce.Message.Contains(errorMessage)); } callCount = 0; FeedIterator streamIterator = containerWithThrottle.GetItemQueryStreamIterator( "select * from T where STARTSWITH(T.id, \"BasicQueryItem\")", requestOptions: new QueryRequestOptions() { MaxItemCount = 1, MaxConcurrency = 1 }); // First request should be a success using (ResponseMessage response = await streamIterator.ReadNextAsync()) { response.EnsureSuccessStatusCode(); Assert.IsNotNull(response.Content); } // Second page should be a failure using (ResponseMessage response = await streamIterator.ReadNextAsync()) { Assert.AreEqual(429, (int)response.StatusCode); Assert.AreEqual("42", response.Headers.RetryAfterLiteral); Assert.AreEqual(activityId, response.Headers.ActivityId); Assert.IsNotNull(response.DiagnosticsContext); Assert.IsTrue(response.ErrorMessage.Contains(errorMessage)); } }