Skip to content

Commit

Permalink
Add smoke test for config builder instrumentation issue (#6224)
Browse files Browse the repository at this point in the history
## Summary of changes

Adds a smoke test for the issue fixed in #6147 

## Reason for change

The issue in #6147 is complex and subtle, with a high risk of
regression, so we want to have smoke tests to catch it`

## Implementation details

Add a sample app very similar to the one tested with in #6147. Without
the fix, [the test fails
with](https://dev.azure.com/datadoghq/dd-trace-dotnet/_build/results?buildId=166792&view=results)

```html
<b> Description: </b>An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.
<br><br>
<b> Parser Error Message: </b>The configBuilder 'CustomBuilder' failed while processing the configuration section 'appSettings'.: The ConfigurationBuilder 'CustomBuilder[Microsoft.Configuration.ConfigurationBuilders.CustomConfigBuilder]' has recursively re-entered processing of the 'appSettings' section.<br><br>
```

After the fix (now merged) the tests pass

## Test coverage

This is primarily a smoke test, so we confirm
- The sites are running and responding to HTTP requests correctly
- We instrument the application (it has logs)
- There are no errors in the logs

## Other details

For some reason, I had massive issues getting the app to "recognize" the
`DD_TRACE_AGENT_URL=http://test-agent.windows:8126` env var setting
that's required to talk to the test agent. I have no idea why, and the
only resolution I could find was to use powershell to set the variables
inside the docker image

---------

Co-authored-by: Kevin Gosse <[email protected]>
  • Loading branch information
andrewlock and kevingosse authored Nov 4, 2024
1 parent bf5333d commit 64c02f7
Show file tree
Hide file tree
Showing 27 changed files with 2,025 additions and 1 deletion.
8 changes: 7 additions & 1 deletion .azure-pipelines/ultimate-pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2037,14 +2037,20 @@ stages:
- powershell: |
mkdir -Force ./artifacts/build_data/snapshots
mkdir -Force ./artifacts/build_data/logs/LoaderOptimizationStartup
mkdir -Force ./artifacts/build_data/logs/MultipleAppsInDomain
docker compose -f docker-compose.windows.yml run --rm start-test-agent.windows
docker compose -f docker-compose.windows.yml build `
--build-arg DOTNET_TRACER_MSI=.$(relativeMsiOutputDirectory)/*.msi `
--build-arg ENABLE_32_BIT=$(enable32bit) `
IntegrationTests.IIS.LoaderOptimizationStartup
docker compose -f docker-compose.windows.yml up -d IntegrationTests.IIS.LoaderOptimizationStartup
docker compose -f docker-compose.windows.yml build `
--build-arg DOTNET_TRACER_MSI=.$(relativeMsiOutputDirectory)/*.msi `
--build-arg ENABLE_32_BIT=$(enable32bit) `
IntegrationTests.IIS.MultipleAppsInDomain
docker compose -f docker-compose.windows.yml up -d IntegrationTests.IIS.LoaderOptimizationStartup IntegrationTests.IIS.MultipleAppsInDomain
displayName: docker-compose start IntegrationTests.IIS
retryCountOnTaskFailure: 5
env:
Expand Down
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ packages/
**/obj/

!tracer/test/test-applications/aspnet/Samples.AspNet472.LoaderOptimizationRegKey/bin/
!tracer/test/test-applications/aspnet/Samples.AspNet.MultipleAppsInDomain/bin/
!artifacts/msi/

!tracer/test/Datadog.Trace.TestHelpers/
Expand Down
7 changes: 7 additions & 0 deletions Datadog.Trace.sln
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Samples.AWS.EventBridge", "
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssemblyLoadContextResolve", "tracer\test\test-applications\regression\AssemblyLoadContextResolve\AssemblyLoadContextResolve.csproj", "{8B1AF6A7-DD41-4347-B637-90C23D69B50E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples.AspNet.MultipleAppsInDomain", "tracer\test\test-applications\aspnet\Samples.AspNet.MultipleAppsInDomain\Samples.AspNet.MultipleAppsInDomain.csproj", "{A82EB6F8-D8D0-4763-B252-08CA3F39D153}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -1421,6 +1423,10 @@ Global
{8B1AF6A7-DD41-4347-B637-90C23D69B50E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8B1AF6A7-DD41-4347-B637-90C23D69B50E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8B1AF6A7-DD41-4347-B637-90C23D69B50E}.Release|Any CPU.Build.0 = Release|Any CPU
{A82EB6F8-D8D0-4763-B252-08CA3F39D153}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A82EB6F8-D8D0-4763-B252-08CA3F39D153}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A82EB6F8-D8D0-4763-B252-08CA3F39D153}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A82EB6F8-D8D0-4763-B252-08CA3F39D153}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -1652,6 +1658,7 @@ Global
{E1B0F72C-991A-409D-9266-DE5ED1BD940E} = {A0C5FBBB-CFB2-4FB9-B8F0-55676E9DCF06}
{D6155F26-8245-4B66-8944-79C3DF9F9DA3} = {BAF8F246-3645-42AD-B1D0-0F7EAFBAB34A}
{8B1AF6A7-DD41-4347-B637-90C23D69B50E} = {498A300E-D036-49B7-A43D-821D1CAF11A5}
{A82EB6F8-D8D0-4763-B252-08CA3F39D153} = {AFA0AB23-64F0-4AC1-9050-6CE8FE06F580}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {160A1D00-1F5B-40F8-A155-621B4459D78F}
Expand Down
45 changes: 45 additions & 0 deletions docker-compose.windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,51 @@ services:
- DD_LOGGER_DD_TAGS
- IS_SSI_RUN

