Added EmptyApp20 and FunctionalTestUtils20
This commit is contained in:
Родитель
36d363c61c
Коммит
4d91ca68aa
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 15
|
# Visual Studio 15
|
||||||
VisualStudioVersion = 15.0.26430.14
|
VisualStudioVersion = 15.0.26730.3
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{2E6DDE9E-8C75-4F9C-8906-08EBDD6E73EF}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{2E6DDE9E-8C75-4F9C-8906-08EBDD6E73EF}"
|
||||||
EndProject
|
EndProject
|
||||||
|
@ -38,6 +38,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EmptyApp.FunctionalTests",
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MVCFramework45.FunctionalTests", "test\MVCFramework45.FunctionalTests\MVCFramework45.FunctionalTests.csproj", "{9F83564A-F84D-494A-9658-B080757EA82C}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MVCFramework45.FunctionalTests", "test\MVCFramework45.FunctionalTests\MVCFramework45.FunctionalTests.csproj", "{9F83564A-F84D-494A-9658-B080757EA82C}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EmptyApp20.FunctionalTests", "test\EmptyApp20.FunctionalTests\EmptyApp20.FunctionalTests.csproj", "{C47AFD8A-3326-4391-8115-69349C04C3DA}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FunctionalTestUtils20", "test\FunctionalTestUtils20\FunctionalTestUtils20.csproj", "{937AF006-898E-43FD-80A6-B20D7E3A1944}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
@ -68,6 +72,14 @@ Global
|
||||||
{9F83564A-F84D-494A-9658-B080757EA82C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{9F83564A-F84D-494A-9658-B080757EA82C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{9F83564A-F84D-494A-9658-B080757EA82C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{9F83564A-F84D-494A-9658-B080757EA82C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{9F83564A-F84D-494A-9658-B080757EA82C}.Release|Any CPU.Build.0 = Release|Any CPU
|
{9F83564A-F84D-494A-9658-B080757EA82C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{C47AFD8A-3326-4391-8115-69349C04C3DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{C47AFD8A-3326-4391-8115-69349C04C3DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{C47AFD8A-3326-4391-8115-69349C04C3DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{C47AFD8A-3326-4391-8115-69349C04C3DA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{937AF006-898E-43FD-80A6-B20D7E3A1944}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{937AF006-898E-43FD-80A6-B20D7E3A1944}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{937AF006-898E-43FD-80A6-B20D7E3A1944}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{937AF006-898E-43FD-80A6-B20D7E3A1944}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -80,5 +92,10 @@ Global
|
||||||
{11FB2EE6-7199-4AFF-BC73-25F35675F233} = {8B5230E5-8138-44D6-839F-DF9248F195EE}
|
{11FB2EE6-7199-4AFF-BC73-25F35675F233} = {8B5230E5-8138-44D6-839F-DF9248F195EE}
|
||||||
{71CE2DB2-C7AA-4454-B5F2-774BC575E321} = {8B5230E5-8138-44D6-839F-DF9248F195EE}
|
{71CE2DB2-C7AA-4454-B5F2-774BC575E321} = {8B5230E5-8138-44D6-839F-DF9248F195EE}
|
||||||
{9F83564A-F84D-494A-9658-B080757EA82C} = {8B5230E5-8138-44D6-839F-DF9248F195EE}
|
{9F83564A-F84D-494A-9658-B080757EA82C} = {8B5230E5-8138-44D6-839F-DF9248F195EE}
|
||||||
|
{C47AFD8A-3326-4391-8115-69349C04C3DA} = {8B5230E5-8138-44D6-839F-DF9248F195EE}
|
||||||
|
{937AF006-898E-43FD-80A6-B20D7E3A1944} = {8B5230E5-8138-44D6-839F-DF9248F195EE}
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {047855A4-470F-43B1-8B74-69651DD6B8A6}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|
Двоичные данные
NuGet.exe
Двоичные данные
NuGet.exe
Двоичный файл не отображается.
10
dirs.proj
10
dirs.proj
|
@ -12,10 +12,14 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<!--<Solution Include="src\Microsoft.ApplicationInsights.AspNetCore\Microsoft.ApplicationInsights.AspNetCore.xproj" />-->
|
<!--<Solution Include="src\Microsoft.ApplicationInsights.AspNetCore\Microsoft.ApplicationInsights.AspNetCore.xproj" />-->
|
||||||
<!-- Tests -->
|
<!-- Tests -->
|
||||||
<TestProject Include="test\Microsoft.ApplicationInsights.AspNetCore.Tests\ " />
|
<!--
|
||||||
|
<TestProject Include="test\Microsoft.ApplicationInsights.AspNetCore.Tests\ " />
|
||||||
<TestProject Include="test\WebApiShimFw46.FunctionalTests\ " />
|
<TestProject Include="test\WebApiShimFw46.FunctionalTests\ " />
|
||||||
<TestProject Include="test\EmptyApp.FunctionalTests\ " />
|
<TestProject Include="test\EmptyApp.FunctionalTests\ " />
|
||||||
|
<TestProject Include="test\EmptyApp20.FunctionalTests\ " />
|
||||||
<TestProject Include="test\MVCFramework45.FunctionalTests\ " />
|
<TestProject Include="test\MVCFramework45.FunctionalTests\ " />
|
||||||
|
-->
|
||||||
|
<TestProject Include="test\EmptyApp20.FunctionalTests\ " />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<UsingTask TaskName="DownloadFile" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
|
<UsingTask TaskName="DownloadFile" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
|
||||||
|
@ -169,7 +173,7 @@
|
||||||
<Exec Command=".\nuget.exe locals all -clear" ContinueOnError="ErrorAndStop" />
|
<Exec Command=".\nuget.exe locals all -clear" ContinueOnError="ErrorAndStop" />
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
<Target Name="Build" DependsOnTargets="CheckBuildParameters;DownloadCLI">
|
<Target Name="Build">
|
||||||
<Exec Command='"$(CliToolsPath)\dotnet.exe" --version' />
|
<Exec Command='"$(CliToolsPath)\dotnet.exe" --version' />
|
||||||
<Exec Command='"nuget.exe" restore' ContinueOnError="ErrorAndStop" />
|
<Exec Command='"nuget.exe" restore' ContinueOnError="ErrorAndStop" />
|
||||||
<Exec Command='"$(CliToolsPath)\dotnet.exe" build $(ProjectToBuild) -c $(Configuration)' ContinueOnError="ErrorAndStop" />
|
<Exec Command='"$(CliToolsPath)\dotnet.exe" build $(ProjectToBuild) -c $(Configuration)' ContinueOnError="ErrorAndStop" />
|
||||||
|
@ -178,7 +182,7 @@
|
||||||
|
|
||||||
<Target Name="Test" AfterTargets="Build" DependsOnTargets="Build">
|
<Target Name="Test" AfterTargets="Build" DependsOnTargets="Build">
|
||||||
<Message Condition="$(RunTests) != '' And $(RunTests)" Importance="high" Text="Running tests..."></Message>
|
<Message Condition="$(RunTests) != '' And $(RunTests)" Importance="high" Text="Running tests..."></Message>
|
||||||
<Exec Condition="$(RunTests) != '' And $(RunTests)" Command='"$(CliToolsPath)\dotnet.exe" test' WorkingDirectory='%(TestProject.Identity)' ContinueOnError="ErrorAndStop" />
|
<Exec Condition="$(RunTests) != '' And $(RunTests)" Command='"$(CliToolsPath)\dotnet.exe" test -l trx' WorkingDirectory='%(TestProject.Identity)' ContinueOnError="ErrorAndContinue" />
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
<Target Name="Clean">
|
<Target Name="Clean">
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<configuration>
|
||||||
|
<runtime>
|
||||||
|
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||||
|
<dependentAssembly>
|
||||||
|
<assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||||
|
<bindingRedirect oldVersion="4.0.0.0" newVersion="4.0.2.0" />
|
||||||
|
</dependentAssembly>
|
||||||
|
<dependentAssembly>
|
||||||
|
<assemblyIdentity name="System.Text.Encodings.Web" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||||
|
<bindingRedirect oldVersion="4.0.0.0" newVersion="4.0.1.1" />
|
||||||
|
</dependentAssembly>
|
||||||
|
</assemblyBinding>
|
||||||
|
</runtime>
|
||||||
|
</configuration>
|
|
@ -0,0 +1,50 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<VersionPrefix>2.0.0</VersionPrefix>
|
||||||
|
<TargetFrameworks>net46;netcoreapp2.0</TargetFrameworks>
|
||||||
|
<RuntimeIdentifier Condition=" '$(TargetFramework)' == 'net46' ">win7-x86</RuntimeIdentifier>
|
||||||
|
<DelaySign>true</DelaySign>
|
||||||
|
<PreserveCompilationContext>true</PreserveCompilationContext>
|
||||||
|
<AssemblyName>EmptyApp20.FunctionalTests</AssemblyName>
|
||||||
|
<AssemblyOriginatorKeyFile>../../keys/35MSSharedLib1024.snk</AssemblyOriginatorKeyFile>
|
||||||
|
<SignAssembly>true</SignAssembly>
|
||||||
|
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
|
||||||
|
<PackageId>EmptyApp.FunctionalTests</PackageId>
|
||||||
|
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
|
||||||
|
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp2.0' ">2.0.0</RuntimeFrameworkVersion>
|
||||||
|
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\test\$(MSBuildProjectName)</OutputPath>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0-preview-20170106-08" />
|
||||||
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
|
||||||
|
<PackageReference Condition=" '$(TargetFramework)' != 'net46' " Include="Microsoft.AspNetCore.Diagnostics" Version="2.0.0" />
|
||||||
|
<PackageReference Include="xunit" Version="2.2.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup Condition=" '$(TargetFramework)' == 'net46' ">
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\FunctionalTestUtils20\FunctionalTestUtils20.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Update="App.config">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
<Generator>SettingsSingleFileGenerator</Generator>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
|
@ -0,0 +1,44 @@
|
||||||
|
using System.Diagnostics;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
[assembly: CollectionBehavior(DisableTestParallelization = true)]
|
||||||
|
namespace EmptyApp20.FunctionalTests.FunctionalTest
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using FunctionalTestUtils;
|
||||||
|
using Microsoft.ApplicationInsights.DataContracts;
|
||||||
|
|
||||||
|
public class ExceptionTelemetryEmptyAppTests : TelemetryTestsBase
|
||||||
|
{
|
||||||
|
private const string assemblyName = "EmptyApp20.FunctionalTests";
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestBasicRequestPropertiesAfterRequestingRequestThatThrows()
|
||||||
|
{
|
||||||
|
using (var server = new InProcessServer(assemblyName))
|
||||||
|
{
|
||||||
|
const string RequestPath = "/Exception";
|
||||||
|
|
||||||
|
var expectedRequestTelemetry = new RequestTelemetry();
|
||||||
|
|
||||||
|
expectedRequestTelemetry.Name = "GET /Exception";
|
||||||
|
expectedRequestTelemetry.ResponseCode = "500";
|
||||||
|
expectedRequestTelemetry.Success = false;
|
||||||
|
expectedRequestTelemetry.Url = new System.Uri(server.BaseHost + RequestPath);
|
||||||
|
this.ValidateBasicRequest(server, "/Exception", expectedRequestTelemetry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestBasicExceptionPropertiesAfterRequestingRequestThatThrows()
|
||||||
|
{
|
||||||
|
using (var server = new InProcessServer(assemblyName))
|
||||||
|
{
|
||||||
|
var expectedExceptionTelemetry = new ExceptionTelemetry();
|
||||||
|
expectedExceptionTelemetry.Exception = new InvalidOperationException();
|
||||||
|
|
||||||
|
this.ValidateBasicException(server, "/Exception", expectedExceptionTelemetry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
namespace EmptyApp20.FunctionalTests.FunctionalTest
|
||||||
|
{
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
|
using FunctionalTestUtils;
|
||||||
|
using Microsoft.ApplicationInsights.DataContracts;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
public class RequestTelemetryEmptyAppTests : TelemetryTestsBase
|
||||||
|
{
|
||||||
|
private const string assemblyName = "EmptyApp20.FunctionalTests";
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestBasicRequestPropertiesAfterRequestingBasicPage()
|
||||||
|
{
|
||||||
|
using (var server = new InProcessServer(assemblyName))
|
||||||
|
{
|
||||||
|
const string RequestPath = "/";
|
||||||
|
|
||||||
|
var expectedRequestTelemetry = new RequestTelemetry();
|
||||||
|
expectedRequestTelemetry.Name = "GET /";
|
||||||
|
expectedRequestTelemetry.ResponseCode = "200";
|
||||||
|
expectedRequestTelemetry.Success = true;
|
||||||
|
expectedRequestTelemetry.Url = new System.Uri(server.BaseHost + RequestPath);
|
||||||
|
|
||||||
|
this.ValidateBasicRequest(server, RequestPath, expectedRequestTelemetry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestBasicRequestPropertiesAfterRequestingNotExistingPage()
|
||||||
|
{
|
||||||
|
using (var server = new InProcessServer(assemblyName))
|
||||||
|
{
|
||||||
|
const string RequestPath = "/not/existing/controller";
|
||||||
|
|
||||||
|
var expectedRequestTelemetry = new RequestTelemetry();
|
||||||
|
expectedRequestTelemetry.Name = "GET /not/existing/controller";
|
||||||
|
expectedRequestTelemetry.ResponseCode = "404";
|
||||||
|
expectedRequestTelemetry.Success = false;
|
||||||
|
expectedRequestTelemetry.Url = new System.Uri(server.BaseHost + RequestPath);
|
||||||
|
|
||||||
|
this.ValidateBasicRequest(server, RequestPath, expectedRequestTelemetry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestMixedTelemetryItemsReceived()
|
||||||
|
{
|
||||||
|
InProcessServer server;
|
||||||
|
using (server = new InProcessServer(assemblyName))
|
||||||
|
{
|
||||||
|
using (var httpClient = new HttpClient())
|
||||||
|
{
|
||||||
|
var task = httpClient.GetAsync(server.BaseHost + "/Mixed");
|
||||||
|
task.Wait(TestTimeoutMs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var telemetries = server.BackChannel.Buffer;
|
||||||
|
Assert.Contains(telemetries.OfType<DependencyTelemetry>(), t => t.Name == "GET /Mixed");
|
||||||
|
Assert.True(telemetries.Count >= 4);
|
||||||
|
Assert.Contains(telemetries.OfType<RequestTelemetry>(), t => t.Name == "GET /Mixed");
|
||||||
|
Assert.Contains(telemetries.OfType<EventTelemetry>(), t => t.Name == "GetContact");
|
||||||
|
Assert.Contains(telemetries.OfType<MetricTelemetry>(),
|
||||||
|
t => t.Name == "ContactFile" && t.Value == 1);
|
||||||
|
|
||||||
|
Assert.Contains(telemetries.OfType<TraceTelemetry>(),
|
||||||
|
t => t.Message == "Fetched contact details." && t.SeverityLevel == SeverityLevel.Information);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
namespace EmptyApp20.FunctionalTests.FunctionalTest
|
||||||
|
{
|
||||||
|
using FunctionalTestUtils;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
public class TelemetryModuleWorkingEmptyAppTests : TelemetryTestsBase
|
||||||
|
{
|
||||||
|
private const string assemblyName = "EmptyApp20.FunctionalTests";
|
||||||
|
|
||||||
|
// The NET451 conditional check is wrapped inside the test to make the tests visible in the test explorer. We can move them to the class level once if the issue is resolved.
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestBasicDependencyPropertiesAfterRequestingBasicPage()
|
||||||
|
{
|
||||||
|
this.ValidateBasicDependency(assemblyName, "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestIfPerformanceCountersAreCollected()
|
||||||
|
{
|
||||||
|
#if NET451 || NET46
|
||||||
|
ValidatePerformanceCountersAreCollected(assemblyName);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": false,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:4828/",
|
||||||
|
"sslPort": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"profiles": {
|
||||||
|
"IIS Express": {
|
||||||
|
"commandName": "IISExpress",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNET_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"web": {
|
||||||
|
"commandName": "web",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNET_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
namespace EmptyApp.FunctionalTests
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.ApplicationInsights.AspNetCore.Extensions;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.ApplicationInsights.Channel;
|
||||||
|
using FunctionalTestUtils;
|
||||||
|
using Microsoft.ApplicationInsights;
|
||||||
|
using Microsoft.ApplicationInsights.DataContracts;
|
||||||
|
|
||||||
|
public class Startup
|
||||||
|
{
|
||||||
|
// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
|
||||||
|
public void ConfigureServices(IServiceCollection services)
|
||||||
|
{
|
||||||
|
services.AddSingleton<ITelemetryChannel>(new BackTelemetryChannel());
|
||||||
|
|
||||||
|
var builder = new ConfigurationBuilder();
|
||||||
|
builder.AddApplicationInsightsSettings(instrumentationKey: "Foo");
|
||||||
|
services.AddApplicationInsightsTelemetry(builder.Build());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Configure(IApplicationBuilder app)
|
||||||
|
{
|
||||||
|
#if !NET46
|
||||||
|
app.UseDeveloperExceptionPage();
|
||||||
|
#endif
|
||||||
|
app.Use(next =>
|
||||||
|
{
|
||||||
|
return async context =>
|
||||||
|
{
|
||||||
|
if (context.Request.GetUri().ToString().Contains("Exception"))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
else if (context.Request.GetUri().PathAndQuery == "/")
|
||||||
|
{
|
||||||
|
await context.Response.WriteAsync("Hello!");
|
||||||
|
}
|
||||||
|
else if (context.Request.GetUri().ToString().Contains("Mixed"))
|
||||||
|
{
|
||||||
|
TelemetryClient telemetryClient = (TelemetryClient)context.RequestServices.GetService(typeof(TelemetryClient));
|
||||||
|
telemetryClient.TrackEvent("GetContact");
|
||||||
|
telemetryClient.TrackMetric("ContactFile", 1);
|
||||||
|
telemetryClient.TrackTrace("Fetched contact details.", SeverityLevel.Information);
|
||||||
|
await context.Response.WriteAsync("Hello!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await next(context);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
namespace FunctionalTestUtils
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.ApplicationInsights.Channel;
|
||||||
|
|
||||||
|
public class BackTelemetryChannel : ITelemetryChannel
|
||||||
|
{
|
||||||
|
private IList<ITelemetry> buffer;
|
||||||
|
|
||||||
|
public BackTelemetryChannel()
|
||||||
|
{
|
||||||
|
this.buffer = new List<ITelemetry>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IList<ITelemetry> Buffer
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return this.buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool? DeveloperMode
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string EndpointAddress
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return "https://dc.services.visualstudio.com/v2/track";
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Flush()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Send(ITelemetry item)
|
||||||
|
{
|
||||||
|
this.buffer.Add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<VersionPrefix>1.0.2</VersionPrefix>
|
||||||
|
<TargetFrameworks>net46;netstandard2.0</TargetFrameworks>
|
||||||
|
<DelaySign>true</DelaySign>
|
||||||
|
<PreserveCompilationContext>true</PreserveCompilationContext>
|
||||||
|
<AssemblyName>FunctionalTestUtils20</AssemblyName>
|
||||||
|
<AssemblyOriginatorKeyFile>../../keys/35MSSharedLib1024.snk</AssemblyOriginatorKeyFile>
|
||||||
|
<SignAssembly>true</SignAssembly>
|
||||||
|
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
|
||||||
|
<PackageId>FunctionalTestUtils</PackageId>
|
||||||
|
<NetStandardImplicitPackageVersion>1.6.1</NetStandardImplicitPackageVersion>
|
||||||
|
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\test\$(MSBuildProjectName)</OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src\Microsoft.ApplicationInsights.AspNetCore\Microsoft.ApplicationInsights.AspNetCore.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Condition=" '$(TargetFramework)' == 'net46' " Include="Microsoft.AspNetCore.Server.Kestrel" Version="1.0.3" />
|
||||||
|
<PackageReference Condition=" '$(TargetFramework)' != 'net46' " Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.0.0" />
|
||||||
|
<PackageReference Condition=" '$(TargetFramework)' != 'net46' " Include="Microsoft.AspNetCore" Version="2.0.0" />
|
||||||
|
<PackageReference Condition=" '$(TargetFramework)' != 'net46' " Include="NETStandard.Library" Version="2.0.0" />
|
||||||
|
<PackageReference Include="xunit" Version="2.2.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup Condition=" '$(TargetFramework)' == 'net46' ">
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
|
@ -0,0 +1,86 @@
|
||||||
|
namespace FunctionalTestUtils
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using Microsoft.ApplicationInsights.Channel;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.AspNetCore;
|
||||||
|
|
||||||
|
// a variant of aspnet/Hosting/test/Microsoft.AspNetCore.Hosting.Tests/HostingEngineTests.cs
|
||||||
|
public class InProcessServer : IDisposable
|
||||||
|
{
|
||||||
|
private static Random random = new Random();
|
||||||
|
|
||||||
|
public static Func<IWebHostBuilder, IWebHostBuilder> UseApplicationInsights =
|
||||||
|
builder => builder.UseApplicationInsights();
|
||||||
|
|
||||||
|
private readonly Func<IWebHostBuilder, IWebHostBuilder> configureHost;
|
||||||
|
private IWebHost hostingEngine;
|
||||||
|
private string url;
|
||||||
|
|
||||||
|
private readonly BackTelemetryChannel backChannel;
|
||||||
|
|
||||||
|
public BackTelemetryChannel BackChannel
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return this.backChannel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public InProcessServer(string assemblyName, Func<IWebHostBuilder, IWebHostBuilder> configureHost = null)
|
||||||
|
{
|
||||||
|
this.configureHost = configureHost;
|
||||||
|
var machineName = Environment.GetEnvironmentVariable("COMPUTERNAME");
|
||||||
|
this.url = "http://" + machineName + ":" + random.Next(5000, 14000).ToString();
|
||||||
|
this.backChannel = this.Start(assemblyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string BaseHost
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return this.url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IServiceProvider ApplicationServices { get; private set; }
|
||||||
|
|
||||||
|
private BackTelemetryChannel Start(string assemblyName)
|
||||||
|
{
|
||||||
|
|
||||||
|
#if NET46
|
||||||
|
var builder = new WebHostBuilder()
|
||||||
|
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||||
|
.UseUrls(this.BaseHost)
|
||||||
|
.UseKestrel()
|
||||||
|
.UseStartup(assemblyName)
|
||||||
|
.UseEnvironment("Production");
|
||||||
|
#else
|
||||||
|
|
||||||
|
var builder = WebHost.CreateDefaultBuilder().UseStartup(assemblyName);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (configureHost != null)
|
||||||
|
{
|
||||||
|
builder = configureHost(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.hostingEngine = builder.Build();
|
||||||
|
|
||||||
|
this.hostingEngine.Start();
|
||||||
|
|
||||||
|
this.ApplicationServices = this.hostingEngine.Services;
|
||||||
|
return (BackTelemetryChannel)this.hostingEngine.Services.GetService<ITelemetryChannel>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (this.hostingEngine != null)
|
||||||
|
{
|
||||||
|
this.hostingEngine.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": false,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:4824/",
|
||||||
|
"sslPort": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"profiles": {
|
||||||
|
"IIS Express": {
|
||||||
|
"commandName": "IISExpress",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNET_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,159 @@
|
||||||
|
namespace FunctionalTestUtils
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.ApplicationInsights.DataContracts;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Xunit;
|
||||||
|
#if NET451 || NET46
|
||||||
|
using System.Net;
|
||||||
|
using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector;
|
||||||
|
using Microsoft.ApplicationInsights.Extensibility;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public abstract class TelemetryTestsBase
|
||||||
|
{
|
||||||
|
protected const int TestTimeoutMs = 10000;
|
||||||
|
private object noParallelism = new object();
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.NoOptimization)]
|
||||||
|
public void ValidateBasicRequest(InProcessServer server, string requestPath, RequestTelemetry expected)
|
||||||
|
{
|
||||||
|
lock (noParallelism)
|
||||||
|
{
|
||||||
|
// Subtract 50 milliseconds to hack around strange behavior on build server where the RequestTelemetry.Timestamp is somehow sometimes earlier than now by a few milliseconds.
|
||||||
|
expected.Timestamp = DateTimeOffset.Now.Subtract(TimeSpan.FromMilliseconds(50));
|
||||||
|
server.BackChannel.Buffer.Clear();
|
||||||
|
Stopwatch timer = Stopwatch.StartNew();
|
||||||
|
|
||||||
|
var httpClientHandler = new HttpClientHandler();
|
||||||
|
httpClientHandler.UseDefaultCredentials = true;
|
||||||
|
|
||||||
|
Task<HttpResponseMessage> task;
|
||||||
|
using (HttpClient httpClient = new HttpClient(httpClientHandler, true))
|
||||||
|
{
|
||||||
|
task = httpClient.GetAsync(server.BaseHost + requestPath);
|
||||||
|
task.Wait(TestTimeoutMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
timer.Stop();
|
||||||
|
server.Dispose();
|
||||||
|
|
||||||
|
RequestTelemetry actual = server.BackChannel.Buffer.OfType<RequestTelemetry>().Where(t => t.Name == expected.Name).Single();
|
||||||
|
server.BackChannel.Buffer.Clear();
|
||||||
|
|
||||||
|
Assert.Equal(expected.ResponseCode, actual.ResponseCode);
|
||||||
|
Assert.Equal(expected.Name, actual.Name);
|
||||||
|
Assert.Equal(expected.Success, actual.Success);
|
||||||
|
Assert.Equal(expected.Url, actual.Url);
|
||||||
|
InRange(actual.Timestamp, expected.Timestamp, DateTimeOffset.Now);
|
||||||
|
Assert.True(actual.Duration < timer.Elapsed, "duration");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ValidateBasicException(InProcessServer server, string requestPath, ExceptionTelemetry expected)
|
||||||
|
{
|
||||||
|
var httpClientHandler = new HttpClientHandler();
|
||||||
|
httpClientHandler.UseDefaultCredentials = true;
|
||||||
|
|
||||||
|
Task<HttpResponseMessage> task;
|
||||||
|
using (var httpClient = new HttpClient(httpClientHandler, true))
|
||||||
|
{
|
||||||
|
task = httpClient.GetAsync(server.BaseHost + requestPath);
|
||||||
|
task.Wait(TestTimeoutMs);
|
||||||
|
}
|
||||||
|
var result = task.Result;
|
||||||
|
server.Dispose();
|
||||||
|
var actual = server.BackChannel.Buffer.OfType<ExceptionTelemetry>().Single();
|
||||||
|
|
||||||
|
Assert.Equal(expected.Exception.GetType(), actual.Exception.GetType());
|
||||||
|
Assert.NotEmpty(actual.Exception.StackTrace);
|
||||||
|
Assert.NotEmpty(actual.Context.Operation.Name);
|
||||||
|
Assert.NotEmpty(actual.Context.Operation.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ValidateBasicDependency(string assemblyName, string requestPath, Func<IWebHostBuilder, IWebHostBuilder> configureHost = null)
|
||||||
|
{
|
||||||
|
DependencyTelemetry expected = new DependencyTelemetry();
|
||||||
|
expected.ResultCode = "200";
|
||||||
|
expected.Success = true;
|
||||||
|
expected.Name = "GET " + requestPath;
|
||||||
|
|
||||||
|
InProcessServer server;
|
||||||
|
using (server = new InProcessServer(assemblyName, configureHost))
|
||||||
|
{
|
||||||
|
expected.Data = server.BaseHost + requestPath;
|
||||||
|
|
||||||
|
var timer = Stopwatch.StartNew();
|
||||||
|
Task<HttpResponseMessage> task;
|
||||||
|
using (var httpClient = new HttpClient())
|
||||||
|
{
|
||||||
|
task = httpClient.GetAsync(server.BaseHost + requestPath);
|
||||||
|
task.Wait(TestTimeoutMs);
|
||||||
|
}
|
||||||
|
var result = task.Result;
|
||||||
|
timer.Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerable<DependencyTelemetry> dependencies = server.BackChannel.Buffer.OfType<DependencyTelemetry>();
|
||||||
|
Assert.NotNull(dependencies);
|
||||||
|
Assert.NotEmpty(dependencies);
|
||||||
|
|
||||||
|
var dependencyTelemetry = dependencies.FirstOrDefault(d => d.Name == expected.Name
|
||||||
|
&& d.Data == expected.Data
|
||||||
|
&& d.Success == expected.Success
|
||||||
|
&& d.ResultCode == expected.ResultCode);
|
||||||
|
Assert.NotNull(dependencyTelemetry);
|
||||||
|
|
||||||
|
#if !NET451
|
||||||
|
var requestTelemetry = server.BackChannel.Buffer.OfType<RequestTelemetry>().Single();
|
||||||
|
Assert.Equal(requestTelemetry.Context.Operation.ParentId, dependencyTelemetry.Id);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if NET451 || NET46
|
||||||
|
public void ValidatePerformanceCountersAreCollected(string assemblyName, Func<IWebHostBuilder, IWebHostBuilder> configureHost = null)
|
||||||
|
{
|
||||||
|
using (var server = new InProcessServer(assemblyName, configureHost))
|
||||||
|
{
|
||||||
|
// Reconfigure the PerformanceCollectorModule timer.
|
||||||
|
Type perfModuleType = typeof(PerformanceCollectorModule);
|
||||||
|
PerformanceCollectorModule perfModule = (PerformanceCollectorModule)server.ApplicationServices.GetServices<ITelemetryModule>().FirstOrDefault(m => m.GetType() == perfModuleType);
|
||||||
|
FieldInfo timerField = perfModuleType.GetField("timer", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||||
|
var timer = timerField.GetValue(perfModule);
|
||||||
|
timerField.FieldType.InvokeMember("ScheduleNextTick", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, timer, new object[] { TimeSpan.FromMilliseconds(10) });
|
||||||
|
|
||||||
|
DateTime timeout = DateTime.UtcNow.AddMilliseconds(TestTimeoutMs);
|
||||||
|
int numberOfCountersSent = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Thread.Sleep(1000);
|
||||||
|
numberOfCountersSent += server.BackChannel.Buffer.OfType<MetricTelemetry>().Distinct().Count();
|
||||||
|
} while (numberOfCountersSent == 0 && DateTime.UtcNow < timeout);
|
||||||
|
|
||||||
|
Assert.True(numberOfCountersSent > 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests if a DateTimeOffset is in a specified range and prints a more detailed error message if it is not.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="actual">The actual value to test.</param>
|
||||||
|
/// <param name="low">The minimum of the range.</param>
|
||||||
|
/// <param name="high">The maximum of the range.</param>
|
||||||
|
private void InRange(DateTimeOffset actual, DateTimeOffset low, DateTimeOffset high)
|
||||||
|
{
|
||||||
|
string dateFormat = "yyyy-MM-dd HH:mm:ss.ffffzzz";
|
||||||
|
Assert.True(low <= actual && actual <= high, $"Range: ({low.ToString(dateFormat)} - {high.ToString(dateFormat)})\nActual: {actual.ToString(dateFormat)}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Загрузка…
Ссылка в новой задаче