Skip to content

Commit ffe504e

Browse files
authored
Merge branch 'master' into kr-igor/apms-17551-v2
2 parents fe285fe + 24c865f commit ffe504e

File tree

13 files changed

+253
-30
lines changed

13 files changed

+253
-30
lines changed

.azure-pipelines/ultimate-pipeline.yml

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -947,7 +947,7 @@ stages:
947947
timeoutInMinutes: 60 #default value
948948
dependsOn: [ ]
949949
pool:
950-
vmImage: macos-13
950+
vmImage: macos-14
951951
steps:
952952
- template: steps/clone-repo.yml
953953
parameters:
@@ -967,7 +967,7 @@ stages:
967967
timeoutInMinutes: 60 #default value
968968
dependsOn: [ ]
969969
pool:
970-
vmImage: macos-13
970+
vmImage: macos-14
971971
steps:
972972
- template: steps/clone-repo.yml
973973
parameters:
@@ -992,7 +992,7 @@ stages:
992992
timeoutInMinutes: 60 #default value
993993
dependsOn: [native_tracer, native_loader_and_managed ]
994994
pool:
995-
vmImage: macos-13
995+
vmImage: macos-14
996996
steps:
997997
- checkout: none
998998

@@ -1288,7 +1288,7 @@ stages:
12881288
timeoutInMinutes: 60 #default value
12891289
dependsOn: [ ]
12901290
pool:
1291-
vmImage: macos-13
1291+
vmImage: macos-14
12921292
steps:
12931293
- template: steps/clone-repo.yml
12941294
parameters:
@@ -1363,7 +1363,7 @@ stages:
13631363
$[stageDependencies.generate_variables.generate_variables_job.outputs['generate_variables_step.unit_tests_macos_matrix'] ]
13641364
timeoutInMinutes: 90
13651365
pool:
1366-
vmImage: macos-13
1366+
vmImage: macos-14
13671367
steps:
13681368
- template: steps/clone-repo.yml
13691369
parameters:
@@ -1619,7 +1619,7 @@ stages:
16191619
- job: macos
16201620
timeoutInMinutes: 60 #default value
16211621
pool:
1622-
vmImage: macos-13
1622+
vmImage: macos-14
16231623
steps:
16241624
- template: steps/clone-repo.yml
16251625
parameters:
@@ -1979,7 +1979,7 @@ stages:
19791979
timeoutInMinutes: 60 #default value
19801980
dependsOn: [ ]
19811981
pool:
1982-
vmImage: macos-13
1982+
vmImage: macos-14
19831983
steps:
19841984
- template: steps/clone-repo.yml
19851985
parameters:
@@ -2302,7 +2302,6 @@ stages:
23022302
variables:
23032303
TestAllPackageVersions: true
23042304
IncludeMinorPackageVersions: $[eq(variables.perform_comprehensive_testing, 'true')]
2305-
IntegrationTestFilter: DockerGroup=$(dockerGroup)
23062305

23072306
pool:
23082307
name: $(linuxX64Pool)
@@ -2319,6 +2318,14 @@ stages:
23192318
- template: steps/download-samples.yml
23202319
parameters:
23212320
framework: $(publishTargetFramework)
2321+
- bash: |
2322+
if [ -z "$(IntegrationTestFilter)" ]; then
2323+
newFilter="DockerGroup=$(dockerGroup)"
2324+
else
2325+
newFilter="$(IntegrationTestFilter)&(DockerGroup=$(dockerGroup))"
2326+
fi
2327+
echo "##vso[task.setvariable variable=IntegrationTestFilter]$newFilter"
2328+
displayName: "Calculate IntegrationTestFilter"
23222329
23232330
# when we build samples separately, we could run this step and the docker-compose one below in //
23242331
# (currently the docker-compose step relies on serverless samples)

