Skip to content

Commit cfb871a

Browse files
Update integration tests (#3007)
* Updated tests * Fix warning * Add dependency support * Other changes
1 parent 1250451 commit cfb871a

File tree

12 files changed

+838
-257
lines changed

12 files changed

+838
-257
lines changed

NETCORE/src/Microsoft.ApplicationInsights.AspNetCore/Extensions/ApplicationInsightsExtensions.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,10 @@ internal static IOpenTelemetryBuilder UseApplicationInsightsTelemetry(this IOpen
192192
{
193193
exporterOptions.EnableLiveMetrics = true;
194194
}
195+
else
196+
{
197+
exporterOptions.EnableLiveMetrics = false;
198+
}
195199
});
196200

197201
builder.UseAzureMonitorExporter();

NETCORE/test/IntegrationTests.Tests/CustomWebApplicationFactory.cs

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,51 @@
1-
using Microsoft.ApplicationInsights;
2-
using Microsoft.ApplicationInsights.AspNetCore.Extensions;
3-
using Microsoft.ApplicationInsights.Channel;
1+
using System.Diagnostics;
2+
using Azure.Core.Pipeline;
3+
using Azure.Monitor.OpenTelemetry.Exporter;
44
using Microsoft.AspNetCore.Hosting;
55
using Microsoft.AspNetCore.Mvc.Testing;
66
using Microsoft.Extensions.DependencyInjection;
77
using Microsoft.Extensions.Logging;
8-
using Microsoft.Extensions.Logging.ApplicationInsights;
9-
using System;
10-
using System.Collections.Concurrent;
11-
using System.Collections.Generic;
12-
using System.Linq;
13-
using System.Threading.Tasks;
148

