diff --git a/NuGet.config b/NuGet.config
index fd1f2a9ce2..de789f31f8 100644
--- a/NuGet.config
+++ b/NuGet.config
@@ -7,7 +7,6 @@
-
diff --git a/diagnostics.sln b/diagnostics.sln
index 5f940760e0..1a0860f67d 100644
--- a/diagnostics.sln
+++ b/diagnostics.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.29019.234
+# Visual Studio Version 17
+VisualStudioVersion = 17.3.32519.111
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Diagnostics.TestHelpers", "src\Microsoft.Diagnostics.TestHelpers\Microsoft.Diagnostics.TestHelpers.csproj", "{730C1201-1848-4F1E-8C1F-6316FB886C35}"
EndProject
@@ -41,9 +41,6 @@ EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SOS.Symbol.Package", "src\SOS\SOS.Package\SOS.Symbol.Package.csproj", "{410394E0-7F4F-42D5-B5FA-30956F44ACBC}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{03479E19-3F18-49A6-910A-F5041E27E7C0}"
- ProjectSection(SolutionItems) = preProject
- src\tests\eventpipe\EventPipe.UnitTests.csproj = src\tests\eventpipe\EventPipe.UnitTests.csproj
- EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotnetTrace.UnitTests", "src\tests\dotnet-trace\DotnetTrace.UnitTests.csproj", "{AEDCCF5B-5AD0-4D64-BF73-5CF468E07D22}"
EndProject
@@ -173,8 +170,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "inc", "inc", "{41BDFD6D-D16
src\shared\inc\sstring.h = src\shared\inc\sstring.h
src\shared\inc\sstring.inl = src\shared\inc\sstring.inl
src\shared\inc\stacktrace.h = src\shared\inc\stacktrace.h
- src\shared\inc\static_assert.h = src\shared\inc\static_assert.h
src\shared\inc\staticcontract.h = src\shared\inc\staticcontract.h
+ src\shared\inc\static_assert.h = src\shared\inc\static_assert.h
src\shared\inc\stdmacros.h = src\shared\inc\stdmacros.h
src\shared\inc\stresslog.h = src\shared\inc\stresslog.h
src\shared\inc\switches.h = src\shared\inc\switches.h
@@ -265,6 +262,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "minipal", "minipal", "{795B
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DbgShim.UnitTests", "src\tests\DbgShim.UnitTests\DbgShim.UnitTests.csproj", "{DD60B7C4-BECC-4C7D-A53B-FCDD4C92B728}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommonTestRunner", "src\tests\CommonTestRunner\CommonTestRunner.csproj", "{DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotnetStack.UnitTests", "src\tests\dotnet-stack\DotnetStack.UnitTests.csproj", "{E8F133F8-4D20-475D-9D16-2BA236DAB65F}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Checked|Any CPU = Checked|Any CPU
@@ -1786,6 +1787,84 @@ Global
{DD60B7C4-BECC-4C7D-A53B-FCDD4C92B728}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
{DD60B7C4-BECC-4C7D-A53B-FCDD4C92B728}.RelWithDebInfo|x86.ActiveCfg = Release|Any CPU
{DD60B7C4-BECC-4C7D-A53B-FCDD4C92B728}.RelWithDebInfo|x86.Build.0 = Release|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.Checked|Any CPU.Build.0 = Debug|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.Checked|ARM.ActiveCfg = Debug|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.Checked|ARM.Build.0 = Debug|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.Checked|ARM64.ActiveCfg = Debug|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.Checked|ARM64.Build.0 = Debug|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.Checked|x64.ActiveCfg = Debug|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.Checked|x64.Build.0 = Debug|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.Checked|x86.ActiveCfg = Debug|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.Checked|x86.Build.0 = Debug|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.Debug|ARM.Build.0 = Debug|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.Debug|ARM64.ActiveCfg = Debug|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.Debug|ARM64.Build.0 = Debug|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.Debug|x64.Build.0 = Debug|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.Debug|x86.Build.0 = Debug|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.Release|ARM.ActiveCfg = Release|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.Release|ARM.Build.0 = Release|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.Release|ARM64.ActiveCfg = Release|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.Release|ARM64.Build.0 = Release|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.Release|x64.ActiveCfg = Release|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.Release|x64.Build.0 = Release|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.Release|x86.ActiveCfg = Release|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.Release|x86.Build.0 = Release|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.RelWithDebInfo|ARM.ActiveCfg = Release|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.RelWithDebInfo|ARM.Build.0 = Release|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.RelWithDebInfo|ARM64.ActiveCfg = Release|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.RelWithDebInfo|ARM64.Build.0 = Release|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.RelWithDebInfo|x86.ActiveCfg = Release|Any CPU
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F}.RelWithDebInfo|x86.Build.0 = Release|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.Checked|Any CPU.Build.0 = Debug|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.Checked|ARM.ActiveCfg = Debug|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.Checked|ARM.Build.0 = Debug|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.Checked|ARM64.ActiveCfg = Debug|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.Checked|ARM64.Build.0 = Debug|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.Checked|x64.ActiveCfg = Debug|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.Checked|x64.Build.0 = Debug|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.Checked|x86.ActiveCfg = Debug|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.Checked|x86.Build.0 = Debug|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.Debug|ARM.Build.0 = Debug|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.Debug|ARM64.ActiveCfg = Debug|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.Debug|ARM64.Build.0 = Debug|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.Debug|x64.Build.0 = Debug|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.Debug|x86.Build.0 = Debug|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.Release|ARM.ActiveCfg = Release|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.Release|ARM.Build.0 = Release|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.Release|ARM64.ActiveCfg = Release|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.Release|ARM64.Build.0 = Release|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.Release|x64.ActiveCfg = Release|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.Release|x64.Build.0 = Release|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.Release|x86.ActiveCfg = Release|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.Release|x86.Build.0 = Release|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.RelWithDebInfo|ARM.ActiveCfg = Release|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.RelWithDebInfo|ARM.Build.0 = Release|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.RelWithDebInfo|ARM64.ActiveCfg = Release|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.RelWithDebInfo|ARM64.Build.0 = Release|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.RelWithDebInfo|x86.ActiveCfg = Release|Any CPU
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F}.RelWithDebInfo|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1842,6 +1921,8 @@ Global
{8C35FEF8-1101-38F6-ACD0-462A1EA53A7D} = {7852EDE4-93DF-4DB1-8A86-C521703811AF}
{795B7A50-1B1F-406E-94E0-F9B35104EF22} = {7852EDE4-93DF-4DB1-8A86-C521703811AF}
{DD60B7C4-BECC-4C7D-A53B-FCDD4C92B728} = {03479E19-3F18-49A6-910A-F5041E27E7C0}
+ {DFF48CB6-4504-41C6-A8F1-F4A3D316D49F} = {03479E19-3F18-49A6-910A-F5041E27E7C0}
+ {E8F133F8-4D20-475D-9D16-2BA236DAB65F} = {03479E19-3F18-49A6-910A-F5041E27E7C0}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {46465737-C938-44FC-BE1A-4CE139EBB5E0}
diff --git a/eng/InstallRuntimes.proj b/eng/InstallRuntimes.proj
index c11cd5f6ac..eac7bdc378 100644
--- a/eng/InstallRuntimes.proj
+++ b/eng/InstallRuntimes.proj
@@ -15,16 +15,17 @@
$(MicrosoftDotnetSdkInternalVersion) - .NET SDK to use for testing
- $(VSRedistCommonNetCoreSharedFrameworkx6460Version) - latest dotnet runtime package version (the version to install)
- $(MicrosoftNETCoreAppRuntimewinx64Version) - latest dotnet runtime stable version (the version that actually is installed)
+ $(VSRedistCommonNetCoreSharedFrameworkx6470Version) - latest dotnet runtime package version (the version to install)
+ $(MicrosoftNETCoreAppRuntimewinx64Version) - latest dotnet runtime stable version (the version that actually is installed)
- $(MicrosoftAspNetCoreAppRefInternalVersion) - latest dotnet aspnetcore package version (the version to install)
- $(MicrosoftAspNetCoreAppRefVersion) - latest dotnet aspnetcore stable version (the version that actually is installed)
+ $(MicrosoftAspNetCoreAppRefInternalVersion) - latest dotnet aspnetcore package version (the version to install)
+ $(MicrosoftAspNetCoreAppRefVersion) - latest dotnet aspnetcore stable version (the version that actually is installed)
- $(MicrosoftNETCoreApp50Version) $(MicrosoftAspNetCoreApp50Version) - 5.0 version
- $(MicrosoftNETCoreApp31Version) $(MicrosoftAspNetCoreApp31Version) - 3.1 version
+ $(MicrosoftNETCoreApp60Version) $(MicrosoftAspNetCoreApp60Version) - 6.0 version
+ $(MicrosoftNETCoreApp31Version) $(MicrosoftAspNetCoreApp31Version) - 3.1 version
- $(SingleFileRuntimeVersion) - The version of the runtime used to build single-file apps
+ $(SingleFileRuntimeLatestVersion) - The latest version of the runtime used to build single-file apps
+ $(SingleFileRuntime60Version) - The 6.0.x version of the runtime used to build single-file apps
From Arcade:
@@ -63,6 +64,11 @@
regedit.exe
+
+ true
+ false
+
+
@@ -78,14 +84,14 @@
-
-
-
+
+
+
-
+
@@ -147,11 +153,11 @@
Outputs="$(TestConfigFileName)">
- $(MicrosoftNETCoreApp31Version)
- $(MicrosoftAspNetCoreApp31Version)
+ $(MicrosoftNETCoreApp31Version)
+ $(MicrosoftAspNetCoreApp31Version)
- $(MicrosoftNETCoreApp50Version)
- $(MicrosoftAspNetCoreApp50Version)
+ $(MicrosoftNETCoreApp60Version)
+ $(MicrosoftAspNetCoreApp60Version)
@@ -170,13 +176,14 @@
$(RuntimeVersion31)
$(AspNetCoreVersion31)
- $(RuntimeVersion50)
- $(AspNetCoreVersion50)
+ $(RuntimeVersion60)
+ $(AspNetCoreVersion60)
$(RuntimeVersionLatest)
$(AspNetCoreVersionLatest)
- $(SingleFileRuntimeVersion)
+ $(SingleFileRuntimeLatestVersion)
+ $(SingleFileRuntime60Version)
]]>
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index b85fc624a4..244495331c 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -14,7 +14,7 @@
https://github.com/dotnet/source-build-reference-packages
- 993b067a1849e4884360b4548cbf74f0bfaa2f35
+ 3dbb19f76474f2f22749b2e64d34c15178381ffb
@@ -28,25 +28,25 @@
https://github.com/dotnet/arcade
ccfe6da198c5f05534863bbb1bff66e830e0c6ab
-
+
https://github.com/dotnet/installer
- d62c7a24e4421ec3d70783fad181f50fde2e3901
+ 51211d8d2eb12dfbee4d88d24eff9af26d6b7262
-
+
https://github.com/dotnet/aspnetcore
- 511eaa8ee5923bf6e33fe86ae424bc79e4723003
+ 154d0530fb24e142c22b5b737e881f1b7c0c65d3
-
+
https://github.com/dotnet/aspnetcore
511eaa8ee5923bf6e33fe86ae424bc79e4723003
-
+
https://github.com/dotnet/runtime
- a21b9a2dd4c31cf5bd37626562b7612faf21cee6
+ f21ace52e357bbf0019da5c9e42d66705a087235
-
+
https://github.com/dotnet/runtime
- a21b9a2dd4c31cf5bd37626562b7612faf21cee6
+ f21ace52e357bbf0019da5c9e42d66705a087235
diff --git a/eng/Versions.props b/eng/Versions.props
index c1b8d7af23..72cc436113 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -15,23 +15,26 @@
true
-
- 6.0.5
1.0.332901
-
- 3.1.18
- $(MicrosoftNETCoreApp31Version)
- 5.0.9
- $(MicrosoftNETCoreApp50Version)
- 6.0.5-servicing.22213.11
- 6.0.5
+ 7.0.0-preview.6.22329.5
+ 7.0.0-preview.6.22329.5
- 6.0.7-servicing.22313.13
- 6.0.7
+ 7.0.0-preview.7.22330.6
+ 7.0.0-preview.7.22330.6
- 6.0.107-servicing.22310.12
+ 7.0.100-preview.7.22351.2
+
+
+
+ 3.1.25
+ $(MicrosoftNETCoreApp31Version)
+ 6.0.6
+ $(MicrosoftNETCoreApp60Version)
+
+ 6.0.6
+ 7.0.0-preview.6.22329.5
diff --git a/global.json b/global.json
index 4f9b7f2039..ef7df67613 100644
--- a/global.json
+++ b/global.json
@@ -1,16 +1,20 @@
{
"tools": {
- "dotnet": "7.0.100-preview.2.22153.17",
+ "dotnet": "7.0.100-preview.3.22179.4",
"runtimes": {
"dotnet/x64": [
"$(MicrosoftNETCoreApp31Version)",
- "$(MicrosoftNETCoreApp50Version)",
- "$(VSRedistCommonNetCoreSharedFrameworkx6460Version)"
+ "$(MicrosoftNETCoreApp60Version)",
+ "$(VSRedistCommonNetCoreSharedFrameworkx6470Version)"
],
"dotnet/x86": [
"$(MicrosoftNETCoreApp31Version)",
- "$(MicrosoftNETCoreApp50Version)",
- "$(VSRedistCommonNetCoreSharedFrameworkx6460Version)"
+ "$(MicrosoftNETCoreApp60Version)",
+ "$(VSRedistCommonNetCoreSharedFrameworkx6470Version)"
+ ],
+ "dotnet/arm64": [
+ "$(MicrosoftNETCoreApp60Version)",
+ "$(VSRedistCommonNetCoreSharedFrameworkx6470Version)"
]
}
},
diff --git a/src/Microsoft.Diagnostics.DebugServices.Implementation/TargetFromDataReader.cs b/src/Microsoft.Diagnostics.DebugServices.Implementation/TargetFromDataReader.cs
index ee499a3022..07d901bb04 100644
--- a/src/Microsoft.Diagnostics.DebugServices.Implementation/TargetFromDataReader.cs
+++ b/src/Microsoft.Diagnostics.DebugServices.Implementation/TargetFromDataReader.cs
@@ -49,8 +49,10 @@ public TargetFromDataReader(IDataReader dataReader, OSPlatform targetOS, IHost h
{
memoryService = new ImageMappingMemoryService(this, memoryService);
// Any dump created for a MacOS target does not have managed assemblies in the module service so
- // we need to use the metadata mapping memory service to make sure the metadata is available.
- if (targetOS == OSPlatform.OSX)
+ // we need to use the metadata mapping memory service to make sure the metadata is available and
+ // 7.0 Linux builds have an extra System.Private.CoreLib module mapping that causes the image
+ // mapper not to be able to map in the metadata.
+ if (targetOS == OSPlatform.OSX || targetOS == OSPlatform.Linux)
{
memoryService = new MetadataMappingMemoryService(this, memoryService);
}
diff --git a/src/Microsoft.Diagnostics.ExtensionCommands/Host/ModulesCommand.cs b/src/Microsoft.Diagnostics.ExtensionCommands/Host/ModulesCommand.cs
index 9a450ea1ad..74fd7a9cab 100644
--- a/src/Microsoft.Diagnostics.ExtensionCommands/Host/ModulesCommand.cs
+++ b/src/Microsoft.Diagnostics.ExtensionCommands/Host/ModulesCommand.cs
@@ -28,51 +28,73 @@ public class ModulesCommand : CommandBase
[Option(Name = "--name", Aliases = new string[] { "-n" }, Help = "RegEx filter on module name (path not included).")]
public string ModuleName { get; set; }
+ [Option(Name = "--address", Aliases = new string[] { "-a" }, Help = "Lookup address in module list.")]
+ public ulong? Address { get; set; }
+
public IModuleService ModuleService { get; set; }
public override void Invoke()
{
- Regex regex = ModuleName is not null ? new Regex(ModuleName, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant) : null;
- ulong totalSize = 0;
-
- foreach (IModule module in ModuleService.EnumerateModules().OrderBy((m) => m.ModuleIndex))
+ if (Address.HasValue)
{
- totalSize += module.ImageSize;
- if (regex is null || !string.IsNullOrEmpty(module.FileName) && regex.IsMatch(Path.GetFileName(module.FileName)))
+ IModule module = ModuleService.GetModuleFromAddress(Address.Value);
+ if (module != null)
{
- if (Verbose)
- {
- WriteLine("{0} {1}", module.ModuleIndex, module.FileName);
- WriteLine(" Address: {0:X16}", module.ImageBase);
- WriteLine(" ImageSize: {0:X8}", module.ImageSize);
- WriteLine(" IsPEImage: {0}", module.IsPEImage);
- WriteLine(" IsManaged: {0}", module.IsManaged);
- WriteLine(" IsFileLayout: {0}", module.IsFileLayout?.ToString() ?? "");
- WriteLine(" IndexFileSize: {0}", module.IndexFileSize?.ToString("X8") ?? "");
- WriteLine(" IndexTimeStamp: {0}", module.IndexTimeStamp?.ToString("X8") ?? "");
- WriteLine(" Version: {0}", module.GetVersionData()?.ToString() ?? "");
- string versionString = module.GetVersionString();
- if (!string.IsNullOrEmpty(versionString))
- {
- WriteLine(" {0}", versionString);
- }
- foreach (PdbFileInfo pdbFileInfo in module.GetPdbFileInfos())
- {
- WriteLine(" PdbInfo: {0}", pdbFileInfo);
- }
- WriteLine(" BuildId: {0}", !module.BuildId.IsDefaultOrEmpty ? string.Concat(module.BuildId.Select((b) => b.ToString("x2"))) : "");
- }
- else
- {
- WriteLine("{0:X16} {1:X8} {2}", module.ImageBase, module.ImageSize, module.FileName);
- }
- if (Segment)
+ DisplayModule(module);
+ }
+ else
+ {
+ WriteLineError($"Address 0x{Address:X16} not found");
+ }
+ }
+ else
+ {
+ Regex regex = ModuleName is not null ? new Regex(ModuleName, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant) : null;
+ ulong totalSize = 0;
+ foreach (IModule module in ModuleService.EnumerateModules().OrderBy((m) => m.ModuleIndex))
+ {
+ totalSize += module.ImageSize;
+ if (regex is null || !string.IsNullOrEmpty(module.FileName) && regex.IsMatch(Path.GetFileName(module.FileName)))
{
- DisplaySegments(module);
+ DisplayModule(module);
}
}
+ WriteLine("Total image size: {0}", totalSize);
+ }
+ }
+
+ void DisplayModule(IModule module)
+ {
+ if (Verbose)
+ {
+ WriteLine("{0} {1}", module.ModuleIndex, module.FileName);
+ WriteLine(" Address: {0:X16}", module.ImageBase);
+ WriteLine(" ImageSize: {0:X8}", module.ImageSize);
+ WriteLine(" IsPEImage: {0}", module.IsPEImage);
+ WriteLine(" IsManaged: {0}", module.IsManaged);
+ WriteLine(" IsFileLayout: {0}", module.IsFileLayout?.ToString() ?? "");
+ WriteLine(" IndexFileSize: {0}", module.IndexFileSize?.ToString("X8") ?? "");
+ WriteLine(" IndexTimeStamp: {0}", module.IndexTimeStamp?.ToString("X8") ?? "");
+ WriteLine(" Version: {0}", module.GetVersionData()?.ToString() ?? "");
+ string versionString = module.GetVersionString();
+ if (!string.IsNullOrEmpty(versionString))
+ {
+ WriteLine(" {0}", versionString);
+ }
+ foreach (PdbFileInfo pdbFileInfo in module.GetPdbFileInfos())
+ {
+ WriteLine(" PdbInfo: {0}", pdbFileInfo);
+ }
+ WriteLine(" BuildId: {0}", !module.BuildId.IsDefaultOrEmpty ? string.Concat(module.BuildId.Select((b) => b.ToString("x2"))) : "");
+ }
+ else
+ {
+ WriteLine("{0:X16} {1:X8} {2}", module.ImageBase, module.ImageSize, module.FileName);
+ }
+ if (Segment)
+ {
+ DisplaySegments(module);
}
- WriteLine("Total image size: {0}", totalSize);
}
public ITarget Target { get; set; }
diff --git a/src/Microsoft.Diagnostics.TestHelpers/IProcessLogger.cs b/src/Microsoft.Diagnostics.TestHelpers/IProcessLogger.cs
index 233372a1f5..f99080b752 100644
--- a/src/Microsoft.Diagnostics.TestHelpers/IProcessLogger.cs
+++ b/src/Microsoft.Diagnostics.TestHelpers/IProcessLogger.cs
@@ -15,6 +15,7 @@ public enum ProcessStream
public enum KillReason
{
TimedOut,
+ Stopped,
Unknown
}
diff --git a/src/Microsoft.Diagnostics.TestHelpers/ProcessRunner.cs b/src/Microsoft.Diagnostics.TestHelpers/ProcessRunner.cs
index e5bca1393d..9bee89c895 100644
--- a/src/Microsoft.Diagnostics.TestHelpers/ProcessRunner.cs
+++ b/src/Microsoft.Diagnostics.TestHelpers/ProcessRunner.cs
@@ -29,7 +29,7 @@ namespace Microsoft.Diagnostics.TestHelpers
/// only calls to Kill() and property getters invoked within the logging callbacks will be called
/// asynchronously.
///
- public class ProcessRunner
+ public class ProcessRunner : IDisposable
{
// All of the locals might accessed from multiple threads and need to read/written under
// the _lock. We also use the lock to synchronize property access on the process object.
@@ -232,6 +232,11 @@ public int ExitCode
get { lock (_lock) { return _p.ExitCode; } }
}
+ public int ModuleCount
+ {
+ get { lock (_lock) { return _p.Modules.Count; } }
+ }
+
public void StandardInputWriteLine(string line)
{
IProcessLogger[] loggers = null;
@@ -246,6 +251,7 @@ public void StandardInputWriteLine(string line)
logger.WriteLine(this, line, ProcessStream.StandardIn);
}
inputStream.WriteLine(line);
+ inputStream.Flush();
}
public Task Run()
@@ -262,6 +268,16 @@ public Task WaitForExit()
}
}
+ public void Dispose()
+ {
+ Process p = null;
+ lock (_lock)
+ {
+ p = _p;
+ }
+ p?.Dispose();
+ }
+
public ProcessRunner Start()
{
Process p = null;
diff --git a/src/Microsoft.Diagnostics.TestHelpers/TestConfiguration.cs b/src/Microsoft.Diagnostics.TestHelpers/TestConfiguration.cs
index ece382ad0d..5aa681063e 100644
--- a/src/Microsoft.Diagnostics.TestHelpers/TestConfiguration.cs
+++ b/src/Microsoft.Diagnostics.TestHelpers/TestConfiguration.cs
@@ -454,6 +454,10 @@ private string GetStringViewWithVersion(string version)
sb.Append(".");
sb.Append(debuggeeBuildProcess);
}
+ if (PublishSingleFile)
+ {
+ sb.Append(".singlefile");
+ }
if (!string.IsNullOrEmpty(version))
{
sb.Append(".");
@@ -781,6 +785,18 @@ public string LinkerPackageVersion
get { return GetValue("LinkerPackageVersion"); }
}
+ ///
+ /// The root of the dotnet install to use to run the test (i.e. $(RepoRootDir)/.dotnet-test)
+ ///
+ public string DotNetRoot
+ {
+ get
+ {
+ string dotnetRoot = GetValue("DotNetRoot");
+ return MakeCanonicalPath(dotnetRoot);
+ }
+ }
+
#region Runtime Features properties
///
diff --git a/src/Microsoft.Diagnostics.TestHelpers/TestOutputProcessLogger.cs b/src/Microsoft.Diagnostics.TestHelpers/TestOutputProcessLogger.cs
index 6966668dd7..475d45398f 100644
--- a/src/Microsoft.Diagnostics.TestHelpers/TestOutputProcessLogger.cs
+++ b/src/Microsoft.Diagnostics.TestHelpers/TestOutputProcessLogger.cs
@@ -12,9 +12,9 @@ namespace Microsoft.Diagnostics.TestHelpers
{
public class TestOutputProcessLogger : IProcessLogger
{
- string _timeFormat = "mm\\:ss\\.fff";
- ITestOutputHelper _output;
- StringBuilder[] _lineBuffers;
+ private static readonly string _timeFormat = "mm\\:ss\\.fff";
+ private readonly ITestOutputHelper _output;
+ private readonly StringBuilder[] _lineBuffers;
public TestOutputProcessLogger(ITestOutputHelper output)
{
@@ -69,7 +69,7 @@ public virtual void ProcessExited(ProcessRunner runner)
{
TimeSpan offset = runner.StartTime - DateTime.Now;
_output.WriteLine("}");
- _output.WriteLine("Exit code: " + runner.ExitCode + " ( " + offset.ToString(_timeFormat) + " elapsed)");
+ _output.WriteLine($"Process {runner.ProcessId} exited {runner.ExitCode} ({offset.ToString(_timeFormat)} elapsed)");
_output.WriteLine("");
}
}
@@ -79,16 +79,14 @@ public void ProcessKilled(ProcessRunner runner, KillReason reason)
lock (this)
{
TimeSpan offset = runner.StartTime - DateTime.Now;
- string reasonText = "";
- if (reason == KillReason.TimedOut)
+ string reasonText = reason switch
{
- reasonText = "Process timed out";
- }
- else if (reason == KillReason.Unknown)
- {
- reasonText = "Kill() was called";
- }
- _output.WriteLine(" Killing process: " + offset.ToString(_timeFormat) + ": " + reasonText);
+ KillReason.TimedOut => "Process timed out",
+ KillReason.Stopped => "Process was stopped",
+ KillReason.Unknown => "Kill() was called",
+ _ => "Reason Unknown"
+ };
+ _output.WriteLine($"Killing process {runner.ProcessId}: {offset.ToString(_timeFormat)} - {reasonText}");
}
}
diff --git a/src/SOS/SOS.Hosting/SymbolServiceExtensions.cs b/src/SOS/SOS.Hosting/SymbolServiceExtensions.cs
index 285b1cace5..2317f10981 100644
--- a/src/SOS/SOS.Hosting/SymbolServiceExtensions.cs
+++ b/src/SOS/SOS.Hosting/SymbolServiceExtensions.cs
@@ -120,18 +120,26 @@ public static int GetICorDebugMetadataLocator(
{
SymbolStoreKey key = PEFileKeyGenerator.GetKey(imagePath, imageTimestamp, imageSize);
string localFilePath = symbolService.DownloadFile(key);
- localFilePath += "\0"; // null terminate the string
- actualSize = localFilePath.Length;
-
- if (pathBufferSize > actualSize)
+ if (!string.IsNullOrWhiteSpace(localFilePath))
{
- Trace.TraceInformation($"GetICorDebugMetadataLocator: SUCCEEDED {localFilePath}");
- Marshal.Copy(localFilePath.ToCharArray(), 0, pwszPathBuffer, actualSize);
+ localFilePath += "\0"; // null terminate the string
+ actualSize = localFilePath.Length;
+
+ if (pathBufferSize > actualSize)
+ {
+ Trace.TraceInformation($"GetICorDebugMetadataLocator: SUCCEEDED {localFilePath}");
+ Marshal.Copy(localFilePath.ToCharArray(), 0, pwszPathBuffer, actualSize);
+ }
+ else
+ {
+ Trace.TraceError("GetICorDebugMetadataLocator: E_INSUFFICIENT_BUFFER");
+ hr = E_INSUFFICIENT_BUFFER;
+ }
}
- else
+ else
{
- Trace.TraceError("GetICorDebugMetadataLocator: E_INSUFFICIENT_BUFFER");
- hr = E_INSUFFICIENT_BUFFER;
+ Trace.TraceError($"GetICorDebugMetadataLocator: {imagePath} {imageTimestamp:X8} {imageSize:X8} download FAILED");
+ hr = HResult.E_FAIL;
}
}
else
diff --git a/src/SOS/SOS.UnitTests/ConfigFiles/Unix/Debugger.Tests.Config.txt b/src/SOS/SOS.UnitTests/ConfigFiles/Unix/Debugger.Tests.Config.txt
index 38cab1529a..3e76b20f05 100644
--- a/src/SOS/SOS.UnitTests/ConfigFiles/Unix/Debugger.Tests.Config.txt
+++ b/src/SOS/SOS.UnitTests/ConfigFiles/Unix/Debugger.Tests.Config.txt
@@ -24,19 +24,19 @@
true
false
-
- net6.0
+ net7.0
net5.0
+ net6.0
netcoreapp3.1
$(RepoRootDir)/src/SOS/SOS.UnitTests/Debuggees
sdk.prebuilt
$(RootBinDir)
-
- $(RepoRootDir)/.dotnet/dotnet
+ $(DotNetRoot)/dotnet
+ dotnet7=https://dnceng.pkgs.visualstudio.com/public/_packaging/dotnet7/nuget/v3/index.json;
dotnet6=https://dnceng.pkgs.visualstudio.com/public/_packaging/dotnet6/nuget/v3/index.json;
dotnet-core=https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json;
dotnet-public=https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public/nuget/v3/index.json
@@ -50,7 +50,7 @@
cli
$(RootBinDir)/Debuggees/SingleFile
$(BuildProjectFrameworkLatest)
- $(RuntimeVersionLatest)
+ $(SingleFileRuntimeLatestVersion)
true
@@ -66,9 +75,9 @@
$(RuntimeVersionLatest)
$(DotNetRoot)/shared/Microsoft.NETCore.App/$(RuntimeFrameworkVersion)
-
+
-
-
-
+
-
+
-
diff --git a/src/SOS/SOS.UnitTests/Debuggees/WebApp3/WebApp3.csproj b/src/SOS/SOS.UnitTests/Debuggees/WebApp3/WebApp3.csproj
index efd2369d3a..9474bd6558 100644
--- a/src/SOS/SOS.UnitTests/Debuggees/WebApp3/WebApp3.csproj
+++ b/src/SOS/SOS.UnitTests/Debuggees/WebApp3/WebApp3.csproj
@@ -1,7 +1,8 @@
- netcoreapp3.1;net5.0;net6.0
+ $(BuildProjectFramework)
+ $(BuildTargetFrameworks)
diff --git a/src/SOS/SOS.UnitTests/SOS.cs b/src/SOS/SOS.UnitTests/SOS.cs
index e2883e1c94..df0b0b4b6c 100644
--- a/src/SOS/SOS.UnitTests/SOS.cs
+++ b/src/SOS/SOS.UnitTests/SOS.cs
@@ -421,7 +421,7 @@ public async Task LLDBPluginTests(TestConfiguration config)
// Create the python script process runner
ProcessRunner processRunner = new ProcessRunner(program, arguments.ToString()).
- WithEnvironmentVariable("DOTNET_ROOT", config.DotNetRoot()).
+ WithEnvironmentVariable("DOTNET_ROOT", config.DotNetRoot).
WithLog(new TestRunner.TestLogger(outputHelper.IndentedOutput)).
WithTimeout(TimeSpan.FromMinutes(10)).
WithExpectedExitCode(0).
diff --git a/src/SOS/SOS.UnitTests/SOSRunner.cs b/src/SOS/SOS.UnitTests/SOSRunner.cs
index 7c6c3243e8..2b6c697e17 100644
--- a/src/SOS/SOS.UnitTests/SOSRunner.cs
+++ b/src/SOS/SOS.UnitTests/SOSRunner.cs
@@ -317,7 +317,7 @@ public static async Task CreateDump(TestInformation information)
// Create the debuggee process runner
ProcessRunner processRunner = new ProcessRunner(exePath, ReplaceVariables(variables, arguments.ToString())).
WithEnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0").
- WithEnvironmentVariable("DOTNET_ROOT", config.DotNetRoot()).
+ WithEnvironmentVariable("DOTNET_ROOT", config.DotNetRoot).
WithEnvironmentVariable("COMPlus_DbgEnableElfDumpOnMacOS", "1").
WithLog(new TestRunner.TestLogger(outputHelper.IndentedOutput)).
WithTimeout(TimeSpan.FromMinutes(10));
@@ -672,7 +672,7 @@ public static async Task StartDebugger(TestInformation information, D
// Create the native debugger process running
ProcessRunner processRunner = new ProcessRunner(debuggerPath, ReplaceVariables(variables, arguments.ToString())).
WithEnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0").
- WithEnvironmentVariable("DOTNET_ROOT", config.DotNetRoot()).
+ WithEnvironmentVariable("DOTNET_ROOT", config.DotNetRoot).
WithLog(scriptLogger).
WithTimeout(TimeSpan.FromMinutes(10));
@@ -682,6 +682,10 @@ public static async Task StartDebugger(TestInformation information, D
processRunner.WithExpectedExitCode(0);
}
+ // Disable W^E so that the bpmd command and the tests pass
+ // Issue: https://github.com/dotnet/diagnostics/issues/3126
+ processRunner.WithEnvironmentVariable("COMPlus_EnableWriteXorExecute", "0");
+
DumpType? dumpType = null;
if (action == DebuggerAction.LoadDump || action == DebuggerAction.LoadDumpWithDotNetDump)
{
@@ -901,9 +905,8 @@ public async Task LoadSosExtension()
{
commands.Add($"!SetHostRuntime {setHostRuntime}");
}
- // If there is no host runtime and a single-file app or a triage dump, add the path to runtime so SOS can find DAC/DBI.
- if ((isHostRuntimeNone && _config.PublishSingleFile) ||
- (_dumpType.HasValue && _dumpType.Value == DumpType.Triage))
+ // If a single-file app or a triage dump, add the path to runtime so SOS can find DAC/DBI locally.
+ if (_config.PublishSingleFile || (_dumpType.HasValue && _dumpType.Value == DumpType.Triage))
{
if (!string.IsNullOrEmpty(runtimeSymbolsPath))
{
@@ -921,8 +924,8 @@ public async Task LoadSosExtension()
{
commands.Add($"sethostruntime {setHostRuntime}");
}
- // If there is no host runtime and a single-file app, add the path to runtime so SOS can find DAC/DBI.
- if (isHostRuntimeNone && _config.PublishSingleFile)
+ // If a single-file app, add the path to runtime so SOS can find DAC/DBI locally.
+ if (_config.PublishSingleFile)
{
if (!string.IsNullOrEmpty(runtimeSymbolsPath))
{
@@ -938,6 +941,14 @@ public async Task LoadSosExtension()
case NativeDebugger.Gdb:
break;
case NativeDebugger.DotNetDump:
+ // If a single-file app, add the path to runtime so SOS can find DAC/DBI locally.
+ if (_config.PublishSingleFile)
+ {
+ if (!string.IsNullOrEmpty(runtimeSymbolsPath))
+ {
+ commands.Add($"setclrpath {runtimeSymbolsPath}");
+ }
+ }
if (!string.IsNullOrEmpty(setSymbolServer))
{
commands.Add($"setsymbolserver {setSymbolServer}");
@@ -1582,12 +1593,6 @@ public static string GDBPath(this TestConfiguration config)
return TestConfiguration.MakeCanonicalPath(gdbPath);
}
- public static string DotNetRoot(this TestConfiguration config)
- {
- string dotnetRoot = config.GetValue("DotNetRoot");
- return TestConfiguration.MakeCanonicalPath(dotnetRoot);
- }
-
public static string DotNetDumpHost(this TestConfiguration config)
{
string dotnetDumpHost = config.GetValue("DotNetDumpHost");
diff --git a/src/SOS/SOS.UnitTests/Scripts/ConcurrentDictionaries.script b/src/SOS/SOS.UnitTests/Scripts/ConcurrentDictionaries.script
index 8e513c3e09..cc08b813e1 100644
--- a/src/SOS/SOS.UnitTests/Scripts/ConcurrentDictionaries.script
+++ b/src/SOS/SOS.UnitTests/Scripts/ConcurrentDictionaries.script
@@ -8,6 +8,9 @@
!IFDEF:LLDB
IFDEF:NETCORE_OR_DOTNETDUMP
+# Load SOS even though it doesn't actually load the sos module on dotnet-dump but it runs some initial settings/commands.
+LOADSOS
+
COMMAND: dcd
VERIFY: Missing ConcurrentDictionary address
diff --git a/src/SOS/SOS.UnitTests/Scripts/DumpGen.script b/src/SOS/SOS.UnitTests/Scripts/DumpGen.script
index 1f8e489cb5..23b894e450 100644
--- a/src/SOS/SOS.UnitTests/Scripts/DumpGen.script
+++ b/src/SOS/SOS.UnitTests/Scripts/DumpGen.script
@@ -8,6 +8,9 @@
!IFDEF:LLDB
IFDEF:NETCORE_OR_DOTNETDUMP
+# Load SOS even though it doesn't actually load the sos module on dotnet-dump but it runs some initial settings/commands.
+LOADSOS
+
COMMAND: dumpgen
VERIFY: Generation argument is missing
diff --git a/src/SOS/SOS.UnitTests/Scripts/StackAndOtherTests.script b/src/SOS/SOS.UnitTests/Scripts/StackAndOtherTests.script
index f9026c031e..fa13732493 100644
--- a/src/SOS/SOS.UnitTests/Scripts/StackAndOtherTests.script
+++ b/src/SOS/SOS.UnitTests/Scripts/StackAndOtherTests.script
@@ -82,9 +82,12 @@ ENDIF:DESKTOP
SOSCOMMAND:SOSStatus
+# Issue:https://github.com/dotnet/diagnostics/issues/3155
+!IFDEF:MAJOR_RUNTIME_VERSION_GE_7
# Test eeversion command
SOSCOMMAND:EEVersion
VERIFY:\s+....*
+ENDIF:MAJOR_RUNTIME_VERSION_GE_7
# Verify that ClrStack with managed/native mixed works
SOSCOMMAND:ClrStack -f
diff --git a/src/SOS/SOS.UnitTests/Scripts/StackTests.script b/src/SOS/SOS.UnitTests/Scripts/StackTests.script
index 90d04f6578..6288d66c21 100644
--- a/src/SOS/SOS.UnitTests/Scripts/StackTests.script
+++ b/src/SOS/SOS.UnitTests/Scripts/StackTests.script
@@ -8,9 +8,12 @@ LOADSOS
# Issue: https://github.com/dotnet/diagnostics/issues/1567
!IFDEF:ALPINE
+# Issue:https://github.com/dotnet/diagnostics/issues/3155
+!IFDEF:MAJOR_RUNTIME_VERSION_GE_7
# Test eeversion command
SOSCOMMAND:EEVersion
VERIFY:\s+....*
+ENDIF:MAJOR_RUNTIME_VERSION_GE_7
ENDIF:ALPINE
# 1) Verifying that ClrStack with no options works
diff --git a/src/tests/CommonTestRunner/CommonTestRunner.csproj b/src/tests/CommonTestRunner/CommonTestRunner.csproj
new file mode 100644
index 0000000000..1f5b049fdf
--- /dev/null
+++ b/src/tests/CommonTestRunner/CommonTestRunner.csproj
@@ -0,0 +1,51 @@
+
+
+
+ netcoreapp3.1
+ $(OutputPath)$(TargetFramework)\Debugger.Tests.Common.txt
+
+
+
+
+
+
+
+
+ Debugger.Tests.Config.txt
+ Always
+
+
+ Debugger.Tests.Config.txt
+ Always
+
+
+ Debugger.Tests.Common.txt
+ Always
+
+
+
+
+
+
+
+ $(Configuration)
+ $(RepoRoot)
+
+]]>
+
+
+
+
+
+
+ @(ConfigFileEntries->Metadata("ConfigFileEntry"))
+
+
+
+
+
+
+
+
+
diff --git a/src/tests/CommonTestRunner/ConfigFiles/Unix/Debugger.Tests.Config.txt b/src/tests/CommonTestRunner/ConfigFiles/Unix/Debugger.Tests.Config.txt
new file mode 100644
index 0000000000..1518328255
--- /dev/null
+++ b/src/tests/CommonTestRunner/ConfigFiles/Unix/Debugger.Tests.Config.txt
@@ -0,0 +1,54 @@
+
+
+ $(RepoRootDir)/.dotnet-test
+
+
+ $(RepoRootDir)/artifacts
+ $(RootBinDir)/bin/$(OS).$(TargetArchitecture).$(TargetConfiguration)
+ $(RootBinDir)/TestResults/$(TargetConfiguration)/common.unittests_$(Timestamp)
+
+
+ net7.0
+ net6.0
+ net5.0
+ netcoreapp3.1
+
+ ProjectK
+ $(RepoRootDir)/src/tests
+ cli
+ sdk.prebuilt
+ $(RootBinDir)
+
+ $(DotNetRoot)/dotnet
+
+
+ dotnet6=https://dnceng.pkgs.visualstudio.com/public/_packaging/dotnet6/nuget/v3/index.json;
+ dotnet-core=https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json;
+ dotnet-public=https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public/nuget/v3/index.json
+
+
+
+
+
+
+
+
+
+
+ $(DotNetRoot)/dotnet
+ --fx-version $(RuntimeFrameworkVersion)
+
+ $(DotNetRoot)/dotnet
+ $(RootBinDir)/bin/dotnet-trace/$(TargetConfiguration)/netcoreapp3.1/dotnet-trace.dll
+
diff --git a/src/tests/CommonTestRunner/ConfigFiles/Windows/Debugger.Tests.Config.txt b/src/tests/CommonTestRunner/ConfigFiles/Windows/Debugger.Tests.Config.txt
new file mode 100644
index 0000000000..fc0ad14297
--- /dev/null
+++ b/src/tests/CommonTestRunner/ConfigFiles/Windows/Debugger.Tests.Config.txt
@@ -0,0 +1,53 @@
+
+
+ $(RepoRootDir)\.dotnet-test
+ $(RepoRootDir)\.dotnet-test\x86
+
+
+ $(RepoRootDir)\artifacts
+ $(RootBinDir)\bin\Windows_NT.$(TargetArchitecture).$(TargetConfiguration)
+ $(RootBinDir)\TestResults\$(TargetConfiguration)\common.unittests_$(Timestamp)
+
+
+ net7.0
+ net6.0
+ net5.0
+ netcoreapp3.1
+
+ ProjectK
+ $(RepoRootDir)\src\tests
+ sdk.prebuilt
+ $(RootBinDir)
+ $(DotNetRoot)\dotnet.exe
+
+
+ dotnet6=https://dnceng.pkgs.visualstudio.com/public/_packaging/dotnet6/nuget/v3/index.json;
+ dotnet-core=https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json;
+ dotnet-public=https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public/nuget/v3/index.json
+
+
+
+
+
+
+
+
+
+
+ $(DotNetRoot)\dotnet.exe
+ --fx-version $(RuntimeFrameworkVersion)
+
+ $(DotNetRoot)\dotnet.exe
+ $(RootBinDir)\bin\dotnet-trace\$(TargetConfiguration)\netcoreapp3.1\dotnet-trace.dll
+
diff --git a/src/tests/Microsoft.Diagnostics.NETCore.Client/DiagnosticPortsHelper.cs b/src/tests/CommonTestRunner/DiagnosticPortsHelper.cs
similarity index 92%
rename from src/tests/Microsoft.Diagnostics.NETCore.Client/DiagnosticPortsHelper.cs
rename to src/tests/CommonTestRunner/DiagnosticPortsHelper.cs
index c5b3122790..3abb327a32 100644
--- a/src/tests/Microsoft.Diagnostics.NETCore.Client/DiagnosticPortsHelper.cs
+++ b/src/tests/CommonTestRunner/DiagnosticPortsHelper.cs
@@ -4,11 +4,10 @@
using System.IO;
using System.Runtime.InteropServices;
-using Xunit.Abstractions;
-namespace Microsoft.Diagnostics.NETCore.Client
+namespace Microsoft.Diagnostics.CommonTestRunner
{
- internal static class DiagnosticPortsHelper
+ public static class DiagnosticPortsHelper
{
private const string DiagnosticPortsEnvName = "DOTNET_DiagnosticPorts";
private const string DefaultDiagnosticPortSuspendEnvName = "DOTNET_DefaultDiagnosticPortSuspend";
diff --git a/src/tests/CommonTestRunner/TestRunner.cs b/src/tests/CommonTestRunner/TestRunner.cs
new file mode 100644
index 0000000000..0837a05e86
--- /dev/null
+++ b/src/tests/CommonTestRunner/TestRunner.cs
@@ -0,0 +1,342 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+
+using Microsoft.Diagnostics.TestHelpers;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.IO;
+using System.IO.Pipes;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Xunit.Abstractions;
+
+namespace Microsoft.Diagnostics.CommonTestRunner
+{
+ public class TestRunner : IAsyncDisposable
+ {
+ private static readonly string _timeFormat = "mm\\:ss\\.fff";
+ private readonly ITestOutputHelper _outputHelper;
+ private readonly ProcessRunner _runner;
+ private readonly DateTime _startTime;
+ private readonly NamedPipeServerStream _pipeServer;
+
+ static TestRunner()
+ {
+ TestConfiguration.BaseDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
+ }
+
+ public static IEnumerable
diff --git a/src/tests/Microsoft.Diagnostics.DebugServices.UnitTests/Microsoft.Diagnostics.DebugServices.UnitTests.csproj b/src/tests/Microsoft.Diagnostics.DebugServices.UnitTests/Microsoft.Diagnostics.DebugServices.UnitTests.csproj
index d41a2bd2d9..ed9a4290f1 100644
--- a/src/tests/Microsoft.Diagnostics.DebugServices.UnitTests/Microsoft.Diagnostics.DebugServices.UnitTests.csproj
+++ b/src/tests/Microsoft.Diagnostics.DebugServices.UnitTests/Microsoft.Diagnostics.DebugServices.UnitTests.csproj
@@ -1,8 +1,7 @@
-
- netcoreapp3.1
+ net6.0
$(OutputPath)$(TargetFramework)\Debugger.Tests.Common.txt
1.0.257801
diff --git a/src/tests/Microsoft.Diagnostics.Monitoring.EventPipe/EventCounterPipelineUnitTests.cs b/src/tests/Microsoft.Diagnostics.Monitoring.EventPipe/EventCounterPipelineUnitTests.cs
index cf7cc8e976..bfb15c6b6b 100644
--- a/src/tests/Microsoft.Diagnostics.Monitoring.EventPipe/EventCounterPipelineUnitTests.cs
+++ b/src/tests/Microsoft.Diagnostics.Monitoring.EventPipe/EventCounterPipelineUnitTests.cs
@@ -3,14 +3,15 @@
// See the LICENSE file in the project root for more information.
using Microsoft.Diagnostics.NETCore.Client;
-using Microsoft.Diagnostics.NETCore.Client.UnitTests;
-using System;
+using Microsoft.Diagnostics.TestHelpers;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;
+using Xunit.Extensions;
+using TestRunner = Microsoft.Diagnostics.CommonTestRunner.TestRunner;
namespace Microsoft.Diagnostics.Monitoring.EventPipe.UnitTests
{
@@ -18,6 +19,8 @@ public class EventCounterPipelineUnitTests
{
private readonly ITestOutputHelper _output;
+ public static IEnumerable Configurations => TestRunner.Configurations;
+
public EventCounterPipelineUnitTests(ITestOutputHelper output)
{
_output = output;
@@ -83,8 +86,8 @@ private static string CreateKey(string providerName, string counterName)
}
}
- [Fact]
- public async Task TestCounterEventPipeline()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public async Task TestCounterEventPipeline(TestConfiguration config)
{
var expectedCounters = new[] { "cpu-usage", "working-set" };
string expectedProvider = "System.Runtime";
@@ -96,11 +99,9 @@ public async Task TestCounterEventPipeline()
var logger = new TestMetricsLogger(expectedMap, foundExpectedCountersSource);
- await using (var testExecution = StartTraceeProcess("CounterRemoteTest"))
+ await using (var testRunner = await PipelineTestUtilities.StartProcess(config, "CounterRemoteTest", _output))
{
- //TestRunner should account for start delay to make sure that the diagnostic pipe is available.
-
- var client = new DiagnosticsClient(testExecution.TestRunner.Pid);
+ var client = new DiagnosticsClient(testRunner.Pid);
await using EventCounterPipeline pipeline = new EventCounterPipeline(client, new EventPipeCounterPipelineSettings
{
@@ -116,10 +117,9 @@ public async Task TestCounterEventPipeline()
CounterIntervalSeconds = 1
}, new[] { logger });
- await PipelineTestUtilities.ExecutePipelineWithDebugee(
- _output,
+ await PipelineTestUtilities.ExecutePipelineWithTracee(
pipeline,
- testExecution,
+ testRunner,
foundExpectedCountersSource);
}
@@ -130,10 +130,5 @@ await PipelineTestUtilities.ExecutePipelineWithDebugee(
Assert.Equal(expectedCounters, actualMetrics);
Assert.True(logger.Metrics.All(m => string.Equals(m.Provider, expectedProvider)));
}
-
- private RemoteTestExecution StartTraceeProcess(string loggerCategory)
- {
- return RemoteTestExecution.StartProcess(CommonHelper.GetTraceePathWithArgs("EventPipeTracee") + " " + loggerCategory, _output);
- }
}
}
diff --git a/src/tests/Microsoft.Diagnostics.Monitoring.EventPipe/EventCounterTriggerTests.cs b/src/tests/Microsoft.Diagnostics.Monitoring.EventPipe/EventCounterTriggerTests.cs
index 257b6b078c..4b6fd60137 100644
--- a/src/tests/Microsoft.Diagnostics.Monitoring.EventPipe/EventCounterTriggerTests.cs
+++ b/src/tests/Microsoft.Diagnostics.Monitoring.EventPipe/EventCounterTriggerTests.cs
@@ -5,8 +5,9 @@
using Microsoft.Diagnostics.Monitoring.EventPipe.Triggers.EventCounter;
using Microsoft.Diagnostics.Monitoring.EventPipe.Triggers.Pipelines;
using Microsoft.Diagnostics.NETCore.Client;
-using Microsoft.Diagnostics.NETCore.Client.UnitTests;
+using Microsoft.Diagnostics.TestHelpers;
using System;
+using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Runtime.InteropServices;
@@ -15,6 +16,7 @@
using Xunit;
using Xunit.Abstractions;
using Xunit.Extensions;
+using TestRunner = Microsoft.Diagnostics.CommonTestRunner.TestRunner;
namespace Microsoft.Diagnostics.Monitoring.EventPipe.UnitTests
{
@@ -22,6 +24,8 @@ public class EventCounterTriggerTests
{
private readonly ITestOutputHelper _output;
+ public static IEnumerable Configurations => TestRunner.Configurations;
+
public EventCounterTriggerTests(ITestOutputHelper output)
{
_output = output;
@@ -315,12 +319,12 @@ public void EventCounterTriggerDropTest()
/// Tests that the trigger condition can be detected on a live application
/// using the EventPipeTriggerPipeline.
///
- [SkippableFact]
- public async Task EventCounterTriggerWithEventPipePipelineTest()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public async Task EventCounterTriggerWithEventPipePipelineTest(TestConfiguration config)
{
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && config.RuntimeFrameworkVersionMajor < 5)
{
- throw new SkipTestException("https://github.com/dotnet/diagnostics/issues/2568");
+ throw new SkipTestException("Unreliable on Linux .NET 3.1");
}
EventCounterTriggerSettings settings = new()
{
@@ -331,11 +335,9 @@ public async Task EventCounterTriggerWithEventPipePipelineTest()
CounterIntervalSeconds = 1
};
- await using (var testExecution = StartTraceeProcess("TriggerRemoteTest"))
+ await using (var testRunner = await PipelineTestUtilities.StartProcess(config, "TriggerRemoteTest SpinWait10", _output, testProcessTimeout: 2 * 60 * 1000))
{
- //TestRunner should account for start delay to make sure that the diagnostic pipe is available.
-
- DiagnosticsClient client = new(testExecution.TestRunner.Pid);
+ DiagnosticsClient client = new(testRunner.Pid);
TaskCompletionSource waitSource = new(TaskCreationOptions.RunContinuationsAsynchronously);
@@ -353,10 +355,9 @@ public async Task EventCounterTriggerWithEventPipePipelineTest()
waitSource.TrySetResult(null);
});
- await PipelineTestUtilities.ExecutePipelineWithDebugee(
- _output,
+ await PipelineTestUtilities.ExecutePipelineWithTracee(
pipeline,
- testExecution,
+ testRunner,
waitSource);
Assert.True(waitSource.Task.IsCompletedSuccessfully);
@@ -404,11 +405,6 @@ private void SimulateDataVerifyTrigger(EventCounterTriggerSettings settings, Cpu
}
}
- private RemoteTestExecution StartTraceeProcess(string loggerCategory)
- {
- return RemoteTestExecution.StartProcess(CommonHelper.GetTraceePathWithArgs("EventPipeTracee") + " " + loggerCategory + " SpinWait10", _output);
- }
-
private sealed class CpuData
{
public CpuData(double value, bool? result, bool drop = false)
diff --git a/src/tests/Microsoft.Diagnostics.Monitoring.EventPipe/EventLogsPipelineUnitTests.cs b/src/tests/Microsoft.Diagnostics.Monitoring.EventPipe/EventLogsPipelineUnitTests.cs
index a53777ed37..abd792d9f4 100644
--- a/src/tests/Microsoft.Diagnostics.Monitoring.EventPipe/EventLogsPipelineUnitTests.cs
+++ b/src/tests/Microsoft.Diagnostics.Monitoring.EventPipe/EventLogsPipelineUnitTests.cs
@@ -2,8 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using Microsoft.Diagnostics.CommonTestRunner;
using Microsoft.Diagnostics.NETCore.Client;
-using Microsoft.Diagnostics.NETCore.Client.UnitTests;
+using Microsoft.Diagnostics.TestHelpers;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
@@ -15,6 +16,7 @@
using Xunit;
using Xunit.Abstractions;
using Xunit.Extensions;
+using TestRunner = Microsoft.Diagnostics.CommonTestRunner.TestRunner;
namespace Microsoft.Diagnostics.Monitoring.EventPipe.UnitTests
{
@@ -26,6 +28,8 @@ public class EventLogsPipelineUnitTests
private readonly ITestOutputHelper _output;
+ public static IEnumerable Configurations => TestRunner.Configurations;
+
public EventLogsPipelineUnitTests(ITestOutputHelper output)
{
_output = output;
@@ -34,15 +38,10 @@ public EventLogsPipelineUnitTests(ITestOutputHelper output)
///
/// Test that all log events are collected if no filters are specified.
///
- [SkippableFact]
- public async Task TestLogsAllCategoriesAllLevels()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public async Task TestLogsAllCategoriesAllLevels(TestConfiguration config)
{
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- {
- throw new SkipTestException("https://github.com/dotnet/diagnostics/issues/2541");
- }
-
- using Stream outputStream = await GetLogsAsync(settings =>
+ using Stream outputStream = await GetLogsAsync(config, settings =>
{
settings.UseAppFilters = false;
});
@@ -63,15 +62,10 @@ public async Task TestLogsAllCategoriesAllLevels()
///
/// Test that log events at or above the default level are collected.
///
- [SkippableFact]
- public async Task TestLogsAllCategoriesDefaultLevel()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public async Task TestLogsAllCategoriesDefaultLevel(TestConfiguration config)
{
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- {
- throw new SkipTestException("https://github.com/dotnet/diagnostics/issues/2541");
- }
-
- using Stream outputStream = await GetLogsAsync(settings =>
+ using Stream outputStream = await GetLogsAsync(config, settings =>
{
settings.UseAppFilters = false;
settings.LogLevel = LogLevel.Warning;
@@ -91,15 +85,10 @@ public async Task TestLogsAllCategoriesDefaultLevel()
///
/// Test that log events at the default level are collected for categories without a specified level.
///
- [SkippableFact]
- public async Task TestLogsAllCategoriesDefaultLevelFallback()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public async Task TestLogsAllCategoriesDefaultLevelFallback(TestConfiguration config)
{
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- {
- throw new SkipTestException("https://github.com/dotnet/diagnostics/issues/2541");
- }
-
- using Stream outputStream = await GetLogsAsync(settings =>
+ using Stream outputStream = await GetLogsAsync(config, settings =>
{
settings.UseAppFilters = false;
settings.LogLevel = LogLevel.Error;
@@ -124,12 +113,13 @@ public async Task TestLogsAllCategoriesDefaultLevelFallback()
///
/// Test that LogLevel.None is not supported as the default log level.
///
- [Fact]
- public async Task TestLogsAllCategoriesDefaultLevelNoneNotSupported()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public async Task TestLogsAllCategoriesDefaultLevelNoneNotSupported(TestConfiguration config)
{
// Pipeline should throw PipelineException with inner exception of NotSupportedException.
PipelineException exception = await Assert.ThrowsAsync(
() => GetLogsAsync(
+ config,
settings =>
{
settings.UseAppFilters = false;
@@ -142,10 +132,10 @@ public async Task TestLogsAllCategoriesDefaultLevelNoneNotSupported()
///
/// Test that log events are collected for the categories and levels specified by the application.
///
- [Fact]
- public async Task TestLogsUseAppFilters()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public async Task TestLogsUseAppFilters(TestConfiguration config)
{
- using Stream outputStream = await GetLogsAsync();
+ using Stream outputStream = await GetLogsAsync(config);
Assert.True(outputStream.Length > 0, "No data written by logging process.");
@@ -161,15 +151,10 @@ public async Task TestLogsUseAppFilters()
/// Test that log events are collected for the categories and levels specified by the application
/// and for the categories and levels specified in the filter specs.
///
- [SkippableFact]
- public async Task TestLogsUseAppFiltersAndFilterSpecs()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public async Task TestLogsUseAppFiltersAndFilterSpecs(TestConfiguration config)
{
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- {
- throw new SkipTestException("https://github.com/dotnet/diagnostics/issues/2541");
- }
-
- using Stream outputStream = await GetLogsAsync(settings =>
+ using Stream outputStream = await GetLogsAsync(config, settings =>
{
settings.FilterSpecs = new Dictionary()
{
@@ -191,14 +176,10 @@ public async Task TestLogsUseAppFiltersAndFilterSpecs()
///
/// Test that log events are collected for wildcard categories.
///
- [SkippableFact]
- public async Task TestLogsWildcardCategory()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public async Task TestLogsWildcardCategory(TestConfiguration config)
{
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- {
- throw new SkipTestException("https://github.com/dotnet/diagnostics/issues/2568");
- }
- using Stream outputStream = await GetLogsAsync(settings =>
+ using Stream outputStream = await GetLogsAsync(config, settings =>
{
settings.UseAppFilters = false;
settings.LogLevel = LogLevel.Critical;
@@ -219,16 +200,14 @@ public async Task TestLogsWildcardCategory()
Assert.True(reader.EndOfStream, "Expected to have read all entries from stream.");
}
- private async Task GetLogsAsync(Action settingsCallback = null)
+ private async Task GetLogsAsync(TestConfiguration config, Action settingsCallback = null)
{
var outputStream = new MemoryStream();
- await using (var testExecution = StartTraceeProcess(LoggerRemoteTestName))
+ await using (var testRunner = await PipelineTestUtilities.StartProcess(config, LoggerRemoteTestName, _output))
{
- //TestRunner should account for start delay to make sure that the diagnostic pipe is available.
-
using var loggerFactory = new LoggerFactory(new[] { new TestStreamingLoggerProvider(outputStream) });
- var client = new DiagnosticsClient(testExecution.TestRunner.Pid);
+ var client = new DiagnosticsClient(testRunner.Pid);
var logSettings = new EventLogsPipelineSettings { Duration = Timeout.InfiniteTimeSpan };
if (null != settingsCallback)
@@ -237,7 +216,7 @@ private async Task GetLogsAsync(Action settin
}
await using var pipeline = new EventLogsPipeline(client, logSettings, loggerFactory);
- await PipelineTestUtilities.ExecutePipelineWithDebugee(_output, pipeline, testExecution);
+ await PipelineTestUtilities.ExecutePipelineWithTracee(pipeline, testRunner);
}
outputStream.Position = 0L;
@@ -335,11 +314,6 @@ private static void Validate(IDictionary values, params (st
}
}
- private RemoteTestExecution StartTraceeProcess(string loggerCategory)
- {
- return RemoteTestExecution.StartProcess(CommonHelper.GetTraceePathWithArgs("EventPipeTracee") + " " + loggerCategory, _output);
- }
-
private sealed class LoggerTestResult
{
public string Category { get; set; }
diff --git a/src/tests/Microsoft.Diagnostics.Monitoring.EventPipe/EventTracePipelineUnitTests.cs b/src/tests/Microsoft.Diagnostics.Monitoring.EventPipe/EventTracePipelineUnitTests.cs
index 13dd2bbb80..8c88286e28 100644
--- a/src/tests/Microsoft.Diagnostics.Monitoring.EventPipe/EventTracePipelineUnitTests.cs
+++ b/src/tests/Microsoft.Diagnostics.Monitoring.EventPipe/EventTracePipelineUnitTests.cs
@@ -2,22 +2,20 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using Microsoft.Diagnostics.CommonTestRunner;
+using Microsoft.Diagnostics.NETCore.Client;
+using Microsoft.Diagnostics.TestHelpers;
+using Microsoft.Diagnostics.Tracing;
using System;
using System.Collections.Generic;
-using System.Diagnostics;
using System.IO;
-using System.Linq;
using System.Runtime.InteropServices;
-using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
-using Microsoft.Diagnostics.NETCore.Client;
-using Microsoft.Diagnostics.NETCore.Client.UnitTests;
-using Microsoft.Diagnostics.Tracing;
-using Microsoft.Extensions.Logging;
using Xunit;
using Xunit.Abstractions;
using Xunit.Extensions;
+using TestRunner = Microsoft.Diagnostics.CommonTestRunner.TestRunner;
namespace Microsoft.Diagnostics.Monitoring.EventPipe.UnitTests
{
@@ -25,20 +23,20 @@ public class EventTracePipelineUnitTests
{
private readonly ITestOutputHelper _output;
+ public static IEnumerable Configurations => TestRunner.Configurations;
+
public EventTracePipelineUnitTests(ITestOutputHelper output)
{
_output = output;
}
- [Fact]
- public async Task TestTraceStopAsync()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public async Task TestTraceStopAsync(TestConfiguration config)
{
Stream eventStream = null;
- await using (var testExecution = StartTraceeProcess("TraceStopTest"))
+ await using (var testRunner = await PipelineTestUtilities.StartProcess(config, "TraceStopTest", _output))
{
- //TestRunner should account for start delay to make sure that the diagnostic pipe is available.
-
- var client = new DiagnosticsClient(testExecution.TestRunner.Pid);
+ var client = new DiagnosticsClient(testRunner.Pid);
var settings = new EventTracePipelineSettings()
{
Duration = Timeout.InfiniteTimeSpan,
@@ -67,10 +65,9 @@ public async Task TestTraceStopAsync()
await Task.Run(() => Assert.True(eventSource.Process()), token);
});
- await PipelineTestUtilities.ExecutePipelineWithDebugee(
- _output,
+ await PipelineTestUtilities.ExecutePipelineWithTracee(
pipeline,
- testExecution,
+ testRunner,
foundProviderSource);
}
@@ -78,21 +75,19 @@ await PipelineTestUtilities.ExecutePipelineWithDebugee(
Assert.Throws(() => eventStream.Read(new byte[4], 0, 4));
}
- [SkippableFact]
- public async Task TestEventStreamCleanup()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public async Task TestEventStreamCleanup(TestConfiguration config)
{
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
- throw new SkipTestException("Test debugee sigfaults for OSX/Linux");
+ throw new SkipTestException("Test tracee sigfaults for OSX/Linux");
}
Stream eventStream = null;
using var cancellationTokenSource = new CancellationTokenSource();
- await using (var testExecution = StartTraceeProcess("TestEventStreamCleanup"))
+ await using (var testRunner = await PipelineTestUtilities.StartProcess(config, "TestEventStreamCleanup", _output))
{
- //TestRunner should account for start delay to make sure that the diagnostic pipe is available.
-
- var client = new DiagnosticsClient(testExecution.TestRunner.Pid);
+ var client = new DiagnosticsClient(testRunner.Pid);
var settings = new EventTracePipelineSettings()
{
Duration = Timeout.InfiniteTimeSpan,
@@ -108,20 +103,14 @@ public async Task TestEventStreamCleanup()
});
await Assert.ThrowsAsync(
- async () => await PipelineTestUtilities.ExecutePipelineWithDebugee(
- _output,
+ async () => await PipelineTestUtilities.ExecutePipelineWithTracee(
pipeline,
- testExecution,
+ testRunner,
cancellationTokenSource.Token));
}
//Validate that the stream is only valid for the lifetime of the callback in the trace pipeline.
Assert.Throws(() => eventStream.Read(new byte[4], 0, 4));
}
-
- private RemoteTestExecution StartTraceeProcess(string loggerCategory)
- {
- return RemoteTestExecution.StartProcess(CommonHelper.GetTraceePathWithArgs("EventPipeTracee") + " " + loggerCategory, _output);
- }
}
}
diff --git a/src/tests/Microsoft.Diagnostics.Monitoring.EventPipe/Microsoft.Diagnostics.Monitoring.EventPipe.UnitTests.csproj b/src/tests/Microsoft.Diagnostics.Monitoring.EventPipe/Microsoft.Diagnostics.Monitoring.EventPipe.UnitTests.csproj
index 8410ef25cd..2b066212c5 100644
--- a/src/tests/Microsoft.Diagnostics.Monitoring.EventPipe/Microsoft.Diagnostics.Monitoring.EventPipe.UnitTests.csproj
+++ b/src/tests/Microsoft.Diagnostics.Monitoring.EventPipe/Microsoft.Diagnostics.Monitoring.EventPipe.UnitTests.csproj
@@ -1,16 +1,13 @@
- netcoreapp3.1;net5.0
+ $(UnitTestTargetFrameworks)
-
-
- false
-
+
diff --git a/src/tests/Microsoft.Diagnostics.Monitoring.EventPipe/PipelineTestUtilities.cs b/src/tests/Microsoft.Diagnostics.Monitoring.EventPipe/PipelineTestUtilities.cs
index bc7992542a..4941ff9ecd 100644
--- a/src/tests/Microsoft.Diagnostics.Monitoring.EventPipe/PipelineTestUtilities.cs
+++ b/src/tests/Microsoft.Diagnostics.Monitoring.EventPipe/PipelineTestUtilities.cs
@@ -2,84 +2,85 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using Microsoft.Diagnostics.NETCore.Client.UnitTests;
+using Microsoft.Diagnostics.TestHelpers;
using System;
using System.Threading;
using System.Threading.Tasks;
using Xunit.Abstractions;
+using TestRunner = Microsoft.Diagnostics.CommonTestRunner.TestRunner;
namespace Microsoft.Diagnostics.Monitoring.EventPipe.UnitTests
{
internal static class PipelineTestUtilities
{
- private static readonly TimeSpan DefaultPipelineRunTimeout = TimeSpan.FromMinutes(1);
+ private static readonly TimeSpan DefaultPipelineRunTimeout = TimeSpan.FromMinutes(2);
- public static async Task ExecutePipelineWithDebugee(
- ITestOutputHelper outputHelper,
+ public static async Task StartProcess(TestConfiguration config, string testArguments, ITestOutputHelper outputHelper, int testProcessTimeout = 60_000)
+ {
+ TestRunner runner = await TestRunner.Create(config, outputHelper, "EventPipeTracee", testArguments);
+ await runner.Start(testProcessTimeout);
+ return runner;
+ }
+
+ public static async Task ExecutePipelineWithTracee(
Pipeline pipeline,
- RemoteTestExecution testExecution,
+ TestRunner testRunner,
TaskCompletionSource waitTaskSource = null)
{
using var cancellation = new CancellationTokenSource(DefaultPipelineRunTimeout);
- await ExecutePipelineWithDebugee(
- outputHelper,
+ await ExecutePipelineWithTracee(
pipeline,
- testExecution,
+ testRunner,
cancellation.Token,
waitTaskSource);
}
- public static async Task ExecutePipelineWithDebugee(
- ITestOutputHelper outputHelper,
+ public static async Task ExecutePipelineWithTracee(
EventSourcePipeline pipeline,
- RemoteTestExecution testExecution,
+ TestRunner testRunner,
TaskCompletionSource waitTaskSource = null)
where T : EventSourcePipelineSettings
{
using var cancellation = new CancellationTokenSource(DefaultPipelineRunTimeout);
- await ExecutePipelineWithDebugee(
- outputHelper,
+ await ExecutePipelineWithTracee(
pipeline,
(p, t) => p.StartAsync(t),
- testExecution,
+ testRunner,
cancellation.Token,
waitTaskSource);
}
- public static Task ExecutePipelineWithDebugee(
- ITestOutputHelper outputHelper,
+ public static Task ExecutePipelineWithTracee(
Pipeline pipeline,
- RemoteTestExecution testExecution,
+ TestRunner testRunner,
CancellationToken token,
TaskCompletionSource waitTaskSource = null)
{
- return ExecutePipelineWithDebugee(
- outputHelper,
+ return ExecutePipelineWithTracee(
pipeline,
(p, t) => Task.FromResult(p.RunAsync(t)),
- testExecution,
+ testRunner,
token,
waitTaskSource);
}
- private static async Task ExecutePipelineWithDebugee(
- ITestOutputHelper outputHelper,
+ private static async Task ExecutePipelineWithTracee(
TPipeline pipeline,
Func> startPipelineAsync,
- RemoteTestExecution testExecution,
+ TestRunner testRunner,
CancellationToken token,
TaskCompletionSource waitTaskSource = null)
where TPipeline : Pipeline
{
Task runTask = await startPipelineAsync(pipeline, token);
- //Begin event production
- testExecution.SendSignal();
+ // Begin event production
+ testRunner.WakeupTracee();
- //Wait for event production to be done
- testExecution.WaitForSignal();
+ // Wait for event production to be done
+ testRunner.WaitForSignal();
try
{
@@ -88,7 +89,7 @@ private static async Task ExecutePipelineWithDebugee(
{
using var _ = token.Register(() =>
{
- outputHelper.WriteLine("Did not receive completion signal before cancellation.");
+ testRunner.WriteLine("Did not receive completion signal before cancellation.");
waitTaskSource.TrySetCanceled(token);
});
@@ -103,8 +104,8 @@ private static async Task ExecutePipelineWithDebugee(
}
finally
{
- //Signal for debugee that's ok to end/move on.
- testExecution.SendSignal();
+ // Signal for debugee that's ok to end/move on.
+ testRunner.WakeupTracee();
}
}
}
diff --git a/src/tests/Microsoft.Diagnostics.Monitoring/Microsoft.Diagnostics.Monitoring.UnitTests.csproj b/src/tests/Microsoft.Diagnostics.Monitoring/Microsoft.Diagnostics.Monitoring.UnitTests.csproj
index a7ee91a2ff..7b2263b52e 100644
--- a/src/tests/Microsoft.Diagnostics.Monitoring/Microsoft.Diagnostics.Monitoring.UnitTests.csproj
+++ b/src/tests/Microsoft.Diagnostics.Monitoring/Microsoft.Diagnostics.Monitoring.UnitTests.csproj
@@ -1,17 +1,13 @@
- netcoreapp3.1;net5.0
+ $(UnitTestTargetFrameworks)
-
-
- false
-
diff --git a/src/tests/Microsoft.Diagnostics.Monitoring/PipelineTests.cs b/src/tests/Microsoft.Diagnostics.Monitoring/PipelineTests.cs
index 227e4a2927..eab58c889f 100644
--- a/src/tests/Microsoft.Diagnostics.Monitoring/PipelineTests.cs
+++ b/src/tests/Microsoft.Diagnostics.Monitoring/PipelineTests.cs
@@ -2,11 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using Microsoft.Diagnostics.Monitoring;
-using Microsoft.Diagnostics.Tracing.Parsers.Kernel;
using System;
-using System.Collections.Generic;
-using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
diff --git a/src/tests/Microsoft.Diagnostics.NETCore.Client/CommonHelper.cs b/src/tests/Microsoft.Diagnostics.NETCore.Client/CommonHelper.cs
deleted file mode 100644
index 965759bc5e..0000000000
--- a/src/tests/Microsoft.Diagnostics.NETCore.Client/CommonHelper.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.IO;
-using System.Runtime.InteropServices;
-
-namespace Microsoft.Diagnostics.NETCore.Client
-{
- public partial class CommonHelper
- {
- public static string HostExe = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ?
- (RuntimeInformation.ProcessArchitecture == Architecture.X86 ?
- "..\\..\\..\\..\\..\\.dotnet\\x86\\dotnet.exe" :
- "..\\..\\..\\..\\..\\.dotnet\\dotnet.exe") :
- "../../../../../.dotnet/dotnet";
-
- ///
- /// gets the tracee path, with args for the dotnet host for finding the correct version of the runtime.!--
- /// example: "--fx-version 5.0.0-rc.1.12345.12 /path/to/tracee"
- ///
- public static string GetTraceePathWithArgs(string traceeName = "Tracee", string targetFramework = "netcoreapp3.1")
- {
- var curPath = Directory.GetCurrentDirectory();
-
- var traceePath = curPath
- .Replace(System.Reflection.Assembly.GetCallingAssembly().GetName().Name, traceeName)
- .Replace("netcoreapp3.1", targetFramework);
-
- traceePath = Path.Combine(traceePath, Path.ChangeExtension(traceeName, ".dll"));
-
-
- // CurrentDARCVersion is generated at build time by Microsoft.Diagnostics.NETCore.Client.UnitTests.csproj
- // This value will be set to whatever the value for the newest runtime in eng/Versions.Props is
- if (targetFramework.Equals("net5.0", StringComparison.InvariantCultureIgnoreCase))
- traceePath = $"--fx-version {CurrentDARCVersion} {traceePath}";
-
- return traceePath;
- }
- }
-}
\ No newline at end of file
diff --git a/src/tests/Microsoft.Diagnostics.NETCore.Client/EventPipeSessionTests.cs b/src/tests/Microsoft.Diagnostics.NETCore.Client/EventPipeSessionTests.cs
index 8a761289ca..1a3c39212e 100644
--- a/src/tests/Microsoft.Diagnostics.NETCore.Client/EventPipeSessionTests.cs
+++ b/src/tests/Microsoft.Diagnostics.NETCore.Client/EventPipeSessionTests.cs
@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using Microsoft.Diagnostics.CommonTestRunner;
+using Microsoft.Diagnostics.TestHelpers;
using Microsoft.Diagnostics.Tracing;
using System;
using System.Collections.Generic;
@@ -9,71 +11,72 @@
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;
+using Xunit.Extensions;
+using TestRunner = Microsoft.Diagnostics.CommonTestRunner.TestRunner;
namespace Microsoft.Diagnostics.NETCore.Client
{
public class EventPipeSessionTests
{
- private readonly ITestOutputHelper output;
+ private readonly ITestOutputHelper _output;
+
+ public static IEnumerable Configurations => TestRunner.Configurations;
public EventPipeSessionTests(ITestOutputHelper outputHelper)
{
- output = outputHelper;
+ _output = outputHelper;
}
- [Fact]
- public Task BasicEventPipeSessionTest()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public Task BasicEventPipeSessionTest(TestConfiguration config)
{
- return BasicEventPipeSessionTestCore(useAsync: false);
+ return BasicEventPipeSessionTestCore(config, useAsync: false);
}
- [Fact]
- public Task BasicEventPipeSessionTestAsync()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public Task BasicEventPipeSessionTestAsync(TestConfiguration config)
{
- return BasicEventPipeSessionTestCore(useAsync: true);
+ return BasicEventPipeSessionTestCore(config, useAsync: true);
}
///
/// A simple test that checks if we can create an EventPipeSession on a child process
///
- private async Task BasicEventPipeSessionTestCore(bool useAsync)
-
+ private async Task BasicEventPipeSessionTestCore(TestConfiguration config, bool useAsync)
{
- using TestRunner runner = new TestRunner(CommonHelper.GetTraceePathWithArgs(), output);
- runner.Start(timeoutInMSPipeCreation: 15_000, testProcessTimeout: 60_000);
+ await using TestRunner runner = await TestRunner.Create(config, _output, "Tracee");
+ await runner.Start(testProcessTimeout: 60_000);
DiagnosticsClientApiShim clientShim = new DiagnosticsClientApiShim(new DiagnosticsClient(runner.Pid), useAsync);
- using (var session = await clientShim.StartEventPipeSession(new List()
+ // Don't dispose of the session here because it unnecessarily hangs the test for 30 secs
+ EventPipeSession session = await clientShim.StartEventPipeSession(new List()
{
new EventPipeProvider("Microsoft-Windows-DotNETRuntime", EventLevel.Informational)
- }))
- {
- Assert.True(session.EventStream != null);
- }
+ });
+ Assert.True(session.EventStream != null);
runner.Stop();
}
- [Fact]
- public Task EventPipeSessionStreamTest()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public Task EventPipeSessionStreamTest(TestConfiguration config)
{
- return EventPipeSessionStreamTestCore(useAsync: false);
+ return EventPipeSessionStreamTestCore(config, useAsync: false);
}
- [Fact]
- public Task EventPipeSessionStreamTestAsync()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public Task EventPipeSessionStreamTestAsync(TestConfiguration config)
{
- return EventPipeSessionStreamTestCore(useAsync: true);
+ return EventPipeSessionStreamTestCore(config, useAsync: true);
}
///
/// Checks if we can create an EventPipeSession and can get some expected events out of it.
///
- private async Task EventPipeSessionStreamTestCore(bool useAsync)
+ private async Task EventPipeSessionStreamTestCore(TestConfiguration config, bool useAsync)
{
- TestRunner runner = new TestRunner(CommonHelper.GetTraceePathWithArgs(), output);
- runner.Start(timeoutInMSPipeCreation: 15_000, testProcessTimeout: 60_000);
+ await using TestRunner runner = await TestRunner.Create(config, _output, "Tracee");
+ await runner.Start(testProcessTimeout: 60_000);
DiagnosticsClientApiShim clientShim = new DiagnosticsClientApiShim(new DiagnosticsClient(runner.Pid), useAsync);
- runner.PrintStatus();
- output.WriteLine($"[{DateTime.Now.ToString()}] Trying to start an EventPipe session on process {runner.Pid}");
+ runner.WriteLine($"Trying to start an EventPipe session");
using (var session = await clientShim.StartEventPipeSession(new List()
{
new EventPipeProvider("System.Runtime", EventLevel.Informational, 0, new Dictionary() {
@@ -86,47 +89,46 @@ private async Task EventPipeSessionStreamTestCore(bool useAsync)
Task streamTask = Task.Run(() => {
var source = new EventPipeEventSource(session.EventStream);
source.Dynamic.All += (TraceEvent obj) => {
- output.WriteLine("Got an event");
+ runner.WriteLine("Got an event");
evntCnt += 1;
};
try
{
source.Process();
}
- catch (Exception e)
+ catch (Exception ex)
{
// This exception can happen if the target process exits while EventPipeEventSource is in the middle of reading from the pipe.
- output.WriteLine("Error encountered while processing events");
- output.WriteLine(e.ToString());
+ runner.WriteLine($"Error encountered while processing events {ex}");
}
finally
{
- runner.Stop();
+ runner.WakeupTracee();
}
});
- output.WriteLine("Waiting for stream Task");
+ runner.WriteLine("Waiting for stream Task");
streamTask.Wait(10000);
- output.WriteLine("Done waiting for stream Task");
+ runner.WriteLine("Done waiting for stream Task");
Assert.True(evntCnt > 0);
}
}
- [Fact]
- public Task EventPipeSessionUnavailableTest()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public Task EventPipeSessionUnavailableTest(TestConfiguration config)
{
- return EventPipeSessionUnavailableTestCore(useAsync: false);
+ return EventPipeSessionUnavailableTestCore(config, useAsync: false);
}
- [Fact]
- public Task EventPipeSessionUnavailableTestAsync()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public Task EventPipeSessionUnavailableTestAsync(TestConfiguration config)
{
- return EventPipeSessionUnavailableTestCore(useAsync: true);
+ return EventPipeSessionUnavailableTestCore(config, useAsync: true);
}
///
/// Tries to start an EventPipe session on a non-existent process
///
- private async Task EventPipeSessionUnavailableTestCore(bool useAsync)
+ private async Task EventPipeSessionUnavailableTestCore(TestConfiguration config, bool useAsync)
{
List pids = new List(DiagnosticsClient.GetPublishedProcesses());
int arbitraryPid = 1;
@@ -139,30 +141,29 @@ await Assert.ThrowsAsync(() => clientShim.StartEven
}));
}
- [Fact]
- public Task StartEventPipeSessionWithSingleProviderTest()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public Task StartEventPipeSessionWithSingleProviderTest(TestConfiguration config)
{
- return StartEventPipeSessionWithSingleProviderTestCore(useAsync: false);
+ return StartEventPipeSessionWithSingleProviderTestCore(config, useAsync: false);
}
- [Fact]
- public Task StartEventPipeSessionWithSingleProviderTestAsync()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public Task StartEventPipeSessionWithSingleProviderTestAsync(TestConfiguration config)
{
- return StartEventPipeSessionWithSingleProviderTestCore(useAsync: true);
+ return StartEventPipeSessionWithSingleProviderTestCore(config, useAsync: true);
}
///
/// Test for the method overload: public EventPipeSession StartEventPipeSession(EventPipeProvider provider, bool requestRundown=true, int circularBufferMB=256)
///
- private async Task StartEventPipeSessionWithSingleProviderTestCore(bool useAsync)
+ private async Task StartEventPipeSessionWithSingleProviderTestCore(TestConfiguration config, bool useAsync)
{
- using TestRunner runner = new TestRunner(CommonHelper.GetTraceePathWithArgs(), output);
- runner.Start(timeoutInMSPipeCreation: 15_000, testProcessTimeout: 60_000);
+ await using TestRunner runner = await TestRunner.Create(config, _output, "Tracee");
+ await runner.Start(testProcessTimeout: 60_000);
DiagnosticsClientApiShim clientShim = new DiagnosticsClientApiShim(new DiagnosticsClient(runner.Pid), useAsync);
- using (var session = await clientShim.StartEventPipeSession(new EventPipeProvider("Microsoft-Windows-DotNETRuntime", EventLevel.Informational)))
- {
- Assert.True(session.EventStream != null);
- }
+ // Don't dispose of the session here because it unnecessarily hangs the test for 30 secs
+ EventPipeSession session = await clientShim.StartEventPipeSession(new EventPipeProvider("Microsoft-Windows-DotNETRuntime", EventLevel.Informational));
+ Assert.True(session.EventStream != null);
runner.Stop();
}
}
diff --git a/src/tests/Microsoft.Diagnostics.NETCore.Client/GetProcessEnvironmentTests.cs b/src/tests/Microsoft.Diagnostics.NETCore.Client/GetProcessEnvironmentTests.cs
index 5a27f825fc..d191b42e20 100644
--- a/src/tests/Microsoft.Diagnostics.NETCore.Client/GetProcessEnvironmentTests.cs
+++ b/src/tests/Microsoft.Diagnostics.NETCore.Client/GetProcessEnvironmentTests.cs
@@ -2,53 +2,61 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System;
+using Microsoft.Diagnostics.TestHelpers;
using System.Collections.Generic;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;
+using Xunit.Extensions;
+using TestRunner = Microsoft.Diagnostics.CommonTestRunner.TestRunner;
namespace Microsoft.Diagnostics.NETCore.Client
{
public class ProcessEnvironmentTests
{
- private readonly ITestOutputHelper output;
+ private readonly ITestOutputHelper _output;
+
+ public static IEnumerable Configurations => TestRunner.Configurations;
public ProcessEnvironmentTests(ITestOutputHelper outputHelper)
{
- output = outputHelper;
+ _output = outputHelper;
}
- [Fact]
- public Task BasicEnvTest()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public Task BasicEnvTest(TestConfiguration config)
{
- return BasicEnvTestCore(useAsync: false);
+ return BasicEnvTestCore(config, useAsync: false);
}
- [Fact]
- public Task BasicEnvTestAsync()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public Task BasicEnvTestAsync(TestConfiguration config)
{
- return BasicEnvTestCore(useAsync: true);
+ return BasicEnvTestCore(config, useAsync: true);
}
///
/// A simple test that collects process environment.
///
- private async Task BasicEnvTestCore(bool useAsync)
+ private async Task BasicEnvTestCore(TestConfiguration config, bool useAsync)
{
+ if (config.RuntimeFrameworkVersionMajor < 5)
+ {
+ throw new SkipTestException("Not supported on < .NET 5.0");
+ }
// as the attribute says, this test requires 5.0-rc1 or newer. This has been tested locally on
// an rc1 build and passes. It is equivalent to the dotnet/runtime version of this test.
- using TestRunner runner = new TestRunner(CommonHelper.GetTraceePathWithArgs(targetFramework: "net5.0"), output);
+ await using TestRunner runner = await TestRunner.Create(config, _output, "Tracee");
string testKey = "FOO";
string testVal = "BAR";
runner.AddEnvVar(testKey, testVal);
- runner.Start(timeoutInMSPipeCreation: 3000);
+ await runner.Start();
var clientShim = new DiagnosticsClientApiShim(new DiagnosticsClient(runner.Pid), useAsync);
Dictionary env = await clientShim.GetProcessEnvironment();
Assert.True(env.ContainsKey(testKey) && env[testKey].Equals(testVal));
- runner.Stop();
+ runner.WakeupTracee();
}
}
}
diff --git a/src/tests/Microsoft.Diagnostics.NETCore.Client/GetProcessInfoTests.cs b/src/tests/Microsoft.Diagnostics.NETCore.Client/GetProcessInfoTests.cs
index 53b514b1e4..2b986fabf8 100644
--- a/src/tests/Microsoft.Diagnostics.NETCore.Client/GetProcessInfoTests.cs
+++ b/src/tests/Microsoft.Diagnostics.NETCore.Client/GetProcessInfoTests.cs
@@ -2,10 +2,16 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using Microsoft.Diagnostics.CommonTestRunner;
+using Microsoft.Diagnostics.TestHelpers;
using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;
+using Xunit.Extensions;
+using TestRunner = Microsoft.Diagnostics.CommonTestRunner.TestRunner;
namespace Microsoft.Diagnostics.NETCore.Client
{
@@ -13,43 +19,49 @@ public class GetProcessInfoTests
{
private readonly ITestOutputHelper _output;
+ public static IEnumerable Configurations => TestRunner.Configurations;
+
public GetProcessInfoTests(ITestOutputHelper outputHelper)
{
_output = outputHelper;
}
- [Fact]
- public Task BasicProcessInfoNoSuspendTest()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public Task BasicProcessInfoNoSuspendTest(TestConfiguration config)
{
- return BasicProcessInfoTestCore(useAsync: false, suspend: false);
+ return BasicProcessInfoTestCore(config, useAsync: false, suspend: false);
}
- [Fact]
- public Task BasicProcessInfoNoSuspendTestAsync()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public Task BasicProcessInfoNoSuspendTestAsync(TestConfiguration config)
{
- return BasicProcessInfoTestCore(useAsync: true, suspend: false);
+ return BasicProcessInfoTestCore(config, useAsync: true, suspend: false);
}
- [Fact]
- public Task BasicProcessInfoSuspendTest()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public Task BasicProcessInfoSuspendTest(TestConfiguration config)
{
- return BasicProcessInfoTestCore(useAsync: false, suspend: true);
+ return BasicProcessInfoTestCore(config, useAsync: false, suspend: true);
}
- [Fact]
- public Task BasicProcessInfoSuspendTestAsync()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public Task BasicProcessInfoSuspendTestAsync(TestConfiguration config)
{
- return BasicProcessInfoTestCore(useAsync: true, suspend: true);
+ return BasicProcessInfoTestCore(config, useAsync: true, suspend: true);
}
- private async Task BasicProcessInfoTestCore(bool useAsync, bool suspend)
+ private async Task BasicProcessInfoTestCore(TestConfiguration config, bool useAsync, bool suspend)
{
- using TestRunner runner = new TestRunner(CommonHelper.GetTraceePathWithArgs(targetFramework: "net5.0"), _output);
+ if (config.RuntimeFrameworkVersionMajor < 5)
+ {
+ throw new SkipTestException("Not supported on < .NET 5.0");
+ }
+ await using TestRunner runner = await TestRunner.Create(config, _output, "Tracee");
if (suspend)
{
runner.SuspendDefaultDiagnosticPort();
}
- runner.Start();
+ await runner.Start(testProcessTimeout: 60_000, waitForTracee: !suspend);
try
{
@@ -64,23 +76,36 @@ private async Task BasicProcessInfoTestCore(bool useAsync, bool suspend)
Assert.True(string.IsNullOrEmpty(processInfoBeforeResume.ManagedEntrypointAssemblyName));
await clientShim.ResumeRuntime();
+
+ await runner.WaitForTracee();
}
// The entrypoint information is available some short time after the runtime
// begins to execute. Retry getting process information until entrypoint is available.
ProcessInfo processInfo = await GetProcessInfoWithEntrypointAsync(clientShim);
ValidateProcessInfo(runner.Pid, processInfo);
+
+ // This is only true if targetFramework for the tracee app is greater than
Assert.Equal("Tracee", processInfo.ManagedEntrypointAssemblyName);
- // Validate values before resume (except for entrypoint) are the same after resume.
if (suspend)
{
Assert.Equal(processInfoBeforeResume.ProcessId, processInfo.ProcessId);
Assert.Equal(processInfoBeforeResume.RuntimeInstanceCookie, processInfo.RuntimeInstanceCookie);
- Assert.Equal(processInfoBeforeResume.CommandLine, processInfo.CommandLine);
Assert.Equal(processInfoBeforeResume.OperatingSystem, processInfo.OperatingSystem);
Assert.Equal(processInfoBeforeResume.ProcessArchitecture, processInfo.ProcessArchitecture);
Assert.Equal(processInfoBeforeResume.ClrProductVersionString, processInfo.ClrProductVersionString);
+ // Given we are in a .NET 6.0+ app, we should have ProcessInfo2 available. Pre and post pause should differ.
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ Assert.Equal($"\"{runner.ExePath}\" {runner.Arguments}", processInfoBeforeResume.CommandLine);
+ Assert.Equal($"\"{runner.ExePath}\" {runner.Arguments}", processInfo.CommandLine);
+ }
+ else
+ {
+ Assert.Equal($"{runner.ExePath}", processInfoBeforeResume.CommandLine);
+ Assert.Equal($"{runner.ExePath} {runner.ManagedArguments}", processInfo.CommandLine);
+ }
}
}
finally
diff --git a/src/tests/Microsoft.Diagnostics.NETCore.Client/GetPublishedProcessesTests.cs b/src/tests/Microsoft.Diagnostics.NETCore.Client/GetPublishedProcessesTests.cs
index 9f571b465e..ff77348124 100644
--- a/src/tests/Microsoft.Diagnostics.NETCore.Client/GetPublishedProcessesTests.cs
+++ b/src/tests/Microsoft.Diagnostics.NETCore.Client/GetPublishedProcessesTests.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using Microsoft.Diagnostics.TestHelpers;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
@@ -9,6 +10,8 @@
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;
+using Xunit.Extensions;
+using TestRunner = Microsoft.Diagnostics.CommonTestRunner.TestRunner;
namespace Microsoft.Diagnostics.NETCore.Client
{
@@ -18,76 +21,75 @@ namespace Microsoft.Diagnostics.NETCore.Client
///
public class GetPublishedProcessesTest
{
- private readonly ITestOutputHelper output;
+ private readonly ITestOutputHelper _output;
+
+ public static IEnumerable Configurations => TestRunner.Configurations;
public GetPublishedProcessesTest(ITestOutputHelper outputHelper)
{
- output = outputHelper;
+ _output = outputHelper;
}
- [Fact]
- public void PublishedProcessTest1()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public async Task PublishedProcessTest1(TestConfiguration config)
{
- using TestRunner runner = new TestRunner(CommonHelper.GetTraceePathWithArgs(), output);
- runner.Start(timeoutInMSPipeCreation: 3000);
- // On Windows, runner.Start will not wait for named pipe creation since for other tests, NamedPipeClientStream will
- // just wait until the named pipe is created.
- // For these tests, we need to sleep an arbitrary time before pipe is created.
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- {
- Thread.Sleep(5000);
- }
+ await using TestRunner runner = await TestRunner.Create(config, _output, "Tracee");
+ await runner.Start();
+
List publishedProcesses = new List(DiagnosticsClient.GetPublishedProcesses());
foreach (int p in publishedProcesses)
{
- output.WriteLine($"[{DateTime.Now.ToString()}] Saw published process {p}");
+ runner.WriteLine($"Saw published process {p}");
}
Assert.Contains(publishedProcesses, p => p == runner.Pid);
- runner.Stop();
+ runner.WakeupTracee();
}
- [Fact]
- public void MultiplePublishedProcessTest()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public async Task MultiplePublishedProcessTest(TestConfiguration config)
{
TestRunner[] runner = new TestRunner[3];
int[] pids = new int[3];
- for (var i = 0; i < 3; i++)
- {
- runner[i] = new TestRunner(CommonHelper.GetTraceePathWithArgs(), output);
- runner[i].Start();
- pids[i] = runner[i].Pid;
- }
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- {
- Thread.Sleep(5000);
- }
- List publishedProcesses = new List(DiagnosticsClient.GetPublishedProcesses());
- foreach (int p in publishedProcesses)
+ try
{
- output.WriteLine($"[{DateTime.Now.ToString()}] Saw published process {p}");
- }
+ for (var i = 0; i < 3; i++)
+ {
+ runner[i] = await TestRunner.Create(config, _output, "Tracee");
+ await runner[i].Start();
+ pids[i] = runner[i].Pid;
+ }
- for (var i = 0; i < 3; i++)
- {
- Assert.Contains(publishedProcesses, p => p == pids[i]);
- }
+ List publishedProcesses = new List(DiagnosticsClient.GetPublishedProcesses());
+ foreach (int p in publishedProcesses)
+ {
+ _output.WriteLine($"[{DateTime.Now}] Saw published process {p}");
+ }
+
+ for (var i = 0; i < 3; i++)
+ {
+ Assert.Contains(publishedProcesses, p => p == pids[i]);
+ }
- for (var i = 0 ; i < 3; i++)
+ for (var i = 0; i < 3; i++)
+ {
+ runner[i].WakeupTracee();
+ }
+ }
+ finally
{
- runner[i].Stop();
+ for (var i = 0; i < 3; i++)
+ {
+ await runner[i].DisposeAsync();
+ }
}
}
- [Fact]
- public async Task WaitForConnectionTest()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public async Task WaitForConnectionTest(TestConfiguration config)
{
- using TestRunner runner = new TestRunner(CommonHelper.GetTraceePathWithArgs(), output);
- runner.Start(timeoutInMSPipeCreation: 3000);
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- {
- Thread.Sleep(5000);
- }
+ await using TestRunner runner = await TestRunner.Create(config, _output, "Tracee");
+ await runner.Start();
var client = new DiagnosticsClient(runner.Pid);
using var timeoutSource = new CancellationTokenSource(TimeSpan.FromMilliseconds(250));
@@ -97,7 +99,7 @@ public async Task WaitForConnectionTest()
}
finally
{
- runner.Stop();
+ runner.WakeupTracee();
}
}
}
diff --git a/src/tests/Microsoft.Diagnostics.NETCore.Client/Microsoft.Diagnostics.NETCore.Client.UnitTests.csproj b/src/tests/Microsoft.Diagnostics.NETCore.Client/Microsoft.Diagnostics.NETCore.Client.UnitTests.csproj
index b1c14ebee1..8db5cfa78f 100644
--- a/src/tests/Microsoft.Diagnostics.NETCore.Client/Microsoft.Diagnostics.NETCore.Client.UnitTests.csproj
+++ b/src/tests/Microsoft.Diagnostics.NETCore.Client/Microsoft.Diagnostics.NETCore.Client.UnitTests.csproj
@@ -1,66 +1,17 @@
-
-
-
- $(IntermediateOutputPath)/DARCVersion.g.cs
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- netcoreapp3.1;net5.0
+ $(UnitTestTargetFrameworks)
-
-
-
+
+
+
+
-
-
-
-
+
diff --git a/src/tests/Microsoft.Diagnostics.NETCore.Client/RemoteTestExecution.cs b/src/tests/Microsoft.Diagnostics.NETCore.Client/RemoteTestExecution.cs
deleted file mode 100644
index a3b592339d..0000000000
--- a/src/tests/Microsoft.Diagnostics.NETCore.Client/RemoteTestExecution.cs
+++ /dev/null
@@ -1,110 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.IO;
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.Diagnostics.NETCore.Client;
-using Xunit.Abstractions;
-
-namespace Microsoft.Diagnostics.NETCore.Client.UnitTests
-{
- ///
- /// Utility class to control remote test execution.
- ///
- public sealed class RemoteTestExecution : IAsyncDisposable
- {
- private Task IoReadingTask { get; }
-
- private ITestOutputHelper OutputHelper { get; }
-
- public TestRunner TestRunner { get; }
-
- private RemoteTestExecution(TestRunner runner, Task ioReadingTask, ITestOutputHelper outputHelper)
- {
- TestRunner = runner;
- IoReadingTask = ioReadingTask;
- OutputHelper = outputHelper;
- }
-
- //Very simple signals that synchronize execution between the test process and the debuggee process.
-
- public void SendSignal()
- {
- //We cannot use named synchronization primitives since they do not work across processes
- //on Linux. Use redirected standard input instead.
- TestRunner.StandardInput.Write('0');
- TestRunner.StandardInput.Flush();
- }
-
- public void WaitForSignal()
- {
- var result = TestRunner.StandardOutput.ReadLine();
- if (string.Equals(result, "1"))
- {
- return;
- }
- }
-
- public static RemoteTestExecution StartProcess(string commandLine, ITestOutputHelper outputHelper, string reversedServerTransportName = null)
- {
- TestRunner runner = new TestRunner(commandLine, outputHelper, redirectError: true, redirectInput: true);
- if (!string.IsNullOrEmpty(reversedServerTransportName))
- {
- runner.SetDiagnosticPort(reversedServerTransportName, suspend: false);
- }
- runner.Start(testProcessTimeout: 60_000);
-
- Task readingTask = ReadAllOutput(runner.StandardOutput, runner.StandardError, outputHelper);
-
- return new RemoteTestExecution(runner, readingTask, outputHelper);
- }
-
- private static Task ReadAllOutput(StreamReader output, StreamReader error, ITestOutputHelper outputHelper)
- {
- return Task.Run(async () =>
- {
- try
- {
- Task stdErrorTask = error.ReadToEndAsync();
-
- try
- {
- string result = await stdErrorTask;
- outputHelper.WriteLine("Stderr:");
- if (result != null)
- {
- outputHelper.WriteLine(result);
- }
- }
- catch (Exception e)
- {
- outputHelper.WriteLine("Error reading standard error from child process: " + e.ToString());
- }
- }
- catch (ObjectDisposedException)
- {
- outputHelper.WriteLine("Failed to collect remote process's output");
- }
- });
- }
-
- public async ValueTask DisposeAsync()
- {
- using var timeoutSource = new CancellationTokenSource(TimeSpan.FromSeconds(1));
- try
- {
- await TestRunner.WaitForExitAsync(timeoutSource.Token);
- }
- catch (OperationCanceledException)
- {
- OutputHelper.WriteLine("Remote process did not exit within timeout period. Forcefully stopping process.");
- TestRunner.Stop();
- }
-
- await IoReadingTask;
- }
- }
-}
diff --git a/src/tests/Microsoft.Diagnostics.NETCore.Client/ReversedServerTests.cs b/src/tests/Microsoft.Diagnostics.NETCore.Client/ReversedServerTests.cs
index 07f6a17170..e7a1867f1c 100644
--- a/src/tests/Microsoft.Diagnostics.NETCore.Client/ReversedServerTests.cs
+++ b/src/tests/Microsoft.Diagnostics.NETCore.Client/ReversedServerTests.cs
@@ -2,6 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using Microsoft.Diagnostics.CommonTestRunner;
+using Microsoft.Diagnostics.TestHelpers;
+using Microsoft.Diagnostics.Tracing;
using System;
using System.Collections.Generic;
using System.Diagnostics.Tracing;
@@ -9,9 +12,10 @@
using System.Net;
using System.Threading;
using System.Threading.Tasks;
-using Microsoft.Diagnostics.Tracing;
using Xunit;
using Xunit.Abstractions;
+using Xunit.Extensions;
+using TestRunner = Microsoft.Diagnostics.CommonTestRunner.TestRunner;
namespace Microsoft.Diagnostics.NETCore.Client
{
@@ -23,6 +27,8 @@ public class ReversedServerTests
private readonly ITestOutputHelper _outputHelper;
+ public static IEnumerable Configurations => TestRunner.Configurations;
+
public ReversedServerTests(ITestOutputHelper outputHelper)
{
_outputHelper = outputHelper;
@@ -111,22 +117,22 @@ public async Task ReversedServerAcceptAsyncYieldsTest()
Assert.True(acceptTask.IsCanceled);
}
- [Fact]
- public async Task ReversedServerNonExistingRuntimeIdentifierTest()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public async Task ReversedServerNonExistingRuntimeIdentifierTest(TestConfiguration config)
{
- await ReversedServerNonExistingRuntimeIdentifierTestCore(useAsync: false);
+ await ReversedServerNonExistingRuntimeIdentifierTestCore(config, useAsync: false);
}
- [Fact]
- public async Task ReversedServerNonExistingRuntimeIdentifierTestAsync()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public async Task ReversedServerNonExistingRuntimeIdentifierTestAsync(TestConfiguration config)
{
- await ReversedServerNonExistingRuntimeIdentifierTestCore(useAsync: true);
+ await ReversedServerNonExistingRuntimeIdentifierTestCore(config, useAsync: true);
}
///
/// Tests that invoking server methods with non-existing runtime identifier appropriately fail.
///
- private async Task ReversedServerNonExistingRuntimeIdentifierTestCore(bool useAsync)
+ private async Task ReversedServerNonExistingRuntimeIdentifierTestCore(TestConfiguration config, bool useAsync)
{
await using var server = CreateReversedServer(out string transportName);
@@ -149,16 +155,16 @@ private async Task ReversedServerNonExistingRuntimeIdentifierTestCore(bool useAs
Assert.False(server.RemoveConnection(Guid.NewGuid()), "Removal of nonexisting connection should fail.");
}
- [Fact]
- public async Task ReversedServerSingleTargetMultipleUseClientTest()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public async Task ReversedServerSingleTargetMultipleUseClientTest(TestConfiguration config)
{
- await ReversedServerSingleTargetMultipleUseClientTestCore(useAsync: false);
+ await ReversedServerSingleTargetMultipleUseClientTestCore(config, useAsync: false);
}
- [Fact]
- public async Task ReversedServerSingleTargetMultipleUseClientTestAsync()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public async Task ReversedServerSingleTargetMultipleUseClientTestAsync(TestConfiguration config)
{
- await ReversedServerSingleTargetMultipleUseClientTestCore(useAsync: true);
+ await ReversedServerSingleTargetMultipleUseClientTestCore(config, useAsync: true);
}
///
@@ -170,18 +176,19 @@ public async Task ReversedServerSingleTargetMultipleUseClientTestAsync()
/// because of how the endpoint is updated with new stream information each
/// time the target process reconnects to the server.
///
- private async Task ReversedServerSingleTargetMultipleUseClientTestCore(bool useAsync)
+ private async Task ReversedServerSingleTargetMultipleUseClientTestCore(TestConfiguration config, bool useAsync)
{
+ if (config.RuntimeFrameworkVersionMajor < 5)
+ {
+ throw new SkipTestException("Not supported on < .NET 5.0");
+ }
await using var server = CreateReversedServer(out string transportName);
server.Start();
-
- TestRunner runner = null;
IpcEndpointInfo info;
- try
- {
- // Start client pointing to diagnostics server
- runner = StartTracee(transportName);
+ // Start client pointing to diagnostics server
+ await using (TestRunner runner = await StartTracee(config, transportName))
+ {
info = await AcceptEndpointInfo(server, useAsync);
await VerifyEndpointInfo(runner, info, useAsync);
@@ -191,13 +198,10 @@ private async Task ReversedServerSingleTargetMultipleUseClientTestCore(bool useA
await ResumeRuntime(info, useAsync);
+ await runner.WaitForTracee();
+
await VerifySingleSession(info, useAsync);
}
- finally
- {
- _outputHelper.WriteLine("Stopping tracee.");
- runner?.Stop();
- }
// Wait some time for the process to exit
await Task.Delay(TimeSpan.FromSeconds(1));
@@ -211,33 +215,34 @@ private async Task ReversedServerSingleTargetMultipleUseClientTestCore(bool useA
await VerifyNoNewEndpointInfos(server, useAsync);
}
- [Fact]
- public async Task ReversedServerSingleTargetExitsClientInviableTest()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public async Task ReversedServerSingleTargetExitsClientInviableTest(TestConfiguration config)
{
- await ReversedServerSingleTargetExitsClientInviableTestCore(useAsync: false);
+ await ReversedServerSingleTargetExitsClientInviableTestCore(config, useAsync: false);
}
- [Fact]
- public async Task ReversedServerSingleTargetExitsClientInviableTestAsync()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public async Task ReversedServerSingleTargetExitsClientInviableTestAsync(TestConfiguration config)
{
- await ReversedServerSingleTargetExitsClientInviableTestCore(useAsync: true);
+ await ReversedServerSingleTargetExitsClientInviableTestCore(config, useAsync: true);
}
///
/// Tests that a DiagnosticsClient is not viable after target exists.
///
- private async Task ReversedServerSingleTargetExitsClientInviableTestCore(bool useAsync)
+ private async Task ReversedServerSingleTargetExitsClientInviableTestCore(TestConfiguration config, bool useAsync)
{
+ if (config.RuntimeFrameworkVersionMajor < 5)
+ {
+ throw new SkipTestException("Not supported on < .NET 5.0");
+ }
await using var server = CreateReversedServer(out string transportName);
server.Start();
- TestRunner runner = null;
+ // Start client pointing to diagnostics server
IpcEndpointInfo info;
- try
+ await using (TestRunner runner = await StartTracee(config, transportName))
{
- // Start client pointing to diagnostics server
- runner = StartTracee(transportName);
-
// Get client connection
info = await AcceptEndpointInfo(server, useAsync);
@@ -248,13 +253,10 @@ private async Task ReversedServerSingleTargetExitsClientInviableTestCore(bool us
await ResumeRuntime(info, useAsync);
+ await runner.WaitForTracee();
+
await VerifyWaitForConnection(info, useAsync);
}
- finally
- {
- _outputHelper.WriteLine("Stopping tracee.");
- runner?.Stop();
- }
// Wait some time for the process to exit
await Task.Delay(TimeSpan.FromSeconds(1));
@@ -272,22 +274,22 @@ private async Task ReversedServerSingleTargetExitsClientInviableTestCore(bool us
/// Validates that the does not create a new server
/// transport during disposal.
///
- [Fact]
- public async Task ReversedServerNoCreateTransportAfterDispose()
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public async Task ReversedServerNoCreateTransportAfterDispose(TestConfiguration config)
{
+ if (config.RuntimeFrameworkVersionMajor < 5)
+ {
+ throw new SkipTestException("Not supported on < .NET 5.0");
+ }
var transportCallback = new IpcServerTransportCallback();
-
int transportVersion = 0;
- TestRunner runner = null;
- try
- {
- await using var server = CreateReversedServer(out string transportName);
- server.TransportCallback = transportCallback;
- server.Start();
- // Start client pointing to diagnostics server
- runner = StartTracee(transportName);
+ await using var server = CreateReversedServer(out string transportName);
+ server.TransportCallback = transportCallback;
+ server.Start();
+ await using (TestRunner runner = await StartTracee(config, transportName))
+ {
// Get client connection
IpcEndpointInfo info = await AcceptEndpointInfo(server, useAsync: true);
@@ -298,17 +300,14 @@ public async Task ReversedServerNoCreateTransportAfterDispose()
await ResumeRuntime(info, useAsync: true);
+ await runner.WaitForTracee();
+
await VerifyWaitForConnection(info, useAsync: true);
transportVersion = await transportCallback.GetStableTransportVersion();
// Server will be disposed
}
- finally
- {
- _outputHelper.WriteLine("Stopping tracee.");
- runner?.Stop();
- }
// Check that the reversed server did not create a new server transport upon disposal.
Assert.Equal(transportVersion, await transportCallback.GetStableTransportVersion());
@@ -328,12 +327,11 @@ private async Task AcceptEndpointInfo(ReversedDiagnosticsServer
return await shim.Accept(DefaultPositiveVerificationTimeout);
}
- private TestRunner StartTracee(string transportName)
+ private async Task StartTracee(TestConfiguration config, string transportName)
{
- _outputHelper.WriteLine("Starting tracee.");
- var runner = new TestRunner(CommonHelper.GetTraceePathWithArgs(targetFramework: "net5.0"), _outputHelper);
+ TestRunner runner = await TestRunner.Create(config, _outputHelper, "Tracee");
runner.SetDiagnosticPort(transportName, suspend: true);
- runner.Start();
+ await runner.Start(waitForTracee: false);
return runner;
}
@@ -364,7 +362,7 @@ private async Task VerifyNoNewEndpointInfos(ReversedDiagnosticsServer server, bo
///
private async Task VerifyEndpointInfo(TestRunner runner, IpcEndpointInfo info, bool useAsync, bool expectTimeout = false)
{
- _outputHelper.WriteLine($"Verifying connection information for process ID {runner.Pid}.");
+ runner.WriteLine("Verifying connection information for process");
Assert.NotNull(runner);
Assert.Equal(runner.Pid, info.ProcessId);
Assert.NotEqual(Guid.Empty, info.RuntimeInstanceCookie);
@@ -372,7 +370,7 @@ private async Task VerifyEndpointInfo(TestRunner runner, IpcEndpointInfo info, b
await VerifyWaitForConnection(info, useAsync, expectTimeout);
- _outputHelper.WriteLine($"Connection: {info.DebuggerDisplay}");
+ runner.WriteLine($"Connection: {info.DebuggerDisplay}");
}
private async Task ResumeRuntime(IpcEndpointInfo info, bool useAsync)
diff --git a/src/tests/Microsoft.Diagnostics.NETCore.Client/TestRunner.cs b/src/tests/Microsoft.Diagnostics.NETCore.Client/TestRunner.cs
deleted file mode 100644
index 88fa0014ee..0000000000
--- a/src/tests/Microsoft.Diagnostics.NETCore.Client/TestRunner.cs
+++ /dev/null
@@ -1,178 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-
-using System;
-using System.Linq;
-using System.ComponentModel;
-using System.Diagnostics;
-using System.IO;
-using System.Runtime.InteropServices;
-using System.Threading;
-using System.Threading.Tasks;
-using Xunit.Abstractions;
-using System.Collections.Generic;
-
-namespace Microsoft.Diagnostics.NETCore.Client
-{
- public class TestRunner : IDisposable
- {
- private Process testProcess;
- private ProcessStartInfo startInfo;
- private ITestOutputHelper outputHelper;
- private CancellationTokenSource cts;
-
- public TestRunner(string testExePath, ITestOutputHelper _outputHelper = null,
- bool redirectError = false, bool redirectInput = false, Dictionary envVars = null)
- {
- startInfo = new ProcessStartInfo(CommonHelper.HostExe, testExePath);
- startInfo.UseShellExecute = false;
- startInfo.RedirectStandardOutput = true;
- startInfo.RedirectStandardError = redirectError;
- startInfo.RedirectStandardInput = redirectInput;
- envVars?.ToList().ForEach(item => startInfo.Environment.Add(item.Key, item.Value));
- outputHelper = _outputHelper;
- }
-
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- protected virtual void Dispose(bool disposing)
- {
- try
- {
- // Make a good will attempt to end the tracee process
- // and its process tree
- testProcess?.Kill(entireProcessTree: true);
- }
- catch {}
-
- if(disposing)
- {
- testProcess?.Dispose();
- }
-
- cts.Dispose();
- }
-
- public void AddEnvVar(string key, string value)
- {
- startInfo.EnvironmentVariables[key] = value;
- }
-
- public StreamWriter StandardInput => testProcess.StandardInput;
- public StreamReader StandardOutput => testProcess.StandardOutput;
- public StreamReader StandardError => testProcess.StandardError;
-
- public void Start(int timeoutInMSPipeCreation=15_000, int testProcessTimeout=30_000)
- {
- if (outputHelper != null)
- outputHelper.WriteLine($"[{DateTime.Now.ToString()}] Launching test: " + startInfo.FileName + " " + startInfo.Arguments);
-
- testProcess = new Process();
- testProcess.StartInfo = startInfo;
- testProcess.EnableRaisingEvents = true;
-
- if (!testProcess.Start())
- {
- outputHelper.WriteLine($"Could not start process: " + startInfo.FileName);
- }
-
- if (testProcess.HasExited)
- {
- outputHelper.WriteLine($"Process " + startInfo.FileName + " came back as exited");
- }
-
- cts = new CancellationTokenSource(testProcessTimeout);
- cts.Token.Register(() => testProcess.Kill());
-
- if (outputHelper != null)
- {
- outputHelper.WriteLine($"[{DateTime.Now.ToString()}] Successfully started process {testProcess.Id}");
- // Retry getting the module count because we can catch the process during startup and it fails temporarily.
- for (int retry = 0; retry < 5; retry++)
- {
- try
- {
- outputHelper.WriteLine($"Have total {testProcess.Modules.Count} modules loaded");
- break;
- }
- catch (Win32Exception)
- {
- }
- }
- }
-
- // Block until we see the IPC channel created, or until timeout specified.
- Task monitorSocketTask = Task.Run(() =>
- {
- while (true)
- {
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- {
- // On Windows, named pipe connection will block until the named pipe is ready to connect so no need to block here
- break;
- }
- else
- {
- // On Linux, we wait until the socket is created.
- var matchingFiles = Directory.GetFiles(Path.GetTempPath(), $"dotnet-diagnostic-{testProcess.Id}-*-socket"); // Try best match.
- if (matchingFiles.Length > 0)
- {
- break;
- }
- }
- Task.Delay(100);
- }
- });
-
- monitorSocketTask.Wait(TimeSpan.FromMilliseconds(timeoutInMSPipeCreation));
- }
-
- public void Stop()
- {
- this.Dispose();
- }
-
- public int Pid {
- get { return testProcess.Id; }
- }
-
- public void PrintStatus()
- {
- if (testProcess.HasExited)
- {
- outputHelper.WriteLine($"Process {testProcess.Id} status: Exited 0x{testProcess.ExitCode:X}");
- }
- else
- {
- outputHelper.WriteLine($"Process {testProcess.Id} status: Running");
- }
- }
-
- public async Task WaitForExitAsync(CancellationToken token)
- {
- TaskCompletionSource exitedSource = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
- EventHandler exitedHandler = (s, e) => exitedSource.TrySetResult(null);
-
- testProcess.Exited += exitedHandler;
- try
- {
- if (!testProcess.HasExited)
- {
- using var _ = token.Register(() => exitedSource.TrySetCanceled(token));
-
- await exitedSource.Task;
- }
- }
- finally
- {
- testProcess.Exited -= exitedHandler;
- }
- }
- }
-}
diff --git a/src/tests/StackTracee/Program.cs b/src/tests/StackTracee/Program.cs
index 12dc739197..efbd514851 100644
--- a/src/tests/StackTracee/Program.cs
+++ b/src/tests/StackTracee/Program.cs
@@ -10,7 +10,7 @@ class Program
{
static void Main(string[] args)
{
- Console.ReadKey();
+ Console.Read();
}
}
}
diff --git a/src/tests/StackTracee/StackTracee.csproj b/src/tests/StackTracee/StackTracee.csproj
index cd0510ad22..6b634ef181 100644
--- a/src/tests/StackTracee/StackTracee.csproj
+++ b/src/tests/StackTracee/StackTracee.csproj
@@ -2,6 +2,6 @@
Exe
$(BuildProjectFramework)
- netcoreapp3.1;net5.0
+ netcoreapp3.1;net6.0;net7.0
diff --git a/src/tests/Tracee/Program.cs b/src/tests/Tracee/Program.cs
index 8250ea7c8e..2107a7f9fa 100644
--- a/src/tests/Tracee/Program.cs
+++ b/src/tests/Tracee/Program.cs
@@ -3,27 +3,50 @@
// See the LICENSE file in the project root for more information.
using System;
-using System.Threading;
+using System.Diagnostics;
+using System.IO.Pipes;
namespace Tracee
{
class Program
{
- private const int LoopCount = 30;
-
- static void Main(string[] args)
+ public static int Main(string[] args)
{
- Console.WriteLine("Sleep in loop for {0} seconds.", LoopCount);
-
- // Runs for max of 30 sec
- for (var i = 0; i < LoopCount; i++)
+ int pid = Process.GetCurrentProcess().Id;
+ string pipeServerName = args.Length > 0 ? args[0] : null;
+ if (pipeServerName == null)
{
- Console.WriteLine("Iteration #{0}", i);
- Thread.Sleep(1000);
+ Console.Error.WriteLine($"{pid} Tracee: no pipe name");
+ Console.Error.Flush();
+ return -1;
}
+ Console.WriteLine($"{pid} Tracee: pipe server: {pipeServerName}");
+ Console.Out.Flush();
+ try
+ {
+ using var pipeStream = new NamedPipeClientStream(pipeServerName);
+
+ Console.WriteLine("{0} Tracee: connecting to pipe", pid);
+ Console.Out.Flush();
+ pipeStream.Connect(5 * 60 * 1000);
+ Console.WriteLine("{0} Tracee: connected to pipe", pid);
+ Console.Out.Flush();
- Console.WriteLine("Press any key to exit.");
- Console.ReadKey();
+ // Wait for server to send something
+ int input = pipeStream.ReadByte();
+
+ Console.WriteLine("{0} Tracee: waking up {1}", pid, input);
+ Console.Out.Flush();
+ }
+ catch (Exception ex)
+ {
+ Console.Error.WriteLine(ex.ToString());
+ Console.Error.Flush();
+ return -1;
+ }
+ Console.WriteLine("{0} Tracee: exiting normally", pid);
+ Console.Out.Flush();
+ return 0;
}
}
}
diff --git a/src/tests/Tracee/Tracee.csproj b/src/tests/Tracee/Tracee.csproj
index cd0510ad22..6b634ef181 100644
--- a/src/tests/Tracee/Tracee.csproj
+++ b/src/tests/Tracee/Tracee.csproj
@@ -2,6 +2,6 @@
Exe
$(BuildProjectFramework)
- netcoreapp3.1;net5.0
+ netcoreapp3.1;net6.0;net7.0
diff --git a/src/tests/dotnet-counters/DotnetCounters.UnitTests.csproj b/src/tests/dotnet-counters/DotnetCounters.UnitTests.csproj
index 3e891e2a45..06c1878141 100644
--- a/src/tests/dotnet-counters/DotnetCounters.UnitTests.csproj
+++ b/src/tests/dotnet-counters/DotnetCounters.UnitTests.csproj
@@ -1,7 +1,7 @@
- net5.0
+ net6.0
diff --git a/src/tests/dotnet-stack/DotnetStack.UnitTests.csproj b/src/tests/dotnet-stack/DotnetStack.UnitTests.csproj
index 94b587a2ec..7cdad15afc 100644
--- a/src/tests/dotnet-stack/DotnetStack.UnitTests.csproj
+++ b/src/tests/dotnet-stack/DotnetStack.UnitTests.csproj
@@ -1,12 +1,12 @@
- net5.0
+ net6.0
-
-
+
+
diff --git a/src/tests/dotnet-stack/StackTests.cs b/src/tests/dotnet-stack/StackTests.cs
index e98820c08e..c106d1e366 100644
--- a/src/tests/dotnet-stack/StackTests.cs
+++ b/src/tests/dotnet-stack/StackTests.cs
@@ -2,45 +2,71 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using Microsoft.Diagnostics.NETCore.Client;
+using Microsoft.Diagnostics.TestHelpers;
using System;
+using System.Collections.Generic;
using System.CommandLine;
using System.CommandLine.IO;
using System.CommandLine.Parsing;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;
+using Xunit.Extensions;
+using TestRunner = Microsoft.Diagnostics.CommonTestRunner.TestRunner;
namespace Microsoft.Diagnostics.Tools.Stack
{
public class StackTests
{
- private readonly ITestOutputHelper output;
+ private readonly ITestOutputHelper _output;
+
+ private const string _correctStack70 = @" [Native Frames]
+ System.Console.il!Interop+Kernel32.ReadFile(int,unsigned int8*,int32,int32&,int)
+ System.Console.il!System.ConsolePal+WindowsConsoleStream.ReadFileNative(int,value class System.Span`1,bool,int32&,bool)
+ System.Console.il!System.ConsolePal+WindowsConsoleStream.Read(value class System.Span`1)
+ System.Console.il!System.IO.ConsoleStream.Read(unsigned int8[],int32,int32)
+ System.Private.CoreLib.il!System.IO.StreamReader.ReadBuffer()
+ System.Private.CoreLib.il!System.IO.StreamReader.Read()
+ System.Console.il!System.IO.SyncTextReader.Read()
+ System.Console.il!System.Console.Read()
+ ?!?";
+
+ private const string _correctStack60 = @" [Native Frames]
+ System.Console.il!System.ConsolePal+WindowsConsoleStream.ReadFileNative(int,value class System.Span`1,bool,int32&,bool)
+ System.Console.il!System.ConsolePal+WindowsConsoleStream.Read(value class System.Span`1)
+ System.Console.il!System.IO.ConsoleStream.Read(unsigned int8[],int32,int32)
+ System.Private.CoreLib.il!System.IO.StreamReader.ReadBuffer()
+ System.Private.CoreLib.il!System.IO.StreamReader.Read()
+ System.Console.il!System.IO.SyncTextReader.Read()
+ System.Console.il!System.Console.Read()
+ StackTracee!Tracee.Program.Main(class System.String[])";
- private readonly string correctStack = @" [Native Frames]
- System.Console!System.IO.StdInReader.ReadKey(bool&)
- System.Console!System.IO.SyncTextReader.ReadKey(bool&)
- System.Console!System.ConsolePal.ReadKey(bool)
- System.Console!System.Console.ReadKey()
+ private const string _correctStack31 = @" [Native Frames]
+ System.Console.il!System.ConsolePal+WindowsConsoleStream.ReadFileNative(int,unsigned int8[],int32,int32,bool,int32&,bool)
+ System.Console.il!System.ConsolePal+WindowsConsoleStream.Read(unsigned int8[],int32,int32)
+ System.Private.CoreLib.il!System.IO.StreamReader.ReadBuffer()
+ System.Private.CoreLib.il!System.IO.StreamReader.Read()
+ System.Console.il!System.IO.SyncTextReader.Read()
+ System.Console.il!System.Console.Read()
StackTracee!Tracee.Program.Main(class System.String[])";
+ public static IEnumerable Configurations => TestRunner.Configurations;
+
public StackTests(ITestOutputHelper outputHelper)
{
- output = outputHelper;
+ _output = outputHelper;
}
- [Theory]
- [InlineData("netcoreapp3.1")]
- [InlineData("net5.0")]
- public async Task ReportsStacksCorrectly(string traceeFramework)
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public async Task ReportsStacksCorrectly(TestConfiguration config)
{
Command reportCommand = ReportCommandHandler.ReportCommand();
var console = new TestConsole();
var parser = new Parser(reportCommand);
- using TestRunner runner = new TestRunner(CommonHelper.GetTraceePathWithArgs(traceeName: "StackTracee", targetFramework: traceeFramework), output);
- runner.Start();
+ await using TestRunner runner = await TestRunner.Create(config, _output, "StackTracee", usePipe: false);
+ await runner.Start();
// Wait for tracee to get to readkey call
await Task.Delay(TimeSpan.FromSeconds(1));
@@ -49,10 +75,16 @@ public async Task ReportsStacksCorrectly(string traceeFramework)
string report = console.Out.ToString();
- output.WriteLine($"REPORT_START\n{report}REPORT_END");
+ runner.WriteLine($"REPORT_START\n{report}REPORT_END");
Assert.True(!string.IsNullOrEmpty(report));
-
+ string correctStack = config.RuntimeFrameworkVersionMajor switch
+ {
+ 7 => _correctStack70,
+ 6 => _correctStack60,
+ 3 => _correctStack31,
+ _ => throw new NotSupportedException($"Runtime version {config.RuntimeFrameworkVersionMajor} not supported")
+ };
string[] correctStackParts = correctStack.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries);
string[] stackParts = report.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries);
@@ -68,4 +100,4 @@ public async Task ReportsStacksCorrectly(string traceeFramework)
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/tests/dotnet-trace/ChildProcessTests.cs b/src/tests/dotnet-trace/ChildProcessTests.cs
index 14101e28c9..35a003046f 100644
--- a/src/tests/dotnet-trace/ChildProcessTests.cs
+++ b/src/tests/dotnet-trace/ChildProcessTests.cs
@@ -2,19 +2,23 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using Microsoft.Diagnostics.NETCore.Client;
-using System;
-using Xunit;
-using Xunit.Abstractions;
+using Microsoft.Diagnostics.CommonTestRunner;
+using Microsoft.Diagnostics.TestHelpers;
using System.Collections.Generic;
-using System.Linq;
using System.Diagnostics;
+using System.Text;
+using Xunit;
+using Xunit.Abstractions;
+using Xunit.Extensions;
+using TestRunner = Microsoft.Diagnostics.CommonTestRunner.TestRunner;
namespace Microsoft.Diagnostics.Tools.Trace
{
public class ChildProcessTests
{
+ public static IEnumerable Configurations => TestRunner.Configurations;
+
// Pass ITestOutputHelper into the test class, which xunit provides per-test
public ChildProcessTests(ITestOutputHelper outputHelper)
{
@@ -23,10 +27,35 @@ public ChildProcessTests(ITestOutputHelper outputHelper)
private ITestOutputHelper OutputHelper { get; }
- private void LaunchDotNetTrace(string command, out int exitCode, out string stdOut, out string stdErr)
+ private void LaunchDotNetTrace(TestConfiguration config, string dotnetTraceCommand, string traceeArguments, out int exitCode, out string stdOut, out string stdErr)
{
- string dotnetTracePathWithArgs = CommonHelper.GetTraceePathWithArgs(traceeName: "dotnet-trace").Replace("net5.0", "netcoreapp3.1");
- ProcessStartInfo startInfo = new ProcessStartInfo(CommonHelper.HostExe, $"{dotnetTracePathWithArgs} {command}");
+ if (config.RuntimeFrameworkVersionMajor < 5)
+ {
+ throw new SkipTestException("Not supported on < .NET 5.0");
+ }
+ DebuggeeConfiguration debuggeeConfig = DebuggeeCompiler.Execute(config, "ExitCodeTracee", OutputHelper).GetAwaiter().GetResult();
+
+ var dotnetTraceArguments = new StringBuilder();
+ dotnetTraceArguments.Append(config.DotNetTracePath());
+ dotnetTraceArguments.Append(' ');
+ dotnetTraceArguments.Append(dotnetTraceCommand);
+ dotnetTraceArguments.Append(" -- ");
+
+ if (!string.IsNullOrWhiteSpace(config.HostExe))
+ {
+ dotnetTraceArguments.Append(config.HostExe);
+ dotnetTraceArguments.Append(' ');
+ if (!string.IsNullOrWhiteSpace(config.HostArgs))
+ {
+ dotnetTraceArguments.Append(config.HostArgs);
+ dotnetTraceArguments.Append(' ');
+ }
+ }
+ dotnetTraceArguments.Append(debuggeeConfig.BinaryExePath);
+ dotnetTraceArguments.Append(' ');
+ dotnetTraceArguments.Append(traceeArguments);
+
+ ProcessStartInfo startInfo = new ProcessStartInfo(config.DotNetTraceHost(), dotnetTraceArguments.ToString());
OutputHelper.WriteLine($"Launching: {startInfo.FileName} {startInfo.Arguments}");
startInfo.RedirectStandardInput = true;
@@ -53,45 +82,47 @@ private void LaunchDotNetTrace(string command, out int exitCode, out string stdO
Assert.True(processExitedCleanly, "Launched process failed to exit");
exitCode = process.ExitCode;
}
+
+ if (!string.IsNullOrWhiteSpace(stdErr))
+ {
+ OutputHelper.WriteLine(stdErr);
+ }
}
- [Theory]
- [InlineData("232", 232)]
- [InlineData("0", 0)]
- public void VerifyExitCode(string commandLineArg, int exitCode)
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public void VerifyExitCode(TestConfiguration config)
{
- string exitCodeTraceePath = CommonHelper.GetTraceePathWithArgs(traceeName: "ExitCodeTracee", targetFramework: "net5.0");
+ VerifyExitCodeX(config, "232", 232);
+ VerifyExitCodeX(config, "0", 0);
+ }
- LaunchDotNetTrace($"collect -o verifyexitcode.nettrace -- {CommonHelper.HostExe} {exitCodeTraceePath} {commandLineArg}", out int dotnetTraceExitCode, out string stdOut, out string stdErr);
+ private void VerifyExitCodeX(TestConfiguration config, string commandLineArg, int exitCode)
+ {
+ LaunchDotNetTrace(config, "collect -o verifyexitcode.nettrace", commandLineArg, out int dotnetTraceExitCode, out string stdOut, out string stdErr);
Assert.Equal(exitCode, dotnetTraceExitCode);
-
Assert.Contains($"Process exited with code '{exitCode}'.", stdOut);
}
- [Theory]
- [InlineData("0 this is a message", new string[] { "\nthis\n", "\nis\n", "\na\n" })]
- public void VerifyHideIO(string commandLineArg, string[] stringsInOutput)
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public void VerifyHideIO(TestConfiguration config)
{
- string exitCodeTraceePath = CommonHelper.GetTraceePathWithArgs(traceeName: "ExitCodeTracee", targetFramework: "net5.0");
-
- LaunchDotNetTrace($"collect -o VerifyHideIO.nettrace -- {CommonHelper.HostExe} {exitCodeTraceePath} {commandLineArg}", out int dotnetTraceExitCode, out string stdOut, out string stdErr);
+ LaunchDotNetTrace(config, "collect -o VerifyHideIO.nettrace", "0 this is a message", out int dotnetTraceExitCode, out string stdOut, out string stdErr);
Assert.Equal(0, dotnetTraceExitCode);
stdOut = stdOut.Replace("\r", "");
+ string[] stringsInOutput = new string[] { "\nthis\n", "\nis\n", "\na\n" };
foreach (string s in stringsInOutput)
Assert.DoesNotContain(s, stdOut);
}
- [Theory]
- [InlineData("0 this is a message", new string[] { "\nthis\n", "\nis\n", "\na\n" })]
- public void VerifyShowIO(string commandLineArg, string[] stringsInOutput)
+ [SkippableTheory, MemberData(nameof(Configurations))]
+ public void VerifyShowIO(TestConfiguration config)
{
- string exitCodeTraceePath = CommonHelper.GetTraceePathWithArgs(traceeName: "ExitCodeTracee", targetFramework: "net5.0");
-
- LaunchDotNetTrace($"collect -o VerifyShowIO.nettrace --show-child-io -- {CommonHelper.HostExe} {exitCodeTraceePath} {commandLineArg}", out int dotnetTraceExitCode, out string stdOut, out string stdErr);
+ LaunchDotNetTrace(config, "collect -o VerifyShowIO.nettrace --show-child-io", "0 this is a message", out int dotnetTraceExitCode, out string stdOut, out string stdErr);
Assert.Equal(0, dotnetTraceExitCode);
stdOut = stdOut.Replace("\r", "");
+ string[] stringsInOutput = new string[] { "\nthis\n", "\nis\n", "\na\n" };
foreach (string s in stringsInOutput)
Assert.Contains(s, stdOut);
}
diff --git a/src/tests/dotnet-trace/DotnetTrace.UnitTests.csproj b/src/tests/dotnet-trace/DotnetTrace.UnitTests.csproj
index 5c99730da2..fb372850fe 100644
--- a/src/tests/dotnet-trace/DotnetTrace.UnitTests.csproj
+++ b/src/tests/dotnet-trace/DotnetTrace.UnitTests.csproj
@@ -1,13 +1,12 @@
-
+
- net5.0
+ net6.0
-
-
-
+
+
diff --git a/src/tests/eventpipe/EventPipe.UnitTests.csproj b/src/tests/eventpipe/EventPipe.UnitTests.csproj
index f6c26727c4..efa46f1b5c 100644
--- a/src/tests/eventpipe/EventPipe.UnitTests.csproj
+++ b/src/tests/eventpipe/EventPipe.UnitTests.csproj
@@ -1,7 +1,7 @@
-
+
- netcoreapp3.1
+ $(UnitTestTargetFrameworks)
diff --git a/src/tests/eventpipe/GCEvents.cs b/src/tests/eventpipe/GCEvents.cs
index ad36377fa2..02f4fd5093 100644
--- a/src/tests/eventpipe/GCEvents.cs
+++ b/src/tests/eventpipe/GCEvents.cs
@@ -10,6 +10,8 @@
using EventPipe.UnitTests.Common;
using Microsoft.Diagnostics.NETCore.Client;
using Microsoft.Diagnostics.Tracing;
+using System.Reflection;
+using System.Runtime.InteropServices;
namespace EventPipe.UnitTests.GCEventsValidation
{
@@ -188,8 +190,16 @@ await RemoteTestExecutorHelper.RunTestCaseAsync(() =>
Action _eventGeneratingAction = () =>
{
List testList = new List();
- for(int i = 0; i < 100000000; i ++)
+ for (int i = 0; i < 100_000_000; i ++)
{
+ // This test was failing (no GCFreeSegment callbacks) on x86 until this GC Collects happened.
+ if (RuntimeInformation.ProcessArchitecture == Architecture.X86)
+ {
+ if (i % 1_000_000 == 0)
+ {
+ GC.Collect();
+ }
+ }
string t = "Test string!";
testList.Add(t);
}
@@ -216,7 +226,9 @@ await RemoteTestExecutorHelper.RunTestCaseAsync(() =>
Logger.logger.Log("GCCreateSegmentEvents: " + GCCreateSegmentEvents);
Logger.logger.Log("GCFreeSegmentEvents: " + GCFreeSegmentEvents);
- bool GCSegmentResult = GCCreateSegmentEvents > 0 && GCFreeSegmentEvents > 0;
+
+ // Disable checking GCFreeSegmentEvents on .NET 7.0 issue: https://github.com/dotnet/diagnostics/issues/3143
+ bool GCSegmentResult = GCCreateSegmentEvents > 0 && (GCFreeSegmentEvents > 0 || Environment.Version.Major >= 7);
Logger.logger.Log("GCSegmentResult: " + GCSegmentResult);
Logger.logger.Log("GCAllocationTickEvents: " + GCAllocationTickEvents);
diff --git a/src/tests/eventpipe/LoaderEvents.cs b/src/tests/eventpipe/LoaderEvents.cs
index 6f68063aa7..50c21c4ebb 100644
--- a/src/tests/eventpipe/LoaderEvents.cs
+++ b/src/tests/eventpipe/LoaderEvents.cs
@@ -54,7 +54,7 @@ await RemoteTestExecutorHelper.RunTestCaseAsync(() =>
GetAssemblyPath();
try
{
- for(int i=0; i<100; i++)
+ for (int i = 0; i < 100; i++)
{
if (i % 10 == 0)
Logger.logger.Log($"Load/Unload Assembly {i} times...");
@@ -62,6 +62,7 @@ await RemoteTestExecutorHelper.RunTestCaseAsync(() =>
assemblyLoad.LoadFromAssemblyPath(assemblyPath+"\\Microsoft.Diagnostics.Runtime.dll");
assemblyLoad.Unload();
}
+ GC.Collect();
}
catch(Exception ex)
{