diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs index 8d7581e49fe..557b1c50312 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs @@ -40,7 +40,11 @@ public HttpClientTests() this.serverLifeTime = TestHttpServer.RunServer( (ctx) => { - if (ctx.Request.Url.PathAndQuery.Contains("redirect")) + if (ctx.Request.Url.PathAndQuery.Contains("500")) + { + ctx.Response.StatusCode = 500; + } + else if (ctx.Request.Url.PathAndQuery.Contains("redirect")) { ctx.Response.RedirectLocation = "/"; ctx.Response.StatusCode = 302; @@ -462,6 +466,89 @@ public async Task HttpClientInstrumentationContextPropagation() Assert.Equal("b1=v1", baggages.Single()); } + [Fact] + public async Task HttpClientInstrumentationReportsExceptionEventForNetworkFailuresWithGetAsync() + { + var exportedItems = new List(); + bool exceptionThrown = false; + + using var traceprovider = Sdk.CreateTracerProviderBuilder() + .AddHttpClientInstrumentation(o => o.RecordException = true) + .AddInMemoryExporter(exportedItems) + .Build(); + + using var c = new HttpClient(); + try + { + await c.GetAsync("https://sdlfaldfjalkdfjlkajdflkajlsdjf.sdlkjafsdjfalfadslkf.com/"); + } + catch + { + exceptionThrown = true; + } + + // Exception is thrown and collected as event + Assert.True(exceptionThrown); + Assert.Single(exportedItems[0].Events.Where(evt => evt.Name.Equals("exception"))); + } + + [Fact] + public async Task HttpClientInstrumentationDoesNotReportExceptionEventOnErrorResponseWithGetAsync() + { + var exportedItems = new List(); + bool exceptionThrown = false; + + using var traceprovider = Sdk.CreateTracerProviderBuilder() + .AddHttpClientInstrumentation(o => o.RecordException = true) + .AddInMemoryExporter(exportedItems) + .Build(); + + using var c = new HttpClient(); + try + { + await c.GetAsync($"{this.url}500"); + } + catch + { + exceptionThrown = true; + } + + // Exception is not thrown and not collected as event + Assert.False(exceptionThrown); + Assert.Empty(exportedItems[0].Events); + } + + [Fact] + public async Task HttpClientInstrumentationDoesNotReportExceptionEventOnErrorResponseWithGetStringAsync() + { + var exportedItems = new List(); + bool exceptionThrown = false; + var request = new HttpRequestMessage + { + RequestUri = new Uri($"{this.url}500"), + Method = new HttpMethod("GET"), + }; + + using var traceprovider = Sdk.CreateTracerProviderBuilder() + .AddHttpClientInstrumentation(o => o.RecordException = true) + .AddInMemoryExporter(exportedItems) + .Build(); + + using var c = new HttpClient(); + try + { + await c.GetStringAsync($"{this.url}500"); + } + catch + { + exceptionThrown = true; + } + + // Exception is thrown and not collected as event + Assert.True(exceptionThrown); + Assert.Empty(exportedItems[0].Events); + } + public void Dispose() { this.serverLifeTime?.Dispose(); diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.Basic.netfx.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.Basic.netfx.cs index 382a1016343..36b838087ff 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.Basic.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.Basic.netfx.cs @@ -15,6 +15,7 @@ // #if NETFRAMEWORK using System; +using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Net; @@ -45,7 +46,15 @@ public HttpWebRequestTests() this.serverLifeTime = TestHttpServer.RunServer( (ctx) => { - ctx.Response.StatusCode = 200; + if (ctx.Request.Url.PathAndQuery.Contains("500")) + { + ctx.Response.StatusCode = 500; + } + else + { + ctx.Response.StatusCode = 200; + } + ctx.Response.OutputStream.Close(); }, out var host, @@ -296,6 +305,147 @@ public async Task HttpWebRequestInstrumentationOnExistingInstance() Assert.Equal(3, activityProcessor.Invocations.Count); // SetParentProvider/Begin/End called } + + [Fact] + public async Task HttpClientInstrumentationReportsExceptionEventForNetworkFailuresWithGetAsync() + { + var exportedItems = new List(); + bool exceptionThrown = false; + + using var traceprovider = Sdk.CreateTracerProviderBuilder() + .AddHttpClientInstrumentation(o => o.RecordException = true) + .AddInMemoryExporter(exportedItems) + .Build(); + + using var c = new HttpClient(); + try + { + await c.GetAsync("https://sdlfaldfjalkdfjlkajdflkajlsdjf.sdlkjafsdjfalfadslkf.com/"); + } + catch + { + exceptionThrown = true; + } + + // Exception is thrown and collected as event + Assert.True(exceptionThrown); + Assert.Single(exportedItems[0].Events.Where(evt => evt.Name.Equals("exception"))); + } + + [Fact] + public async Task HttpClientInstrumentationDoesNotReportExceptionEventOnErrorResponseWithGetAsync() + { + var exportedItems = new List(); + bool exceptionThrown = false; + + using var traceprovider = Sdk.CreateTracerProviderBuilder() + .AddHttpClientInstrumentation(o => o.RecordException = true) + .AddInMemoryExporter(exportedItems) + .Build(); + + using var c = new HttpClient(); + try + { + await c.GetAsync($"{this.url}500"); + } + catch + { + exceptionThrown = true; + } + + // Exception is not thrown and not collected as event + Assert.False(exceptionThrown); + Assert.Empty(exportedItems[0].Events); + } + + [Fact] + public async Task HttpClientInstrumentationDoesNotReportExceptionEventOnErrorResponseWithGetStringAsync() + { + var exportedItems = new List(); + bool exceptionThrown = false; + var request = new HttpRequestMessage + { + RequestUri = new Uri($"{this.url}500"), + Method = new HttpMethod("GET"), + }; + + using var traceprovider = Sdk.CreateTracerProviderBuilder() + .AddHttpClientInstrumentation(o => o.RecordException = true) + .AddInMemoryExporter(exportedItems) + .Build(); + + using var c = new HttpClient(); + try + { + await c.GetStringAsync($"{this.url}500"); + } + catch + { + exceptionThrown = true; + } + + // Exception is thrown and not collected as event + Assert.True(exceptionThrown); + Assert.Empty(exportedItems[0].Events); + } + + [Fact] + public async Task HttpWebRequestInstrumentationReportsExceptionEventForNetworkFailures() + { + var exportedItems = new List(); + bool exceptionThrown = false; + + using var traceprovider = Sdk.CreateTracerProviderBuilder() + .AddHttpClientInstrumentation(o => o.RecordException = true) + .AddInMemoryExporter(exportedItems) + .Build(); + + try + { + var request = (HttpWebRequest)WebRequest.Create("https://sdlfaldfjalkdfjlkajdflkajlsdjf.sdlkjafsdjfalfadslkf.com/"); + + request.Method = "GET"; + + using var response = await request.GetResponseAsync(); + } + catch + { + exceptionThrown = true; + } + + // Exception is thrown and collected as event + Assert.True(exceptionThrown); + Assert.Single(exportedItems[0].Events.Where(evt => evt.Name.Equals("exception"))); + } + + [Fact] + public async Task HttpWebRequestInstrumentationReportsExceptionEventOnErrorResponse() + { + var exportedItems = new List(); + bool exceptionThrown = false; + + using var traceprovider = Sdk.CreateTracerProviderBuilder() + .AddHttpClientInstrumentation(o => o.RecordException = true) + .AddInMemoryExporter(exportedItems) + .Build(); + + try + { + var request = (HttpWebRequest)WebRequest.Create($"{this.url}500"); + + request.Method = "GET"; + + using var response = await request.GetResponseAsync(); + } + catch + { + exceptionThrown = true; + } + + // Exception is thrown and collected as event + Assert.True(exceptionThrown); + Assert.Single(exportedItems[0].Events.Where(evt => evt.Name.Equals("exception"))); + } } } #endif