IntegrationTests.IIS.MultipleAppsInDomain:
build:
context: ./
args:
- ENABLE_32_BIT
- DOTNET_TRACER_MSI
dockerfile: ./tracer/build/_build/docker/iis.multipleappsindomain.dockerfile
image: datadog-iis-multipleappsindomain
volumes:
- ./artifacts/build_data/logs/MultipleAppsInDomain:c:/ProgramData/Datadog .NET Tracer/logs
ports:
- "8081:8081"
- "8082:8082"
depends_on:
- test-agent.windows
environment:
- DD_TRACE_AGENT_URL=http://test-agent.windows:8126
- DD_CLR_ENABLE_NGEN=${DD_CLR_ENABLE_NGEN:-1}
- DD_LOGGER_DD_API_KEY
- DD_LOGGER_DD_SERVICE
- DD_LOGGER_DD_ENV
- DD_LOGGER_ENABLED
- DD_LOGGER_TF_BUILD=${TF_BUILD:-}
- DD_LOGGER_BUILD_BUILDID
- DD_LOGGER_BUILD_DEFINITIONNAME
- DD_LOGGER_BUILD_SOURCESDIRECTORY
- DD_LOGGER_BUILD_REPOSITORY_URI
- DD_LOGGER_BUILD_SOURCEVERSION
- DD_LOGGER_BUILD_SOURCEBRANCH
- DD_LOGGER_BUILD_SOURCEBRANCHNAME
- DD_LOGGER_BUILD_SOURCEVERSIONMESSAGE
- DD_LOGGER_BUILD_REQUESTEDFORID
- DD_LOGGER_BUILD_REQUESTEDFOREMAIL
- DD_LOGGER_SYSTEM_TEAMFOUNDATIONSERVERURI
- DD_LOGGER_SYSTEM_TEAMPROJECTID
- DD_LOGGER_SYSTEM_STAGEDISPLAYNAME
- DD_LOGGER_SYSTEM_JOBDISPLAYNAME
- DD_LOGGER_SYSTEM_JOBID
- DD_LOGGER_SYSTEM_TASKINSTANCEID=${SYSTEM_TASKINSTANCEID:-}
- DD_LOGGER_SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI
- DD_LOGGER_SYSTEM_PULLREQUEST_SOURCECOMMITID
- DD_LOGGER_SYSTEM_PULLREQUEST_SOURCEBRANCH
- DD_LOGGER_DD_TAGS
- IS_SSI_RUN

smoke-tests.windows:
build:
context: ./tracer/ # have to use this as the context, as Dockercompose requires dockerfile to be inside context dir
Expand Down
34 changes: 34 additions & 0 deletions tracer/build/_build/docker/iis.multipleappsindomain.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
FROM mcr.microsoft.com/dotnet/framework/aspnet:4.8-windowsservercore-ltsc2022
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]

# Copy IIS websites
ADD tracer/test/test-applications/aspnet/Samples.AspNet.MultipleAppsInDomain/bin/Release/publish MultipleAppsInDomain

# Set up multiple apps in single domain with custom config IIS websites
ARG ENABLE_32_BIT
ENV ENABLE_32_BIT=${ENABLE_32_BIT:-false}

RUN c:\Windows\System32\inetsrv\appcmd add apppool /name:mutliAppPool /managedRuntimeVersion:"v4.0" /managedPipelineMode:"Integrated" /enable32bitapponwin64:$env:ENABLE_32_BIT

