Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test startup hooks #1167

Merged
merged 22 commits into from
Feb 11, 2021
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .ci/docker/sdk-linux/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:${DOTNET_R
RUN curl -s -O -L https://dotnet.microsoft.com/download/dotnet-core/scripts/v1/dotnet-install.sh

# Install .Net SDKs
RUN /bin/bash ./dotnet-install.sh --install-dir "${DOTNET_ROOT}" -version "3.1.100"
RUN /bin/bash ./dotnet-install.sh --install-dir "${DOTNET_ROOT}" -version "2.1.505"
RUN /bin/bash ./dotnet-install.sh --install-dir "${DOTNET_ROOT}" -version "3.0.103"
RUN /bin/bash ./dotnet-install.sh --install-dir "${DOTNET_ROOT}" -version "3.1.100"


# Install docker
RUN apt update \
Expand Down
3 changes: 3 additions & 0 deletions .ci/linux/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ set -euxo pipefail
# Remove Full Framework projects
.ci/linux/remove-projects.sh

# Build agent zip file
./build.sh agent-zip

# Run tests for all solution
dotnet test -c Release ElasticApmAgent.sln \
--verbosity normal \
Expand Down
3 changes: 3 additions & 0 deletions .ci/windows/dotnet.bat
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@ dotnet sln remove test/Elastic.Apm.AspNetFullFramework.Tests/Elastic.Apm.AspNetF
dotnet sln remove test/Elastic.Apm.SqlClient.Tests/Elastic.Apm.SqlClient.Tests.csproj
dotnet sln remove test/Elastic.Apm.EntityFramework6.Tests/Elastic.Apm.EntityFramework6.Tests.csproj

:: Remove startup hooks tests, which are tested separately- require agent zip to be built
dotnet sln remove test/Elastic.Apm.StartupHook.Tests/Elastic.Apm.StartupHook.Tests.csproj

dotnet build -c Release --verbosity detailed
5 changes: 5 additions & 0 deletions .ci/windows/test-zip.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
dotnet test -c Release test\Elastic.Apm.StartupHook.Tests --no-build ^
--verbosity normal ^
--results-directory target ^
--diag target\diag-startuphook.log ^
--logger:"junit;LogFilePath=junit-{framework}-{assembly}.xml;MethodFormat=Class;FailureBodyFormat=Verbose"
4 changes: 3 additions & 1 deletion .ci/windows/tools.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ Add-WindowsFeature NET-Framework-45-ASPNET ;
Add-WindowsFeature Web-Asp-Net45 ;

# Install .Net SDKs
choco install dotnetcore-sdk -m -y --no-progress -r --version 3.1.100
choco install dotnetcore-sdk -m -y --no-progress -r --version 2.1.505
choco install dotnetcore-sdk -m -y --no-progress -r --version 2.2.104
choco install dotnetcore-sdk -m -y --no-progress -r --version 3.0.103
choco install dotnetcore-sdk -m -y --no-progress -r --version 3.1.100

choco install dotnet-sdk -m -y --no-progress -r --version 5.0.100

# Install NuGet Tool
Expand Down
1 change: 1 addition & 0 deletions .ci/windows/zip.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.\build.bat agent-zip
14 changes: 14 additions & 0 deletions ElasticApmAgent.sln
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elastic.Apm.StaticImplicitI
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elastic.Apm.StaticExplicitInitialization.Tests", "test\Elastic.Apm.StaticExplicitInitialization.Tests\Elastic.Apm.StaticExplicitInitialization.Tests.csproj", "{DC879845-353B-4C62-9640-6EA3008326F7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elastic.Apm.StartupHook.Sample", "sample\Elastic.Apm.StartupHook.Sample\Elastic.Apm.StartupHook.Sample.csproj", "{B168C594-0314-4201-A55B-13DBBE2796FE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elastic.Apm.StartupHook.Tests", "test\Elastic.Apm.StartupHook.Tests\Elastic.Apm.StartupHook.Tests.csproj", "{9AE4805D-2586-4FA5-A0D0-885264EBC565}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
test\Elastic.Apm.DatabaseTests.Common\Elastic.Apm.DatabaseTests.Common.projitems*{968e1e85-e996-42de-9845-d20dae16165a}*SharedItemsImports = 5
Expand Down Expand Up @@ -300,6 +304,14 @@ Global
{DC879845-353B-4C62-9640-6EA3008326F7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DC879845-353B-4C62-9640-6EA3008326F7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DC879845-353B-4C62-9640-6EA3008326F7}.Release|Any CPU.Build.0 = Release|Any CPU
{B168C594-0314-4201-A55B-13DBBE2796FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B168C594-0314-4201-A55B-13DBBE2796FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B168C594-0314-4201-A55B-13DBBE2796FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B168C594-0314-4201-A55B-13DBBE2796FE}.Release|Any CPU.Build.0 = Release|Any CPU
{9AE4805D-2586-4FA5-A0D0-885264EBC565}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9AE4805D-2586-4FA5-A0D0-885264EBC565}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9AE4805D-2586-4FA5-A0D0-885264EBC565}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9AE4805D-2586-4FA5-A0D0-885264EBC565}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -347,6 +359,8 @@ Global
{B5200DC5-5E48-4F72-ADA9-96D0380A00CB} = {3734A52F-2222-454B-BF58-1BA5C1F29D77}
{CE0120A5-A094-40A3-905E-8E14526800D3} = {267A241E-571F-458F-B04C-B6C4DE79E735}
{DC879845-353B-4C62-9640-6EA3008326F7} = {267A241E-571F-458F-B04C-B6C4DE79E735}
{B168C594-0314-4201-A55B-13DBBE2796FE} = {3C791D9C-6F19-4F46-B367-2EC0F818762D}
{9AE4805D-2586-4FA5-A0D0-885264EBC565} = {267A241E-571F-458F-B04C-B6C4DE79E735}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {69E02FD9-C9DE-412C-AB6B-5B8BECC6BFA5}
Expand Down
23 changes: 23 additions & 0 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,29 @@ pipeline {
}
}
}
stage('Startup Hook Tests') {
steps {
withGithubNotify(context: 'Test startup hooks - Windows', tab: 'tests') {
cleanDir("${WORKSPACE}/${BASE_DIR}")
unstash 'source'
dir("${BASE_DIR}"){
powershell label: 'Install test tools', script: '.ci\\windows\\test-tools.ps1'
retry(3) {
bat label: 'Build', script: '.ci/windows/zip.bat'
}
bat label: 'Test & coverage', script: '.ci/windows/test-zip.bat'
}
}
}
post {
always {
reportTests()
}
unsuccessful {
archiveArtifacts(allowEmptyArchive: true, artifacts: "${MSBUILDDEBUGPATH}/**/MSBuild_*.failure.txt")
}
}
}
}
post {
always {
Expand Down
39 changes: 22 additions & 17 deletions build/scripts/Build.fs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,16 @@ open Buildalyzer
open Fake.Core
open Fake.DotNet
open Fake.IO
open Fake.IO
open Fake.IO.Globbing.Operators
open Fake.SystemHelper
open Fake.SystemHelper
open Tooling

module Build =

let private isCI = Environment.hasEnvironVar "BUILD_ID"

let private oldDiagnosticSourceVersion = SemVer.parse "4.6.0"

let mutable private currentDiagnosticSourceVersion = None
Expand Down Expand Up @@ -69,20 +74,20 @@ module Build =
let private dotnet target projectOrSln =
DotNet.Exec [target; projectOrSln; "-c"; "Release"; "-v"; "q"; "--nologo"]

let private msBuild target projectOrSln =
MSBuild.build (fun p -> {
p with
Verbosity = Some(Quiet)
Targets = [target]
Properties = [
"Configuration", "Release"
"Optimize", "True"
]
// current version of Fake MSBuild module does not support latest bin log file
// version of MSBuild in VS 16.8, so disable for now.
DisableInternalBinLog = true
NoLogo = true
}) projectOrSln
let private msBuild target projectOrSln =
MSBuild.build (fun p ->
{ p with
Verbosity = Some(Quiet)
Targets = [target]
Properties = [
"Configuration", "Release"
"Optimize", "True"
]
// current version of Fake MSBuild module does not support latest bin log file
// version of MSBuild in VS 16.8, so disable for now.
DisableInternalBinLog = true
NoLogo = true
}) projectOrSln

/// Gets the current version of System.Diagnostics.DiagnosticSource referenced by Elastic.Apm
let private getCurrentApmDiagnosticSourceVersion =
Expand Down Expand Up @@ -134,10 +139,10 @@ module Build =
|> Seq.iter (fun proj -> DotNet.Exec ["sln" ; Paths.SolutionNetCore; "remove"; proj])

/// Runs dotnet build on all .NET core projects in the solution.
/// When running on Windows, also runs MSBuild Build on .NET Framework
/// When running on Windows and not CI, also runs MSBuild Build on .NET Framework
let Build () =
dotnet "build" Paths.SolutionNetCore
if isWindows then msBuild "Build" aspNetFullFramework
if isWindows && not isCI then msBuild "Build" aspNetFullFramework
copyBinRelease()

/// Publishes all projects with framework versions
Expand Down Expand Up @@ -180,7 +185,7 @@ module Build =
let Clean () =
Shell.cleanDir Paths.BuildOutputFolder
dotnet "clean" Paths.SolutionNetCore
if isWindows then msBuild "Clean" aspNetFullFramework
if isWindows && not isCI then msBuild "Clean" aspNetFullFramework

/// Restores all packages for the solution
let Restore () =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Elastic.Apm.StartupHook.Sample.Models;

namespace Elastic.Apm.StartupHook.Sample.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;

public HomeController(ILogger<HomeController> logger) => _logger = logger;

public IActionResult Index() => View();

public IActionResult Privacy() => View();

[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error() => View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFrameworks>netcoreapp3.0;netcoreapp3.1;net5.0</TargetFrameworks>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.0' ">
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="3.0.0" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="3.1.0" />
</ItemGroup>

</Project>
11 changes: 11 additions & 0 deletions sample/Elastic.Apm.StartupHook.Sample/Models/ErrorViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System;

namespace Elastic.Apm.StartupHook.Sample.Models
{
public class ErrorViewModel
{
public string RequestId { get; set; }

public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
}
}
14 changes: 14 additions & 0 deletions sample/Elastic.Apm.StartupHook.Sample/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;

namespace Elastic.Apm.StartupHook.Sample
{
public class Program
{
public static void Main(string[] args) => CreateHostBuilder(args).Build().Run();

public static IWebHostBuilder CreateHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args).UseStartup<Startup>();
}
}
32 changes: 32 additions & 0 deletions sample/Elastic.Apm.StartupHook.Sample/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Sample ASP.NET (Core) application for startup hooks

This sample application is a default ASP.NET (Core) application
configured to run with

- `netcoreapp3.0`
- `netcoreapp3.1`
- `net5.0`

target frameworks that can be used to try out the [Elastic APM
startup hooks implementation](../../src/ElasticApmAgentStartupHook).

## How to use

1. Obtain the zip file containing the Elastic APM startup hooks and unzip it in a location accessible to this application.
2. Set the `DOTNET_STARTUP_HOOKS` environment variable to point to the `ElasticApmAgentStartupHook.dll` in the unzipped directory

```
set DOTNET_STARTUP_HOOKS=[pathToAgent]\ElasticApmAgentStartupHook.dll
```
3. Set any other APM agent configuration using environment variables. For example,

```
set ELASTIC_APM_SERVER_URL=http://localhost:8200
set ELASTIC_APM_LOG_LEVEL=Trace
```
4. Start the sample application with the specified target framework. From the `sample/Elastic.Apm.StartupHook.Sample` directory

```
dotnet run -f net5.0
```
5. Observe APM data collected.
47 changes: 47 additions & 0 deletions sample/Elastic.Apm.StartupHook.Sample/Startup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using IHostingEnvironment = Microsoft.AspNetCore.Hosting.IHostingEnvironment;

namespace Elastic.Apm.StartupHook.Sample
{
public class Startup
{
public Startup(IConfiguration configuration) => Configuration = configuration;

public IConfiguration Configuration { get; }

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
#if NET5_0
services.AddControllersWithViews();
#else
services.AddMvc();
#endif
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseDeveloperExceptionPage();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
}
8 changes: 8 additions & 0 deletions sample/Elastic.Apm.StartupHook.Sample/Views/Home/Index.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
@{
ViewData["Title"] = "Home Page";
}

<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@{
ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>

<p>Use this page to detail your site's privacy policy.</p>
25 changes: 25 additions & 0 deletions sample/Elastic.Apm.StartupHook.Sample/Views/Shared/Error.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
@model ErrorViewModel
@{
ViewData["Title"] = "Error";
}

<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>

@if (Model.ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@Model.RequestId</code>
</p>
}

<h3>Development Mode</h3>
<p>
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app.
</p>
Loading