Skip to content

Commit

Permalink
Revert "Disable appdomain usage by default (#1555)"
Browse files Browse the repository at this point in the history
This reverts commit 02cebe5.
  • Loading branch information
engyebrahim committed May 17, 2023
1 parent d6d5481 commit 7b9ce8a
Show file tree
Hide file tree
Showing 9 changed files with 23 additions and 234 deletions.
41 changes: 4 additions & 37 deletions src/Adapter/MSTest.TestAdapter/ObjectModel/TestMethod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Text;

using Microsoft.TestPlatform.AdapterUtilities;
using Microsoft.TestPlatform.AdapterUtilities.ManagedNameUtilities;
Expand Down Expand Up @@ -174,42 +173,10 @@ public string? DeclaringClassFullName
/// </summary>
internal string? DisplayName { get; set; }

public string UniqueName
{
get
{
var uniqueNameBuilder = new StringBuilder();

if (HasManagedMethodAndTypeProperties)
{
uniqueNameBuilder.Append(ManagedTypeName);
uniqueNameBuilder.Append('.');
uniqueNameBuilder.Append(ManagedMethodName);
}
else
{
uniqueNameBuilder.Append(FullClassName);
uniqueNameBuilder.Append('.');
uniqueNameBuilder.Append(Name);
}

if (SerializedData is not null)
{
uniqueNameBuilder.Append("->");
for (int i = 0; i < SerializedData.Length; i++)
{
if (i > 0)
{
uniqueNameBuilder.Append(", ");
}

uniqueNameBuilder.Append(SerializedData[i]);
}
}

return uniqueNameBuilder.ToString();
}
}
internal string UniqueName
=> HasManagedMethodAndTypeProperties
? $"{ManagedTypeName}.{ManagedMethodName}->{string.Join(", ", SerializedData ?? Array.Empty<string>())}"
: $"{FullClassName}.{Name}->{string.Join(", ", SerializedData ?? Array.Empty<string>())}";

internal TestMethod Clone() => (TestMethod)MemberwiseClone();
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
#nullable enable
Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.MSTestSettings.TreatDiscoveryWarningsAsErrors.get -> bool
Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel.TestMethod.UniqueName.get -> string!
Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.MSTestSettings.TreatDiscoveryWarningsAsErrors.get -> bool
Original file line number Diff line number Diff line change
Expand Up @@ -129,21 +129,17 @@ public static MSTestAdapterSettings ToSettings(XmlReader reader)

