diff --git a/DiagnosticsPages.sln b/DiagnosticsPages.sln
index 03831ee26b..f46829d52a 100644
--- a/DiagnosticsPages.sln
+++ b/DiagnosticsPages.sln
@@ -44,6 +44,12 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ElmPageSample", "samples\El
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "DatabaseErrorPageSample", "samples\DatabaseErrorPageSample\DatabaseErrorPageSample.xproj", "{FF7F11A1-14E7-4948-A853-2487D99DE0C6}"
EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.MiddlewareAnalysis", "src\Microsoft.AspNet.MiddlewareAnalysis\Microsoft.AspNet.MiddlewareAnalysis.xproj", "{C2DEDD37-D1EB-4819-9A9C-475E37A52358}"
+EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "MiddlewareAnalysisSample", "samples\MiddlewareAnalysisSample\MiddlewareAnalysisSample.xproj", "{95981429-F212-44E1-83AA-32DA9E2A517C}"
+EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.MiddlewareAnalysis.Tests", "test\Microsoft.AspNet.MiddlewareAnalysis.Tests\Microsoft.AspNet.MiddlewareAnalysis.Tests.xproj", "{B0166AED-738F-42EE-AF4D-C487C8B21521}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -220,6 +226,42 @@ Global
{FF7F11A1-14E7-4948-A853-2487D99DE0C6}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{FF7F11A1-14E7-4948-A853-2487D99DE0C6}.Release|x86.ActiveCfg = Release|Any CPU
{FF7F11A1-14E7-4948-A853-2487D99DE0C6}.Release|x86.Build.0 = Release|Any CPU
+ {C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Debug|x86.Build.0 = Debug|Any CPU
+ {C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Release|x86.ActiveCfg = Release|Any CPU
+ {C2DEDD37-D1EB-4819-9A9C-475E37A52358}.Release|x86.Build.0 = Release|Any CPU
+ {95981429-F212-44E1-83AA-32DA9E2A517C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {95981429-F212-44E1-83AA-32DA9E2A517C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {95981429-F212-44E1-83AA-32DA9E2A517C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {95981429-F212-44E1-83AA-32DA9E2A517C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {95981429-F212-44E1-83AA-32DA9E2A517C}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {95981429-F212-44E1-83AA-32DA9E2A517C}.Debug|x86.Build.0 = Debug|Any CPU
+ {95981429-F212-44E1-83AA-32DA9E2A517C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {95981429-F212-44E1-83AA-32DA9E2A517C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {95981429-F212-44E1-83AA-32DA9E2A517C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {95981429-F212-44E1-83AA-32DA9E2A517C}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {95981429-F212-44E1-83AA-32DA9E2A517C}.Release|x86.ActiveCfg = Release|Any CPU
+ {95981429-F212-44E1-83AA-32DA9E2A517C}.Release|x86.Build.0 = Release|Any CPU
+ {B0166AED-738F-42EE-AF4D-C487C8B21521}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B0166AED-738F-42EE-AF4D-C487C8B21521}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B0166AED-738F-42EE-AF4D-C487C8B21521}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {B0166AED-738F-42EE-AF4D-C487C8B21521}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {B0166AED-738F-42EE-AF4D-C487C8B21521}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {B0166AED-738F-42EE-AF4D-C487C8B21521}.Debug|x86.Build.0 = Debug|Any CPU
+ {B0166AED-738F-42EE-AF4D-C487C8B21521}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B0166AED-738F-42EE-AF4D-C487C8B21521}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B0166AED-738F-42EE-AF4D-C487C8B21521}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {B0166AED-738F-42EE-AF4D-C487C8B21521}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {B0166AED-738F-42EE-AF4D-C487C8B21521}.Release|x86.ActiveCfg = Release|Any CPU
+ {B0166AED-738F-42EE-AF4D-C487C8B21521}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -240,5 +282,8 @@ Global
{83FFB65A-97B1-45AA-BCB8-3F43966BC8A3} = {509A6F36-AD80-4A18-B5B1-717D38DFF29D}
{FFD28DCF-C24F-4C59-9B6B-F3B74CE13129} = {ACAA0157-A8C4-4152-93DE-90CCDF304087}
{FF7F11A1-14E7-4948-A853-2487D99DE0C6} = {ACAA0157-A8C4-4152-93DE-90CCDF304087}
+ {C2DEDD37-D1EB-4819-9A9C-475E37A52358} = {509A6F36-AD80-4A18-B5B1-717D38DFF29D}
+ {95981429-F212-44E1-83AA-32DA9E2A517C} = {ACAA0157-A8C4-4152-93DE-90CCDF304087}
+ {B0166AED-738F-42EE-AF4D-C487C8B21521} = {2AF90579-B118-4583-AE88-672EFACB5BC4}
EndGlobalSection
EndGlobal
diff --git a/samples/MiddlewareAnalysisSample/MiddlewareAnalysisSample.xproj b/samples/MiddlewareAnalysisSample/MiddlewareAnalysisSample.xproj
new file mode 100644
index 0000000000..92177a647e
--- /dev/null
+++ b/samples/MiddlewareAnalysisSample/MiddlewareAnalysisSample.xproj
@@ -0,0 +1,19 @@
+
+
+
+ 14.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+
+ 95981429-f212-44e1-83aa-32da9e2a517c
+ MiddlewareAnalysisSample
+ ..\..\artifacts\obj\$(MSBuildProjectName)
+ ..\..\artifacts\bin\$(MSBuildProjectName)\
+
+
+ 2.0
+ 2764
+
+
+
\ No newline at end of file
diff --git a/samples/MiddlewareAnalysisSample/Startup.cs b/samples/MiddlewareAnalysisSample/Startup.cs
new file mode 100644
index 0000000000..3a10098043
--- /dev/null
+++ b/samples/MiddlewareAnalysisSample/Startup.cs
@@ -0,0 +1,106 @@
+using System;
+using System.Diagnostics;
+using Microsoft.AspNet.Builder;
+using Microsoft.AspNet.Http;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DiagnosticAdapter;
+using Microsoft.Extensions.Logging;
+
+namespace MiddlewareAnaysisSample
+{
+ public class Startup
+ {
+ public void ConfigureServices(IServiceCollection services)
+ {
+ services.AddMiddlewareAnalysis();
+ }
+
+ public void Configure(IApplicationBuilder app, ILoggerFactory factory, DiagnosticListener diagnosticListener)
+ {
+ // Displays all log levels
+ factory.AddConsole(LogLevel.Verbose);
+
+ // Listen for middleware events and log them to the console.
+ var listener = new TestDiagnosticListener();
+ diagnosticListener.SubscribeWithAdapter(listener);
+
+ // Build our application pipeline
+
+ // Named via app.UseMiddleware()
+ app.UseDeveloperExceptionPage();
+ app.UseIISPlatformHandler();
+
+ // Anonymous method inline middleware
+ app.Use((context, next) =>
+ {
+ // No-op
+ return next();
+ });
+
+ app.Map("/map", subApp =>
+ {
+ subApp.Run(context =>
+ {
+ return context.Response.WriteAsync("Hello World");
+ });
+ });
+
+ // Low level anonymous method inline middleware, named Diagnostics.Middleware.Analysis.Startup+<>c by default
+ app.Use(next =>
+ {
+ return context =>
+ {
+ return next(context);
+ };
+ });
+
+ app.Map("/throw", throwApp =>
+ {
+ throwApp.Run(context => { throw new Exception("Application Exception"); });
+ });
+
+ // The home page.
+ app.Properties["analysis.NextMiddlewareName"] = "HomePage";
+ app.Use(async (context, next) =>
+ {
+ if (context.Request.Path == "/")
+ {
+ context.Response.ContentType = "text/html";
+ await context.Response.WriteAsync("Welcome to the sample
\r\n");
+ await context.Response.WriteAsync("Click here to take a side branch: Map
\r\n");
+ await context.Response.WriteAsync("Click here to throw an exception: Throw
\r\n");
+ await context.Response.WriteAsync("Click here to for a 404: 404
\r\n");
+ await context.Response.WriteAsync("\r\n");
+ return;
+ }
+ else
+ {
+ await next();
+ }
+ });
+
+ // Note there's always a default 404 middleware at the end of the pipeline.
+ }
+
+ public class TestDiagnosticListener
+ {
+ [DiagnosticName("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareStarting")]
+ public virtual void OnMiddlewareStarting(HttpContext httpContext, string name)
+ {
+ Console.WriteLine($"MiddlewareStarting: {name}; {httpContext.Request.Path}");
+ }
+
+ [DiagnosticName("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareException")]
+ public virtual void OnMiddlewareException(Exception exception, string name)
+ {
+ Console.WriteLine($"MiddlewareException: {name}; {exception.Message}");
+ }
+
+ [DiagnosticName("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareFinished")]
+ public virtual void OnMiddlewareFinished(HttpContext httpContext, string name)
+ {
+ Console.WriteLine($"MiddlewareFinished: {name}; {httpContext.Response.StatusCode}");
+ }
+ }
+ }
+}
diff --git a/samples/MiddlewareAnalysisSample/project.json b/samples/MiddlewareAnalysisSample/project.json
new file mode 100644
index 0000000000..b717045670
--- /dev/null
+++ b/samples/MiddlewareAnalysisSample/project.json
@@ -0,0 +1,19 @@
+{
+ "dependencies": {
+ "Microsoft.AspNet.Diagnostics": "1.0.0-*",
+ "Microsoft.AspNet.IISPlatformHandler": "1.0.0-*",
+ "Microsoft.AspNet.MiddlewareAnalysis": "1.0.0-*",
+ "Microsoft.AspNet.Server.Kestrel": "1.0.0-*",
+ "Microsoft.AspNet.Server.WebListener": "1.0.0-*",
+ "Microsoft.Extensions.DiagnosticAdapter": "1.0.0-*",
+ "Microsoft.Extensions.Logging.Console": "1.0.0-*"
+ },
+ "commands": {
+ "web": "Microsoft.AspNet.Server.Kestrel",
+ "weblistener": "Microsoft.AspNet.Server.WebListener"
+ },
+ "frameworks": {
+ "dnx451": { },
+ "dnxcore50": { }
+ }
+}
diff --git a/src/Microsoft.AspNet.MiddlewareAnalysis/AnalysisBuilder.cs b/src/Microsoft.AspNet.MiddlewareAnalysis/AnalysisBuilder.cs
new file mode 100644
index 0000000000..ca4f2c360d
--- /dev/null
+++ b/src/Microsoft.AspNet.MiddlewareAnalysis/AnalysisBuilder.cs
@@ -0,0 +1,65 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using Microsoft.AspNet.Builder;
+using Microsoft.AspNet.Http;
+using Microsoft.AspNet.Http.Features;
+
+namespace Microsoft.AspNet.MiddlewareAnalysis
+{
+ public class AnalysisBuilder : IApplicationBuilder
+ {
+ private const string NextMiddlewareName = "analysis.NextMiddlewareName";
+
+ public AnalysisBuilder(IApplicationBuilder inner)
+ {
+ InnerBuilder = inner;
+ }
+
+ private IApplicationBuilder InnerBuilder { get; }
+
+ public IServiceProvider ApplicationServices
+ {
+ get { return InnerBuilder.ApplicationServices; }
+ set { InnerBuilder.ApplicationServices = value; }
+ }
+
+ public IDictionary Properties
+ {
+ get { return InnerBuilder.Properties; }
+ }
+
+ public IFeatureCollection ServerFeatures
+ {
+ get { return InnerBuilder.ServerFeatures;}
+ }
+
+ public RequestDelegate Build()
+ {
+ // Add one maker at the end before the default 404 middleware (or any fancy Join middleware).
+ return InnerBuilder.UseMiddleware("EndOfPipeline")
+ .Build();
+ }
+
+ public IApplicationBuilder New()
+ {
+ return new AnalysisBuilder(InnerBuilder.New());
+ }
+
+ public IApplicationBuilder Use(Func middleware)
+ {
+ string middlewareName = string.Empty; // UseMiddleware doesn't work with null params.
+ object middlewareNameObj;
+ if (Properties.TryGetValue(NextMiddlewareName, out middlewareNameObj))
+ {
+ middlewareName = middlewareNameObj?.ToString();
+ Properties.Remove(NextMiddlewareName);
+ }
+
+ return InnerBuilder.UseMiddleware(middlewareName)
+ .Use(middleware);
+ }
+ }
+}
diff --git a/src/Microsoft.AspNet.MiddlewareAnalysis/AnalysisMiddleware.cs b/src/Microsoft.AspNet.MiddlewareAnalysis/AnalysisMiddleware.cs
new file mode 100644
index 0000000000..79bb52d81b
--- /dev/null
+++ b/src/Microsoft.AspNet.MiddlewareAnalysis/AnalysisMiddleware.cs
@@ -0,0 +1,54 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Diagnostics;
+using System.Threading.Tasks;
+using Microsoft.AspNet.Http;
+
+namespace Microsoft.AspNet.MiddlewareAnalysis
+{
+ public class AnalysisMiddleware
+ {
+ private readonly RequestDelegate _next;
+ private readonly DiagnosticSource _diagnostics;
+ private readonly string _middlewareName;
+
+ public AnalysisMiddleware(RequestDelegate next, DiagnosticSource diagnosticSource, string middlewareName)
+ {
+ _next = next;
+ _diagnostics = diagnosticSource;
+ if (string.IsNullOrEmpty(middlewareName))
+ {
+ middlewareName = next.Target.GetType().FullName;
+ }
+ _middlewareName = middlewareName;
+ }
+
+ public async Task Invoke(HttpContext httpContext)
+ {
+ if (_diagnostics.IsEnabled("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareStarting"))
+ {
+ _diagnostics.Write("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareStarting", new { name = _middlewareName, httpContext = httpContext });
+ }
+
+ try
+ {
+ await _next(httpContext);
+
+ if (_diagnostics.IsEnabled("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareFinished"))
+ {
+ _diagnostics.Write("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareFinished", new { name = _middlewareName, httpContext = httpContext });
+ }
+ }
+ catch (Exception ex)
+ {
+ if (_diagnostics.IsEnabled("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareException"))
+ {
+ _diagnostics.Write("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareException", new { name = _middlewareName, httpContext = httpContext, exception = ex });
+ }
+ throw;
+ }
+ }
+ }
+}
diff --git a/src/Microsoft.AspNet.MiddlewareAnalysis/AnalysisServiceCollectionExtensions.cs b/src/Microsoft.AspNet.MiddlewareAnalysis/AnalysisServiceCollectionExtensions.cs
new file mode 100644
index 0000000000..c337c959a8
--- /dev/null
+++ b/src/Microsoft.AspNet.MiddlewareAnalysis/AnalysisServiceCollectionExtensions.cs
@@ -0,0 +1,19 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.AspNet.Hosting;
+using Microsoft.AspNet.MiddlewareAnalysis;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+
+namespace Microsoft.Extensions.DependencyInjection
+{
+ public static class AnalysisServiceCollectionExtensions
+ {
+ public static IServiceCollection AddMiddlewareAnalysis(this IServiceCollection services)
+ {
+ // This should prevent AnalysisStartupFilter from being registered more than once.
+ services.TryAddEnumerable(ServiceDescriptor.Transient());
+ return services;
+ }
+ }
+}
diff --git a/src/Microsoft.AspNet.MiddlewareAnalysis/AnalysisStartupFilter.cs b/src/Microsoft.AspNet.MiddlewareAnalysis/AnalysisStartupFilter.cs
new file mode 100644
index 0000000000..edb092c918
--- /dev/null
+++ b/src/Microsoft.AspNet.MiddlewareAnalysis/AnalysisStartupFilter.cs
@@ -0,0 +1,27 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Microsoft.AspNet.Builder;
+using Microsoft.AspNet.Hosting;
+
+namespace Microsoft.AspNet.MiddlewareAnalysis
+{
+ public class AnalysisStartupFilter : IStartupFilter
+ {
+ public Action Configure(Action next)
+ {
+ return builder =>
+ {
+ var wrappedBuilder = new AnalysisBuilder(builder);
+ next(wrappedBuilder);
+
+ // The caller doesn't call build on our new builder, they call it on the original. Add this
+ // default middleware to the end. Compare with AnalysisBuilder.Build();
+
+ // Add one maker at the end before the default 404 middleware (or any fancy Join middleware).
+ builder.UseMiddleware("EndOfPipeline");
+ };
+ }
+ }
+}
diff --git a/src/Microsoft.AspNet.MiddlewareAnalysis/Microsoft.AspNet.MiddlewareAnalysis.xproj b/src/Microsoft.AspNet.MiddlewareAnalysis/Microsoft.AspNet.MiddlewareAnalysis.xproj
new file mode 100644
index 0000000000..7b0842ca52
--- /dev/null
+++ b/src/Microsoft.AspNet.MiddlewareAnalysis/Microsoft.AspNet.MiddlewareAnalysis.xproj
@@ -0,0 +1,20 @@
+
+
+
+ 14.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+
+
+ c2dedd37-d1eb-4819-9a9c-475e37a52358
+ Microsoft.AspNet.MiddlewareAnalysis
+ ..\..\artifacts\obj\$(MSBuildProjectName)
+ ..\..\artifacts\bin\$(MSBuildProjectName)\
+
+
+
+ 2.0
+
+
+
diff --git a/src/Microsoft.AspNet.MiddlewareAnalysis/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.MiddlewareAnalysis/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..9cb7b1f01b
--- /dev/null
+++ b/src/Microsoft.AspNet.MiddlewareAnalysis/Properties/AssemblyInfo.cs
@@ -0,0 +1,8 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Reflection;
+using System.Resources;
+
+[assembly: AssemblyMetadata("Serviceable", "True")]
+[assembly: NeutralResourcesLanguage("en-US")]
diff --git a/src/Microsoft.AspNet.MiddlewareAnalysis/project.json b/src/Microsoft.AspNet.MiddlewareAnalysis/project.json
new file mode 100644
index 0000000000..e4b76199f4
--- /dev/null
+++ b/src/Microsoft.AspNet.MiddlewareAnalysis/project.json
@@ -0,0 +1,22 @@
+{
+ "version": "1.0.0-*",
+ "description": "ASP.NET 5 Middleware for analyzing middleware in the request pipeline.",
+ "compilationOptions": {
+ "warningsAsErrors": true,
+ "keyFile": "../../tools/Key.snk"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/aspnet/diagnostics"
+ },
+ "dependencies": {
+ "Microsoft.AspNet.Hosting.Abstractions": "1.0.0-*",
+ "Microsoft.Extensions.DependencyInjection.Abstractions": "1.0.0-*",
+ "System.Diagnostics.DiagnosticSource": "4.0.0-beta-*"
+ },
+
+ "frameworks": {
+ "net451": { },
+ "dotnet5.4": { }
+ }
+}
diff --git a/test/Microsoft.AspNet.MiddlewareAnalysis.Tests/Microsoft.AspNet.MiddlewareAnalysis.Tests.xproj b/test/Microsoft.AspNet.MiddlewareAnalysis.Tests/Microsoft.AspNet.MiddlewareAnalysis.Tests.xproj
new file mode 100644
index 0000000000..5207d14faf
--- /dev/null
+++ b/test/Microsoft.AspNet.MiddlewareAnalysis.Tests/Microsoft.AspNet.MiddlewareAnalysis.Tests.xproj
@@ -0,0 +1,21 @@
+
+
+
+ 14.0.23107
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+
+ b0166aed-738f-42ee-af4d-c487c8b21521
+ Microsoft.AspNet.MiddlewareAnalysis.Tests
+ ..\..\artifacts\obj\$(MSBuildProjectName)
+ ..\..\artifacts\bin\$(MSBuildProjectName)\
+
+
+ 2.0
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/Microsoft.AspNet.MiddlewareAnalysis.Tests/MiddlewareAnalysisTests.cs b/test/Microsoft.AspNet.MiddlewareAnalysis.Tests/MiddlewareAnalysisTests.cs
new file mode 100644
index 0000000000..9c50479053
--- /dev/null
+++ b/test/Microsoft.AspNet.MiddlewareAnalysis.Tests/MiddlewareAnalysisTests.cs
@@ -0,0 +1,49 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Diagnostics;
+using System.Threading.Tasks;
+using Microsoft.AspNet.Builder;
+using Microsoft.AspNet.TestHost;
+using Microsoft.Extensions.DependencyInjection;
+using Xunit;
+
+namespace Microsoft.AspNet.MiddlewareAnalysis
+{
+ public class MiddlewareAnalysisTests
+ {
+ [Fact]
+ public async Task ExceptionWrittenToDiagnostics()
+ {
+ DiagnosticListener diagnosticListener = null;
+
+ var server = TestServer.Create(app =>
+ {
+ diagnosticListener = app.ApplicationServices.GetRequiredService();
+
+ app.UseDeveloperExceptionPage();
+ app.Run(context =>
+ {
+ throw new Exception("Test exception");
+ });
+ }, services => services.AddMiddlewareAnalysis());
+
+ var listener = new TestDiagnosticListener();
+ diagnosticListener.SubscribeWithAdapter(listener);
+
+ await server.CreateClient().GetAsync(string.Empty);
+
+ // "Microsoft.AspnNet.Hosting.RequestServicesContainerMiddleware","Microsoft.AspnNet.Diagnostics.DeveloperExceptionPageMiddleware",
+ // "Microsoft.AspNet.MiddlewareAnalysis.MiddlewareAnalysisTests.+<>c"
+ Assert.Equal(3, listener.MiddlewareStarting.Count);
+ Assert.Equal("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareAnalysisTests+<>c", listener.MiddlewareStarting[2]);
+ // reversed "RunInlineMiddleware"
+ Assert.Equal(1, listener.MiddlewareException.Count);
+ Assert.Equal("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareAnalysisTests+<>c", listener.MiddlewareException[0]);
+ // reversed "Microsoft.AspnNet.Diagnostics.DeveloperExceptionPageMiddleware","Microsoft.AspnNet.Hosting.RequestServicesContainerMiddleware"
+ Assert.Equal(2, listener.MiddlewareFinished.Count);
+ Assert.Equal("Microsoft.AspNet.Diagnostics.DeveloperExceptionPageMiddleware", listener.MiddlewareFinished[0]);
+ }
+ }
+}
diff --git a/test/Microsoft.AspNet.MiddlewareAnalysis.Tests/TestDiagnosticListener.cs b/test/Microsoft.AspNet.MiddlewareAnalysis.Tests/TestDiagnosticListener.cs
new file mode 100644
index 0000000000..035b106648
--- /dev/null
+++ b/test/Microsoft.AspNet.MiddlewareAnalysis.Tests/TestDiagnosticListener.cs
@@ -0,0 +1,35 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using Microsoft.AspNet.Http;
+using Microsoft.Extensions.DiagnosticAdapter;
+
+namespace Microsoft.AspNet.MiddlewareAnalysis
+{
+ public class TestDiagnosticListener
+ {
+ public IList MiddlewareStarting { get; } = new List();
+ public IList MiddlewareFinished { get; } = new List();
+ public IList MiddlewareException { get; } = new List();
+
+ [DiagnosticName("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareStarting")]
+ public virtual void OnMiddlewareStarting(HttpContext httpContext, string name)
+ {
+ MiddlewareStarting.Add(name);
+ }
+
+ [DiagnosticName("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareException")]
+ public virtual void OnMiddlewareException(Exception exception, string name)
+ {
+ MiddlewareException.Add(name);
+ }
+
+ [DiagnosticName("Microsoft.AspNet.MiddlewareAnalysis.MiddlewareFinished")]
+ public virtual void OnMiddlewareFinished(HttpContext httpContext, string name)
+ {
+ MiddlewareFinished.Add(name);
+ }
+ }
+}
diff --git a/test/Microsoft.AspNet.MiddlewareAnalysis.Tests/project.json b/test/Microsoft.AspNet.MiddlewareAnalysis.Tests/project.json
new file mode 100644
index 0000000000..9b014f1cbd
--- /dev/null
+++ b/test/Microsoft.AspNet.MiddlewareAnalysis.Tests/project.json
@@ -0,0 +1,21 @@
+{
+ "compilationOptions": {
+ "warningsAsErrors": false
+ },
+ "dependencies": {
+ "Microsoft.AspNet.Diagnostics": "1.0.0-*",
+ "Microsoft.AspNet.MiddlewareAnalysis": "1.0.0-*",
+ "Microsoft.AspNet.TestHost": "1.0.0-*",
+ "Microsoft.AspNet.Testing": "1.0.0-*",
+ "Microsoft.Extensions.DependencyInjection": "1.0.0-*",
+ "Microsoft.Extensions.DiagnosticAdapter": "1.0.0-*",
+ "xunit.runner.aspnet": "2.0.0-aspnet-*"
+ },
+ "frameworks": {
+ "dnx451": {},
+ "dnxcore50": {}
+ },
+ "commands": {
+ "test": "xunit.runner.aspnet"
+ }
+}