modify AzureMetadataRequestor to accept HttpClient in ctor. rewrite AzureInstanceMetadata tests to mock HttpClient instead of using in-proc server.#2358
Conversation
| azureImsClient.DefaultRequestHeaders.Add("Metadata", "True"); | ||
| azureImsClient.Timeout = this.AzureImsRequestTimeout; | ||
| this.httpClient.MaxResponseContentBufferSize = AzureMetadataRequestor.AzureImsMaxResponseBufferSize; | ||
| this.httpClient.DefaultRequestHeaders.Add("Metadata", "True"); |
There was a problem hiding this comment.
Would this end up adding multiple headers to the httpClient?
| azureImsClient.Timeout = this.AzureImsRequestTimeout; | ||
| this.httpClient.MaxResponseContentBufferSize = AzureMetadataRequestor.AzureImsMaxResponseBufferSize; | ||
| this.httpClient.DefaultRequestHeaders.Add("Metadata", "True"); | ||
| this.httpClient.Timeout = this.AzureImsRequestTimeout; |
There was a problem hiding this comment.
Do we need to change Timeout each time?
|
The change seems to touch things beyond test cases. Either we need to change the PR title/description or scope it down to test cases. |
| internal TimeSpan AzureImsRequestTimeout = TimeSpan.FromSeconds(10); | ||
| private TimeSpan AzureImsRequestTimeout = TimeSpan.FromSeconds(10); | ||
|
|
||
| private readonly HttpClient httpClient; |
There was a problem hiding this comment.
Who owns the lifecycle management for this http client? Who is responsible for Dispose?
What is the thread safety guarantee? Do we allow concurrent invocations?
There was a problem hiding this comment.
this is a miss on my part. I need to implement the correct Dispose pattern.
This code is only ever called once, when the SDK initializes TelemetryModules. There are no retries.
| using Microsoft.ApplicationInsights.WindowsServer.Implementation.DataContracts; | ||
|
|
||
| internal interface IAzureMetadataRequestor | ||
| internal interface IAzureMetadataRequestor : IDisposable |
There was a problem hiding this comment.
The call stack here is: TelemetryModule > Provider > Requestor > HttpClient.
We don't NEED this interface to be disposable.
Alternatively, the Provider can check if it's private requestor implements IDisposable.
This introduces a little more complexity and it's not as obvious that the Requestor needs to be disposed. (The Analyzers can't catch this scenario).
There was a problem hiding this comment.
If we don't need this, let's try not to add it.
There was a problem hiding this comment.
| return hasSetFields; | ||
| } | ||
|
|
||
| public void Dispose() |
There was a problem hiding this comment.
The call stack here is: TelemetryModule > Provider > Requestor > HttpClient.
Inside the TelemetryModule, I moved the Provider into a using to ensure it gets disposed.
There was a problem hiding this comment.
Stepping back, if the whole purpose is to allow mock in the unit test, would reflection (setting some private member instead of having to change any production code) work?
There was a problem hiding this comment.
I'm not sure that a private member helps us here.
The original class doesn't have a private HttpClient. It creates the client just-in-time to make a request.
This is how it avoided the responsibility of Disposing.
I can mock any HTTP response if I can provide a custom HttpMessageHandler into the HttpClient.
var mockHttpMessageHandler = new Mock<HttpMessageHandler>();
new HttpClient(mockHttpMessageHandler.Object)
There was a problem hiding this comment.
I came up with an alternate approach that works.
Tomorrow i'll clean it up and create a new PR.
|
superceded by #2360 |
When switching to FrameworkReferences, discovered a problem with some tests for AzureInstanceMetadada (see full write up in #2357).
Changes
AzureImsResponseTooLargeStopsCollection. HttpClient correctly handles and parses the larger response.AzureImsResponseTimesOutwithAzureImsResponseHandlesException. Could not force a timeout in a test context. HttpClient throws an exception when timeout. I changed this test to throw an exception and verify that this is handled correctly.Checklist
For significant contributions please make sure you have completed the following items:
The PR will trigger build, unit tests, and functional tests automatically. Please follow these instructions to build and test locally.
Notes for authors:
Notes for reviewers:
/AzurePipelines runwill queue all builds/AzurePipelines run <pipeline-name>will queue a specific build