Skip to content

Commit

Permalink
Open experimentally Configuration and Logging (#4795)
Browse files Browse the repository at this point in the history
  • Loading branch information
Evangelink authored Jan 28, 2025
1 parent 8d9b9b3 commit 3c7787e
Show file tree
Hide file tree
Showing 18 changed files with 131 additions and 83 deletions.
2 changes: 2 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,8 @@ dotnet_diagnostic.VSTHRD002.severity = none # VSTHRD002 Avoid proble
dotnet_diagnostic.VSTHRD003.severity = none # VSTHRD003: Avoid awaiting foreign Tasks
dotnet_diagnostic.VSTHRD105.severity = none # VSTHRD105: Avoid method overloads that assume TaskScheduler.Current

dotnet_diagnostic.TPEXP.severity = none # TPEXP: Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.

#### Naming styles ####

## Naming rules (define naming rule using dotnet_naming_rule.<rule_name>.<option>)
Expand Down
5 changes: 0 additions & 5 deletions src/Platform/Microsoft.Testing.Platform/.editorconfig

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@

using Microsoft.Testing.Platform.Capabilities.TestFramework;
using Microsoft.Testing.Platform.CommandLine;
using Microsoft.Testing.Platform.Configurations;
using Microsoft.Testing.Platform.Extensions.TestFramework;
using Microsoft.Testing.Platform.Logging;
using Microsoft.Testing.Platform.TestHost;
using Microsoft.Testing.Platform.TestHostControllers;

Expand All @@ -29,6 +31,12 @@ public interface ITestApplicationBuilder
/// </summary>
ICommandLineManager CommandLine { get; }

[Experimental("TPEXP", UrlFormat = "https://aka.ms/testingplatform/diagnostics#{0}")]
IConfigurationManager Configuration { get; }

[Experimental("TPEXP", UrlFormat = "https://aka.ms/testingplatform/diagnostics#{0}")]
ILoggingManager Logging { get; }

/// <summary>
/// Registers a test framework with the application builder.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,11 @@ internal TestApplicationBuilder(

internal ITestHostOrchestratorManager TestHostOrchestrator => _testHostBuilder.TestHostOrchestratorManager;

internal IConfigurationManager Configuration => _testHostBuilder.Configuration;
[Experimental("TPEXP", UrlFormat = "https://aka.ms/testingplatform/diagnostics#{0}")]
public IConfigurationManager Configuration => _testHostBuilder.Configuration;

internal ILoggingManager Logging => _testHostBuilder.Logging;
[Experimental("TPEXP", UrlFormat = "https://aka.ms/testingplatform/diagnostics#{0}")]
public ILoggingManager Logging => _testHostBuilder.Logging;

internal IPlatformOutputDeviceManager OutputDisplay => _testHostBuilder.OutputDisplay;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,12 +148,12 @@ private static ValidationResult ValidateNoUnknownOptions(
Dictionary<ICommandLineOptionsProvider, IReadOnlyCollection<CommandLineOption>> systemOptionsByProvider)
{
StringBuilder? stringBuilder = null;
foreach (OptionRecord optionRecord in parseResult.Options)
foreach (CommandLineParseOption optionRecord in parseResult.Options)
{
if (!extensionOptionsByProvider.Union(systemOptionsByProvider).Any(tuple => tuple.Value.Any(x => x.Name == optionRecord.Option)))
if (!extensionOptionsByProvider.Union(systemOptionsByProvider).Any(tuple => tuple.Value.Any(x => x.Name == optionRecord.Name)))
{
stringBuilder ??= new();
stringBuilder.AppendLine(string.Format(CultureInfo.InvariantCulture, PlatformResources.CommandLineUnknownOption, optionRecord.Option));
stringBuilder.AppendLine(string.Format(CultureInfo.InvariantCulture, PlatformResources.CommandLineUnknownOption, optionRecord.Name));
}
}

Expand All @@ -167,11 +167,11 @@ private static ValidationResult ValidateOptionsArgumentArity(
Dictionary<string, (ICommandLineOptionsProvider Provider, CommandLineOption Option)> providerAndOptionByOptionName)
{
StringBuilder stringBuilder = new();
foreach (IGrouping<string, OptionRecord> groupedOptions in parseResult.Options.GroupBy(x => x.Option))
foreach (IGrouping<string, CommandLineParseOption> groupedOptions in parseResult.Options.GroupBy(x => x.Name))
{
// getting the arguments count for an option.
int arity = 0;
foreach (OptionRecord optionEntry in groupedOptions)
foreach (CommandLineParseOption optionEntry in groupedOptions)
{
arity += optionEntry.Arguments.Length;
}
Expand Down Expand Up @@ -205,14 +205,14 @@ private static async Task<ValidationResult> ValidateOptionsArgumentsAsync(
ApplicationStateGuard.Ensure(parseResult is not null);

StringBuilder? stringBuilder = null;
foreach (OptionRecord optionRecord in parseResult.Options)
foreach (CommandLineParseOption optionRecord in parseResult.Options)
{
(ICommandLineOptionsProvider provider, CommandLineOption option) = providerAndOptionByOptionName[optionRecord.Option];
(ICommandLineOptionsProvider provider, CommandLineOption option) = providerAndOptionByOptionName[optionRecord.Name];
ValidationResult result = await provider.ValidateOptionArgumentsAsync(option, optionRecord.Arguments);
if (!result.IsValid)
{
stringBuilder ??= new();
stringBuilder.AppendLine(string.Format(CultureInfo.InvariantCulture, PlatformResources.CommandLineInvalidArgumentsForOption, optionRecord.Option, result.ErrorMessage));
stringBuilder.AppendLine(string.Format(CultureInfo.InvariantCulture, PlatformResources.CommandLineInvalidArgumentsForOption, optionRecord.Name, result.ErrorMessage));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@

namespace Microsoft.Testing.Platform.CommandLine;

internal sealed class OptionRecord(string option, string[] arguments)
[Experimental("TPEXP", UrlFormat = "https://aka.ms/testingplatform/diagnostics#{0}")]
public sealed class CommandLineParseOption(string name, string[] arguments)
{
public string Option { get; } = option;
public string Name { get; } = name;

public string[] Arguments { get; } = arguments;
}
26 changes: 14 additions & 12 deletions src/Platform/Microsoft.Testing.Platform/CommandLine/ParseResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@

namespace Microsoft.Testing.Platform.CommandLine;

internal sealed class CommandLineParseResult(string? toolName, IReadOnlyList<OptionRecord> options, IReadOnlyList<string> errors) : IEquatable<CommandLineParseResult>
[Experimental("TPEXP", UrlFormat = "https://aka.ms/testingplatform/diagnostics#{0}")]
public sealed class CommandLineParseResult(string? toolName, IReadOnlyList<CommandLineParseOption> options, IReadOnlyList<string> errors) : IEquatable<CommandLineParseResult>
{
public const char OptionPrefix = '-';

public static CommandLineParseResult Empty => new(null, [], []);

public string? ToolName { get; } = toolName;

public IReadOnlyList<OptionRecord> Options { get; } = options;
public IReadOnlyList<CommandLineParseOption> Options { get; } = options;

public IReadOnlyList<string> Errors { get; } = errors;

Expand Down Expand Up @@ -54,11 +55,11 @@ public bool Equals(CommandLineParseResult? other)
return false;
}

IReadOnlyList<OptionRecord> thisOptions = Options;
IReadOnlyList<OptionRecord> otherOptions = other.Options;
IReadOnlyList<CommandLineParseOption> thisOptions = Options;
IReadOnlyList<CommandLineParseOption> otherOptions = other.Options;
for (int i = 0; i < thisOptions.Count; i++)
{
if (thisOptions[i].Option != otherOptions[i].Option)
if (thisOptions[i].Name != otherOptions[i].Name)
{
return false;
}
Expand All @@ -81,12 +82,12 @@ public bool Equals(CommandLineParseResult? other)
}

public bool IsOptionSet(string optionName)
=> Options.Any(o => o.Option.Equals(optionName.Trim(OptionPrefix), StringComparison.OrdinalIgnoreCase));
=> Options.Any(o => o.Name.Equals(optionName.Trim(OptionPrefix), StringComparison.OrdinalIgnoreCase));

public bool TryGetOptionArgumentList(string optionName, [NotNullWhen(true)] out string[]? arguments)
{
optionName = optionName.Trim(OptionPrefix);
IEnumerable<OptionRecord> result = Options.Where(x => x.Option == optionName);
IEnumerable<CommandLineParseOption> result = Options.Where(x => x.Name == optionName);
if (result.Any())
{
arguments = result.SelectMany(x => x.Arguments).ToArray();
Expand All @@ -97,14 +98,15 @@ public bool TryGetOptionArgumentList(string optionName, [NotNullWhen(true)] out
return false;
}

public override bool Equals(object? obj) => Equals(obj as CommandLineParseResult);
public override bool Equals(object? obj)
=> Equals(obj as CommandLineParseResult);

public override int GetHashCode()
{
HashCode hashCode = default;
foreach (OptionRecord option in Options)
foreach (CommandLineParseOption option in Options)
{
hashCode.Add(option.Option);
hashCode.Add(option.Name);
foreach (string value in option.Arguments)
{
hashCode.Add(value);
Expand Down Expand Up @@ -144,9 +146,9 @@ public override string ToString()
}
else
{
foreach (OptionRecord option in Options)
foreach (CommandLineParseOption option in Options)
{
builder.AppendLine(CultureInfo.InvariantCulture, $" {option.Option}");
builder.AppendLine(CultureInfo.InvariantCulture, $" {option.Name}");
foreach (string arg in option.Arguments)
{
builder.AppendLine(CultureInfo.InvariantCulture, $" {arg}");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public static CommandLineParseResult Parse(string[] args, IEnvironment environme

private static CommandLineParseResult Parse(List<string> args, IEnvironment environment)
{
List<OptionRecord> options = [];
List<CommandLineParseOption> options = [];
List<string> errors = [];

string? currentOption = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@

namespace Microsoft.Testing.Platform.Configurations;

internal interface IConfigurationManager
[Experimental("TPEXP", UrlFormat = "https://aka.ms/testingplatform/diagnostics#{0}")]
public interface IConfigurationManager
{
void AddConfigurationSource(Func<IConfigurationSource> source);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@

namespace Microsoft.Testing.Platform.Configurations;

internal interface IConfigurationProvider
[Experimental("TPEXP", UrlFormat = "https://aka.ms/testingplatform/diagnostics#{0}")]
public interface IConfigurationProvider
{
Task LoadAsync();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

namespace Microsoft.Testing.Platform.Configurations;

internal interface IConfigurationSource : IExtension
[Experimental("TPEXP", UrlFormat = "https://aka.ms/testingplatform/diagnostics#{0}")]
public interface IConfigurationSource : IExtension
{
int Order { get; }

Expand Down
18 changes: 9 additions & 9 deletions src/Platform/Microsoft.Testing.Platform/Hosts/ToolsTestHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,13 @@ private bool UnknownOptions([NotNullWhen(true)] out string? error, ITool tool)
}

StringBuilder stringBuilder = new();
foreach (OptionRecord optionRecord in _commandLineHandler.ParseResult.Options)
foreach (CommandLineParseOption optionRecord in _commandLineHandler.ParseResult.Options)
{
if (!GetAllCommandLineOptionsProviderByOptionName(optionRecord.Option).Any())
if (!GetAllCommandLineOptionsProviderByOptionName(optionRecord.Name).Any())
{
stringBuilder.AppendLine(
CultureInfo.InvariantCulture,
$"Unknown option '{optionRecord.Option}' for tool '{tool.DisplayName}'.");
$"Unknown option '{optionRecord.Name}' for tool '{tool.DisplayName}'.");
}
}

Expand All @@ -122,7 +122,7 @@ private bool ExtensionArgumentArityAreInvalid([NotNullWhen(true)] out string? er
error = null;

StringBuilder stringBuilder = new();
foreach (IGrouping<string, OptionRecord> optionRecord in _commandLineHandler.ParseResult.Options.GroupBy(x => x.Option))
foreach (IGrouping<string, CommandLineParseOption> optionRecord in _commandLineHandler.ParseResult.Options.GroupBy(x => x.Name))
{
string optionName = optionRecord.Key;
int arity = optionRecord.Count();
Expand All @@ -140,7 +140,7 @@ private bool ExtensionArgumentArityAreInvalid([NotNullWhen(true)] out string? er
{
foreach (CommandLineOption option in extension.GetCommandLineOptions())
{
if (_commandLineHandler.ParseResult.Options.Count(x => x.Option == option.Name) < option.Arity.Min)
if (_commandLineHandler.ParseResult.Options.Count(x => x.Name == option.Name) < option.Arity.Min)
{
stringBuilder.AppendLine(
CultureInfo.InvariantCulture,
Expand All @@ -161,13 +161,13 @@ private bool ExtensionArgumentArityAreInvalid([NotNullWhen(true)] out string? er
private async Task<ValidationResult> ValidateOptionsArgumentsAsync(ITool tool)
{
StringBuilder stringBuilder = new();
foreach (OptionRecord optionRecord in _commandLineHandler.ParseResult.Options)
foreach (CommandLineParseOption optionRecord in _commandLineHandler.ParseResult.Options)
{
ICommandLineOptionsProvider extension = GetAllCommandLineOptionsProviderByOptionName(optionRecord.Option).Single();
ValidationResult result = await extension.ValidateOptionArgumentsAsync(extension.GetCommandLineOptions().Single(x => x.Name == optionRecord.Option), optionRecord.Arguments);
ICommandLineOptionsProvider extension = GetAllCommandLineOptionsProviderByOptionName(optionRecord.Name).Single();
ValidationResult result = await extension.ValidateOptionArgumentsAsync(extension.GetCommandLineOptions().Single(x => x.Name == optionRecord.Name), optionRecord.Arguments);
if (!result.IsValid)
{
stringBuilder.AppendLine(CultureInfo.InvariantCulture, $"Invalid arguments for option '--{optionRecord.Option}': {result.ErrorMessage}, tool {tool.DisplayName}");
stringBuilder.AppendLine(CultureInfo.InvariantCulture, $"Invalid arguments for option '--{optionRecord.Name}': {result.ErrorMessage}, tool {tool.DisplayName}");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@

namespace Microsoft.Testing.Platform.Logging;

internal interface ILoggerProvider
[Experimental("TPEXP", UrlFormat = "https://aka.ms/testingplatform/diagnostics#{0}")]
public interface ILoggerProvider
{
ILogger CreateLogger(string categoryName);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@

namespace Microsoft.Testing.Platform.Logging;

internal interface ILoggingManager
[Experimental("TPEXP", UrlFormat = "https://aka.ms/testingplatform/diagnostics#{0}")]
public interface ILoggingManager
{
void AddProvider(Func<LogLevel, IServiceProvider, ILoggerProvider> loggerProviderFactory);
}
Original file line number Diff line number Diff line change
@@ -1 +1,34 @@
#nullable enable
Microsoft.Testing.Platform.Builder.ITestApplicationBuilder.Configuration.get -> Microsoft.Testing.Platform.Configurations.IConfigurationManager!
Microsoft.Testing.Platform.Builder.ITestApplicationBuilder.Logging.get -> Microsoft.Testing.Platform.Logging.ILoggingManager!
[TPEXP]const Microsoft.Testing.Platform.CommandLine.CommandLineParseResult.OptionPrefix = '-' -> char
[TPEXP]Microsoft.Testing.Platform.CommandLine.CommandLineParseOption
[TPEXP]Microsoft.Testing.Platform.CommandLine.CommandLineParseOption.Arguments.get -> string![]!
[TPEXP]Microsoft.Testing.Platform.CommandLine.CommandLineParseOption.CommandLineParseOption(string! name, string![]! arguments) -> void
[TPEXP]Microsoft.Testing.Platform.CommandLine.CommandLineParseOption.Name.get -> string!
[TPEXP]Microsoft.Testing.Platform.CommandLine.CommandLineParseResult
[TPEXP]Microsoft.Testing.Platform.CommandLine.CommandLineParseResult.CommandLineParseResult(string? toolName, System.Collections.Generic.IReadOnlyList<Microsoft.Testing.Platform.CommandLine.CommandLineParseOption!>! options, System.Collections.Generic.IReadOnlyList<string!>! errors) -> void
[TPEXP]Microsoft.Testing.Platform.CommandLine.CommandLineParseResult.Equals(Microsoft.Testing.Platform.CommandLine.CommandLineParseResult? other) -> bool
[TPEXP]Microsoft.Testing.Platform.CommandLine.CommandLineParseResult.Errors.get -> System.Collections.Generic.IReadOnlyList<string!>!
[TPEXP]Microsoft.Testing.Platform.CommandLine.CommandLineParseResult.HasError.get -> bool
[TPEXP]Microsoft.Testing.Platform.CommandLine.CommandLineParseResult.HasTool.get -> bool
[TPEXP]Microsoft.Testing.Platform.CommandLine.CommandLineParseResult.IsOptionSet(string! optionName) -> bool
[TPEXP]Microsoft.Testing.Platform.CommandLine.CommandLineParseResult.Options.get -> System.Collections.Generic.IReadOnlyList<Microsoft.Testing.Platform.CommandLine.CommandLineParseOption!>!
[TPEXP]Microsoft.Testing.Platform.CommandLine.CommandLineParseResult.ToolName.get -> string?
[TPEXP]Microsoft.Testing.Platform.CommandLine.CommandLineParseResult.TryGetOptionArgumentList(string! optionName, out string![]? arguments) -> bool
[TPEXP]Microsoft.Testing.Platform.Configurations.IConfigurationManager
[TPEXP]Microsoft.Testing.Platform.Configurations.IConfigurationManager.AddConfigurationSource(System.Func<Microsoft.Testing.Platform.Configurations.IConfigurationSource!>! source) -> void
[TPEXP]Microsoft.Testing.Platform.Configurations.IConfigurationProvider
[TPEXP]Microsoft.Testing.Platform.Configurations.IConfigurationProvider.LoadAsync() -> System.Threading.Tasks.Task!
[TPEXP]Microsoft.Testing.Platform.Configurations.IConfigurationProvider.TryGet(string! key, out string? value) -> bool
[TPEXP]Microsoft.Testing.Platform.Configurations.IConfigurationSource
[TPEXP]Microsoft.Testing.Platform.Configurations.IConfigurationSource.BuildAsync(Microsoft.Testing.Platform.CommandLine.CommandLineParseResult! commandLineParseResult) -> System.Threading.Tasks.Task<Microsoft.Testing.Platform.Configurations.IConfigurationProvider!>!
[TPEXP]Microsoft.Testing.Platform.Configurations.IConfigurationSource.Order.get -> int
[TPEXP]Microsoft.Testing.Platform.Logging.ILoggerProvider
[TPEXP]Microsoft.Testing.Platform.Logging.ILoggerProvider.CreateLogger(string! categoryName) -> Microsoft.Testing.Platform.Logging.ILogger!
[TPEXP]Microsoft.Testing.Platform.Logging.ILoggingManager
[TPEXP]Microsoft.Testing.Platform.Logging.ILoggingManager.AddProvider(System.Func<Microsoft.Testing.Platform.Logging.LogLevel, System.IServiceProvider!, Microsoft.Testing.Platform.Logging.ILoggerProvider!>! loggerProviderFactory) -> void
[TPEXP]override Microsoft.Testing.Platform.CommandLine.CommandLineParseResult.Equals(object? obj) -> bool
[TPEXP]override Microsoft.Testing.Platform.CommandLine.CommandLineParseResult.GetHashCode() -> int
[TPEXP]override Microsoft.Testing.Platform.CommandLine.CommandLineParseResult.ToString() -> string!
[TPEXP]static Microsoft.Testing.Platform.CommandLine.CommandLineParseResult.Empty.get -> Microsoft.Testing.Platform.CommandLine.CommandLineParseResult!
Original file line number Diff line number Diff line change
Expand Up @@ -249,9 +249,9 @@ public void IsVersionInvoked_VersionOptionSet_ReturnsTrue()
public void GetOptionValue_OptionExists_ReturnsOptionValue()
{
// Arrange
OptionRecord optionRecord = new("name", ["value1", "value2"]);
CommandLineParseOption option = new("name", ["value1", "value2"]);
CommandLineHandler commandLineHandler = new(
new CommandLineParseResult(string.Empty, [optionRecord], []), _extensionCommandLineOptionsProviders,
new CommandLineParseResult(string.Empty, [option], []), _extensionCommandLineOptionsProviders,
_systemCommandLineOptionsProviders, _testApplicationModuleInfoMock.Object, _runtimeFeatureMock.Object);

// Act
Expand Down
Loading

0 comments on commit 3c7787e

Please sign in to comment.