Skip to content

Commit d1f05d2

Browse files
committed
Begin mapping collection rules
Ensure generated type info is passed through for ActionListExecutor testcase
1 parent 771d2f2 commit d1f05d2

File tree

6 files changed

+79
-3
lines changed

6 files changed

+79
-3
lines changed

src/Tests/CollectionRuleActions.UnitTests/ActionListExecutorTests.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using Microsoft.AspNetCore.Http.Validation;
45
using Microsoft.Diagnostics.Monitoring.TestCommon;
56
using Microsoft.Diagnostics.Monitoring.TestCommon.Options;
67
using Microsoft.Diagnostics.Tools.Monitor;
@@ -128,7 +129,7 @@ public Task ActionListExecutor_FirstActionFail_DeferredCompletion()
128129
return ActionListExecutor_FirstActionFail(waitForCompletion: false);
129130
}
130131

131-
[Fact]
132+
[Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/61379")]
132133
public Task ActionListExecutor_FirstActionFail_WaitedCompletion()
133134
{
134135
return ActionListExecutor_FirstActionFail(waitForCompletion: true);
@@ -165,6 +166,9 @@ await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions =>
165166
Assert.Equal(string.Format(Strings.ErrorMessage_NonzeroExitCode, "1"), actionExecutionException.Message);
166167

167168
VerifyStartCallbackCount(waitForCompletion, callbackCount);
169+
}, services =>
170+
{
171+
services.AddValidation();
168172
});
169173
}
170174

src/Tests/CollectionRuleActions.UnitTests/CollectionRuleActions.UnitTests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
<PropertyGroup>
44
<TargetFrameworks>$(ToolTargetFrameworks)</TargetFrameworks>
5+
<InterceptorsNamespaces>$(InterceptorsNamespaces);Microsoft.AspNetCore.Http.Validation.Generated</InterceptorsNamespaces>
56
</PropertyGroup>
67

78
<ItemGroup>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
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.Http.Validation;
5+
using Microsoft.Diagnostics.Monitoring.WebApi;
6+
using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options;
7+
using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options.Actions;
8+
9+
namespace Microsoft.Diagnostics.Tools.Monitor
10+
{
11+
// The Validation source generator doesn't run for libraries that don't call AddValidation,
12+
// so we can't generate IValidatableInfo by using [ValidatableType] directly on types defined
13+
// in ProjectReferences. This is a workaround to force the generator running in this project to
14+
// generate IValidatableInfo for the referenced types. The containing class is not used otherwise.
15+
[ValidatableType]
16+
internal class TestValidatableTypes
17+
{
18+
public required CollectionRuleOptions CollectionRuleOptions { get; init; }
19+
20+
public required ExecuteOptions ExecuteOptions { get; init; }
21+
}
22+
}

