diff --git a/TestPlatform.sln b/TestPlatform.sln
index 1ec85c83de..8fa37dece3 100644
--- a/TestPlatform.sln
+++ b/TestPlatform.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
-VisualStudioVersion = 15.0.26124.0
+VisualStudioVersion = 15.0.26127.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{ED0C35EB-7F31-4841-A24F-8EB708FFA959}"
EndProject
@@ -124,8 +124,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimpleTestProject3", "test\
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "datacollector.UnitTests", "test\datacollector.UnitTests\datacollector.UnitTests.csproj", "{0C6EFAF9-CE3E-4C11-8DD8-D7DABB206E5C}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.TestPlatform.PlatformAbstractions", "src\Microsoft.TestPlatform.PlatformAbstractions\Microsoft.TestPlatform.PlatformAbstractions.csproj", "{CAE652AF-6801-425E-AAF3-AB20DE7DF88E}"
+EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "datacollector.PlatformTests", "test\datacollector.PlatformTests\datacollector.PlatformTests.csproj", "{FF80D706-8309-4E02-BAC0-D28B4CBCF600}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Platform", "Platform", "{7D4082EA-7AC9-4DFB-98E8-C5E08BDC0EC3}"
+EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OutOfProcDataCollector", "test\TestAssets\OutOfProcDataCollector\OutOfProcDataCollector.csproj", "{CB6FA3C6-38E2-4DD1-AAB7-A705EFE114BC}"
EndProject
Global
@@ -690,6 +694,18 @@ Global
{0C6EFAF9-CE3E-4C11-8DD8-D7DABB206E5C}.Release|x64.Build.0 = Release|x64
{0C6EFAF9-CE3E-4C11-8DD8-D7DABB206E5C}.Release|x86.ActiveCfg = Release|x86
{0C6EFAF9-CE3E-4C11-8DD8-D7DABB206E5C}.Release|x86.Build.0 = Release|x86
+ {CAE652AF-6801-425E-AAF3-AB20DE7DF88E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CAE652AF-6801-425E-AAF3-AB20DE7DF88E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CAE652AF-6801-425E-AAF3-AB20DE7DF88E}.Debug|x64.ActiveCfg = Debug|x64
+ {CAE652AF-6801-425E-AAF3-AB20DE7DF88E}.Debug|x64.Build.0 = Debug|x64
+ {CAE652AF-6801-425E-AAF3-AB20DE7DF88E}.Debug|x86.ActiveCfg = Debug|x86
+ {CAE652AF-6801-425E-AAF3-AB20DE7DF88E}.Debug|x86.Build.0 = Debug|x86
+ {CAE652AF-6801-425E-AAF3-AB20DE7DF88E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CAE652AF-6801-425E-AAF3-AB20DE7DF88E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CAE652AF-6801-425E-AAF3-AB20DE7DF88E}.Release|x64.ActiveCfg = Release|x64
+ {CAE652AF-6801-425E-AAF3-AB20DE7DF88E}.Release|x64.Build.0 = Release|x64
+ {CAE652AF-6801-425E-AAF3-AB20DE7DF88E}.Release|x86.ActiveCfg = Release|x86
+ {CAE652AF-6801-425E-AAF3-AB20DE7DF88E}.Release|x86.Build.0 = Release|x86
{FF80D706-8309-4E02-BAC0-D28B4CBCF600}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FF80D706-8309-4E02-BAC0-D28B4CBCF600}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FF80D706-8309-4E02-BAC0-D28B4CBCF600}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -771,6 +787,8 @@ Global
{0D85D957-6FF2-4620-B766-B708801D97F3} = {8DA7CBD9-F17E-41B6-90C4-CFF55848A25A}
{9549C1A4-CB57-4689-B3EB-F752F65F863F} = {8DA7CBD9-F17E-41B6-90C4-CFF55848A25A}
{0C6EFAF9-CE3E-4C11-8DD8-D7DABB206E5C} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6}
+ {CAE652AF-6801-425E-AAF3-AB20DE7DF88E} = {7D4082EA-7AC9-4DFB-98E8-C5E08BDC0EC3}
+ {7D4082EA-7AC9-4DFB-98E8-C5E08BDC0EC3} = {ED0C35EB-7F31-4841-A24F-8EB708FFA959}
{FF80D706-8309-4E02-BAC0-D28B4CBCF600} = {B27FAFDF-2DBA-4AB0-BA85-FD5F21D359D6}
{CB6FA3C6-38E2-4DD1-AAB7-A705EFE114BC} = {8DA7CBD9-F17E-41B6-90C4-CFF55848A25A}
EndGlobalSection
diff --git a/scripts/build.ps1 b/scripts/build.ps1
index fd7a02314c..b907f1c65f 100644
--- a/scripts/build.ps1
+++ b/scripts/build.ps1
@@ -195,6 +195,7 @@ function Publish-Package
$dataCollectorProject = Join-Path $env:TP_ROOT_DIR "src\datacollector\datacollector.csproj"
Write-Log "Package: Publish package\*.csproj"
+
Publish-Package-Internal $packageProject $TPB_TargetFramework $fullCLRPackageDir
Publish-Package-Internal $packageProject $TPB_TargetFrameworkCore $coreCLRPackageDir
@@ -245,7 +246,7 @@ function Publish-Package
foreach($file in $loggers) {
Write-Verbose "Move-Item $fullCLRPackageDir\$file $fullCLRExtensionsDir -Force"
Move-Item $fullCLRPackageDir\$file $fullCLRExtensionsDir -Force
-
+
Write-Verbose "Move-Item $coreCLRPackageDir\$file $coreCLRExtensionsDir -Force"
Move-Item $coreCLRPackageDir\$file $coreCLRExtensionsDir -Force
}
@@ -254,6 +255,26 @@ function Publish-Package
Copy-PackageItems "Microsoft.TestPlatform.Build"
Write-Log "Publish-Package: Complete. {$(Get-ElapsedTime($timer))}"
+
+ Publish-PlatfromAbstractions-Internal
+}
+
+function Publish-PlatfromAbstractions-Internal
+{
+ Write-Log "Publish-PlatfromAbstractions-Internal: Started."
+
+ $timer = Start-Timer
+ $fullCLRPackageDir = Get-FullCLRPackageDirectory
+ $coreCLRPackageDir = Get-CoreCLRPackageDirectory
+
+ $platformAbstraction = Join-Path $env:TP_ROOT_DIR "src\Microsoft.TestPlatform.PlatformAbstractions\bin\$TPB_Configuration"
+ $platformAbstractionNet46 = Join-Path $platformAbstraction $TPB_TargetFramework
+ $platformAbstractionNetCore = Join-Path $platformAbstraction $TPB_TargetFrameworkCore
+
+ Copy-Item $platformAbstractionNet46\* $fullCLRPackageDir -Force
+ Copy-Item $platformAbstractionNetCore\* $coreCLRPackageDir -Force
+
+ Write-Log "Publish-PlatfromAbstractions-Internal:: Complete. {$(Get-ElapsedTime($timer))}"
}
diff --git a/src/Microsoft.TestPlatform.CoreUtilities/Microsoft.TestPlatform.CoreUtilities.csproj b/src/Microsoft.TestPlatform.CoreUtilities/Microsoft.TestPlatform.CoreUtilities.csproj
index b177190955..f8b3af1bda 100644
Binary files a/src/Microsoft.TestPlatform.CoreUtilities/Microsoft.TestPlatform.CoreUtilities.csproj and b/src/Microsoft.TestPlatform.CoreUtilities/Microsoft.TestPlatform.CoreUtilities.csproj differ
diff --git a/src/Microsoft.TestPlatform.CoreUtilities/Tracing/EqtTrace.cs b/src/Microsoft.TestPlatform.CoreUtilities/Tracing/EqtTrace.cs
index 46860c8b6b..f2a01d4762 100644
--- a/src/Microsoft.TestPlatform.CoreUtilities/Tracing/EqtTrace.cs
+++ b/src/Microsoft.TestPlatform.CoreUtilities/Tracing/EqtTrace.cs
@@ -4,15 +4,9 @@
namespace Microsoft.VisualStudio.TestPlatform.ObjectModel
{
using System;
- using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
- using System.IO;
using System.Text;
- using System.Threading;
-
- using Microsoft.VisualStudio.TestPlatform.CoreUtilities;
- using Microsoft.VisualStudio.TestPlatform.CoreUtilities.Resources;
///
/// Wrapper class for tracing.
@@ -29,106 +23,52 @@ namespace Microsoft.VisualStudio.TestPlatform.ObjectModel
///
public static class EqtTrace
{
- ///
- /// Name of the trace listener.
- ///
- private const string ListenerName = "TptTraceListener";
-
- ///
- /// Use a custom trace source. This doesn't pollute the default tracing for user applications.
- ///
- private static readonly TraceSource Source = new TraceSource("TpTrace", SourceLevels.Off);
-
- ///
- /// Create static maps for TraceLevel to SourceLevels. The APIs need to provide TraceLevel
- /// for backward compatibility with older versions of Object Model.
- ///
- private static readonly Dictionary TraceSourceLevelsMap =
- new Dictionary
- {
- { TraceLevel.Error, SourceLevels.Error },
- { TraceLevel.Info, SourceLevels.Information },
- { TraceLevel.Off, SourceLevels.Off },
- { TraceLevel.Verbose, SourceLevels.Verbose },
- { TraceLevel.Warning, SourceLevels.Warning }
- };
-
- ///
- /// Create static maps for SourceLevels to TraceLevel. The APIs need to provide TraceLevel
- /// for backward compatibility with older versions of Object Model.
- ///
- private static readonly Dictionary SourceTraceLevelsMap =
- new Dictionary
- {
- { SourceLevels.Error, TraceLevel.Error },
- { SourceLevels.Information, TraceLevel.Info },
- { SourceLevels.Off, TraceLevel.Off },
- { SourceLevels.Verbose, TraceLevel.Verbose },
- { SourceLevels.Warning, TraceLevel.Warning },
- { SourceLevels.All, TraceLevel.Verbose }
- };
-
- ///
- /// Create static maps for SourceLevels to TraceLevel. The APIs need to provide TraceLevel
- /// for backward compatibility with older versions of Object Model.
- ///
- private static readonly Dictionary TraceLevelEventTypeMap =
- new Dictionary
- {
- { TraceLevel.Error, TraceEventType.Error },
- { TraceLevel.Info, TraceEventType.Information },
- { TraceLevel.Verbose, TraceEventType.Verbose },
- { TraceLevel.Warning, TraceEventType.Warning }
- };
-
- // Current process name/id that called trace so that it's easier to read logs.
- // We cache them for performance reason.
- private static readonly string ProcessName = GetProcessName();
-
- private static readonly int ProcessId = GetProcessId();
-
- ///
- /// Specifies whether the trace is initialized or not
- ///
- private static bool isListenerInitialized = false;
-
- ///
- /// Lock over initialization
- ///
- private static object isInitializationLock = new object();
+ private static IPlatformEqtTrace traceImpl = new PlatformEqtTrace();
- private static int traceFileSize = 0;
- private static int defaultTraceFileSize = 10240; // 10Mb.
+#if NET46
+ public static void SetupRemoteEqtTraceListeners(AppDomain childDomain)
+ {
+ traceImpl.SetupRemoteEqtTraceListeners(childDomain);
+ }
- ///
- /// Gets the log file for tracing.
- ///
- public static string LogFile
+ public static void SetupListener(TraceListener listener)
{
- get;
- private set;
+ traceImpl.SetupListener(listener);
}
- ///
- /// Gets or sets the trace level.
- ///
public static TraceLevel TraceLevel
{
get
{
- return SourceTraceLevelsMap[Source.Switch.Level];
+ return (TraceLevel)traceImpl.GetTraceLevel();
+ }
+ set
+ {
+ traceImpl.SetTraceLevel((PlatformTraceLevel)value);
}
+ }
+
+#endif
+#if NETSTANDARD1_4
+ public static PlatformTraceLevel TraceLevel
+ {
+ get
+ {
+ return traceImpl.GetTraceLevel();
+ }
set
{
- try
- {
- Source.Switch.Level = TraceSourceLevelsMap[value];
- }
- catch (ArgumentException e)
- {
- LogIgnoredException(e);
- }
+ traceImpl.SetTraceLevel(value);
+ }
+ }
+#endif
+
+ public static string LogFile
+ {
+ get
+ {
+ return traceImpl.GetLogFile();
}
}
@@ -139,7 +79,7 @@ public static bool IsErrorEnabled
{
get
{
- return ShouldTrace(TraceLevel.Error);
+ return traceImpl.ShouldTrace(PlatformTraceLevel.Error);
}
}
@@ -150,7 +90,7 @@ public static bool IsInfoEnabled
{
get
{
- return ShouldTrace(TraceLevel.Info);
+ return traceImpl.ShouldTrace(PlatformTraceLevel.Info);
}
}
@@ -161,7 +101,7 @@ public static bool IsVerboseEnabled
{
get
{
- return ShouldTrace(TraceLevel.Verbose);
+ return traceImpl.ShouldTrace(PlatformTraceLevel.Verbose);
}
}
@@ -172,7 +112,7 @@ public static bool IsWarningEnabled
{
get
{
- return ShouldTrace(TraceLevel.Warning);
+ return traceImpl.ShouldTrace(PlatformTraceLevel.Warning);
}
}
@@ -183,93 +123,9 @@ public static bool IsWarningEnabled
/// A custom log file for trace messages.
public static void InitializeVerboseTrace(string customLogFile)
{
- isListenerInitialized = false;
-
- LogFile = customLogFile;
- TraceLevel = TraceLevel.Verbose;
- Source.Switch.Level = SourceLevels.All;
- }
-
-#if NET46
- ///
- /// Setup remote trace listener in the child domain.
- /// If calling domain, doesn't have tracing enabled nothing is done.
- ///
- /// Child AppDomain.
- public static void SetupRemoteEqtTraceListeners(AppDomain childDomain)
- {
- Debug.Assert(childDomain != null, "domain");
- if (childDomain != null)
- {
- RemoteEqtTrace remoteEqtTrace = (RemoteEqtTrace)childDomain.CreateInstanceFromAndUnwrap(
- typeof(RemoteEqtTrace).Assembly.Location,
- typeof(RemoteEqtTrace).FullName);
-
- remoteEqtTrace.TraceLevel = TraceLevel;
-
- if (!Enum.Equals(TraceLevel, TraceLevel.Off))
- {
- TraceListener tptListner = null;
- foreach (TraceListener listener in Trace.Listeners)
- {
- if (string.Equals(listener.Name, ListenerName, StringComparison.OrdinalIgnoreCase))
- {
- Debug.Assert(tptListner == null, "Multiple TptListeners found.");
- tptListner = listener;
- }
- }
-
- remoteEqtTrace.SetupRemoteListeners(tptListner);
- }
- }
- }
-#endif
-
- ///
- /// Setup a custom trace listener instead of default trace listener created by test platform.
- /// This is needed by DTA Agent where it needs to listen test platform traces but doesn't use test platform listener.
- ///
- ///
- /// The listener.
- ///
- public static void SetupListener(TraceListener listener)
- {
- lock (isInitializationLock)
- {
- // Add new listeners.
- if (listener != null)
- {
- Source.Listeners.Add(listener);
- }
-
- isListenerInitialized = true;
- }
+ traceImpl.InitializeVerboseTrace(customLogFile);
}
- ///
- /// Gets a value indicating if tracing is enabled for a trace level.
- ///
- /// Trace level.
- /// True if tracing is enabled.
- public static bool ShouldTrace(TraceLevel traceLevel)
- {
- switch (traceLevel)
- {
- case TraceLevel.Off:
- return false;
- case TraceLevel.Error:
- return Source.Switch.ShouldTrace(TraceEventType.Error);
- case TraceLevel.Warning:
- return Source.Switch.ShouldTrace(TraceEventType.Warning);
- case TraceLevel.Info:
- return Source.Switch.ShouldTrace(TraceEventType.Information);
- case TraceLevel.Verbose:
- return Source.Switch.ShouldTrace(TraceEventType.Verbose);
- default:
- Debug.Fail("Should never get here!");
- return false;
- }
- }
///
/// Prints an error message and prompts with a Debug dialog
@@ -305,9 +161,9 @@ public static void Fail(string format, params object[] args)
[Conditional("TRACE")]
public static void Error(string message)
{
- if (ShouldTrace(TraceLevel.Error))
+ if (traceImpl.ShouldTrace(PlatformTraceLevel.Error))
{
- WriteLine(TraceLevel.Error, message);
+ traceImpl.WriteLine(PlatformTraceLevel.Error, message);
}
}
@@ -344,7 +200,7 @@ public static void ErrorUnless(bool condition, string message)
/// Level for trace.
/// Trace message.
[Conditional("TRACE")]
- public static void ErrorUnlessAlterTrace(bool condition, TraceLevel bumpLevel, string message)
+ public static void ErrorUnlessAlterTrace(bool condition, PlatformTraceLevel bumpLevel, string message)
{
if (condition)
{
@@ -367,7 +223,7 @@ public static void Error(string format, params object[] args)
Debug.Assert(format != null, "format != null");
// Check level before doing string.Format to avoid string creation if tracing is off.
- if (ShouldTrace(TraceLevel.Error))
+ if (traceImpl.ShouldTrace(PlatformTraceLevel.Error))
{
Error(string.Format(CultureInfo.InvariantCulture, format, args));
}
@@ -394,7 +250,7 @@ public static void ErrorUnless(bool condition, string format, params object[] ar
/// Message format.
/// Trace message format arguments.
[Conditional("TRACE")]
- public static void ErrorUnlessAlterTrace(bool condition, TraceLevel bumpLevel, string format, params object[] args)
+ public static void ErrorUnlessAlterTrace(bool condition, PlatformTraceLevel bumpLevel, string format, params object[] args)
{
if (condition)
{
@@ -446,10 +302,10 @@ public static void Error(Exception exceptionToTrace)
// Write only if tracing for error is enabled.
// Done upfront to avoid perf hit.
- if (ShouldTrace(TraceLevel.Error))
+ if (traceImpl.ShouldTrace(PlatformTraceLevel.Error))
{
// Write at error level
- WriteLine(TraceLevel.Error, FormatException(exceptionToTrace));
+ traceImpl.WriteLine(PlatformTraceLevel.Error, FormatException(exceptionToTrace));
}
}
@@ -460,9 +316,9 @@ public static void Error(Exception exceptionToTrace)
[Conditional("TRACE")]
public static void Warning(string message)
{
- if (ShouldTrace(TraceLevel.Warning))
+ if (traceImpl.ShouldTrace(PlatformTraceLevel.Warning))
{
- WriteLine(TraceLevel.Warning, message);
+ traceImpl.WriteLine(PlatformTraceLevel.Warning, message);
}
}
@@ -499,7 +355,7 @@ public static void WarningUnless(bool condition, string message)
/// Trace message level.
/// Message to trace.
[Conditional("TRACE")]
- public static void WarningUnlessAlterTrace(bool condition, TraceLevel bumpLevel, string message)
+ public static void WarningUnlessAlterTrace(bool condition, PlatformTraceLevel bumpLevel, string message)
{
if (condition)
{
@@ -522,7 +378,7 @@ public static void Warning(string format, params object[] args)
Debug.Assert(format != null, "format != null");
// Check level before doing string.Format to avoid string creation if tracing is off.
- if (ShouldTrace(TraceLevel.Warning))
+ if (traceImpl.ShouldTrace(PlatformTraceLevel.Warning))
{
Warning(string.Format(CultureInfo.InvariantCulture, format, args));
}
@@ -564,7 +420,7 @@ public static void WarningUnless(bool condition, string format, params object[]
/// Format of the trace message.
/// Arguments for trace message.
[Conditional("TRACE")]
- public static void WarningUnlessAlterTrace(bool condition, TraceLevel bumpLevel, string format, params object[] args)
+ public static void WarningUnlessAlterTrace(bool condition, PlatformTraceLevel bumpLevel, string format, params object[] args)
{
if (condition)
{
@@ -583,9 +439,9 @@ public static void WarningUnlessAlterTrace(bool condition, TraceLevel bumpLevel,
[Conditional("TRACE")]
public static void Info(string message)
{
- if (ShouldTrace(TraceLevel.Info))
+ if (traceImpl.ShouldTrace(PlatformTraceLevel.Info))
{
- WriteLine(TraceLevel.Info, message);
+ traceImpl.WriteLine(PlatformTraceLevel.Info, message);
}
}
@@ -622,7 +478,7 @@ public static void InfoUnless(bool condition, string message)
/// Trace message level.
/// Trace message.
[Conditional("TRACE")]
- public static void InfoUnlessAlterTrace(bool condition, TraceLevel bumpLevel, string message)
+ public static void InfoUnlessAlterTrace(bool condition, PlatformTraceLevel bumpLevel, string message)
{
if (condition)
{
@@ -645,7 +501,7 @@ public static void Info(string format, params object[] args)
Debug.Assert(format != null, "format != null");
// Check level before doing string.Format to avoid string creation if tracing is off.
- if (ShouldTrace(TraceLevel.Info))
+ if (traceImpl.ShouldTrace(PlatformTraceLevel.Info))
{
Info(string.Format(CultureInfo.InvariantCulture, format, args));
}
@@ -687,7 +543,7 @@ public static void InfoUnless(bool condition, string format, params object[] arg
/// Trace message format.
/// Trace message arguments.
[Conditional("TRACE")]
- public static void InfoUnlessAlterTrace(bool condition, TraceLevel bumpLevel, string format, params object[] args)
+ public static void InfoUnlessAlterTrace(bool condition, PlatformTraceLevel bumpLevel, string format, params object[] args)
{
if (condition)
{
@@ -706,9 +562,9 @@ public static void InfoUnlessAlterTrace(bool condition, TraceLevel bumpLevel, st
[Conditional("TRACE")]
public static void Verbose(string message)
{
- if (ShouldTrace(TraceLevel.Verbose))
+ if (traceImpl.ShouldTrace(PlatformTraceLevel.Verbose))
{
- WriteLine(TraceLevel.Verbose, message);
+ traceImpl.WriteLine(PlatformTraceLevel.Verbose, message);
}
}
@@ -745,7 +601,7 @@ public static void VerboseUnless(bool condition, string message)
/// Trace message level.
/// Trace message.
[Conditional("TRACE")]
- public static void VerboseUnlessAlterTrace(bool condition, TraceLevel level, string message)
+ public static void VerboseUnlessAlterTrace(bool condition, PlatformTraceLevel level, string message)
{
if (condition)
{
@@ -768,7 +624,7 @@ public static void Verbose(string format, params object[] args)
Debug.Assert(format != null, "format != null");
// Check level before doing string.Format to avoid string creation if tracing is off.
- if (ShouldTrace(TraceLevel.Verbose))
+ if (traceImpl.ShouldTrace(PlatformTraceLevel.Verbose))
{
Verbose(string.Format(CultureInfo.InvariantCulture, format, args));
}
@@ -810,7 +666,7 @@ public static void VerboseUnless(bool condition, string format, params object[]
/// Format of the trace message.
/// Arguments for the trace message format.
[Conditional("TRACE")]
- public static void VerboseUnlessAlterTrace(bool condition, TraceLevel level, string format, params object[] args)
+ public static void VerboseUnlessAlterTrace(bool condition, PlatformTraceLevel level, string format, params object[] args)
{
if (condition)
{
@@ -822,64 +678,6 @@ public static void VerboseUnlessAlterTrace(bool condition, TraceLevel level, str
}
}
- ///
- /// Setup trace listeners. It should be called when setting trace listener for child domain.
- ///
- /// New listener.
- internal static void SetupRemoteListeners(TraceListener listener)
- {
- lock (isInitializationLock)
- {
- // Add new listeners.
- if (listener != null)
- {
- Source.Listeners.Add(listener);
- }
-
- isListenerInitialized = true;
- }
- }
-
- ///
- /// Ensure the trace is initialized
- ///
- private static void EnsureTraceIsInitialized()
- {
- if (isListenerInitialized)
- {
- return;
- }
-
- lock (isInitializationLock)
- {
- if (isListenerInitialized)
- {
- return;
- }
-
- string logsDirectory = Path.GetTempPath();
-
- // Set the trace level and add the trace listener
- if (LogFile == null)
- {
- using (var process = Process.GetCurrentProcess())
- {
- // In case of parallel execution, there may be several processes with same name.
- // Add a process id to make the traces unique.
- LogFile = Path.Combine(
- logsDirectory,
- Path.GetFileNameWithoutExtension(process.MainModule.FileName) + "." + process.Id + ".TpTrace.log");
- }
- }
-
- // Add a default listener
- traceFileSize = defaultTraceFileSize;
- Source.Listeners.Add(new RollingFileTraceListener(LogFile, ListenerName, traceFileSize));
-
- isListenerInitialized = true;
- }
- }
-
///
/// Formats an exception into a nice looking message.
///
@@ -949,81 +747,22 @@ private static string FormatException(Exception exceptionToTrace)
return message.ToString();
}
- ///
- /// Get the process name. Note: we cache it, use m_processName.
- ///
- /// Name of the process.
- private static string GetProcessName()
- {
- try
- {
- // return ProcessHelper.GetProcessName();
- string processName = null;
-
- string[] args = Environment.GetCommandLineArgs();
-
- if (args != null && args.Length != 0)
- {
- // Leave the extension if specified, otherwise don't add it (e.g. case a.exe.exe).
- // It seems that if .exe suffix is not specified Framework adds .EXE to agrs[0].
- processName = Path.GetFileName(args[0]);
- }
-
- // If we still have not got process name from command line - use the slow way.
- // This should never happen unless the process is called from execv with empty cmdline.
- if (string.IsNullOrEmpty(processName))
- {
- Debug.Fail("Could not get process name from command line, will try to use the slow way.");
- using (var process = Process.GetCurrentProcess())
- {
- processName = process.ProcessName;
- }
- }
-
- return processName;
- }
- catch (Exception e)
- {
- // valid suppress
- Debug.Fail("Could not get process name: " + e);
- LogIgnoredException(e);
- return Resources.Utility_ProcessNameWhenCannotGetIt;
- }
- }
-
- private static int GetProcessId()
- {
- try
- {
- using (var process = Process.GetCurrentProcess())
- {
- return process.Id;
- }
- }
- catch (InvalidOperationException e)
- {
- Debug.Fail("Could not get process id: " + e);
- LogIgnoredException(e);
- return -1;
- }
- }
-
- private static void WriteAtLevel(TraceLevel level, string message)
+ private static void WriteAtLevel(PlatformTraceLevel level, string message)
{
switch (level)
{
- case TraceLevel.Off:
+ case PlatformTraceLevel.Off:
return;
- case TraceLevel.Error:
+ case PlatformTraceLevel.Error:
Error(message);
break;
- case TraceLevel.Warning:
+ case PlatformTraceLevel.Warning:
Warning(message);
break;
- case TraceLevel.Info:
+ case PlatformTraceLevel.Info:
Info(message);
break;
- case TraceLevel.Verbose:
+ case PlatformTraceLevel.Verbose:
Verbose(message);
break;
default:
@@ -1032,71 +771,10 @@ private static void WriteAtLevel(TraceLevel level, string message)
}
}
- private static void WriteAtLevel(TraceLevel level, string format, params object[] args)
+ private static void WriteAtLevel(PlatformTraceLevel level, string format, params object[] args)
{
Debug.Assert(format != null, "format != null");
WriteAtLevel(level, string.Format(CultureInfo.InvariantCulture, format, args));
}
-
- ///
- /// Adds the message to the trace log.
- /// The line becomes:
- /// [I, PID, ThreadID, 2003/06/11 11:56:07.445] CallingAssemblyName: message.
- ///
- /// Trace level.
- /// The message to add to trace.
- private static void WriteLine(TraceLevel level, string message)
- {
- Debug.Assert(message != null, "message != null");
- Debug.Assert(!string.IsNullOrEmpty(ProcessName), "!string.IsNullOrEmpty(ProcessName)");
-
- // Ensure trace is initlized
- EnsureTraceIsInitialized();
-
- // The format below is a CSV so that Excel could be used easily to
- // view/filter the logs.
- var log = string.Format(
- CultureInfo.InvariantCulture,
- "{0}, {1}, {2:yyyy}/{2:MM}/{2:dd}, {2:HH}:{2:mm}:{2:ss}.{2:fff}, {5}, {3}, {4}",
- ProcessId,
- Thread.CurrentThread.ManagedThreadId,
- DateTime.Now,
- ProcessName,
- message,
- Stopwatch.GetTimestamp());
-
- try
- {
- Source.TraceEvent(TraceLevelEventTypeMap[level], 0, log);
- Source.Flush();
- }
- catch (Exception e)
- {
- // valid suppress
- // Log exception from tracing into event viewer.
- LogIgnoredException(e);
- }
- }
-
- ///
- /// Auxiliary method: logs the exception that is being ignored.
- ///
- /// The exception to log.
- private static void LogIgnoredException(Exception e)
- {
- Debug.Assert(e != null, "e != null");
-
- EnsureTraceIsInitialized();
-
- try
- {
- // Note: Debug.WriteLine may throw if there is a problem in .config file.
- Debug.WriteLine("Ignore exception: " + e);
- }
- catch
- {
- // Ignore everything at this point.
- }
- }
}
}
\ No newline at end of file
diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Microsoft.TestPlatform.CrossPlatEngine.csproj b/src/Microsoft.TestPlatform.CrossPlatEngine/Microsoft.TestPlatform.CrossPlatEngine.csproj
index 4980803b66..e5de06306c 100644
--- a/src/Microsoft.TestPlatform.CrossPlatEngine/Microsoft.TestPlatform.CrossPlatEngine.csproj
+++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Microsoft.TestPlatform.CrossPlatEngine.csproj
@@ -30,6 +30,9 @@
4.3.0
+
+ 4.3.0
+
diff --git a/src/Microsoft.TestPlatform.ObjectModel/Microsoft.TestPlatform.ObjectModel.csproj b/src/Microsoft.TestPlatform.ObjectModel/Microsoft.TestPlatform.ObjectModel.csproj
index 6aaf37270f..d2ab2dc72d 100644
Binary files a/src/Microsoft.TestPlatform.ObjectModel/Microsoft.TestPlatform.ObjectModel.csproj and b/src/Microsoft.TestPlatform.ObjectModel/Microsoft.TestPlatform.ObjectModel.csproj differ
diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/Interfaces/Tracing/IEqtTrace.cs b/src/Microsoft.TestPlatform.PlatformAbstractions/Interfaces/Tracing/IEqtTrace.cs
new file mode 100644
index 0000000000..51132bb553
--- /dev/null
+++ b/src/Microsoft.TestPlatform.PlatformAbstractions/Interfaces/Tracing/IEqtTrace.cs
@@ -0,0 +1,74 @@
+namespace Microsoft.VisualStudio.TestPlatform.ObjectModel
+{
+ //
+ // Summary:
+ // Specifies what messages to output for the System.Diagnostics.Debug, System.Diagnostics.Trace
+ // and System.Diagnostics.TraceSwitch classes.
+ public enum PlatformTraceLevel
+ {
+ //
+ // Summary:
+ // Output no tracing and debugging messages.
+ Off = 0,
+ //
+ // Summary:
+ // Output error-handling messages.
+ Error = 1,
+ //
+ // Summary:
+ // Output warnings and error-handling messages.
+ Warning = 2,
+ //
+ // Summary:
+ // Output informational messages, warnings, and error-handling messages.
+ Info = 3,
+ //
+ // Summary:
+ // Output all debugging and tracing messages.
+ Verbose = 4
+ }
+
+
+ public partial interface IPlatformEqtTrace
+ {
+ ///
+ /// Adds the message to the trace log.
+ /// The line becomes:
+ /// [I, PID, ThreadID, 2003/06/11 11:56:07.445] CallingAssemblyName: message.
+ ///
+ /// Trace level.
+ /// The message to add to trace.
+ void WriteLine(PlatformTraceLevel level, string message);
+
+ ///
+ /// Initializes the verbose tracing with custom log file
+ /// And overrides if any trace is set before
+ ///
+ /// A custom log file for trace messages.
+ void InitializeVerboseTrace(string customLogFile);
+
+ ///
+ /// Gets a value indicating if tracing is enabled for a trace level.
+ ///
+ /// Trace level.
+ /// True if tracing is enabled.
+ bool ShouldTrace(PlatformTraceLevel traceLevel);
+
+ ///
+ /// Gets file path for trace log file.
+ ///
+ /// True if tracing is enabled.
+ string GetLogFile();
+
+ ///
+ /// Sets platfrom specific trace value for tracing verbosity.
+ ///
+ /// PlatformTraceLevel.
+ void SetTraceLevel(PlatformTraceLevel value);
+
+ ///
+ /// Gets platfrom specific trace value for tracing verbosity.
+ ///
+ PlatformTraceLevel GetTraceLevel();
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/Microsoft.TestPlatform.PlatformAbstractions.csproj b/src/Microsoft.TestPlatform.PlatformAbstractions/Microsoft.TestPlatform.PlatformAbstractions.csproj
new file mode 100644
index 0000000000..59eb92501f
Binary files /dev/null and b/src/Microsoft.TestPlatform.PlatformAbstractions/Microsoft.TestPlatform.PlatformAbstractions.csproj differ
diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/common/Tracing/EqtTrace.cs b/src/Microsoft.TestPlatform.PlatformAbstractions/common/Tracing/EqtTrace.cs
new file mode 100644
index 0000000000..318d55f96b
--- /dev/null
+++ b/src/Microsoft.TestPlatform.PlatformAbstractions/common/Tracing/EqtTrace.cs
@@ -0,0 +1,368 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Microsoft.VisualStudio.TestPlatform.ObjectModel
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics;
+ using System.Globalization;
+ using System.IO;
+ using System.Threading;
+
+ ///
+ /// Wrapper class for tracing.
+ /// - Shortcut-methods for Error, Warning, Info, Verbose.
+ /// - Adds additional information to the trace: calling process name, PID, ThreadID, Time.
+ /// - Uses custom switch EqtTraceLevel from .config file.
+ /// - By default tracing if OFF.
+ /// - Our build environment always sets the /d:TRACE so this class is always enabled,
+ /// the Debug class is enabled only in debug builds (/d:DEBUG).
+ /// - We ignore exceptions thrown by underlying TraceSwitch (e.g. due to config file error).
+ /// We log ignored exceptions to system Application log.
+ /// We pass through exceptions thrown due to incorrect arguments to EqtTrace methods.
+ /// Usage: EqtTrace.Info("Here's how to trace info");
+ ///
+ public partial class PlatformEqtTrace : IPlatformEqtTrace
+ {
+ ///
+ /// Name of the trace listener.
+ ///
+ private const string ListenerName = "TptTraceListener";
+
+ ///
+ /// Use a custom trace source. This doesn't pollute the default tracing for user applications.
+ ///
+ private static readonly TraceSource Source = new TraceSource("TpTrace", SourceLevels.Off);
+
+ ///
+ /// Create static maps for TraceLevel to SourceLevels. The APIs need to provide TraceLevel
+ /// for backward compatibility with older versions of Object Model.
+ ///
+ private static readonly Dictionary TraceSourceLevelsMap =
+ new Dictionary
+ {
+ { TraceLevel.Error, SourceLevels.Error },
+ { TraceLevel.Info, SourceLevels.Information },
+ { TraceLevel.Off, SourceLevels.Off },
+ { TraceLevel.Verbose, SourceLevels.Verbose },
+ { TraceLevel.Warning, SourceLevels.Warning }
+ };
+
+ ///
+ /// Create static maps for SourceLevels to TraceLevel. The APIs need to provide TraceLevel
+ /// for backward compatibility with older versions of Object Model.
+ ///
+ private static readonly Dictionary SourceTraceLevelsMap =
+ new Dictionary
+ {
+ { SourceLevels.Error, TraceLevel.Error },
+ { SourceLevels.Information, TraceLevel.Info },
+ { SourceLevels.Off, TraceLevel.Off },
+ { SourceLevels.Verbose, TraceLevel.Verbose },
+ { SourceLevels.Warning, TraceLevel.Warning },
+ { SourceLevels.All, TraceLevel.Verbose }
+ };
+
+ ///
+ /// Create static maps for SourceLevels to TraceLevel. The APIs need to provide TraceLevel
+ /// for backward compatibility with older versions of Object Model.
+ ///
+ private static readonly Dictionary TraceLevelEventTypeMap =
+ new Dictionary
+ {
+ { TraceLevel.Error, TraceEventType.Error },
+ { TraceLevel.Info, TraceEventType.Information },
+ { TraceLevel.Verbose, TraceEventType.Verbose },
+ { TraceLevel.Warning, TraceEventType.Warning }
+ };
+
+ // Current process name/id that called trace so that it's easier to read logs.
+ // We cache them for performance reason.
+ private static readonly string ProcessName = GetProcessName();
+
+ private static readonly int ProcessId = GetProcessId();
+
+ ///
+ /// Specifies whether the trace is initialized or not
+ ///
+ private static bool isInitialized = false;
+
+ ///
+ /// Lock over initialization
+ ///
+ private static object isInitializationLock = new object();
+
+ private static int traceFileSize = 0;
+ private static int defaultTraceFileSize = 10240; // 10Mb.
+
+ public static string LogFile
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Gets or sets the trace level.
+ ///
+ public static TraceLevel TraceLevel
+ {
+ get
+ {
+ return SourceTraceLevelsMap[Source.Switch.Level];
+ }
+
+ set
+ {
+ try
+ {
+ Source.Switch.Level = TraceSourceLevelsMap[value];
+ }
+ catch (ArgumentException e)
+ {
+ LogIgnoredException(e);
+ }
+ }
+ }
+
+ ///
+ /// Setup trace listeners. It should be called when setting trace listener for child domain.
+ ///
+ /// New listener.
+ internal static void SetupRemoteListeners(TraceListener listener)
+ {
+ lock (isInitializationLock)
+ {
+ // Add new listeners.
+ if (listener != null)
+ {
+ Source.Listeners.Add((TraceListener)listener);
+ }
+
+ isInitialized = true;
+ }
+ }
+
+ ///
+ public void InitializeVerboseTrace(string customLogFile)
+ {
+ isInitialized = false;
+
+ LogFile = customLogFile;
+ TraceLevel = TraceLevel.Verbose;
+ Source.Switch.Level = SourceLevels.All;
+ }
+
+ ///
+ public bool ShouldTrace(PlatformTraceLevel traceLevel)
+ {
+ switch (traceLevel)
+ {
+ case PlatformTraceLevel.Off:
+ return false;
+ case PlatformTraceLevel.Error:
+ return Source.Switch.ShouldTrace(TraceEventType.Error);
+ case PlatformTraceLevel.Warning:
+ return Source.Switch.ShouldTrace(TraceEventType.Warning);
+ case PlatformTraceLevel.Info:
+ return Source.Switch.ShouldTrace(TraceEventType.Information);
+ case PlatformTraceLevel.Verbose:
+ return Source.Switch.ShouldTrace(TraceEventType.Verbose);
+ default:
+ Debug.Fail("Should never get here!");
+ return false;
+ }
+ }
+
+ ///
+ public string GetLogFile()
+ {
+ return LogFile;
+ }
+
+ ///
+ /// Ensure the trace is initialized
+ ///
+ private static void EnsureTraceIsInitialized()
+ {
+ if (isInitialized)
+ {
+ return;
+ }
+
+ lock (isInitializationLock)
+ {
+ if (isInitialized)
+ {
+ return;
+ }
+
+ string logsDirectory = Path.GetTempPath();
+
+ // Set the trace level and add the trace listener
+ if (LogFile == null)
+ {
+ using (var process = Process.GetCurrentProcess())
+ {
+ // In case of parallel execution, there may be several processes with same name.
+ // Add a process id to make the traces unique.
+ LogFile = Path.Combine(
+ logsDirectory,
+ Path.GetFileNameWithoutExtension(process.MainModule.FileName) + "." + process.Id + ".TpTrace.log");
+ }
+ }
+
+ // Add a default listener
+ traceFileSize = defaultTraceFileSize;
+ Source.Listeners.Add(new RollingFileTraceListener(LogFile, ListenerName, traceFileSize));
+
+ isInitialized = true;
+ }
+ }
+
+ ///
+ /// Get the process name. Note: we cache it, use m_processName.
+ ///
+ /// Name of the process.
+ private static string GetProcessName()
+ {
+ try
+ {
+ string processName = null;
+
+ string[] args = Environment.GetCommandLineArgs();
+
+ if (args != null && args.Length != 0)
+ {
+ // Leave the extension if specified, otherwise don't add it (e.g. case a.exe.exe).
+ // It seems that if .exe suffix is not specified Framework adds .EXE to agrs[0].
+ processName = Path.GetFileName(args[0]);
+ }
+
+ // If we still have not got process name from command line - use the slow way.
+ // This should never happen unless the process is called from execv with empty cmdline.
+ if (string.IsNullOrEmpty(processName))
+ {
+ Debug.Fail("Could not get process name from command line, will try to use the slow way.");
+ using (var process = Process.GetCurrentProcess())
+ {
+ processName = process.ProcessName;
+ }
+ }
+
+ return processName;
+ }
+ catch (Exception e)
+ {
+ // valid suppress
+ Debug.Fail("Could not get process name: " + e);
+ LogIgnoredException(e);
+ return e.Message;
+ }
+ }
+
+ private static int GetProcessId()
+ {
+ try
+ {
+ using (var process = Process.GetCurrentProcess())
+ {
+ return process.Id;
+ }
+ }
+ catch (InvalidOperationException e)
+ {
+ Debug.Fail("Could not get process id: " + e);
+ LogIgnoredException(e);
+ return -1;
+ }
+ }
+
+
+ ///
+ public void WriteLine(PlatformTraceLevel level, string message)
+ {
+ Debug.Assert(message != null, "message != null");
+ Debug.Assert(!string.IsNullOrEmpty(ProcessName), "!string.IsNullOrEmpty(ProcessName)");
+
+ // Ensure trace is initlized
+ EnsureTraceIsInitialized();
+
+ // The format below is a CSV so that Excel could be used easily to
+ // view/filter the logs.
+ var log = string.Format(
+ CultureInfo.InvariantCulture,
+ "{0}, {1}, {2:yyyy}/{2:MM}/{2:dd}, {2:HH}:{2:mm}:{2:ss}.{2:fff}, {5}, {3}, {4}",
+ ProcessId,
+ Thread.CurrentThread.ManagedThreadId,
+ DateTime.Now,
+ ProcessName,
+ message,
+ Stopwatch.GetTimestamp());
+
+ try
+ {
+ Source.TraceEvent(TraceLevelEventTypeMap[MapPlatformTraceToTrace(level)], 0, log);
+ Source.Flush();
+ }
+ catch (Exception e)
+ {
+ // valid suppress
+ // Log exception from tracing into event viewer.
+ LogIgnoredException(e);
+ }
+ }
+
+ ///
+ /// Auxiliary method: logs the exception that is being ignored.
+ ///
+ /// The exception to log.
+ private static void LogIgnoredException(Exception e)
+ {
+ Debug.Assert(e != null, "e != null");
+
+ EnsureTraceIsInitialized();
+
+ try
+ {
+ // Note: Debug.WriteLine may throw if there is a problem in .config file.
+ Debug.WriteLine("Ignore exception: " + e);
+ }
+ catch
+ {
+ // Ignore everything at this point.
+ }
+ }
+
+ ///
+ public void SetTraceLevel(PlatformTraceLevel value)
+ {
+ Source.Switch.Level = TraceSourceLevelsMap[MapPlatformTraceToTrace(value)];
+ }
+
+ public PlatformTraceLevel GetTraceLevel()
+ {
+ return (PlatformTraceLevel)SourceTraceLevelsMap[Source.Switch.Level];
+ }
+
+ public TraceLevel MapPlatformTraceToTrace(PlatformTraceLevel traceLevel)
+ {
+ switch (traceLevel)
+ {
+ case PlatformTraceLevel.Off:
+ return TraceLevel.Off;
+ case PlatformTraceLevel.Error:
+ return TraceLevel.Error;
+ case PlatformTraceLevel.Warning:
+ return TraceLevel.Warning;
+ case PlatformTraceLevel.Info:
+ return TraceLevel.Info;
+ case PlatformTraceLevel.Verbose:
+ return TraceLevel.Verbose;
+ default:
+ Debug.Fail("Should never get here!");
+ return TraceLevel.Verbose;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.TestPlatform.CoreUtilities/Tracing/RollingFileTraceListener.cs b/src/Microsoft.TestPlatform.PlatformAbstractions/common/Tracing/RollingFileTraceListener.cs
similarity index 98%
rename from src/Microsoft.TestPlatform.CoreUtilities/Tracing/RollingFileTraceListener.cs
rename to src/Microsoft.TestPlatform.PlatformAbstractions/common/Tracing/RollingFileTraceListener.cs
index 0eff163ea3..37f30b30d6 100644
--- a/src/Microsoft.TestPlatform.CoreUtilities/Tracing/RollingFileTraceListener.cs
+++ b/src/Microsoft.TestPlatform.PlatformAbstractions/common/Tracing/RollingFileTraceListener.cs
@@ -9,9 +9,6 @@ namespace Microsoft.VisualStudio.TestPlatform.ObjectModel
using System.IO;
using System.Text;
- using Microsoft.VisualStudio.TestPlatform.CoreUtilities;
- using Microsoft.VisualStudio.TestPlatform.CoreUtilities.Resources;
-
///
/// Performs logging to a file and rolls the output file when either time or size thresholds are
/// exceeded.
@@ -37,7 +34,7 @@ public RollingFileTraceListener(
{
if (string.IsNullOrWhiteSpace(fileName))
{
- throw new ArgumentException(Resources.CannotBeNullOrEmpty, nameof(fileName));
+ throw new ArgumentException(nameof(fileName));
}
if (rollSizeKB <= 0)
diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/net46/Interfaces/Tracing/IEqtTrace.cs b/src/Microsoft.TestPlatform.PlatformAbstractions/net46/Interfaces/Tracing/IEqtTrace.cs
new file mode 100644
index 0000000000..170d9b801d
--- /dev/null
+++ b/src/Microsoft.TestPlatform.PlatformAbstractions/net46/Interfaces/Tracing/IEqtTrace.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Diagnostics;
+
+namespace Microsoft.VisualStudio.TestPlatform.ObjectModel
+{
+
+ public partial interface IPlatformEqtTrace
+ {
+ ///
+ /// Setup remote trace listener in the child domain.
+ /// If calling domain, doesn't have tracing enabled nothing is done.
+ ///
+ /// Child AppDomain.
+ void SetupRemoteEqtTraceListeners(AppDomain childDomain);
+
+ ///
+ /// Setup a custom trace listener instead of default trace listener created by test platform.
+ /// This is needed by DTA Agent where it needs to listen test platform traces but doesn't use test platform listener.
+ ///
+ ///
+ /// The listener.
+ ///
+ void SetupListener(TraceListener listener);
+
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/net46/Tracing/EqtTrace.cs b/src/Microsoft.TestPlatform.PlatformAbstractions/net46/Tracing/EqtTrace.cs
new file mode 100644
index 0000000000..581c8fa225
--- /dev/null
+++ b/src/Microsoft.TestPlatform.PlatformAbstractions/net46/Tracing/EqtTrace.cs
@@ -0,0 +1,72 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Microsoft.VisualStudio.TestPlatform.ObjectModel
+{
+ using System;
+ using System.Diagnostics;
+
+ ///
+ /// Wrapper class for tracing.
+ /// - Shortcut-methods for Error, Warning, Info, Verbose.
+ /// - Adds additional information to the trace: calling process name, PID, ThreadID, Time.
+ /// - Uses custom switch EqtTraceLevel from .config file.
+ /// - By default tracing if OFF.
+ /// - Our build environment always sets the /d:TRACE so this class is always enabled,
+ /// the Debug class is enabled only in debug builds (/d:DEBUG).
+ /// - We ignore exceptions thrown by underlying TraceSwitch (e.g. due to config file error).
+ /// We log ignored exceptions to system Application log.
+ /// We pass through exceptions thrown due to incorrect arguments to EqtTrace methods.
+ /// Usage: EqtTrace.Info("Here's how to trace info");
+ ///
+ public partial class PlatformEqtTrace : IPlatformEqtTrace
+ {
+ ///
+ /// Setup remote trace listener in the child domain.
+ /// If calling domain, doesn't have tracing enabled nothing is done.
+ ///
+ /// Child AppDomain.
+ public void SetupRemoteEqtTraceListeners(AppDomain childDomain)
+ {
+ Debug.Assert(childDomain != null, "domain");
+ if (childDomain != null)
+ {
+ RemoteEqtTrace remoteEqtTrace = (RemoteEqtTrace)childDomain.CreateInstanceFromAndUnwrap(
+ typeof(RemoteEqtTrace).Assembly.Location,
+ typeof(RemoteEqtTrace).FullName);
+
+ remoteEqtTrace.TraceLevel = TraceLevel;
+
+ if (!Enum.Equals(TraceLevel, TraceLevel.Off))
+ {
+ TraceListener tptListner = null;
+ foreach (TraceListener listener in Trace.Listeners)
+ {
+ if (string.Equals(listener.Name, ListenerName, StringComparison.OrdinalIgnoreCase))
+ {
+ Debug.Assert(tptListner == null, "Multiple TptListeners found.");
+ tptListner = listener;
+ }
+ }
+
+ remoteEqtTrace.SetupRemoteListeners(tptListner);
+ }
+ }
+ }
+
+ ///
+ public void SetupListener(TraceListener listener)
+ {
+ lock (isInitializationLock)
+ {
+ // Add new listeners.
+ if (listener != null)
+ {
+ Source.Listeners.Add(listener);
+ }
+
+ isInitialized = true;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.TestPlatform.CoreUtilities/Tracing/RemoteEqtTrace.cs b/src/Microsoft.TestPlatform.PlatformAbstractions/net46/Tracing/RemoteEqtTrace.cs
similarity index 87%
rename from src/Microsoft.TestPlatform.CoreUtilities/Tracing/RemoteEqtTrace.cs
rename to src/Microsoft.TestPlatform.PlatformAbstractions/net46/Tracing/RemoteEqtTrace.cs
index 25f730a0d7..7ec4cd7285 100644
--- a/src/Microsoft.TestPlatform.CoreUtilities/Tracing/RemoteEqtTrace.cs
+++ b/src/Microsoft.TestPlatform.PlatformAbstractions/net46/Tracing/RemoteEqtTrace.cs
@@ -3,7 +3,6 @@
namespace Microsoft.VisualStudio.TestPlatform.ObjectModel
{
-#if NET46
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
@@ -20,12 +19,12 @@ public TraceLevel TraceLevel
{
get
{
- return EqtTrace.TraceLevel;
+ return PlatformEqtTrace.TraceLevel;
}
set
{
- EqtTrace.TraceLevel = value;
+ PlatformEqtTrace.TraceLevel = value;
}
}
@@ -36,8 +35,7 @@ public TraceLevel TraceLevel
[SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Used in remote objects.")]
internal void SetupRemoteListeners(TraceListener listener)
{
- EqtTrace.SetupRemoteListeners(listener);
+ PlatformEqtTrace.SetupRemoteListeners(listener);
}
}
-#endif
}
diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/netstandard1.0/Tracing/EqtTrace.cs b/src/Microsoft.TestPlatform.PlatformAbstractions/netstandard1.0/Tracing/EqtTrace.cs
new file mode 100644
index 0000000000..209fda1143
--- /dev/null
+++ b/src/Microsoft.TestPlatform.PlatformAbstractions/netstandard1.0/Tracing/EqtTrace.cs
@@ -0,0 +1,54 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Microsoft.VisualStudio.TestPlatform.ObjectModel
+{
+ using System;
+ using System.Diagnostics;
+
+ ///
+ /// Wrapper class for tracing.
+ /// - Shortcut-methods for Error, Warning, Info, Verbose.
+ /// - Adds additional information to the trace: calling process name, PID, ThreadID, Time.
+ /// - Uses custom switch EqtTraceLevel from .config file.
+ /// - By default tracing if OFF.
+ /// - Our build environment always sets the /d:TRACE so this class is always enabled,
+ /// the Debug class is enabled only in debug builds (/d:DEBUG).
+ /// - We ignore exceptions thrown by underlying TraceSwitch (e.g. due to config file error).
+ /// We log ignored exceptions to system Application log.
+ /// We pass through exceptions thrown due to incorrect arguments to EqtTrace methods.
+ /// Usage: EqtTrace.Info("Here's how to trace info");
+ ///
+ public class PlatformEqtTrace : IPlatformEqtTrace
+ {
+ public void WriteLine(PlatformTraceLevel level, string message)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void InitializeVerboseTrace(string customLogFile)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool ShouldTrace(PlatformTraceLevel traceLevel)
+ {
+ throw new NotImplementedException();
+ }
+
+ public string GetLogFile()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void SetTraceLevel(PlatformTraceLevel value)
+ {
+ throw new NotImplementedException();
+ }
+
+ public PlatformTraceLevel GetTraceLevel()
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/TestPlatform.ObjectModel.nuspec b/src/TestPlatform.ObjectModel.nuspec
index cfba78533b..5c9467fa93 100644
--- a/src/TestPlatform.ObjectModel.nuspec
+++ b/src/TestPlatform.ObjectModel.nuspec
@@ -49,9 +49,11 @@
+
+
diff --git a/src/TestPlatform.TranslationLayer.nuspec b/src/TestPlatform.TranslationLayer.nuspec
index 1c6c181794..e41ae1363d 100644
--- a/src/TestPlatform.TranslationLayer.nuspec
+++ b/src/TestPlatform.TranslationLayer.nuspec
@@ -47,11 +47,13 @@
+
+
diff --git a/test/Microsoft.TestPlatform.CoreUtilities.UnitTests/Microsoft.TestPlatform.CoreUtilities.UnitTests.csproj b/test/Microsoft.TestPlatform.CoreUtilities.UnitTests/Microsoft.TestPlatform.CoreUtilities.UnitTests.csproj
index 1140979e15..51b77ff7a0 100644
--- a/test/Microsoft.TestPlatform.CoreUtilities.UnitTests/Microsoft.TestPlatform.CoreUtilities.UnitTests.csproj
+++ b/test/Microsoft.TestPlatform.CoreUtilities.UnitTests/Microsoft.TestPlatform.CoreUtilities.UnitTests.csproj
@@ -14,6 +14,20 @@
+
+
+ 4.3.0
+
+
+ 4.3.0
+
+
+ 4.3.0
+
+
+ 4.3.0
+
+
diff --git a/test/Microsoft.TestPlatform.CoreUtilities.UnitTests/Tracing/EqtTraceTests.cs b/test/Microsoft.TestPlatform.CoreUtilities.UnitTests/Tracing/EqtTraceTests.cs
new file mode 100644
index 0000000000..93b2451b4b
--- /dev/null
+++ b/test/Microsoft.TestPlatform.CoreUtilities.UnitTests/Tracing/EqtTraceTests.cs
@@ -0,0 +1,155 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace TestPlatform.CoreUtilities.UnitTests
+{
+ using System.Diagnostics;
+ using System.IO;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+ using Microsoft.VisualStudio.TestPlatform.ObjectModel;
+ using System;
+ using System.Text;
+
+ [TestClass]
+ public class EqtTraceTests
+ {
+ private static string dirPath = null;
+ private static string logFile = null;
+
+ [ClassInitialize]
+ public static void Init(TestContext testContext)
+ {
+ dirPath = Path.Combine(Path.GetTempPath(), "TraceUT");
+ try
+ {
+ Directory.CreateDirectory(dirPath);
+ logFile = Path.Combine(dirPath, "trace.log");
+
+ }
+ catch(Exception ex)
+ {
+ Console.WriteLine(ex.Message);
+ }
+
+ EqtTrace.InitializeVerboseTrace(logFile);
+ }
+
+ [TestMethod]
+ public void CheckInitializeLogFileTest()
+ {
+ Assert.AreEqual(logFile, EqtTrace.LogFile, "Expected log file to be {0}", logFile);
+ }
+
+ [TestMethod]
+ public void CheckIfTraceStateIsVerboseEnabled()
+ {
+#if NET46
+ EqtTrace.TraceLevel = TraceLevel.Verbose;
+#else
+ EqtTrace.TraceLevel = PlatformTraceLevel.Verbose;
+#endif
+ Assert.AreEqual(true, EqtTrace.IsVerboseEnabled, "Expected trace state to be verbose actual state {0}", EqtTrace.IsVerboseEnabled);
+ }
+
+ [TestMethod]
+ public void CheckIfTraceStateIsErrorEnabled()
+ {
+#if NET46
+ EqtTrace.TraceLevel = TraceLevel.Error;
+#else
+ EqtTrace.TraceLevel = PlatformTraceLevel.Error;
+#endif
+ Assert.AreEqual(true, EqtTrace.IsErrorEnabled, "Expected trace state to be error actual state {0}", EqtTrace.IsErrorEnabled);
+ }
+
+ [TestMethod]
+ public void CheckIfTraceStateIsInfoEnabled()
+ {
+#if NET46
+ EqtTrace.TraceLevel = TraceLevel.Info;
+#else
+ EqtTrace.TraceLevel = PlatformTraceLevel.Info;
+#endif
+ Assert.AreEqual(true, EqtTrace.IsInfoEnabled, "Expected trace state to be info actual state {0}", EqtTrace.IsInfoEnabled);
+ }
+
+ [TestMethod]
+ public void CheckIfTraceStateIsWarningEnabled()
+ {
+#if NET46
+ EqtTrace.TraceLevel = TraceLevel.Warning;
+#else
+ EqtTrace.TraceLevel = PlatformTraceLevel.Warning;
+#endif
+ Assert.AreEqual(true, EqtTrace.IsWarningEnabled, "Expected trace state to be warning actual state {0}", EqtTrace.IsWarningEnabled);
+ }
+
+ [TestMethod]
+ public void TraceShouldWriteError()
+ {
+#if NET46
+ EqtTrace.TraceLevel = TraceLevel.Error;
+#else
+ EqtTrace.TraceLevel = PlatformTraceLevel.Error;
+#endif
+ EqtTrace.Error(new NotImplementedException());
+ Assert.IsNotNull(ReadLogFile(), "Expected error message");
+ }
+
+ [TestMethod]
+ public void TraceShouldWriteWarning()
+ {
+#if NET46
+ EqtTrace.TraceLevel = TraceLevel.Warning;
+#else
+ EqtTrace.TraceLevel = PlatformTraceLevel.Warning;
+#endif
+ EqtTrace.Warning("Dummy Warning Message");
+ Assert.IsTrue(ReadLogFile().Contains("Dummy Warning Message"), "Expected Warning message");
+ }
+
+ [TestMethod]
+ public void TraceShouldWriteVerbose()
+ {
+#if NET46
+ EqtTrace.TraceLevel = TraceLevel.Verbose;
+#else
+ EqtTrace.TraceLevel = PlatformTraceLevel.Verbose;
+#endif
+ EqtTrace.Verbose("Dummy Verbose Message");
+ Assert.IsTrue(ReadLogFile().Contains("Dummy Verbose Message"), "Expected Verbose message");
+ }
+ [TestMethod]
+ public void TraceShouldWriteInfo()
+ {
+#if NET46
+ EqtTrace.TraceLevel = TraceLevel.Info;
+#else
+ EqtTrace.TraceLevel = PlatformTraceLevel.Info;
+#endif
+ EqtTrace.Info("Dummy Info Message");
+ Assert.IsTrue(ReadLogFile().Contains("Dummy Info Message"), "Expected Info message");
+ }
+
+ private string ReadLogFile()
+ {
+ string log = null;
+ try
+ {
+ using (var fs = new FileStream(logFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
+ {
+ using (var sr = new StreamReader(fs))
+ {
+ log = sr.ReadToEnd();
+ }
+ }
+ }
+ catch(Exception ex)
+ {
+ Console.WriteLine(ex.Message);
+ }
+
+ return log;
+ }
+ }
+}
diff --git a/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/ProxyOperationManagerTests.cs b/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/ProxyOperationManagerTests.cs
index dc8f68d97f..c1c9df1ad1 100644
--- a/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/ProxyOperationManagerTests.cs
+++ b/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/ProxyOperationManagerTests.cs
@@ -79,7 +79,11 @@ public void SetupChannelShouldCreateTimestampedLogFileForHost()
It.Is(
t => t.LogFile.Contains("log.host." + DateTime.Now.ToString("yy-MM-dd"))
&& t.LogFile.Contains("_" + Thread.CurrentThread.ManagedThreadId + ".txt"))));
+#if NET46
EqtTrace.TraceLevel = TraceLevel.Off;
+#else
+ EqtTrace.TraceLevel = PlatformTraceLevel.Off;
+#endif
}
[TestMethod]
diff --git a/test/vstest.console.UnitTests/Processors/EnableDiagArgumentProcessorTests.cs b/test/vstest.console.UnitTests/Processors/EnableDiagArgumentProcessorTests.cs
index 9e343c27fd..7c60cfe10a 100644
--- a/test/vstest.console.UnitTests/Processors/EnableDiagArgumentProcessorTests.cs
+++ b/test/vstest.console.UnitTests/Processors/EnableDiagArgumentProcessorTests.cs
@@ -33,8 +33,14 @@ public EnableDiagArgumentProcessorTests()
this.diagProcessor = new TestableEnableDiagArgumentProcessor(this.mockFileHelper.Object);
// Saving the EqtTrace state
+#if NET46
traceLevel = EqtTrace.TraceLevel;
EqtTrace.TraceLevel = TraceLevel.Off;
+#else
+ traceLevel = (TraceLevel)EqtTrace.TraceLevel;
+ EqtTrace.TraceLevel = (PlatformTraceLevel)TraceLevel.Off;
+#endif
+
traceFileName = EqtTrace.LogFile;
}
@@ -43,7 +49,11 @@ public void Cleanup()
{
// Restoring to initial state for EqtTrace
EqtTrace.InitializeVerboseTrace(traceFileName);
+#if NET46
EqtTrace.TraceLevel = traceLevel;
+#else
+ EqtTrace.TraceLevel = (PlatformTraceLevel)traceLevel;
+#endif
}
[TestMethod]
@@ -106,7 +116,11 @@ public void EnableDiagArgumentProcessorExecutorShouldEnableVerboseLogging()
this.diagProcessor.Executor.Value.Initialize(this.dummyFilePath);
Assert.IsTrue(EqtTrace.IsVerboseEnabled);
+#if NET46
EqtTrace.TraceLevel = TraceLevel.Off;
+#else
+ EqtTrace.TraceLevel = PlatformTraceLevel.Off;
+#endif
}
private class TestableEnableDiagArgumentProcessor : EnableDiagArgumentProcessor