Skip to content

Commit

Permalink
Add support for filtering out enviornment variables in tests
Browse files Browse the repository at this point in the history
Only enabled for OPENSSL_CONF for now.

See: #51
  • Loading branch information
omajid committed Aug 26, 2021
1 parent a8d662a commit 296508b
Show file tree
Hide file tree
Showing 13 changed files with 203 additions and 18 deletions.
12 changes: 12 additions & 0 deletions Samples/PassingBashTestWithEnvironmentVariables/test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "PassingBashTestWithEnvironmentVariables",
"enabled": true,
"requiresSdk": true,
"version": "1.0",
"versionSpecific": false,
"type": "bash",
"cleanup": true,
"ignoredRIDs":[
]
}

8 changes: 8 additions & 0 deletions Samples/PassingBashTestWithEnvironmentVariables/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash

env

if [[ -n "${OPENSSL_CONF}" ]]; then
echo "error: OPENSSL_CONF should never be set"
exit 1
fi
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;
using Xunit;

namespace Samples
{
public class PassingXUnitTestWithEnvironmentVariables
{
[Fact]
public void Test1()
{
Assert.Null(Environment.GetEnvironmentVariable("OPENSSL_CONF"));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<TargetFramework>netcoreapp3.1</TargetFramework>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
<PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
</ItemGroup>

</Project>
12 changes: 12 additions & 0 deletions Samples/PassingXUnitTestWithEnvironmentVariables/test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "PassingXUnitTestWithEnvironmentVariables",
"enabled": true,
"requiresSdk": true,
"version": "1.0",
"versionSpecific": false,
"type": "xunit",
"cleanup": true,
"ignoredRIDs":[
]
}

54 changes: 54 additions & 0 deletions Turkey.Tests/EnvironmentVariableSanitizerTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

using Xunit;

namespace Turkey.Tests
{
public class EnvironmentVariableSanitizerTest
{
[Theory]
// TODO enable these too
// [InlineData("ASPNETCORE_URLS")]
// [InlineData("COREHOST_TRACE")]
// [InlineData("DOTNET_FOO_BAR")]
// [InlineData("DOTNET_ROLL_FORWARD")]
// [InlineData("DOTNET_RUNTIME_ID")]
// [InlineData("DOTNET_STARTUP_HOOKS")]
// [InlineData("NUGET_PACKAGES")]
[InlineData("OPENSSL_CONF")]
public void EnvironmentVariablesAreRemoved(string name)
{
var environment = new Dictionary<string, string>()
{
{ name, "foobar" },
};

var sanitizer = new EnvironmentVariableSanitizer();
var result = sanitizer.SanitizeEnvironmentVariables(environment);

Assert.DoesNotContain(name, result.Keys);
}

[InlineData("DOTNET_ROOT")]
[InlineData("DOTNET_CLI_TELEMETRY_OPTOUT")]
[InlineData("PATH")]
[InlineData("USER")]
[InlineData("HOME")]
public void EnvironmentVariablesAreKept(string name)
{
var environment = new Dictionary<string, string>()
{
{ name, "foobar" },
};

var sanitizer = new EnvironmentVariableSanitizer();
var result = sanitizer.SanitizeEnvironmentVariables(environment);

Assert.Contains(name, result.Keys);

}
}
}
20 changes: 13 additions & 7 deletions Turkey.Tests/TestParserTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class TestParserTests
public void DisabledTestShouldBeSkipped()
{
TestParser parser = new TestParser();
SystemUnderTest system = new SystemUnderTest(null, null, null);
SystemUnderTest system = new SystemUnderTest(null, null, null, null);
TestDescriptor test = new TestDescriptor()
{
Enabled = false,
Expand Down Expand Up @@ -41,7 +41,8 @@ public void TestShouldBeRunForSameOrHigherVersions(string version, bool expected
SystemUnderTest system = new SystemUnderTest(
runtimeVersion: Version.Parse(version),
sdkVersion: null,
platformIds: new List<string>());
platformIds: new List<string>(),
environmentVariables: null);

TestDescriptor test = new TestDescriptor()
{
Expand Down Expand Up @@ -75,7 +76,8 @@ public void VersionSpecificTestShouldBeRunForSameMajorMinorVersion(string versio
SystemUnderTest system = new SystemUnderTest(
runtimeVersion: Version.Parse(version),
sdkVersion: null,
platformIds: new List<string>());
platformIds: new List<string>(),
environmentVariables: null);
TestDescriptor test = new TestDescriptor()
{
Enabled = true,
Expand Down Expand Up @@ -111,7 +113,8 @@ public void VersionSpecificTestWithWildcardShouldBeRunForSameMajorVersion(string
SystemUnderTest system = new SystemUnderTest(
runtimeVersion: Version.Parse(version),
sdkVersion: null,
platformIds: new List<string>());
platformIds: new List<string>(),
environmentVariables: null);
TestDescriptor test = new TestDescriptor()
{
Enabled = true,
Expand All @@ -132,7 +135,8 @@ public void MissingIgnoredRIDsIsOkay()
SystemUnderTest system = new SystemUnderTest(
runtimeVersion: Version.Parse("2.1"),
sdkVersion: null,
platformIds: new string[] { "linux" }.ToList());
platformIds: new string[] { "linux" }.ToList(),
environmentVariables: null);
TestDescriptor test = new TestDescriptor()
{
Enabled = true,
Expand All @@ -159,7 +163,8 @@ public void TestShouldNotRunOnIgnoredPlatforms(string[] currentPlatforms, string
SystemUnderTest system = new SystemUnderTest(
runtimeVersion: Version.Parse("2.1"),
sdkVersion: null,
platformIds: currentPlatforms.ToList());
platformIds: currentPlatforms.ToList(),
environmentVariables: null);
TestDescriptor test = new TestDescriptor()
{
Enabled = true,
Expand All @@ -183,7 +188,8 @@ public void SdkTestsShouldRunOnlyWithSdk(string sdkVersion, bool requiresSdk, bo
SystemUnderTest system = new SystemUnderTest(
runtimeVersion: Version.Parse("3.1"),
sdkVersion: Version.Parse(sdkVersion),
platformIds: new List<string>());
platformIds: new List<string>(),
environmentVariables: null);
TestDescriptor test = new TestDescriptor()
{
Enabled = true,
Expand Down
8 changes: 8 additions & 0 deletions Turkey/BashTest.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading;
Expand Down Expand Up @@ -36,6 +37,13 @@ protected override async Task<TestResult> InternalRunAsync(CancellationToken can
RedirectStandardOutput = true,
RedirectStandardError = true,
};

startInfo.EnvironmentVariables.Clear();
foreach (var (key, value) in SystemUnderTest.EnvironmentVariables)
{
startInfo.EnvironmentVariables.Add(key, value);
}

standardOutputWriter.WriteLine($"Executing {startInfo.FileName} with arguments {startInfo.Arguments} in working directory {startInfo.WorkingDirectory}");
using (Process p = Process.Start(startInfo))
{
Expand Down
20 changes: 13 additions & 7 deletions Turkey/DotNet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public ProcessResult(int exitCode, string stdout, string stderr)
}
}

public static async Task<ProcessResult> BuildAsync(DirectoryInfo workingDirectory, CancellationToken token)
public static async Task<ProcessResult> BuildAsync(DirectoryInfo workingDirectory, IReadOnlyDictionary<string, string> environment, CancellationToken token)
{
var arguments = new string[]
{
Expand All @@ -102,21 +102,21 @@ public static async Task<ProcessResult> BuildAsync(DirectoryInfo workingDirector
"-p:UseSharedCompilation=false",
"-m:1",
};
var result = await RunDotNetCommandAsync(workingDirectory, arguments, token);
var result = await RunDotNetCommandAsync(workingDirectory, arguments, environment, token);
return result;
}

public static async Task<ProcessResult> RunAsync(DirectoryInfo workingDirectory, CancellationToken token)
public static async Task<ProcessResult> RunAsync(DirectoryInfo workingDirectory, IReadOnlyDictionary<string, string> environment, CancellationToken token)
{
return await RunDotNetCommandAsync(workingDirectory, new string[] { "run", "--no-restore", "--no-build"} , token);
return await RunDotNetCommandAsync(workingDirectory, new string[] { "run", "--no-restore", "--no-build"} , environment, token);
}

public static async Task<ProcessResult> TestAsync(DirectoryInfo workingDirectory, CancellationToken token)
public static async Task<ProcessResult> TestAsync(DirectoryInfo workingDirectory, IReadOnlyDictionary<string, string> environment, CancellationToken token)
{
return await RunDotNetCommandAsync(workingDirectory, new string[] { "test", "--no-restore", "--no-build"} , token);
return await RunDotNetCommandAsync(workingDirectory, new string[] { "test", "--no-restore", "--no-build"} , environment, token);
}

private static async Task<ProcessResult> RunDotNetCommandAsync(DirectoryInfo workingDirectory, string[] commands, CancellationToken token)
private static async Task<ProcessResult> RunDotNetCommandAsync(DirectoryInfo workingDirectory, string[] commands, IReadOnlyDictionary<string, string> environment, CancellationToken token)
{
var arguments = string.Join(" ", commands);
ProcessStartInfo startInfo = new ProcessStartInfo()
Expand All @@ -128,6 +128,12 @@ private static async Task<ProcessResult> RunDotNetCommandAsync(DirectoryInfo wor
RedirectStandardError = true,
};

startInfo.EnvironmentVariables.Clear();
foreach (var (key, value) in environment)
{
startInfo.EnvironmentVariables.Add(key, value);
}

using (var process = Process.Start(startInfo))
{
StringWriter standardOutputWriter = new StringWriter();
Expand Down
40 changes: 40 additions & 0 deletions Turkey/EnvironmentVariableSanitizer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Threading.Tasks;

namespace Turkey
{
public class EnvironmentVariableSanitizer
{
private readonly List<string> ToFilter = new List<string>()
{
"OPENSSL_CONF",
};

public Dictionary<string, string> SanitizeCurrentEnvironmentVariables()
{
return SanitizeEnvironmentVariables(Environment.GetEnvironmentVariables());
}

public Dictionary<string, string> SanitizeEnvironmentVariables(IDictionary environmentVariables)
{
var result = new Dictionary<string, string>();

foreach (DictionaryEntry entry in environmentVariables)
{
if (ToFilter.Contains((string)entry.Key))
{
continue;
}

result.Add((string)entry.Key, (string)entry.Value);
}

return result;
}
}
}
7 changes: 6 additions & 1 deletion Turkey/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,15 +100,20 @@ public static async Task<int> Run(string testRoot,
List<string> platformIds = new PlatformId().CurrentIds;
Console.WriteLine($"Current platform is: {string.Join(", ", platformIds)}");

var sanitizer = new EnvironmentVariableSanitizer();
var envVars = sanitizer.SanitizeCurrentEnvironmentVariables();

SystemUnderTest system = new SystemUnderTest(
runtimeVersion: dotnet.LatestRuntimeVersion,
sdkVersion: dotnet.LatestSdkVersion,
platformIds: platformIds
platformIds: platformIds,
environmentVariables: envVars
);

Version packageVersion = dotnet.LatestRuntimeVersion;
string nuGetConfig = await GenerateNuGetConfigIfNeededAsync(additionalFeed, packageVersion);


TestRunner runner = new TestRunner(
cleaner: cleaner,
system: system,
Expand Down
4 changes: 3 additions & 1 deletion Turkey/TestRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ public class SystemUnderTest
public Version RuntimeVersion { get; }
public Version SdkVersion { get; }
public List<string> CurrentPlatformIds { get; }
public IReadOnlyDictionary<string, string> EnvironmentVariables;

public SystemUnderTest(Version runtimeVersion, Version sdkVersion, List<string> platformIds)
public SystemUnderTest(Version runtimeVersion, Version sdkVersion, List<string> platformIds, IReadOnlyDictionary<string, string> environmentVariables)
{
RuntimeVersion = runtimeVersion;
SdkVersion = sdkVersion;
CurrentPlatformIds = platformIds;
EnvironmentVariables = environmentVariables;
}
}

Expand Down
5 changes: 3 additions & 2 deletions Turkey/XUnitTest.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -47,12 +48,12 @@ protected override async Task<TestResult> InternalRunAsync(CancellationToken can

private async Task<PartialResult> BuildProjectAsync(CancellationToken token)
{
return ProcessResultToPartialResult(await DotNet.BuildAsync(Directory, token));
return ProcessResultToPartialResult(await DotNet.BuildAsync(Directory, SystemUnderTest.EnvironmentVariables, token));
}

private async Task<PartialResult> TestProjectAsync(CancellationToken token)
{
return ProcessResultToPartialResult(await DotNet.TestAsync(Directory, token));
return ProcessResultToPartialResult(await DotNet.TestAsync(Directory, SystemUnderTest.EnvironmentVariables, token));
}

private static PartialResult ProcessResultToPartialResult(DotNet.ProcessResult result)
Expand Down

0 comments on commit 296508b

Please sign in to comment.