src/Tools/dotnet-monitor/CollectionRules/Options/ValidationHelper.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ public static bool TryValidateObject(object options, Type type, ValidationOption
8282
var validateContext = new ValidateContext()
8383
{
8484
ValidationOptions = validationOptions,
85-
ValidationContext = new(options, validationContext.MemberName, null, items: null)
85+
ValidationContext = validationContext
8686
};
8787
validatableTypeInfo.ValidateAsync(options, validateContext, CancellationToken.None).GetAwaiter().GetResult();
8888
if (validateContext.ValidationErrors is Dictionary<string, string[]> validationErrors)

src/Tools/dotnet-monitor/CommonOptionsExtensions.cs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using Microsoft.Diagnostics.Monitoring.TestCommon;
88
#endif
99
using Microsoft.Diagnostics.Monitoring.WebApi;
10+
using Microsoft.Diagnostics.Tools.Monitor.CollectionRules.Options;
1011
using Microsoft.Extensions.Configuration;
1112
using System;
1213
using System.Collections.Generic;
@@ -95,6 +96,7 @@ private static void MapRootOptions(RootOptions obj, string prefix, string separa
9596
{
9697
// TODO: in Tests, it has an additional property. Weird.
9798
MapAuthenticationOptions(obj.Authentication, FormattableString.Invariant($"{prefix}{nameof(obj.Authentication)}"), separator, map);
99+
MapCollectionRules(obj.CollectionRules, FormattableString.Invariant($"{prefix}{nameof(obj.CollectionRules)}"), separator, map);
98100
// GlobalCounterOptions
99101
MapGlobalCounterOptions(obj.GlobalCounter, FormattableString.Invariant($"{prefix}{nameof(obj.GlobalCounter)}"), separator, map);
100102
// InProcessFeaturesOptions
@@ -126,6 +128,49 @@ private static void MapRootOptions(RootOptions obj, string prefix, string separa
126128
// }
127129
// }
128130

131+
private static void MapCollectionRules(IDictionary<string, CollectionRuleOptions>? obj, string valueName, string separator, IDictionary<string, string> map)
132+
{
133+
if (null != obj)
134+
{
135+
System.Console.WriteLine("MapCollectionRules");
136+
var prefix = FormattableString.Invariant($"{valueName}{separator}"); // passed to mapdictionary.
137+
foreach ((string key, CollectionRuleOptions value) in obj)
138+
{
139+
string keyString = ConvertUtils.ToString(key, CultureInfo.InvariantCulture);
140+
System.Console.WriteLine($"key: {keyString}");
141+
MapCollectionRuleOptions(value, FormattableString.Invariant($"{prefix}{keyString}"), separator, map);
142+
}
143+
}
144+
}
145+
146+
private static void MapCollectionRuleOptions(CollectionRuleOptions obj, string valueName, string separator, IDictionary<string, string> map)
147+
{
148+
string prefix = FormattableString.Invariant($"{valueName}{separator}");
149+
// MapFilters(obj.Filters, FormattableString.Invariant($"{prefix}{nameof(obj.Filters)}"), separator, map);
150+
// MapTrigger(obj.Trigger, FormattableString.Invariant($"{prefix}{nameof(obj.Trigger)}"), separator, map);
151+
MapActions(obj.Actions, FormattableString.Invariant($"{prefix}{nameof(obj.Actions)}"), separator, map);
152+
// MapLimits(obj.Limits, FormattableString.Invariant($"{prefix}{nameof(obj.Limits)}"), separator, map);
153+
}
154+
155+
private static void MapActions(List<CollectionRuleActionOptions> obj, string valueName, string separator, IDictionary<string, string> map)
156+
{
157+
string prefix = FormattableString.Invariant($"{valueName}{separator}");
158+
for (int index = 0; index < obj.Count; index++)
159+
{
160+
CollectionRuleActionOptions value = obj[index];
161+
MapCollectionRuleActionOptions(value, FormattableString.Invariant($"{prefix}{index}"), separator, map);
162+
}
163+
}
164+
165+
private static void MapCollectionRuleActionOptions(CollectionRuleActionOptions obj, string valueName, string separator, IDictionary<string, string> map)
166+
{
167+
string prefix = FormattableString.Invariant($"{valueName}{separator}");
168+
MapString(obj.Name, FormattableString.Invariant($"{prefix}{nameof(obj.Name)}"), map);
169+
MapString(obj.Type, FormattableString.Invariant($"{prefix}{nameof(obj.Type)}"), map);
170+
// TODO: map object Settings
171+
MapBool(obj.WaitForCompletion, FormattableString.Invariant($"{prefix}{nameof(obj.WaitForCompletion)}"), map);
172+
}
173+
129174
private static void MapAuthenticationOptions(AuthenticationOptions? obj, string valueName, string separator, IDictionary<string, string> map)
130175
{
131176
if (null != obj)

src/Tools/dotnet-monitor/DataAnnotationValidateOptions.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,11 @@ public DataAnnotationValidateOptions(IServiceProvider serviceProvider)
3535
public ValidateOptionsResult Validate(string? name, TOptions options)
3636
{
3737
var results = new List<ValidationResult>();
38-
if (!ValidationHelper.TryValidateObject(options, typeof(TOptions), _validationOptions, results))
38+
var typeName = typeof(TOptions).Name;
39+
var validationContext = new ValidationContext(options, typeName, _serviceProvider, items: null) {
40+
MemberName = typeName
41+
};
42+
if (!ValidationHelper.TryValidateObject(options, typeof(TOptions), _validationOptions, validationContext, results))
3943
{
4044
IList<string> failures = new List<string>();
4145
foreach (ValidationResult result in results)

0 commit comments

Comments
 (0)