Skip to content

Commit 5026817

Browse files
authored
Add a test confirming that X509Certificate is trimmed (#48295)
* Add a test confirming that X509Certificate is trimmed ...when using `CreateSlimBuilder`. * Disable IsReflectionEnabledByDefault to eliminate warning * Switch to trimming tests ...since we're testing trimming behavior and add a test in the other direction (i.e. `UseHttps` does cause `X509Certificate` to be preserved). * Hack around the need for a certificate * Mitigate missing dev cert in a way that doesn't invalidate the test * Delay-build trimming test projects * Add copyright headers * Use negative exit codes in error scenarios * Simplify type lookup * Allow X509Certificate to be preserved if it has no members
1 parent 8aa4a52 commit 5026817

File tree

5 files changed

+102
-0
lines changed

5 files changed

+102
-0
lines changed

eng/RequiresDelayedBuildProjects.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
<ItemGroup>
1111
<RequiresDelayedBuild Include="$(RepoRoot)src\DataProtection\DataProtection\test\Microsoft.AspNetCore.DataProtection.TrimmingTests\Microsoft.AspNetCore.DataProtection.TrimmingTests.proj" />
1212
<RequiresDelayedBuild Include="$(RepoRoot)src\DefaultBuilder\test\Microsoft.AspNetCore.NativeAotTests\Microsoft.AspNetCore.NativeAotTests.proj" />
13+
<RequiresDelayedBuild Include="$(RepoRoot)src\DefaultBuilder\test\Microsoft.AspNetCore.TrimmingTests\Microsoft.AspNetCore.TrimmingTests.proj" />
1314
<RequiresDelayedBuild Include="$(RepoRoot)src\Grpc\JsonTranscoding\perf\Microsoft.AspNetCore.Grpc.Microbenchmarks\Microsoft.AspNetCore.Grpc.Microbenchmarks.csproj" />
1415
<RequiresDelayedBuild Include="$(RepoRoot)src\Grpc\JsonTranscoding\src\Microsoft.AspNetCore.Grpc.JsonTranscoding\Microsoft.AspNetCore.Grpc.JsonTranscoding.csproj" />
1516
<RequiresDelayedBuild Include="$(RepoRoot)src\Grpc\JsonTranscoding\src\Microsoft.AspNetCore.Grpc.Swagger\Microsoft.AspNetCore.Grpc.Swagger.csproj" />
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<ItemGroup>
4+
<TestConsoleAppSourceFiles Include="SlimBuilderDoesNotDependOnX509Test.cs">
5+
<DisabledFeatureSwitches>System.Text.Json.JsonSerializer.IsReflectionEnabledByDefault</DisabledFeatureSwitches>
6+
<AdditionalSourceFiles>X509Utilities.cs</AdditionalSourceFiles>
7+
</TestConsoleAppSourceFiles>
8+
<TestConsoleAppSourceFiles Include="UseHttpsDoesDependOnX509Test.cs">
9+
<DisabledFeatureSwitches>System.Text.Json.JsonSerializer.IsReflectionEnabledByDefault</DisabledFeatureSwitches>
10+
<AdditionalSourceFiles>X509Utilities.cs</AdditionalSourceFiles>
11+
</TestConsoleAppSourceFiles>
12+
</ItemGroup>
13+
14+
</Project>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using Microsoft.AspNetCore.Builder;
5+
6+
var builder = WebApplication.CreateSlimBuilder(args);
7+
var app = builder.Build();
8+
9+
if (X509Utilities.HasCertificateType)
10+
{
11+
return -1;
12+
}
13+
14+
return 100; // Success
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.Security.Cryptography.X509Certificates;
6+
using Microsoft.AspNetCore.Builder;
7+
using Microsoft.AspNetCore.Hosting;
8+
9+
var builder = WebApplication.CreateSlimBuilder(args);
10+
11+
builder.WebHost.UseKestrel(serverOptions =>
12+
{
13+
serverOptions.ListenLocalhost(5000, listenOptions =>
14+
{
15+
listenOptions.UseHttps();
16+
});
17+
});
18+
19+
try
20+
{
21+
_ = builder.Build();
22+
}
23+
catch (InvalidOperationException)
24+
{
25+
// Expected if there's no dev cert installed
26+
}
27+
28+
if (!X509Utilities.HasCertificateType)
29+
{
30+
return -1;
31+
}
32+
33+
return 100; // Success
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.Diagnostics.CodeAnalysis;
6+
using System.Linq;
7+
using System.Reflection;
8+
using Microsoft.AspNetCore.Builder;
9+
10+
#nullable enable
11+
12+
public static class X509Utilities
13+
{
14+
public static bool HasCertificateType
15+
{
16+
get
17+
{
18+
var certificateType = GetType("System.Security.Cryptography", "System.Security.Cryptography.X509Certificates.X509Certificate");
19+
20+
// We're checking for members, rather than just the presence of the type,
21+
// because Debugger Display types may reference it without actually
22+
// causing a meaningful binary size increase.
23+
return certificateType is not null && GetMembers(certificateType).Any();
24+
}
25+
}
26+
27+
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2057:UnrecognizedReflectionPattern",
28+
Justification = "Returning null when the type is unreferenced is desirable")]
29+
private static Type? GetType(string assemblyName, string typeName)
30+
{
31+
return Type.GetType($"{typeName}, {assemblyName}");
32+
}
33+
34+
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern",
35+
Justification = "Returning null when the type is unreferenced is desirable")]
36+
private static MemberInfo[] GetMembers(Type type)
37+
{
38+
return type.GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);
39+
}
40+
}

0 commit comments

Comments
 (0)