tracer/build/_build/Build.VariableGenerations.cs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ void GenerateConditionVariableBasedOnGitChange(ChangedTeamValue changedTeamValue
107107
{
108108
var baseBranch = string.IsNullOrEmpty(TargetBranch) ? ReleaseBranchForCurrentVersion() : $"origin/{TargetBranch}";
109109
bool isChanged = false;
110-
var forceExplorationTestsWithVariableName = $"force_exploration_tests_with_{changedTeamValue.VariableName}";
110+
var forceExplorationTestsWithVariableName = $"force_run_tests_with_{changedTeamValue.VariableName}";
111111

112112
if (Environment.GetEnvironmentVariable("BUILD_REASON") == "Schedule" && bool.Parse(Environment.GetEnvironmentVariable("isMainBranch") ?? "false"))
113113
{
@@ -1782,16 +1782,13 @@ void GenerateMacosDotnetToolNugetSmokeTestsMatrix()
17821782
{
17831783
var images = new SmokeTestImage[]
17841784
{
1785-
// macos-11/12 environments are no longer available in Azure Devops
1786-
new (publishFramework: TargetFramework.NETCOREAPP3_1, "macos-13", "macos", "13"),
1787-
new (publishFramework: TargetFramework.NET5_0, "macos-13", "macos", "13"),
1788-
new (publishFramework: TargetFramework.NET6_0, "macos-13", "macos", "13"),
1789-
new (publishFramework: TargetFramework.NET7_0, "macos-13", "macos", "13"),
1790-
new (publishFramework: TargetFramework.NET8_0, "macos-13", "macos", "13"),
1791-
new (publishFramework: TargetFramework.NET9_0, "macos-13", "macos", "13"),
1785+
// macos-11/12/13 environments are no longer available in Azure Devops
17921786
new (publishFramework: TargetFramework.NETCOREAPP3_1, "macos-14", "macos", "14"),
1787+
new (publishFramework: TargetFramework.NET5_0, "macos-14", "macos", "14"),
17931788
new (publishFramework: TargetFramework.NET6_0, "macos-14", "macos", "14"),
1789+
new (publishFramework: TargetFramework.NET7_0, "macos-14", "macos", "14"),
17941790
new (publishFramework: TargetFramework.NET8_0, "macos-14", "macos", "14"),
1791+
new (publishFramework: TargetFramework.NET9_0, "macos-14", "macos", "14"),
17951792
new (publishFramework: TargetFramework.NET10_0, "macos-14", "macos-14_net10.0", "14"),
17961793
new (publishFramework: TargetFramework.NET6_0, "macos-15", "macos", "15"),
17971794
new (publishFramework: TargetFramework.NET8_0, "macos-15", "macos", "15"),

tracer/src/Datadog.Trace.Tools.dd_dotnet/CheckIisCommand.cs

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ internal static async Task<int> ExecuteAsync(string? siteAndApplicationName, str
133133

134134
try
135135
{
136-
appSettings = application.GetAppSettings();
136+
appSettings = application.GetAppSettings(siteName);
137137
}
138138
catch (Exception ex)
139139
{
@@ -231,6 +231,11 @@ internal static async Task<int> ExecuteAsync(string? siteAndApplicationName, str
231231
}
232232
}
233233

234+
if (!CheckApplicationConfiguration(application, siteName))
235+
{
236+
return 1;
237+
}
238+
234239
if (!GacCheck.Run())
235240
{
236241
return 1;
@@ -241,6 +246,38 @@ internal static async Task<int> ExecuteAsync(string? siteAndApplicationName, str
241246
return 0;
242247
}
243248

249+
internal static bool CheckApplicationConfiguration(Application application, string siteName)
250+
{
251+
AnsiConsole.WriteLine();
252+
AnsiConsole.WriteLine(SetupChecks);
253+
try
254+
{
255+
// When we're in partial trust, all our _current_ checks can sometimes succeed, even though
256+
// we never actually manage to load, so pre-check the web.config for potential issues.
257+
var partialTrustDetails = application.GetPartialTrustDetails(siteName);
258+
if (!string.Equals(partialTrustDetails.TrustLevel, "Full", StringComparison.OrdinalIgnoreCase))
259+
{
260+
Utils.WriteError(PartialTrustEnvironment(partialTrustDetails.TrustLevel));
261+
262+
return false;
263+
}
264+
265+
if (partialTrustDetails.IslegacyCasModel)
266+
{
267+
Utils.WriteError(LegacyCasEnabled());
268+
return false;
269+
}
270+
271+
Utils.WriteInfo(IisFullTrust);
272+
return true;
273+
}
274+
catch (Exception ex)
275+
{
276+
Utils.WriteError(ErrorReadingIisAppConfiguration(ex.Message));
277+
return false;
278+
}
279+
}
280+
244281
internal static void CheckAppPoolsEnvVars(ApplicationPool? pool, IisManager? serverManager)
245282
{
246283
var relevantProfilerConfiguration = new Dictionary<string, string>

tracer/src/Datadog.Trace.Tools.dd_dotnet/Checks/Resources.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ internal static class Resources
3333
public const string VersionConflict = "Tracer version 1.x can't be loaded simultaneously with other versions and will produce orphaned traces. Make sure to synchronize the Datadog.Trace NuGet version with the installed automatic instrumentation package version.";
3434
public const string IisExpressWorkerProcess = "Cannot detect the worker process when using IIS Express. Use the --workerProcess option to manually provide it.";
3535
public const string IisNotFound = "Could not find IIS. Make sure IIS is properly installed and enable, and run the tool from an elevated prompt.";
36+
public const string IisFullTrust = "IIS site is running in a full trust environment, without code access security (CAS).";
3637

3738
public const string TracingWithBundleProfilerPath = "Check failing with Datadog.Trace.Bundle Nuget, related documentation: https://docs.datadoghq.com/tracing/trace_collection/dd_libraries/dotnet-core/?tab=nuget#install-the-tracer";
3839
public const string TracingWithInstallerWindowsNetFramework = "Installer/MSI related documentation: https://docs.datadoghq.com/tracing/trace_collection/dd_libraries/dotnet-framework?tab=windows#install-the-tracer";
@@ -44,6 +45,7 @@ internal static class Resources
4445
public const string SetupChecks = "---- STARTING TRACER SETUP CHECKS -----";
4546
public const string ConfigurationChecks = "---- CONFIGURATION CHECKS -----";
4647
public const string DdAgentChecks = "---- DATADOG AGENT CHECKS -----";
48+
public const string IisChecks = "---- IIS CHECKS -----";
4749

4850
public const string ContinuousProfilerEnabled = "DD_PROFILING_ENABLED is set.";
4951
public const string ContinuousProfilerEnabledWithHeuristics = "DD_PROFILING_ENABLED is set to 'auto'. The continuous profiler is enabled and may begin profiling based on heuristics.";
@@ -124,6 +126,12 @@ internal static class Resources
124126

125127
public static string IisWorkerProcessError(string error) => $"Could not detect the worker process: {error} Note that you must run the tool from an elevated prompt.";
126128

129+
public static string ErrorReadingIisAppConfiguration(string error) => $"Could not extract configuration information for site: {error}";
130+
131+
public static string PartialTrustEnvironment(string trustLevel) => $"""IIS site is running in a partial trust environment, with level '{trustLevel}'. Partial trust environments are not supported. To enable Datadog, switch to Full trust by removing the system.web/trust node from your web.config, or set <trust level="Full" />. Note that this may change the security posture of your application.""";
132+
133+
public static string LegacyCasEnabled() => """IIS site is running with legacy code access security (CAS) enabled. Applications running with code access security are not supported. To enable Datadog, disable CAS policies by removing the system.web/trust node from your web.config, or set <trust legacyCasModel="false" />. Note that this may change the security posture of your application.""";
134+
127135
public static string ListAllIisApplications(IEnumerable<string> availableApplications)
128136
{
129137
var sb = new StringBuilder();

tracer/src/Datadog.Trace.Tools.dd_dotnet/Checks/Windows/IIS/Application.cs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,13 @@ public void Dispose()
8383
return null;
8484
}
8585

86-
public IReadOnlyDictionary<string, string> GetAppSettings()
86+
public IReadOnlyDictionary<string, string> GetAppSettings(string siteName)
8787
{
8888
var result = new Dictionary<string, string>();
8989

9090
using var configManager = _appHostAdminManager.GetConfigManager();
9191

92-
using var section = _appHostAdminManager.GetAdminSection("appSettings", $"MACHINE/WEBROOT/APPHOST{_application.GetStringProperty("path")}");
92+
using var section = _appHostAdminManager.GetAdminSection("appSettings", $"MACHINE/WEBROOT/APPHOST/{siteName}{_application.GetStringProperty("path")}");
9393

9494
using var collection = section.Collection();
9595
var count = collection.Count();
@@ -102,5 +102,37 @@ public IReadOnlyDictionary<string, string> GetAppSettings()
102102

103103
return result;
104104
}
105+
106+
public (string TrustLevel, bool IslegacyCasModel) GetPartialTrustDetails(string siteName)
107+
{
108+
// This is the "effective" version on the host - even if it doesn't have the settings
109+
// itself, it includes the values set on the parent web.configs
110+
// Note that we don't check <NetFx40_LegacySecurityPolicy>, as that doesn't apply to
111+
// aspnet apps as far as I can tell - legacyCasModel is what takes precedence.
112+
using var section = _appHostAdminManager.GetAdminSection("system.web/trust", $"MACHINE/WEBROOT/APPHOST/{siteName}{_application.GetStringProperty("path")}");
113+
114+
using var properties = section.Properties();
115+
var count = properties.Count();
116+
string? level = null;
117+
bool? isLegacyCasModel = null;
118+
for (var i = 0; i < count; i++)
119+
{
120+
using var prop = properties.GetProperty(i);
121+
var name = prop.Name();
122+
if (string.Equals(name, "level", StringComparison.OrdinalIgnoreCase))
123+
{
124+
level = prop.StringValue();
125+
}
126+
127+
if (string.Equals(name, "legacyCasModel", StringComparison.OrdinalIgnoreCase))
128+
{
129+
var legacyCasModel = prop.StringValue();
130+
isLegacyCasModel = bool.TryParse(legacyCasModel, out var isLegacyCase) && isLegacyCase;
131+
}
132+
}
133+
134+
// Default values are Full and False
135+
return (level ?? "Full", isLegacyCasModel ?? false);
136+
}
105137
}
106138
}

tracer/src/Datadog.Trace/LibDatadog/CString.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,22 @@ internal CString(string? str)
2828
{
2929
var encoding = StringEncoding.UTF8;
3030
var maxBytesCount = encoding.GetMaxByteCount(str.Length);
31-
Ptr = Marshal.AllocHGlobal(maxBytesCount);
31+
Ptr = Marshal.AllocHGlobal(maxBytesCount + 1); // Make space for null character.
3232
unsafe
3333
{
3434
fixed (char* strPtr = str)
3535
{
3636
try
3737
{
38-
Length = (nuint)encoding.GetBytes(strPtr, str.Length, (byte*)Ptr, maxBytesCount);
38+
int byteCount = encoding.GetBytes(strPtr, str.Length, (byte*)Ptr, maxBytesCount);
39+
((byte*)Ptr)[byteCount] = 0;
40+
Length = (nuint)byteCount;
3941
}
4042
catch
4143
{
4244
Marshal.FreeHGlobal(Ptr);
4345
Ptr = IntPtr.Zero;
46+
Length = UIntPtr.Zero;
4447
}
4548
}
4649
}

tracer/src/Datadog.Trace/Logging/Internal/ExceptionRedactor.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,17 @@ static void AddException(StringBuilder sb, Exception ex, bool isInnerException)
6161

6262
sb.Append(ex.GetType().FullName ?? "Unknown Exception");
6363

64-
if (ex.InnerException is { } inner)
64+
if (ex is AggregateException aex
65+
&& aex.Flatten() is { InnerExceptions: { Count: > 1 } exs })
66+
{
67+
// We don't specify the exact number so that we don't impact grouping
68+
sb.Append(" (Multiple Exceptions)");
69+
foreach (var aexInnerException in exs)
70+
{
71+
AddException(sb, aexInnerException, isInnerException: true);
72+
}
73+
}
74+
else if (ex.InnerException is { } inner)
6575
{
6676
AddException(sb, inner, isInnerException: true);
6777
}

tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/IisFixture.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ public sealed class IisFixture : GacFixture, IDisposable
2929

3030
public bool UseGac { get; set; } = true;
3131

32+
public bool UsePartialTrust { get; set; } = false;
33+
34+
public bool UseLegacyCasModel { get; set; } = false;
35+
3236
public async Task TryStartIis(TestHelper helper, IisAppType appType, bool sendHealthCheck = true, string url = "")
3337
{
3438
if (IisExpress.Process == null)
@@ -42,7 +46,7 @@ public async Task TryStartIis(TestHelper helper, IisAppType appType, bool sendHe
4246
Agent = MockTracerAgent.Create(null, initialAgentPort);
4347

4448
HttpPort = TcpPortProvider.GetOpenPort();
45-
IisExpress = await helper.StartIISExpress(Agent, HttpPort, appType, VirtualApplicationPath);
49+
IisExpress = await helper.StartIISExpress(Agent, HttpPort, appType, VirtualApplicationPath, UsePartialTrust, UseLegacyCasModel);
4650

4751
await EnsureServerStarted(sendHealthCheck, url);
4852
}

tracer/test/Datadog.Trace.TestHelpers.AutoInstrumentation/TestHelper.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,8 @@ public ProcessResult WaitForProcessResult(ProcessHelper helper, int expectedExit
214214
return new ProcessResult(process, standardOutput, standardError, exitCode);
215215
}
216216

217-
public async Task<(ProcessHelper Process, string ConfigFile)> StartIISExpress(MockTracerAgent agent, int iisPort, IisAppType appType, string subAppPath)
217+
public async Task<(ProcessHelper Process, string ConfigFile)> StartIISExpress(
218+
MockTracerAgent agent, int iisPort, IisAppType appType, string subAppPath, bool usePartialTrust, bool useLegacyCasModel)
218219
{
219220
var iisExpress = EnvironmentHelper.GetIisExpressPath();
220221

@@ -264,6 +265,20 @@ public ProcessResult WaitForProcessResult(ProcessHelper helper, int expectedExit
264265
.Replace("[HOSTING_MODEL]", hostingModel);
265266
}
266267

268+
if (usePartialTrust || useLegacyCasModel)
269+
{
270+
const string defaultTrust = "<trust />";
271+
var trust = (usePartialTrust, useLegacyCasModel) switch
272+
{
273+
(true, true) => """<trust level="High" legacyCasModel="true" />""",
274+
(true, false) => """<trust level="High" />""",
275+
(false, true) => """<trust level="Full" legacyCasModel="true" />""",
276+
_ => defaultTrust,
277+
};
278+
279+
configTemplate = configTemplate.Replace(defaultTrust, trust);
280+
}
281+
267282
File.WriteAllText(newConfig, configTemplate);
268283

269284
var args = new[]

tracer/test/Datadog.Trace.Tests/Debugger/SnapshotHelper.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
using System;
77
using System.IO;
8+
using Datadog.Trace.Configuration;
9+
using Datadog.Trace.Configuration.Telemetry;
810
using Datadog.Trace.Debugger;
911
using Datadog.Trace.Debugger.Expressions;
1012
using Datadog.Trace.Debugger.Snapshots;
@@ -14,6 +16,21 @@ namespace Datadog.Trace.Tests.Debugger;
1416

1517
internal static class SnapshotHelper
1618
{
19+
static SnapshotHelper()
20+
{
21+
// Configure the serializer with a high timeout for tests to prevent rare timeout failures on slow CI machines
22+
var testSettings = new DebuggerSettings(
23+
new NameValueConfigurationSource(new()
24+
{
25+
{
26+
ConfigurationKeys.Debugger.MaxTimeToSerialize, "1000"
27+
}
28+
}),
29+
NullConfigurationTelemetry.Instance);
30+
31+
DebuggerSnapshotSerializer.SetConfig(testSettings);
32+
}
33+
1734
internal static string GenerateSnapshot(object instance, bool prettify = true)
1835
{
1936
return GenerateSnapshot(null, new object[] { }, new object[] { instance }, prettify);

0 commit comments

Comments
 (0)