# The SetEnvironmentVariable() calls shouldn't _need_ to be here - we should be able to do it just
# using docker-compose, but I can't get that to work for some inexplicable reason, no matter
# what I do, so here we are.
RUN Remove-WebSite -Name 'Default Web Site'; \
Write-Host "Created app pool with 32 bit reg key: $env:ENABLE_32_BIT"; \
Write-Host "Creating multi app domain sites"; \
[System.Environment]::SetEnvironmentVariable('DD_TRACE_AGENT_URL', 'http://test-agent.windows:8126', [System.EnvironmentVariableTarget]::Machine); \
[System.Environment]::SetEnvironmentVariable('DD_TRACE_AGENT_URL', 'http://test-agent.windows:8126', [System.EnvironmentVariableTarget]::Process); \
[System.Environment]::SetEnvironmentVariable('DD_TRACE_AGENT_URL', 'http://test-agent.windows:8126', [System.EnvironmentVariableTarget]::User); \
New-Website -Name 'MultiAppPoolWithCustomConfig1' -ApplicationPool mutliAppPool -Port 8081 -PhysicalPath 'c:\MultipleAppsInDomain'; \
New-Website -Name 'MultiAppPoolWithCustomConfig2' -ApplicationPool mutliAppPool -Port 8082 -PhysicalPath 'c:\MultipleAppsInDomain';

# Install the .NET Tracer MSI
ARG DOTNET_TRACER_MSI
ADD $DOTNET_TRACER_MSI ./datadog-apm.msi
RUN Start-Process -Wait msiexec -ArgumentList '/qn /i datadog-apm.msi'

# Restart IIS
RUN net stop /y was; \
net start w3svc

EXPOSE 80
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// <copyright file="MultipleAppsInDomainWithCustomConfigBuilder.cs" company="Datadog">
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License.
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc.
// </copyright>

#if NETFRAMEWORK
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Datadog.Trace.Configuration.Telemetry;
using Datadog.Trace.Logging;
using FluentAssertions;
using Newtonsoft.Json;
using Xunit;
using Xunit.Abstractions;

namespace Datadog.Trace.ClrProfiler.IntegrationTests.IIS;

public class MultipleAppsInDomainWithCustomConfigBuilder(ITestOutputHelper output)
{
[SkippableFact]
[Trait("RunOnWindows", "True")]
[Trait("IIS", "True")]
[Trait("MSI", "True")]
public async Task ApplicationDoesNotReturnErrors()
{
const string App1Url = "http://localhost:8081";
const string App2Url = "http://localhost:8082";

var intervalMilliseconds = 500;
var intervals = 5;
var serverReady = false;
var client = new HttpClient()
{
Timeout = TimeSpan.FromSeconds(30), // yes, this is a long time, but we're running this in CI, in windows containers...
};

// wait for server to be ready to receive requests
while (intervals-- > 0)
{
try
{
output.WriteLine($"Sending warmup request to App 1 {App1Url}");
var serverReadyResponse = await client.GetAsync(App1Url);
serverReady = serverReadyResponse.StatusCode == HttpStatusCode.OK;
}
catch
{
// ignore
}

if (serverReady)
{
output.WriteLine("The server is ready.");
break;
}

Thread.Sleep(intervalMilliseconds);
}

// Send request to app 1
var responseMessage = await client.GetAsync(App1Url);
var response = await responseMessage.Content.ReadAsStringAsync();
output.WriteLine($"Received response from app1 at {App1Url}: {response}");
responseMessage.StatusCode.Should().Be(HttpStatusCode.OK);

var app1Result = JsonConvert.DeserializeObject<Results>(response);
app1Result.Pid.Should().NotBe(0);
app1Result.AppConfig.Should().ContainKey("DummyKey1").WhoseValue.Should().Be("DummyValue1 - from custom config");

// Send request to app 2
responseMessage = await client.GetAsync(App2Url);
response = await responseMessage.Content.ReadAsStringAsync();
output.WriteLine($"Received response from app2 at {App2Url}: {response}");
responseMessage.StatusCode.Should().Be(HttpStatusCode.OK);

var app2Result = JsonConvert.DeserializeObject<Results>(response);
app2Result.Pid.Should().Be(app1Result.Pid);
app2Result.AppConfig.Should().ContainKey("DummyKey1").WhoseValue.Should().Be("DummyValue1 - from custom config");

// verify we have some logs, so we know instrumentation happened
var logDirectory = Path.Combine(DatadogLoggingFactory.GetLogDirectory(NullConfigurationTelemetry.Instance), "MultipleAppsInDomain");
output.WriteLine($"Reading files from {logDirectory}");
Directory.GetFiles(logDirectory).Should().NotBeEmpty();
}

public class Results
{
public int Pid { get; set; }

public Dictionary<string, string> AppConfig { get; set; }
}
}
#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Web.Mvc;

namespace Samples.AspNet.MultipleAppsInDomain.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
var results = new Results();
results.Pid = Process.GetCurrentProcess().Id;
results.AppConfig = new Dictionary<string, string>();
foreach(var key in System.Configuration.ConfigurationManager.AppSettings.AllKeys)
{
results.AppConfig[key] = System.Configuration.ConfigurationManager.AppSettings[key];
}

return Json(results, JsonRequestBehavior.AllowGet);
}

public class Results
{
public int Pid { get; set; }
public Dictionary<string, string> AppConfig { get; set; }
}
}
}
Loading

0 comments on commit 64c02f7

Please sign in to comment.