Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support runsettings environment variables #3918

Merged
merged 8 commits into from
Oct 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public static void AddMSTest(this ITestApplicationBuilder testApplicationBuilder
testApplicationBuilder.AddRunSettingsService(extension);
testApplicationBuilder.AddTestCaseFilterService(extension);
testApplicationBuilder.AddTestRunParametersService(extension);
testApplicationBuilder.AddRunSettingsEnvironmentVariableProvider(extension);
testApplicationBuilder.RegisterTestFramework(
serviceProvider => new TestFrameworkCapabilities(
new VSTestBridgeExtensionBaseCapabilities(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@

using Microsoft.Testing.Extensions.VSTestBridge.CommandLine;
using Microsoft.Testing.Extensions.VSTestBridge.Configurations;
using Microsoft.Testing.Extensions.VSTestBridge.TestHostControllers;
using Microsoft.Testing.Platform.Builder;
using Microsoft.Testing.Platform.Extensions;
using Microsoft.Testing.Platform.Helpers;
using Microsoft.Testing.Platform.Services;

namespace Microsoft.Testing.Extensions.VSTestBridge.Helpers;

Expand Down Expand Up @@ -44,4 +46,13 @@ public static void AddRunSettingsService(this ITestApplicationBuilder builder, I
/// <param name="extension">The extension that will be used as the source of registration for this helper service.</param>
public static void AddTestRunParametersService(this ITestApplicationBuilder builder, IExtension extension)
=> builder.CommandLine.AddProvider(() => new TestRunParametersCommandLineOptionsProvider(extension));

/// <summary>
/// Register the environment variable provider.
/// </summary>
/// <param name="builder">The test application builder.</param>
/// <param name="extension">The extension that will be used as the source of registration for this helper service.</param>
public static void AddRunSettingsEnvironmentVariableProvider(this ITestApplicationBuilder builder, IExtension extension)
=> builder.TestHostControllers.AddEnvironmentVariableProvider(serviceProvider
=> new RunSettingsEnvironmentVariableProvider(extension, serviceProvider.GetCommandLineOptions(), serviceProvider.GetFileSystem()));
}
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
#nullable enable
static Microsoft.Testing.Extensions.VSTestBridge.Helpers.TestApplicationBuilderExtensions.AddRunSettingsEnvironmentVariableProvider(this Microsoft.Testing.Platform.Builder.ITestApplicationBuilder! builder, Microsoft.Testing.Platform.Extensions.IExtension! extension) -> void
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.Xml.Linq;

using Microsoft.Testing.Extensions.VSTestBridge.CommandLine;
using Microsoft.Testing.Platform.CommandLine;
using Microsoft.Testing.Platform.Extensions;
using Microsoft.Testing.Platform.Extensions.TestHostControllers;
using Microsoft.Testing.Platform.Helpers;

namespace Microsoft.Testing.Extensions.VSTestBridge.TestHostControllers;

internal sealed class RunSettingsEnvironmentVariableProvider : ITestHostEnvironmentVariableProvider
{
private readonly IExtension _extension;
private readonly ICommandLineOptions _commandLineOptions;
private readonly IFileSystem _fileSystem;
private XDocument? _runSettings;

public RunSettingsEnvironmentVariableProvider(IExtension extension, ICommandLineOptions commandLineOptions, IFileSystem fileSystem)
{
_extension = extension;
_commandLineOptions = commandLineOptions;
_fileSystem = fileSystem;
}

public string Uid => _extension.Uid;

public string Version => _extension.Version;

public string DisplayName => _extension.DisplayName;

public string Description => _extension.Description;

public async Task<bool> IsEnabledAsync()
{
if (!_commandLineOptions.TryGetOptionArgumentList(RunSettingsCommandLineOptionsProvider.RunSettingsOptionName, out string[]? runsettings))
{
return false;
}

if (!_fileSystem.Exists(runsettings[0]))
{
return false;
}

using IFileStream fileStream = _fileSystem.NewFileStream(runsettings[0], FileMode.Open, FileAccess.Read);
#if NETCOREAPP
_runSettings = await XDocument.LoadAsync(fileStream.Stream, LoadOptions.None, CancellationToken.None);
#else
using StreamReader streamReader = new(fileStream.Stream);
_runSettings = XDocument.Parse(await streamReader.ReadToEndAsync());
#endif
return _runSettings.Element("RunSettings")?.Element("RunConfiguration")?.Element("EnvironmentVariables") is not null;
}

public Task UpdateAsync(IEnvironmentVariables environmentVariables)
{
foreach (XElement element in _runSettings!.Element("RunSettings")!.Element("RunConfiguration")!.Element("EnvironmentVariables")!.Elements())
{
environmentVariables.SetVariable(new(element.Name.ToString(), element.Value, true, true));
}

return Task.CompletedTask;
}

public Task<ValidationResult> ValidateTestHostEnvironmentVariablesAsync(IReadOnlyEnvironmentVariables environmentVariables)
=> ValidationResult.ValidTask;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.Runtime.InteropServices;

using Microsoft.Testing.Platform.Acceptance.IntegrationTests;
using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers;

Expand All @@ -14,9 +16,21 @@ public sealed class RunSettingsTests : AcceptanceTestBase
public RunSettingsTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture)
: base(testExecutionContext) => _testAssetFixture = testAssetFixture;

public async Task UnsupportedRunSettingsEntriesAreFlagged()
internal static IEnumerable<TestArgumentsEntry<string>> TfmList()
{
yield return TargetFrameworks.NetCurrent;
yield return TargetFrameworks.NetFramework.First();
}

[ArgumentsProvider(nameof(TfmList))]
public async Task UnsupportedRunSettingsEntriesAreFlagged(string tfm)
{
var testHost = TestHost.LocateFrom(_testAssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent.Arguments);
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && tfm == TargetFrameworks.NetFramework.First().Arguments)
{
return;
}

var testHost = TestHost.LocateFrom(_testAssetFixture.ProjectPath, TestAssetFixture.ProjectName, tfm);
TestHostResult testHostResult = await testHost.ExecuteAsync("--settings my.runsettings");

// Assert
Expand Down Expand Up @@ -45,7 +59,7 @@ public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : Test
{
yield return (ProjectName, ProjectName,
SourceCode
.PatchTargetFrameworks(TargetFrameworks.NetCurrent)
.PatchTargetFrameworks(TargetFrameworks.NetCurrent, TargetFrameworks.NetFramework.First())
.PatchCodeWithReplace("$MSTestVersion$", MSTestVersion));
}

Expand All @@ -57,6 +71,7 @@ public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : Test
<OutputType>Exe</OutputType>
<EnableMSTestRunner>true</EnableMSTestRunner>
<TargetFrameworks>$TargetFrameworks$</TargetFrameworks>
<LangVersion>Preview</LangVersion>
</PropertyGroup>

<ItemGroup>
Expand Down Expand Up @@ -105,6 +120,11 @@ public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : Test
<!-- true or false -->
<!-- Value that specifies the exit code when no tests are discovered -->
<TreatNoTestsAsError>true</TreatNoTestsAsError>

<!-- List of environment variables we want to set-->
<EnvironmentVariables>
<SAMPLEKEY>SAMPLEVALUE</SAMPLEKEY>
</EnvironmentVariables>
</RunConfiguration>

<!-- Configurations for data collectors -->
Expand Down Expand Up @@ -200,6 +220,7 @@ public class UnitTest1
[TestMethod]
public void TestMethod()
{
Assert.AreEqual("SAMPLEVALUE", System.Environment.GetEnvironmentVariable("SAMPLEKEY")!);
}
}
""";
Expand Down