Skip to content

Commit

Permalink
Use test host in unit tests (#5040)
Browse files Browse the repository at this point in the history
  • Loading branch information
ngruson authored Nov 22, 2023
1 parent 1f7f931 commit f9c300b
Show file tree
Hide file tree
Showing 2 changed files with 155 additions and 189 deletions.
250 changes: 103 additions & 147 deletions test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Moq;
using OpenTelemetry.Context.Propagation;
Expand Down Expand Up @@ -840,45 +841,42 @@ public async Task DiagnosticSourceCallbacksAreReceivedOnlyForSubscribedEvents()
{
int numberOfUnSubscribedEvents = 0;
int numberofSubscribedEvents = 0;
void ConfigureTestServices(IServiceCollection services)
{
this.tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddAspNetCoreInstrumentation(
new TestHttpInListener(new AspNetCoreInstrumentationOptions())

this.tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddAspNetCoreInstrumentation(
new TestHttpInListener(new AspNetCoreInstrumentationOptions())
{
OnEventWrittenCallback = (name, payload) =>
{
OnEventWrittenCallback = (name, payload) =>
switch (name)
{
switch (name)
{
case HttpInListener.OnStartEvent:
{
numberofSubscribedEvents++;
}
case HttpInListener.OnStartEvent:
{
numberofSubscribedEvents++;
}

break;
case HttpInListener.OnStopEvent:
{
numberofSubscribedEvents++;
}
break;
case HttpInListener.OnStopEvent:
{
numberofSubscribedEvents++;
}

break;
default:
{
numberOfUnSubscribedEvents++;
}
break;
default:
{
numberOfUnSubscribedEvents++;
}

break;
}
},
})
.Build();
}
break;
}
},
})
.Build();

// Arrange
using (var client = this.factory
.WithWebHostBuilder(builder =>
{
builder.ConfigureTestServices(ConfigureTestServices);
builder.ConfigureLogging(loggingBuilder => loggingBuilder.ClearProviders());
})
.CreateClient())
Expand All @@ -899,56 +897,53 @@ public async Task DiagnosticSourceExceptionCallbackIsReceivedForUnHandledExcepti
int numberOfUnSubscribedEvents = 0;
int numberofSubscribedEvents = 0;
int numberOfExceptionCallbacks = 0;
void ConfigureTestServices(IServiceCollection services)
{
this.tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddAspNetCoreInstrumentation(
new TestHttpInListener(new AspNetCoreInstrumentationOptions())

this.tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddAspNetCoreInstrumentation(
new TestHttpInListener(new AspNetCoreInstrumentationOptions())
{
OnEventWrittenCallback = (name, payload) =>
{
OnEventWrittenCallback = (name, payload) =>
switch (name)
{
switch (name)
{
case HttpInListener.OnStartEvent:
{
numberofSubscribedEvents++;
}
case HttpInListener.OnStartEvent:
{
numberofSubscribedEvents++;
}

break;
case HttpInListener.OnStopEvent:
{
numberofSubscribedEvents++;
}
break;
case HttpInListener.OnStopEvent:
{
numberofSubscribedEvents++;
}

break;
break;

// TODO: Add test case for validating name for both the types
// of exception event.
case HttpInListener.OnUnhandledHostingExceptionEvent:
case HttpInListener.OnUnHandledDiagnosticsExceptionEvent:
{
numberofSubscribedEvents++;
numberOfExceptionCallbacks++;
}
// TODO: Add test case for validating name for both the types
// of exception event.
case HttpInListener.OnUnhandledHostingExceptionEvent:
case HttpInListener.OnUnHandledDiagnosticsExceptionEvent:
{
numberofSubscribedEvents++;
numberOfExceptionCallbacks++;
}

break;
default:
{
numberOfUnSubscribedEvents++;
}
break;
default:
{
numberOfUnSubscribedEvents++;
}

break;
}
},
})
.Build();
}
break;
}
},
})
.Build();

// Arrange
using (var client = this.factory
.WithWebHostBuilder(builder =>
{
builder.ConfigureTestServices(ConfigureTestServices);
builder.ConfigureLogging(loggingBuilder => loggingBuilder.ClearProviders());
})
.CreateClient())
Expand All @@ -971,15 +966,15 @@ void ConfigureTestServices(IServiceCollection services)
Assert.Equal(3, numberofSubscribedEvents);
}

