-
Notifications
You must be signed in to change notification settings - Fork 515
GatewayClientStore: Fixes an issue with dealing with invalid JSON HTTP responses #4229
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
microsoft-github-policy-service
merged 16 commits into
master
from
4162-handle-invalid-json-http-response-from-gateway-for-error-scenarios
Jan 10, 2024
Merged
Changes from 6 commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
44f7cd1
initial commit
philipthomas-MSFT bee917f
add back a using to fix build
philipthomas-MSFT b4ab7f5
change exception message
philipthomas-MSFT 8992c0b
check for json validity using parse
philipthomas-MSFT 4886080
some refactoring and tests. I want to see if I can mine more tests la…
philipthomas-MSFT 2f582f6
comment to rethink removing the media type check
philipthomas-MSFT dd71297
more tests and refactoring. going to mine out more tests before I und…
philipthomas-MSFT 4d0fa3c
moved string to top of class
philipthomas-MSFT 573e2ed
more tests and some refactoring
philipthomas-MSFT 74f59af
simplified some more things in tests
philipthomas-MSFT aaaa879
removing this method
philipthomas-MSFT fec474f
removed unnecessary usings
philipthomas-MSFT f6f6770
last refactoring to ignore dealing with Error.Message when empty
philipthomas-MSFT d395a7d
Merge branch 'master' into 4162-handle-invalid-json-http-response-fro…
philipthomas-MSFT 0e158a8
removed null check on 2 arguments because it was breaking other tests…
philipthomas-MSFT 3d25862
&& and > 0 in the conditional
philipthomas-MSFT File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
226 changes: 226 additions & 0 deletions
226
Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/GatewayStoreClientTests.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,226 @@ | ||
//------------------------------------------------------------ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
//------------------------------------------------------------ | ||
namespace Microsoft.Azure.Cosmos | ||
{ | ||
using System; | ||
using System.Net; | ||
using System.Net.Http; | ||
using System.Reflection.Metadata; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using Microsoft.Azure.Cosmos.Tracing; | ||
using Microsoft.Azure.Cosmos.Tracing.TraceData; | ||
using Microsoft.Azure.Documents; | ||
using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
using Newtonsoft.Json; | ||
|
||
/// <summary> | ||
/// Tests for <see cref="GatewayStoreClient"/>. | ||
/// </summary> | ||
[TestClass] | ||
public class GatewayStoreClientTests | ||
{ | ||
/// <summary> | ||
/// Testing CreateDocumentClientExceptionAsync when media type is not application/json. Not meant to be an exhaustive test for all | ||
/// legitimate content media types. | ||
/// </summary> | ||
[TestMethod] | ||
[DataRow("text/html", "<!DOCTYPE html><html><body></body></html>")] | ||
[DataRow("text/plain", "This is a test error message.")] | ||
public async Task TestCreateDocumentClientExceptionWhenMediaTypeIsNotApplicationJsonAsync( | ||
string mediaType, | ||
string contentMessage) | ||
{ | ||
HttpResponseMessage responseMessage = new(statusCode: System.Net.HttpStatusCode.NotFound) | ||
{ | ||
RequestMessage = new HttpRequestMessage( | ||
method: HttpMethod.Get, | ||
requestUri: @"https://pt_ac_test_uri.com/"), | ||
Content = new StringContent( | ||
mediaType: mediaType, | ||
encoding: Encoding.UTF8, | ||
content: JsonConvert.SerializeObject( | ||
value: new Error() { Code = HttpStatusCode.NotFound.ToString(), Message = contentMessage })), | ||
}; | ||
|
||
DocumentClientException documentClientException = await GatewayStoreClient.CreateDocumentClientExceptionAsync( | ||
responseMessage: responseMessage, | ||
requestStatistics: GatewayStoreClientTests.CreateClientSideRequestStatistics()); | ||
|
||
Assert.IsNotNull(value: documentClientException); | ||
Assert.AreEqual(expected: HttpStatusCode.NotFound, actual: documentClientException.StatusCode); | ||
Assert.IsTrue(condition: documentClientException.Message.Contains(contentMessage)); | ||
|
||
Assert.IsNotNull(value: documentClientException.Error); | ||
Assert.AreEqual(expected: HttpStatusCode.NotFound.ToString(), actual: documentClientException.Error.Code); | ||
Assert.IsTrue(documentClientException.Error.Message.Contains(contentMessage)); | ||
} | ||
|
||
/// <summary> | ||
/// Testing CreateDocumentClientExceptionAsync when media type is application/json and the header content length is zero. | ||
/// </summary> | ||
[TestMethod] | ||
public async Task TestCreateDocumentClientExceptionWhenMediaTypeIsApplicationJsonAndHeaderContentLengthIsZeroAsync() | ||
philipthomas-MSFT marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
HttpResponseMessage responseMessage = new(statusCode: System.Net.HttpStatusCode.NotFound) | ||
{ | ||
RequestMessage = new HttpRequestMessage( | ||
method: HttpMethod.Get, | ||
requestUri: @"https://pt_ac_test_uri.com/"), | ||
Content = new StringContent( | ||
mediaType: "application/json", | ||
encoding: Encoding.UTF8, | ||
content: JsonConvert.SerializeObject( | ||
value: new Error() { Code = HttpStatusCode.NotFound.ToString(), Message = "" })), | ||
}; | ||
|
||
IClientSideRequestStatistics requestStatistics = new ClientSideRequestStatisticsTraceDatum( | ||
startTime: DateTime.UtcNow, | ||
trace: NoOpTrace.Singleton); | ||
|
||
DocumentClientException documentClientException = await GatewayStoreClient.CreateDocumentClientExceptionAsync( | ||
responseMessage: responseMessage, | ||
requestStatistics: requestStatistics); | ||
|
||
Assert.IsNotNull(value: documentClientException); | ||
Assert.AreEqual(expected: HttpStatusCode.NotFound, actual: documentClientException.StatusCode); | ||
Assert.IsTrue(condition: documentClientException.Message.Contains("No response content from gateway.")); | ||
|
||
Assert.IsNotNull(value: documentClientException.Error); | ||
Assert.AreEqual(expected: HttpStatusCode.NotFound.ToString(), actual: documentClientException.Error.Code); | ||
Assert.AreEqual(expected: "No response content from gateway.", actual: documentClientException.Error.Message); | ||
} | ||
|
||
/// <summary> | ||
/// Testing CreateDocumentClientExceptionAsync when media type is application/json and the content is not valid json | ||
/// and has a content length that is not zero after trim. | ||
/// </summary> | ||
[TestMethod] | ||
[DataRow(@"<!DOCTYPE html><html><body></body></html>")] | ||
[DataRow(@" <!DOCTYPE html><html><body></body></html>")] | ||
[DataRow(@"<!DOCTYPE html><html><body></body></html> ")] | ||
[DataRow(@" <!DOCTYPE html><html><body></body></html> ")] | ||
[DataRow(@"ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890")] | ||
[DataRow(@" ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890")] | ||
[DataRow(@"ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 ")] | ||
[DataRow(@" ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 ")] | ||
public async Task TestCreateDocumentClientExceptionWhenMediaTypeIsApplicationJsonAndContentIsNotValidJsonAndContentLengthIsNotZeroAsync(string contentMessage) | ||
{ | ||
HttpResponseMessage responseMessage = new(statusCode: System.Net.HttpStatusCode.NotFound) | ||
{ | ||
RequestMessage = new HttpRequestMessage( | ||
method: HttpMethod.Get, | ||
requestUri: @"https://pt_ac_test_uri.com/"), | ||
Content = new StringContent( | ||
mediaType: "application/json", | ||
encoding: Encoding.UTF8, | ||
content: JsonConvert.SerializeObject( | ||
value: new Error() { Code = HttpStatusCode.NotFound.ToString(), Message = contentMessage })), | ||
}; | ||
|
||
IClientSideRequestStatistics requestStatistics = new ClientSideRequestStatisticsTraceDatum( | ||
startTime: DateTime.UtcNow, | ||
trace: NoOpTrace.Singleton); | ||
|
||
DocumentClientException documentClientException = await GatewayStoreClient.CreateDocumentClientExceptionAsync( | ||
responseMessage: responseMessage, | ||
requestStatistics: requestStatistics); | ||
|
||
Assert.IsNotNull(value: documentClientException); | ||
Assert.AreEqual(expected: HttpStatusCode.NotFound, actual: documentClientException.StatusCode); | ||
Assert.IsTrue(condition: documentClientException.Message.Contains(contentMessage)); | ||
|
||
Assert.IsNotNull(value: documentClientException.Error); | ||
Assert.AreEqual(expected: HttpStatusCode.NotFound.ToString(), actual: documentClientException.Error.Code); | ||
Assert.AreEqual(expected: contentMessage, actual: documentClientException.Error.Message); | ||
} | ||
|
||
/// <summary> | ||
/// Testing CreateDocumentClientExceptionAsync when media type is application/json and the content is not valid json | ||
/// and has a content length that is zero after trim. | ||
/// </summary> | ||
[TestMethod] | ||
[DataRow(@"")] | ||
[DataRow(@" ")] | ||
public async Task TestCreateDocumentClientExceptionWhenMediaTypeIsApplicationJsonAndContentIsNotValidJsonAndContentLengthIsZeroAsync(string contentMessage) | ||
{ | ||
HttpResponseMessage responseMessage = new(statusCode: System.Net.HttpStatusCode.NotFound) | ||
{ | ||
RequestMessage = new HttpRequestMessage( | ||
method: HttpMethod.Get, | ||
requestUri: @"https://pt_ac_test_uri.com/"), | ||
Content = new StringContent( | ||
content: JsonConvert.SerializeObject( | ||
value: new Error() { Code = HttpStatusCode.NotFound.ToString(), Message = contentMessage })), | ||
}; | ||
|
||
IClientSideRequestStatistics requestStatistics = new ClientSideRequestStatisticsTraceDatum( | ||
startTime: DateTime.UtcNow, | ||
trace: NoOpTrace.Singleton); | ||
|
||
DocumentClientException documentClientException = await GatewayStoreClient.CreateDocumentClientExceptionAsync( | ||
responseMessage: responseMessage, | ||
requestStatistics: requestStatistics); | ||
|
||
Assert.IsNotNull(value: documentClientException); | ||
Assert.AreEqual(expected: HttpStatusCode.NotFound, actual: documentClientException.StatusCode); | ||
Assert.IsTrue(condition: documentClientException.Message.Contains("No response content from gateway.")); | ||
|
||
Assert.IsNotNull(value: documentClientException.Error); | ||
Assert.AreEqual(expected: HttpStatusCode.NotFound.ToString(), actual: documentClientException.Error.Code); | ||
Assert.AreEqual(expected: "No response content from gateway.", actual: documentClientException.Error.Message); | ||
} | ||
|
||
/// <summary> | ||
/// Testing CreateDocumentClientExceptionAsync when response message argument is null, then expects an argumentNullException. | ||
/// </summary> | ||
[TestMethod] | ||
public async Task TestCreateDocumentClientExceptionWhenResponseMessageIsNullExpectsArgumentNullException() | ||
{ | ||
IClientSideRequestStatistics requestStatistics = new ClientSideRequestStatisticsTraceDatum( | ||
startTime: DateTime.UtcNow, | ||
trace: NoOpTrace.Singleton); | ||
|
||
ArgumentNullException argumentNullException = await Assert.ThrowsExceptionAsync<ArgumentNullException>(async () => await GatewayStoreClient.CreateDocumentClientExceptionAsync( | ||
responseMessage: default, | ||
requestStatistics: requestStatistics) | ||
); | ||
|
||
Assert.IsNotNull(argumentNullException); | ||
Assert.AreEqual(expected: "Value cannot be null. (Parameter 'responseMessage')", actual: argumentNullException.Message); | ||
} | ||
|
||
/// <summary> | ||
/// Testing CreateDocumentClientExceptionAsync when request statistics argument is null, then expects an argumentNullException. | ||
/// </summary> | ||
[TestMethod] | ||
public async Task TestCreateDocumentClientExceptionWhenRequestStatisticsIsNullExpectsArgumentNullException() | ||
{ | ||
HttpResponseMessage responseMessage = new(statusCode: System.Net.HttpStatusCode.NotFound) | ||
{ | ||
RequestMessage = new HttpRequestMessage( | ||
method: HttpMethod.Get, | ||
requestUri: @"https://pt_ac_test_uri.com/"), | ||
Content = new StringContent( | ||
content: JsonConvert.SerializeObject( | ||
value: new Error() { Code = HttpStatusCode.NotFound.ToString(), Message = "" })), | ||
}; | ||
|
||
ArgumentNullException argumentNullException = await Assert.ThrowsExceptionAsync<ArgumentNullException>(async () => await GatewayStoreClient.CreateDocumentClientExceptionAsync( | ||
responseMessage: responseMessage, | ||
requestStatistics: default) | ||
); | ||
|
||
Assert.IsNotNull(argumentNullException); | ||
Assert.AreEqual(expected: "Value cannot be null. (Parameter 'requestStatistics')", actual: argumentNullException.Message); | ||
} | ||
|
||
private static IClientSideRequestStatistics CreateClientSideRequestStatistics() | ||
{ | ||
return new ClientSideRequestStatisticsTraceDatum( | ||
startTime: DateTime.UtcNow, | ||
trace: NoOpTrace.Singleton); | ||
} | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.