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

Add playground project #3200

Merged
merged 18 commits into from
Jan 5, 2022
Merged
35 changes: 35 additions & 0 deletions TestPlatform.sln
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DumpMinitool.x86", "src\Dat
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AttachVS", "src\AttachVS\AttachVS.csproj", "{8238A052-D626-49EB-A011-51DC6D0DBA30}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "playground", "playground", "{6CE2F530-582B-4695-A209-41065E103426}"
ProjectSection(SolutionItems) = preProject
README.md = README.md
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestPlatform.Playground", "playground\TestPlatform.Playground\TestPlatform.Playground.csproj", "{545A88D3-1AE2-4D39-9B7C-C691768AD17F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MSTest1", "playground\MSTest1\MSTest1.csproj", "{57A61A09-10AD-44BE-8DF4-A6FD108F7DF7}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
src\Microsoft.TestPlatform.Execution.Shared\Microsoft.TestPlatform.Execution.Shared.projitems*{10b6ade1-f808-4612-801d-4452f5b52242}*SharedItemsImports = 5
Expand Down Expand Up @@ -835,6 +844,30 @@ Global
{8238A052-D626-49EB-A011-51DC6D0DBA30}.Release|x64.Build.0 = Release|Any CPU
{8238A052-D626-49EB-A011-51DC6D0DBA30}.Release|x86.ActiveCfg = Release|Any CPU
{8238A052-D626-49EB-A011-51DC6D0DBA30}.Release|x86.Build.0 = Release|Any CPU
{545A88D3-1AE2-4D39-9B7C-C691768AD17F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{545A88D3-1AE2-4D39-9B7C-C691768AD17F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{545A88D3-1AE2-4D39-9B7C-C691768AD17F}.Debug|x64.ActiveCfg = Debug|Any CPU
{545A88D3-1AE2-4D39-9B7C-C691768AD17F}.Debug|x64.Build.0 = Debug|Any CPU
{545A88D3-1AE2-4D39-9B7C-C691768AD17F}.Debug|x86.ActiveCfg = Debug|Any CPU
{545A88D3-1AE2-4D39-9B7C-C691768AD17F}.Debug|x86.Build.0 = Debug|Any CPU
{545A88D3-1AE2-4D39-9B7C-C691768AD17F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{545A88D3-1AE2-4D39-9B7C-C691768AD17F}.Release|Any CPU.Build.0 = Release|Any CPU
{545A88D3-1AE2-4D39-9B7C-C691768AD17F}.Release|x64.ActiveCfg = Release|Any CPU
{545A88D3-1AE2-4D39-9B7C-C691768AD17F}.Release|x64.Build.0 = Release|Any CPU
{545A88D3-1AE2-4D39-9B7C-C691768AD17F}.Release|x86.ActiveCfg = Release|Any CPU
{545A88D3-1AE2-4D39-9B7C-C691768AD17F}.Release|x86.Build.0 = Release|Any CPU
{57A61A09-10AD-44BE-8DF4-A6FD108F7DF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{57A61A09-10AD-44BE-8DF4-A6FD108F7DF7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{57A61A09-10AD-44BE-8DF4-A6FD108F7DF7}.Debug|x64.ActiveCfg = Debug|Any CPU
{57A61A09-10AD-44BE-8DF4-A6FD108F7DF7}.Debug|x64.Build.0 = Debug|Any CPU
{57A61A09-10AD-44BE-8DF4-A6FD108F7DF7}.Debug|x86.ActiveCfg = Debug|Any CPU
{57A61A09-10AD-44BE-8DF4-A6FD108F7DF7}.Debug|x86.Build.0 = Debug|Any CPU
{57A61A09-10AD-44BE-8DF4-A6FD108F7DF7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{57A61A09-10AD-44BE-8DF4-A6FD108F7DF7}.Release|Any CPU.Build.0 = Release|Any CPU
{57A61A09-10AD-44BE-8DF4-A6FD108F7DF7}.Release|x64.ActiveCfg = Release|Any CPU
{57A61A09-10AD-44BE-8DF4-A6FD108F7DF7}.Release|x64.Build.0 = Release|Any CPU
{57A61A09-10AD-44BE-8DF4-A6FD108F7DF7}.Release|x86.ActiveCfg = Release|Any CPU
{57A61A09-10AD-44BE-8DF4-A6FD108F7DF7}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -907,6 +940,8 @@ Global
{33A20B85-7024-4112-B1E7-00CD0E4A9F96} = {B705537C-B82C-4A30-AFA5-6244D9A7DAEB}
{2C88C923-3D7A-4492-9241-7A489750CAB7} = {B705537C-B82C-4A30-AFA5-6244D9A7DAEB}
{8238A052-D626-49EB-A011-51DC6D0DBA30} = {ED0C35EB-7F31-4841-A24F-8EB708FFA959}
{545A88D3-1AE2-4D39-9B7C-C691768AD17F} = {6CE2F530-582B-4695-A209-41065E103426}
{57A61A09-10AD-44BE-8DF4-A6FD108F7DF7} = {6CE2F530-582B-4695-A209-41065E103426}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0541B30C-FF51-4E28-B172-83F5F3934BCD}
Expand Down
30 changes: 30 additions & 0 deletions playground/MSTest1/MSTest1.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TestPlatformRoot Condition="$(TestPlatformRoot) == ''">..\..\</TestPlatformRoot>
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
</PropertyGroup>
<Import Project="$(TestPlatformRoot)scripts/build/TestPlatform.Settings.targets" />

<PropertyGroup>
<TargetFrameworks Condition=" '$(OS)' == 'WINDOWS_NT' ">$(TargetFrameworks);net472</TargetFrameworks>
<!-- We build this on linux as well, and are including ref assemblies for this framework only. -->
<TargetFrameworks Condition=" '$(OS)' != 'WINDOWS_NT' ">$(TargetFrameworks);net451</TargetFrameworks>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.1.0" />
<PackageReference Include="MSTest.TestFramework" Version="2.1.0" />
<PackageReference Include="coverlet.collector" Version="1.2.0" />
</ItemGroup>
<ItemGroup Condition=" $(TargetFramework.StartsWith('net4')) AND '$(OS)' != 'Windows_NT' ">
<Reference Include="netstandard" />
<Reference Include="System" />
<Reference Include="System.Runtime" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<Import Project="$(TestPlatformRoot)scripts\build\TestPlatform.targets" />
</Project>
13 changes: 13 additions & 0 deletions playground/MSTest1/UnitTest1.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace MSTest1
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
}
}
}
17 changes: 17 additions & 0 deletions playground/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Playground

This Plaground directory contains projects to aid interactive debugging of test platform. TestPlatform is normally built
as a set of distinct pieces and then assembled in the artifacts folder. This forces rebuilding using build.cmd to try out
changes. The TestPlatform.Playground project builds a simpler version of TestPlatform to avoid always rebuilding via
build.cmd, offering a tighther development loop.

The project references TranslationLayer, vstest.console, TestHostProvider, testhost and MSTest1 projects, to make sure
we build all the dependencies of that are used to run tests via VSTestConsoleWrapper. It then copies the components from
their original build locations, to $(TargetDir)\vstest.console directory, and it's subfolders to create an executable
copy of TestPlatform that is similar to what we ship.

The copying might trigger only on re-build, if you see outdated dependencies, Rebuild this project instead of just Build.

Use this as playground for your debugging of end-to-end scenarios, it will automatically attach vstest.console and teshost
sub-processes. It won't stop at entry-point automatically, don't forget to set your breakpoints, or remove VSTEST_DEBUG_NOBP
from the environment variables of this project.
133 changes: 133 additions & 0 deletions playground/TestPlatform.Playground/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
using Microsoft.TestPlatform.VsTestConsole.TranslationLayer;
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.Interfaces;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading;

namespace TestPlatform.Playground
{
internal class Program
{
static void Main(string[] args)
{
// This project references TranslationLayer, vstest.console, TestHostProvider, testhost and MSTest1 projects, to make sure
// we build all the dependencies of that are used to run tests via VSTestConsoleWrapper. It then copies the components from
// their original build locations, to $(TargetDir)\vstest.console directory, and it's subfolders to create an executable
// copy of TestPlatform that is similar to what we ship.
//
// The copying might trigger only on re-build, if you see outdated dependencies, Rebuild this project instead of just Build.
//
// Use this as playground for your debugging of end-to-end scenarios, it will automatically attach vstest.console and teshost
// sub-processes. It won't stop at entry-point automatically, don't forget to set your breakpoints, or remove VSTEST_DEBUG_NOBP
// from the environment variables of this project.

var thisAssemblyPath = Assembly.GetEntryAssembly().Location;
var here = Path.GetDirectoryName(thisAssemblyPath);
var playground = Path.GetFullPath(Path.Combine(here, "..", "..", "..", ".."));

var console = Path.Combine(here, "vstest.console", "vstest.console.exe");
var consoleOptions = new ConsoleParameters
{
LogFilePath = Path.Combine(here, "logs", "log.txt"),
TraceLevel = TraceLevel.Verbose,
};

var r = new VsTestConsoleWrapper(console, consoleOptions);

var sourceSettings = @"
<RunSettings>
<RunConfiguration>
<InIsolation>true</InIsolation>
</RunConfiguration>
</RunSettings>
";
var sources = new[] {
Path.Combine(playground, "MSTest1", "bin", "Debug", "net472", "MSTest1.dll")
};

var options = new TestPlatformOptions();
r.RunTestsWithCustomTestHost(sources, sourceSettings, options, new TestRunHandler(), new DebuggerTestHostLauncher());
}

public class TestRunHandler : ITestRunEventsHandler
{

public TestRunHandler()
{
}

public void HandleLogMessage(TestMessageLevel level, string message)
{
Console.WriteLine($"[{level.ToString().ToUpper()}]: {message}");
}

public void HandleRawMessage(string rawMessage)
{
Console.WriteLine($"[MESSAGE]: { rawMessage}");
}

public void HandleTestRunComplete(TestRunCompleteEventArgs testRunCompleteArgs, TestRunChangedEventArgs lastChunkArgs, ICollection<AttachmentSet> runContextAttachments, ICollection<string> executorUris)
{
Console.WriteLine($"[COMPLETE]: err: { testRunCompleteArgs.Error }, lastChunk: {WriteTests(lastChunkArgs?.NewTestResults)}");
}

public void HandleTestRunStatsChange(TestRunChangedEventArgs testRunChangedArgs)
{
Console.WriteLine($"[PROGRESS - NEW RESULTS]: {WriteTests(testRunChangedArgs.NewTestResults)}");
}

public int LaunchProcessWithDebuggerAttached(TestProcessStartInfo testProcessStartInfo)
{
throw new NotImplementedException();
}

private string WriteTests(IEnumerable<TestResult> testResults)
{
return WriteTests(testResults?.Select(t => t.TestCase));
}

private string WriteTests(IEnumerable<TestCase> testCases)
{
if (testCases == null)
{
return null;
}

return "\t" + string.Join("\n\t", testCases.Select(r => r.DisplayName));

}
}

internal class DebuggerTestHostLauncher : ITestHostLauncher2
{
public bool IsDebug => true;

public bool AttachDebuggerToProcess(int pid)
{
return true;
}

public bool AttachDebuggerToProcess(int pid, CancellationToken cancellationToken)
{
return true;
}

public int LaunchTestHost(TestProcessStartInfo defaultTestHostStartInfo)
{
return 1;
}

public int LaunchTestHost(TestProcessStartInfo defaultTestHostStartInfo, CancellationToken cancellationToken)
{
return 1;
}
}
}
}
13 changes: 13 additions & 0 deletions playground/TestPlatform.Playground/Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"profiles": {
"TestPlatform.Playground": {
"commandName": "Project",
"environmentVariables": {
"VSTEST_RUNNER_DEBUG_ATTACHVS": "1",
"VSTEST_DEBUG_NOBP": "1",
"VSTEST_HOST_DEBUG_ATTACHVS": "1",
"VSTEST_DATACOLLECTOR_DEBUG_ATTACHVS": "1"
}
}
}
}
42 changes: 42 additions & 0 deletions playground/TestPlatform.Playground/TestPlatform.Playground.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TestPlatformRoot Condition="$(TestPlatformRoot) == ''">..\..\</TestPlatformRoot>
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
</PropertyGroup>

<Import Project="$(TestPlatformRoot)scripts/build/TestPlatform.Settings.targets" />
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks Condition=" '$(OS)' == 'WINDOWS_NT' ">$(TargetFrameworks);net472</TargetFrameworks>
<!-- We build this on linux as well, and are including ref assemblies for this framework only. -->
<TargetFrameworks Condition=" '$(OS)' != 'WINDOWS_NT' ">$(TargetFrameworks);net451</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="MSTest.TestAdapter" Version="2.2.8" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.8" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\datacollector\datacollector.csproj" />
<ProjectReference Include="..\..\src\Microsoft.TestPlatform.TestHostProvider\Microsoft.TestPlatform.TestHostProvider.csproj" />
<ProjectReference Include="..\..\src\Microsoft.TestPlatform.VsTestConsole.TranslationLayer\Microsoft.TestPlatform.VsTestConsole.TranslationLayer.csproj" />
<ProjectReference Include="..\..\src\testhost.x86\testhost.x86.csproj" />
<ProjectReference Include="..\..\src\testhost\testhost.csproj" />
<ProjectReference Include="..\..\src\vstest.console\vstest.console.csproj" />
<ProjectReference Include="..\MSTest1\MSTest1.csproj" />
</ItemGroup>
<ItemGroup Condition=" $(TargetFramework.StartsWith('net4')) AND '$(OS)' != 'Windows_NT' ">
<Reference Include="netstandard" />
<Reference Include="System" />
<Reference Include="System.Runtime" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="Microsoft.CSharp" />
</ItemGroup>

<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition=" '$(OS)' == 'WINDOWS_NT' ">
<Exec Command="xcopy /i /y $(MSBuildProjectDirectory)\..\..\src\vstest.console\bin\Debug\net451\win7-x64\ $(TargetDir)\vstest.console\&#xD;&#xA;xcopy /i /y $(MSBuildProjectDirectory)\..\..\src\testhost\bin\Debug\net451\win7-x64\ $(TargetDir)\vstest.console\&#xD;&#xA;xcopy /i /y $(MSBuildProjectDirectory)\..\..\src\Microsoft.TestPlatform.TestHostProvider\bin\Debug\net451\ $(TargetDir)\vstest.console\Extensions\&#xD;&#xA;xcopy /i /y $(MSBuildProjectDirectory)\..\..\src\testhost.x86\bin\Debug\net472\win7-x86 $(TargetDir)\vstest.console\TestHost\" />
</Target>
<Import Project="$(TestPlatformRoot)scripts\build\TestPlatform.targets" />
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ namespace Microsoft.VisualStudio.TestPlatform.PlatformAbstractions
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Reflection;
Expand Down Expand Up @@ -76,6 +77,7 @@ public object LaunchProcess(string processPath, string arguments, string working
}

// EqtTrace.Verbose("ProcessHelper: Starting process '{0}' with command line '{1}'", processPath, arguments);
// TODO: Enable logging here, and consider wrapping Win32Exeception into another that shows the path of the process.
process.Start();

if (errorCallback != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ public string LogFilePath
{
ValidateArg.NotNullOrEmpty(value, "LogFilePath");
var directoryPath = Path.GetDirectoryName(value);
if (!string.IsNullOrEmpty(directoryPath) && !fileHelper.DirectoryExists(Path.GetDirectoryName(value)))
if (!string.IsNullOrEmpty(directoryPath) && !fileHelper.DirectoryExists(directoryPath))
{
throw new ArgumentException("LogFilePath must point to a valid directory for logging!");
Directory.CreateDirectory(directoryPath);
}

// Ensure path is double quoted. if path has white space then it can create problem.
Expand Down