[Fact(Skip = "https://github.com/open-telemetry/opentelemetry-dotnet/issues/4884")]
[Fact]
public async Task DiagnosticSourceExceptionCallBackIsNotReceivedForExceptionsHandledInMiddleware()
{
int numberOfUnSubscribedEvents = 0;
int numberofSubscribedEvents = 0;
int numberOfSubscribedEvents = 0;
int numberOfExceptionCallbacks = 0;

// configure SDK
using var tracerprovider = Sdk.CreateTracerProviderBuilder()
this.tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddAspNetCoreInstrumentation(
new TestHttpInListener(new AspNetCoreInstrumentationOptions())
{
Expand All @@ -989,13 +984,13 @@ public async Task DiagnosticSourceExceptionCallBackIsNotReceivedForExceptionsHan
{
case HttpInListener.OnStartEvent:
{
numberofSubscribedEvents++;
numberOfSubscribedEvents++;
}

break;
case HttpInListener.OnStopEvent:
{
numberofSubscribedEvents++;
numberOfSubscribedEvents++;
}

break;
Expand All @@ -1005,7 +1000,7 @@ public async Task DiagnosticSourceExceptionCallBackIsNotReceivedForExceptionsHan
case HttpInListener.OnUnhandledHostingExceptionEvent:
case HttpInListener.OnUnHandledDiagnosticsExceptionEvent:
{
numberofSubscribedEvents++;
numberOfSubscribedEvents++;
numberOfExceptionCallbacks++;
}

Expand All @@ -1021,45 +1016,35 @@ public async Task DiagnosticSourceExceptionCallBackIsNotReceivedForExceptionsHan
})
.Build();

var builder = WebApplication.CreateBuilder();
builder.Logging.ClearProviders();
var app = builder.Build();

app.UseExceptionHandler(handler =>
{
handler.Run(async (ctx) =>
using (var client = this.factory
.WithWebHostBuilder(builder =>
{
await ctx.Response.WriteAsync("handled");
});
});

app.Map("/error", ThrowException);

static void ThrowException(IApplicationBuilder app)
builder.ConfigureLogging(loggingBuilder => loggingBuilder.ClearProviders());
builder.Configure(app => app
.UseExceptionHandler(handler =>
{
handler.Run(async (ctx) =>
{
await ctx.Response.WriteAsync("handled");
});
}));
})
.CreateClient())
{
app.Run(context =>
try
{
throw new Exception("CustomException");
});
}

_ = app.RunAsync();

using var client = new HttpClient();
try
{
await client.GetStringAsync("http://localhost:5000/error");
}
catch
{
// ignore 500 error.
using var request = new HttpRequestMessage(HttpMethod.Get, "/api/error");
using var response = await client.SendAsync(request);
}
catch
{
// ignore exception
}
}

Assert.Equal(0, numberOfExceptionCallbacks);
Assert.Equal(0, numberOfUnSubscribedEvents);
Assert.Equal(2, numberofSubscribedEvents);

await app.DisposeAsync();
Assert.Equal(2, numberOfSubscribedEvents);
}

public void Dispose()
Expand Down Expand Up @@ -1128,16 +1113,10 @@ private void ConfigureExceptionFilters(IServiceCollection services, int mode, re
.Build();
}

private class ExtractOnlyPropagator : TextMapPropagator
private class ExtractOnlyPropagator(ActivityContext activityContext, Baggage baggage) : TextMapPropagator
{
private readonly ActivityContext activityContext;
private readonly Baggage baggage;

public ExtractOnlyPropagator(ActivityContext activityContext, Baggage baggage)
{
this.activityContext = activityContext;
this.baggage = baggage;
}
private readonly ActivityContext activityContext = activityContext;
private readonly Baggage baggage = baggage;

public override ISet<string> Fields => throw new NotImplementedException();

Expand All @@ -1152,32 +1131,21 @@ public override void Inject<T>(PropagationContext context, T carrier, Action<T,
}
}

private class TestSampler : Sampler
private class TestSampler(SamplingDecision samplingDecision, IEnumerable<KeyValuePair<string, object>> attributes = null) : Sampler
{
private readonly SamplingDecision samplingDecision;
private readonly IEnumerable<KeyValuePair<string, object>> attributes;

public TestSampler(SamplingDecision samplingDecision, IEnumerable<KeyValuePair<string, object>> attributes = null)
{
this.samplingDecision = samplingDecision;
this.attributes = attributes;
}
private readonly SamplingDecision samplingDecision = samplingDecision;
private readonly IEnumerable<KeyValuePair<string, object>> attributes = attributes;

public override SamplingResult ShouldSample(in SamplingParameters samplingParameters)
{
return new SamplingResult(this.samplingDecision, this.attributes);
}
}

private class TestHttpInListener : HttpInListener
private class TestHttpInListener(AspNetCoreInstrumentationOptions options) : HttpInListener(options)
{
public Action<string, object> OnEventWrittenCallback;

public TestHttpInListener(AspNetCoreInstrumentationOptions options)
: base(options)
{
}

public override void OnEventWritten(string name, object payload)
{
base.OnEventWritten(name, payload);
Expand All @@ -1186,17 +1154,11 @@ public override void OnEventWritten(string name, object payload)
}
}

private class TestNullHostActivityMiddlewareImpl : ActivityMiddleware.ActivityMiddlewareImpl
private class TestNullHostActivityMiddlewareImpl(string activitySourceName, string activityName) : ActivityMiddleware.ActivityMiddlewareImpl
{
private ActivitySource activitySource;
private readonly ActivitySource activitySource = new(activitySourceName);
private readonly string activityName = activityName;
private Activity activity;
private string activityName;

public TestNullHostActivityMiddlewareImpl(string activitySourceName, string activityName)
{
this.activitySource = new ActivitySource(activitySourceName);
this.activityName = activityName;
}

public override void PreProcess(HttpContext context)
{
Expand All @@ -1214,17 +1176,11 @@ public override void PostProcess(HttpContext context)
}
}

private class TestActivityMiddlewareImpl : ActivityMiddleware.ActivityMiddlewareImpl
private class TestActivityMiddlewareImpl(string activitySourceName, string activityName) : ActivityMiddleware.ActivityMiddlewareImpl
{
private ActivitySource activitySource;
private readonly ActivitySource activitySource = new(activitySourceName);
private readonly string activityName = activityName;
private Activity activity;
private string activityName;

public TestActivityMiddlewareImpl(string activitySourceName, string activityName)
{
this.activitySource = new ActivitySource(activitySourceName);
this.activityName = activityName;
}

public override void PreProcess(HttpContext context)
{
Expand Down
Loading

0 comments on commit f9c300b

Please sign in to comment.