public static bool IsAppDomainCreationDisabled(string? settingsXml)
{
// By default appDomain is disabled.
if (StringEx.IsNullOrEmpty(settingsXml))
{
return true;
return false;
}

StringReader stringReader = new(settingsXml);
XmlReader reader = XmlReader.Create(stringReader, XmlRunSettingsUtilities.ReaderSettings);

if (reader.ReadToFollowing("DisableAppDomain") && bool.TryParse(reader.ReadInnerXml(), out var disableAppDomain))
{
return disableAppDomain;
}

return true;
return reader.ReadToFollowing("DisableAppDomain")
&& bool.TryParse(reader.ReadInnerXml(), out var disableAppDomain)
&& disableAppDomain;
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ internal TestSourceHost(string sourceFileName, IRunSettings? runSettings, IFrame
SetContext(sourceFileName);

// Set isAppDomainCreationDisabled flag
_isAppDomainCreationDisabled = MSTestAdapterSettings.IsAppDomainCreationDisabled(_runSettings?.SettingsXml);
_isAppDomainCreationDisabled = _runSettings != null && MSTestAdapterSettings.IsAppDomainCreationDisabled(_runSettings.SettingsXml);
}

/// <summary>
Expand Down
55 changes: 6 additions & 49 deletions test/IntegrationTests/MSTest.IntegrationTests/OutputTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@

using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.Linq;
using System.Reflection;

using FluentAssertions;

Expand All @@ -18,58 +16,17 @@ public class OutputTests : CLITestBase
{
private const string TestAssetName = "OutputTestProject";

private const string RunSettingXml =
@"<RunSettings>
<RunConfiguration>
<DisableAppDomain>False</DisableAppDomain>
</RunConfiguration>
</RunSettings>";

public void OutputIsNotMixedWhenTestsRunInParallel()
{
ValidateOutputForClass("UnitTest1", RunSettingXml);
ValidateOutputForClass("UnitTest1");
}

public void OutputIsNotMixedWhenAsyncTestsRunInParallel()
{
ValidateOutputForClass("UnitTest2", RunSettingXml);
}

public void TestContextWriteLine_WhenTestsRunInParallel_OutputIsNotMixed()
{
// By default no appDomain.
ValidateTestContextOutputForClass("UnitTest3");
}

private void ValidateTestContextOutputForClass(string className)
{
// Arrange
var assemblyPath = GetAssetFullPath(TestAssetName);

// Act
var testCases = DiscoverTests(assemblyPath, null, RunSettingXml).Where(tc => tc.FullyQualifiedName.Contains(className)).ToList();
testCases.Should().HaveCount(4);
testCases.Should().NotContainNulls();

var testResults = RunTests(testCases);
testResults.Should().HaveCount(4);
testResults.Should().NotContainNulls();

// Assert
// Ensure that some tests are running in parallel, because otherwise the output just works correctly.
var firstEnd = testResults.Min(t => t.EndTime);
var someStartedBeforeFirstEnded = testResults.Where(t => t.EndTime != firstEnd).Any(t => firstEnd > t.StartTime);
someStartedBeforeFirstEnded.Should().BeTrue("Tests must run in parallel, but there were no other tests that started, before the first one ended.");

ValidateOutputIsNotMixed(testResults, "TestMethod2(DataRowValue1)", new[] { "TestMethod1", "TestMethod3" }, IsStandardOutputMessage, "TestMethod2 (DataRowValue1)");
ValidateOutputIsNotMixed(testResults, "TestMethod2(DataRowValue2)", new[] { "TestMethod1", "TestMethod3" }, IsStandardOutputMessage, "TestMethod2 (DataRowValue2)");
ValidateOutputIsNotMixed(testResults, "TestMethod1", new[] { "TestMethod2(DataRowValue1)", "TestMethod2(DataRowValue2)", "TestMethod3" }, IsStandardOutputMessage);
ValidateOutputIsNotMixed(testResults, "TestMethod3", new[] { "TestMethod1", "TestMethod2(DataRowValue1)", "TestMethod2(DataRowValue2)", }, IsStandardOutputMessage);

ValidateInitializeAndCleanup(testResults, IsStandardOutputMessage);
ValidateOutputForClass("UnitTest2");
}

private void ValidateOutputForClass(string className, string runSettingXml = "")
private void ValidateOutputForClass(string className)
{
// LogMessageListener uses an implementation of a string writer that captures output per async context.
// This allows us to capture output from tasks even when they are running in parallel.
Expand All @@ -78,7 +35,7 @@ private void ValidateOutputForClass(string className, string runSettingXml = "")
var assemblyPath = GetAssetFullPath(TestAssetName);

// Act
var testCases = DiscoverTests(assemblyPath, null, runSettingXml).Where(tc => tc.FullyQualifiedName.Contains(className)).ToList();
var testCases = DiscoverTests(assemblyPath).Where(tc => tc.FullyQualifiedName.Contains(className)).ToList();
testCases.Should().HaveCount(3);
testCases.Should().NotContainNulls();

Expand Down Expand Up @@ -118,10 +75,10 @@ private static void ValidateInitializationsAndCleanups(IEnumerable<TestResult> t
ValidateInitializeAndCleanup(testResults, IsDebugMessage);
}

private static void ValidateOutputIsNotMixed(IEnumerable<TestResult> testResults, string methodName, string[] shouldNotContain, Func<TestResultMessage, bool> messageFilter, string dataRowDisplayName = null)
private static void ValidateOutputIsNotMixed(IEnumerable<TestResult> testResults, string methodName, string[] shouldNotContain, Func<TestResultMessage, bool> messageFilter)
{
// Make sure that the output between methods is not mixed. And that every method has test initialize and cleanup.
var testMethod = testResults.Single(t => t.DisplayName == (dataRowDisplayName ?? methodName));
var testMethod = testResults.Single(t => t.DisplayName == methodName);

// Test method {methodName} was not found.
testMethod.Should().NotBeNull();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@
namespace Microsoft.MSTestV2.CLIAutomation;
public partial class CLITestBase : TestContainer
{
internal ImmutableArray<TestCase> DiscoverTests(string assemblyPath, string testCaseFilter = null, string settingsXml = "")
internal ImmutableArray<TestCase> DiscoverTests(string assemblyPath, string testCaseFilter = null)
{
var unitTestDiscoverer = new UnitTestDiscoverer();
var logger = new InternalLogger();
var sink = new InternalSink();

string runSettingXml = GetRunSettingXml(settingsXml);
string runSettingXml = GetRunSettingXml(string.Empty);
var context = new InternalDiscoveryContext(runSettingXml, testCaseFilter);

unitTestDiscoverer.DiscoverTestsInSource(assemblyPath, logger, sink, context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,7 @@ public void ChildDomainResolutionPathsShouldHaveSearchDirectoriesSpecifiedInRuns
public void DisposeShouldUnloadChildAppDomain()
{
var testSource = GetTestAssemblyPath("DesktopTestProjectx86Debug");
string runSettingXml =
$@"<RunSettings>
<RunConfiguration>
<DisableAppDomain>False</DisableAppDomain>
</RunConfiguration>
</RunSettings>";
_testSourceHost = new TestSourceHost(testSource, GetMockedIRunSettings(runSettingXml).Object, null);
_testSourceHost = new TestSourceHost(testSource, null, null);
_testSourceHost.SetupHost();

// Check that child appdomain was indeed created
Expand All @@ -101,19 +95,6 @@ public void DisposeShouldUnloadChildAppDomain()
_testSourceHost.AppDomain.Should().BeNull();
}

public void RunSettings_WithoutSetDisableAppDomain_WillNotCreatAppDomain()
{
// Arrange
var testSource = GetTestAssemblyPath("DesktopTestProjectx86Debug");
_testSourceHost = new TestSourceHost(testSource, null, null);

// AcT
_testSourceHost.SetupHost();

// Assert
_testSourceHost.AppDomain.Should().BeNull();
}

private static string GetArtifactsBinDir()
{
var artifactsBinDirPath = Path.GetFullPath(Path.Combine(
Expand Down
85 changes: 0 additions & 85 deletions test/IntegrationTests/TestAssets/OutputTestProject/UnitTest3.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -84,16 +84,8 @@ public void CreateInstanceForTypeShouldCreateTheTypeInANewAppDomain()
// Setup
DummyClass dummyClass = new();
int currentAppDomainId = dummyClass.AppDomainId;
string runSettingxml =
@"<RunSettings>
<RunConfiguration>
<DisableAppDomain>False</DisableAppDomain>
</RunConfiguration>
</RunSettings>";
var mockRunSettings = new Mock<IRunSettings>();
mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingxml);

TestSourceHost sut = new(Assembly.GetExecutingAssembly().Location, mockRunSettings.Object, null);
TestSourceHost sut = new(Assembly.GetExecutingAssembly().Location, null, null);
sut.SetupHost();

// Execute
Expand All @@ -111,18 +103,9 @@ public void SetupHostShouldSetChildDomainsAppBaseToTestSourceLocation()
{
// Arrange
DummyClass dummyClass = new();
string runSettingxml =
@"<RunSettings>
<RunConfiguration>
<DisableAppDomain>False</DisableAppDomain>
</RunConfiguration>
</RunSettings>";
var mockRunSettings = new Mock<IRunSettings>();
mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingxml);

var location = typeof(TestSourceHost).Assembly.Location;

Mock<TestSourceHost> sourceHost = new(location, mockRunSettings.Object, null) { CallBase = true };
Mock<TestSourceHost> sourceHost = new(location, null, null) { CallBase = true };

try
{
Expand Down Expand Up @@ -197,20 +180,11 @@ public void DisposeShouldSetTestHostShutdownOnIssueWithAppDomainUnload()
{
// Arrange
var frameworkHandle = new Mock<IFrameworkHandle>();
string runSettingxml =
@"<RunSettings>
<RunConfiguration>
<DisableAppDomain>False</DisableAppDomain>
</RunConfiguration>
</RunSettings>";
var mockRunSettings = new Mock<IRunSettings>();
mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingxml);

var testableAppDomain = new Mock<IAppDomain>();

testableAppDomain.Setup(ad => ad.CreateDomain(It.IsAny<string>(), It.IsAny<Evidence>(), It.IsAny<AppDomainSetup>())).Returns(AppDomain.CurrentDomain);
testableAppDomain.Setup(ad => ad.Unload(It.IsAny<AppDomain>())).Throws(new CannotUnloadAppDomainException());

var sourceHost = new TestSourceHost(typeof(DesktopTestSourceHostTests).Assembly.Location, mockRunSettings.Object, frameworkHandle.Object, testableAppDomain.Object);
var sourceHost = new TestSourceHost(typeof(DesktopTestSourceHostTests).Assembly.Location, null, frameworkHandle.Object, testableAppDomain.Object);
sourceHost.SetupHost();

// Act
Expand Down

0 comments on commit 7b9ce8a

Please sign in to comment.