159
namespace IntegrationTests.Tests
1610
{
1711
public class CustomWebApplicationFactory<TStartup>
1812
: WebApplicationFactory<TStartup> where TStartup : class
1913
{
20-
internal ConcurrentBag<ITelemetry> sentItems = new ConcurrentBag<ITelemetry>();
21-
14+
internal TelemetryCollector Telemetry { get; } = new TelemetryCollector();
2215

2316
protected override void ConfigureWebHost(IWebHostBuilder builder)
2417
{
18+
Activity.DefaultIdFormat = ActivityIdFormat.W3C;
19+
Activity.ForceDefaultIdFormat = true;
2520

2621
builder.ConfigureServices(services =>
2722
{
2823
services.AddLogging(loggingBuilder =>
29-
loggingBuilder.AddFilter<ApplicationInsightsLoggerProvider>("Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager", LogLevel.None));
24+
loggingBuilder.AddFilter(
25+
"Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager",
26+
LogLevel.None)
27+
.AddFilter(
28+
"IntegrationTests.WebApp.Controllers.HomeController",
29+
LogLevel.Warning));
30+
31+
services.AddSingleton<TelemetryCollector>(_ => this.Telemetry);
32+
services.AddSingleton<HttpPipelineTransport>(provider =>
33+
new RecordingTransport(provider.GetRequiredService<TelemetryCollector>()));
34+
35+
services.AddOptions<AzureMonitorExporterOptions>()
36+
.Configure<HttpPipelineTransport>((options, transport) =>
37+
{
38+
options.Transport = transport;
39+
options.DisableOfflineStorage = true;
40+
});
3041

31-
services.AddSingleton<ITelemetryChannel>(new StubChannel()
42+
services.AddApplicationInsightsTelemetry(options =>
3243
{
33-
OnSend = (item) => this.sentItems.Add(item)
44+
options.AddAutoCollectedMetricExtractor = false;
45+
options.EnableQuickPulseMetricStream = false;
46+
options.EnableAdaptiveSampling = false;
47+
options.ConnectionString = "InstrumentationKey=ikey";
3448
});
35-
var aiOptions = new ApplicationInsightsServiceOptions();
36-
aiOptions.AddAutoCollectedMetricExtractor = false;
37-
aiOptions.EnableAdaptiveSampling = false;
38-
aiOptions.InstrumentationKey = "ikey";
39-
services.AddApplicationInsightsTelemetry(aiOptions);
4049
});
4150
}
4251
}

NETCORE/test/IntegrationTests.Tests/IntegrationTests.Tests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
<PropertyGroup>
1313
<!-- TargetFrameworks are defined in Test.props, but can be overridden here if needed. -->
14-
<TargetFrameworks>$(TargetFrameworks_NetCoreOnly)</TargetFrameworks>
14+
<TargetFrameworks>net9.0;net8.0</TargetFrameworks>
1515
</PropertyGroup>
1616

1717
<ItemGroup>

NETCORE/test/IntegrationTests.Tests/RequestCollectionTest.cs

Lines changed: 50 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
using IntegrationTests.WebApp;
2-
using Microsoft.ApplicationInsights.Channel;
3-
using Microsoft.ApplicationInsights.DataContracts;
42
using System;
5-
using System.Collections.Concurrent;
63
using System.Collections.Generic;
74
using System.Net;
85
using System.Net.Http;
@@ -22,7 +19,7 @@ public RequestCollectionTest(CustomWebApplicationFactory<Startup> factory, ITest
2219
{
2320
this.output = output;
2421
_factory = factory;
25-
_factory.sentItems.Clear();
22+
_factory.Telemetry.Clear();
2623
}
2724

2825
[Fact]
@@ -41,13 +38,13 @@ public async Task RequestSuccess()
4138
// Assert
4239
response.EnsureSuccessStatusCode();
4340

44-
await WaitForTelemetryToArrive();
41+
await WaitForTelemetryToArrive(expectedItemCount: 1);
4542

46-
var items = _factory.sentItems;
43+
var items = _factory.Telemetry.Items;
4744
PrintItems(items);
4845
Assert.Equal(1, items.Count);
4946

50-
var reqs = GetTelemetryOfType<RequestTelemetry>(items);
47+
var reqs = _factory.Telemetry.GetTelemetryOfType<RequestTelemetryEnvelope>();
5148
Assert.Single(reqs);
5249
var req = reqs[0];
5350
Assert.NotNull(req);
@@ -65,7 +62,7 @@ public async Task RequestSuccessActionWithParameter()
6562
// Arrange
6663
var client = _factory.CreateClient();
6764
var path = "Home/5";
68-
var expectedName = "GET Home/Get [id]";
65+
var expectedName = "GET Home/{id:int}";
6966
var url = client.BaseAddress + path;
7067

7168
// Act
@@ -76,18 +73,18 @@ public async Task RequestSuccessActionWithParameter()
7673
// Assert
7774
response.EnsureSuccessStatusCode();
7875

79-
await WaitForTelemetryToArrive();
76+
await WaitForTelemetryToArrive(expectedItemCount: 2);
8077

81-
var items = _factory.sentItems;
78+
var items = _factory.Telemetry.Items;
8279
PrintItems(items);
8380
Assert.Equal(2, items.Count);
8481

85-
var reqs = GetTelemetryOfType<RequestTelemetry>(items);
82+
var reqs = _factory.Telemetry.GetTelemetryOfType<RequestTelemetryEnvelope>();
8683
Assert.Single(reqs);
8784
var req = reqs[0];
8885
Assert.NotNull(req);
8986

90-
var traces = GetTelemetryOfType<TraceTelemetry>(items);
87+
var traces = _factory.Telemetry.GetTelemetryOfType<TraceTelemetryEnvelope>();
9188
Assert.Single(traces);
9289
var trace = traces[0];
9390
Assert.NotNull(trace);
@@ -116,14 +113,14 @@ public async Task RequestFailed()
116113
// Assert
117114
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
118115

119-
await WaitForTelemetryToArrive();
116+
await WaitForTelemetryToArrive(expectedItemCount: 2);
120117

121-
var items = _factory.sentItems;
118+
var items = _factory.Telemetry.Items;
122119
PrintItems(items);
123120
Assert.Equal(2, items.Count);
124121

125-
var reqs = GetTelemetryOfType<RequestTelemetry>(items);
126-
var exceptions = GetTelemetryOfType<ExceptionTelemetry>(items);
122+
var reqs = _factory.Telemetry.GetTelemetryOfType<RequestTelemetryEnvelope>();
123+
var exceptions = _factory.Telemetry.GetTelemetryOfType<ExceptionTelemetryEnvelope>();
127124
Assert.Single(reqs);
128125
Assert.Single(exceptions);
129126

@@ -132,7 +129,9 @@ public async Task RequestFailed()
132129
Assert.NotNull(req);
133130
Assert.NotNull(exc);
134131

135-
Assert.Equal(exc.Context.Operation.Id, req.Context.Operation.Id);
132+
// TODO: Validate Exception.
133+
134+
Assert.Equal(exc.OperationId, req.OperationId);
136135
ValidateRequest(
137136
requestTelemetry: req,
138137
expectedResponseCode: "500",
@@ -157,13 +156,13 @@ public async Task RequestNonExistentPage()
157156
// Assert
158157
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
159158

160-
await WaitForTelemetryToArrive();
159+
await WaitForTelemetryToArrive(expectedItemCount: 1);
161160

162-
var items = _factory.sentItems;
161+
var items = _factory.Telemetry.Items;
163162
PrintItems(items);
164163
Assert.Equal(1, items.Count);
165164

166-
var reqs = GetTelemetryOfType<RequestTelemetry>(items);
165+
var reqs = _factory.Telemetry.GetTelemetryOfType<RequestTelemetryEnvelope>();
167166
Assert.Single(reqs);
168167
var req = reqs[0];
169168
Assert.NotNull(req);
@@ -176,18 +175,25 @@ public async Task RequestNonExistentPage()
176175
expectedSuccess: false);
177176
}
178177

179-
private async Task WaitForTelemetryToArrive()
178+
private async Task WaitForTelemetryToArrive(int expectedItemCount)
180179
{
181-
// The response to the test server request is completed
182-
// before the actual telemetry is sent from HostingDiagnosticListener.
183-
// This could be a TestServer issue/feature. (In a real application, the response is not
184-
// sent to the user until TrackRequest() is called.)
185-
// The simplest workaround is to do a wait here.
186-
// This could be improved when entire functional tests are migrated to use this pattern.
187-
await Task.Delay(1000);
180+
var deadline = DateTime.UtcNow + TimeSpan.FromSeconds(5);
181+
while (DateTime.UtcNow < deadline)
182+
{
183+
await Task.Delay(100);
184+
185+
var currentCount = _factory.Telemetry.Items.Count;
186+
if (currentCount >= expectedItemCount)
187+
{
188+
return;
189+
}
190+
}
191+
192+
// Allow any final exporter flush.
193+
await Task.Delay(200);
188194
}
189195

190-
private void ValidateRequest(RequestTelemetry requestTelemetry,
196+
private void ValidateRequest(RequestTelemetryEnvelope requestTelemetry,
191197
string expectedResponseCode,
192198
string expectedName,
193199
string expectedUrl,
@@ -196,7 +202,7 @@ private void ValidateRequest(RequestTelemetry requestTelemetry,
196202
Assert.Equal(expectedResponseCode, requestTelemetry.ResponseCode);
197203
Assert.Equal(expectedName, requestTelemetry.Name);
198204
Assert.Equal(expectedSuccess, requestTelemetry.Success);
199-
Assert.Equal(expectedUrl, requestTelemetry.Url.ToString());
205+
Assert.Equal(expectedUrl, requestTelemetry.Url?.ToString());
200206
Assert.True(requestTelemetry.Duration.TotalMilliseconds > 0);
201207
// requestTelemetry.Timestamp
202208
}
@@ -216,62 +222,44 @@ private HttpRequestMessage CreateRequestMessage(Dictionary<string, string> reque
216222
return httpRequestMessage;
217223
}
218224

219-
private List<T> GetTelemetryOfType<T>(ConcurrentBag<ITelemetry> items)
220-
{
221-
List<T> foundItems = new List<T>();
222-
foreach (var item in items)
223-
{
224-
if (item is T)
225-
{
226-
foundItems.Add((T)item);
227-
}
228-
}
229-
230-
return foundItems;
231-
}
232-
233-
private void PrintItems(ConcurrentBag<ITelemetry> items)
225+
private void PrintItems(IReadOnlyList<AzureMonitorTelemetryEnvelope> items)
234226
{
235227
int i = 1;
236228
foreach (var item in items)
237229
{
238230
this.output.WriteLine("Item " + (i++) + ".");
239231

240-
if (item is RequestTelemetry req)
232+
this.output.WriteLine("OperationId:" + item.OperationId);
233+
if (!string.IsNullOrEmpty(item.OperationParentId))
234+
{
235+
this.output.WriteLine("OperationParentId:" + item.OperationParentId);
236+
}
237+
238+
if (item is RequestTelemetryEnvelope req)
241239
{
242240
this.output.WriteLine("RequestTelemetry");
243241
this.output.WriteLine(req.Name);
244242
this.output.WriteLine(req.Duration.ToString());
243+
this.output.WriteLine("RequestId:" + req.Id);
245244
}
246-
else if (item is DependencyTelemetry dep)
247-
{
248-
this.output.WriteLine("DependencyTelemetry");
249-
this.output.WriteLine(dep.Name);
250-
}
251-
else if (item is TraceTelemetry trace)
245+
else if (item is TraceTelemetryEnvelope trace)
252246
{
253247
this.output.WriteLine("TraceTelemetry");
254248
this.output.WriteLine(trace.Message);
255249
}
256-
else if (item is ExceptionTelemetry exc)
250+
else if (item is ExceptionTelemetryEnvelope exc)
257251
{
258252
this.output.WriteLine("ExceptionTelemetry");
259253
this.output.WriteLine(exc.Message);
260254
}
261-
else if (item is MetricTelemetry met)
262-
{
263-
this.output.WriteLine("MetricTelemetry");
264-
this.output.WriteLine(met.Name + "" + met.Sum);
265-
}
266-
267-
PrintProperties(item as ISupportProperties);
255+
PrintProperties(item.Properties);
268256
this.output.WriteLine("----------------------------");
269257
}
270258
}
271259

272-
private void PrintProperties(ISupportProperties itemProps)
260+
private void PrintProperties(IReadOnlyDictionary<string, string> itemProps)
273261
{
274-
foreach (var prop in itemProps.Properties)
262+
foreach (var prop in itemProps)
275263
{
276264
this.output.WriteLine(prop.Key + ":" + prop.Value);
277265
}

0 commit comments

Comments
 (0)