Skip to content

Commit

Permalink
Updating debugging features and some code cleanup (#926)
Browse files Browse the repository at this point in the history
* Updating debugging features and some code cleanup

* fix SA error
  • Loading branch information
OsirisTerje authored Dec 11, 2021
1 parent 4d47546 commit e80964e
Show file tree
Hide file tree
Showing 13 changed files with 479 additions and 105 deletions.
368 changes: 360 additions & 8 deletions .editorconfig

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion build.cake
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ var configuration = Argument("configuration", "Release");
//////////////////////////////////////////////////////////////////////

var version = "4.2.0";
var modifier = "-alpha.919.3";
var modifier = "-alpha.4";

var dbgSuffix = configuration.ToLower() == "debug" ? "-dbg" : "";
var packageVersion = version + modifier + dbgSuffix;
Expand Down
14 changes: 13 additions & 1 deletion src/NUnitTestAdapter/AdapterSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ public interface IAdapterSettings
bool StopOnError { get; }
TestOutcome MapWarningTo { get; }
bool UseTestNameInConsoleOutput { get; }
bool FreakMode { get; }
DisplayNameOptions DisplayName { get; }
char FullnameSeparator { get; }
DiscoveryMethod DiscoveryMethod { get; }
Expand All @@ -120,6 +119,12 @@ public interface IAdapterSettings
void RestoreRandomSeed(string dirname);

bool EnsureAttachmentFileScheme { get; }

// For Internal Development use
bool FreakMode { get; } // displays metadata instead of real data in Test Explorer
bool Debug { get; }
bool DebugExecution { get; }
bool DebugDiscovery { get; }
}

public enum VsTestCategoryType
Expand Down Expand Up @@ -269,11 +274,15 @@ public AdapterSettings(ITestLogger logger)
public bool DumpVsInput { get; private set; }

public bool FreakMode { get; private set; }
public bool Debug { get; private set; }
public bool DebugExecution { get; private set; }
public bool DebugDiscovery { get; private set; }

#endregion




#endregion

#region Public Methods
Expand Down Expand Up @@ -393,6 +402,9 @@ private void ExtractNUnitDiagnosticSettings(XmlNode nunitNode)
FreakMode = GetInnerTextAsBool(nunitNode, nameof(FreakMode), false);
InternalTraceLevel = GetInnerTextWithLog(nunitNode, nameof(InternalTraceLevel), "Off", "Error", "Warning",
"Info", "Verbose", "Debug");
Debug = GetInnerTextAsBool(nunitNode, nameof(Debug), false);
DebugExecution = Debug || GetInnerTextAsBool(nunitNode, nameof(DebugExecution), false);
DebugDiscovery = Debug || GetInnerTextAsBool(nunitNode, nameof(DebugDiscovery), false);
}

private void UpdateTestProperties(XmlDocument doc)
Expand Down
8 changes: 4 additions & 4 deletions src/NUnitTestAdapter/CategoryList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,10 @@ private bool IsInternalProperty(NUnitProperty property)
}

// Property names starting with '_' are for internal use only, but over time this has changed, so we now use a list
if (!showInternalProperties &&
_internalProperties.Contains(property.Name))
return true;
return string.IsNullOrEmpty(property.Name) || property.Name[0] == '_' || string.IsNullOrEmpty(property.Value);
return (!showInternalProperties &&
_internalProperties.Contains(property.Name)) || (string.IsNullOrEmpty(property.Name) ||
property.Name[0] == '_' ||
string.IsNullOrEmpty(property.Value));
}

private void AddTraitsToCache(IDictionary<string, TraitsFeature.CachedTestCaseInfo> traitsCache, string key, NUnitProperty property)
Expand Down
7 changes: 1 addition & 6 deletions src/NUnitTestAdapter/Execution.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,7 @@ public interface IExecutionContext

public static class ExecutionFactory
{
public static Execution Create(IExecutionContext ctx)
{
if (ctx.Settings.DesignMode) // We come from IDE
return new IdeExecution(ctx);
return new VsTestExecution(ctx);
}
public static Execution Create(IExecutionContext ctx) => ctx.Settings.DesignMode ? new IdeExecution(ctx) : new VsTestExecution(ctx);
}

public abstract class Execution
Expand Down
2 changes: 1 addition & 1 deletion src/NUnitTestAdapter/Internal/TimingLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public TimingLogger ReStart()

public TimingLogger LogTime(string leadText = "")
{
if (settings.Verbosity < 5)
if (settings.Verbosity < 5 || Stopwatch == null)
return this;
var ts = Stopwatch.Elapsed;
string elapsedTime = $"{ts.Hours:00}:{ts.Minutes:00}:{ts.Seconds:00}.{ts.Milliseconds / 10:00}";
Expand Down
19 changes: 8 additions & 11 deletions src/NUnitTestAdapter/NUnit3TestDiscoverer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,11 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ***********************************************************************

// #define LAUNCHDEBUGGER

using System;
using System.Collections.Generic;
using System.ComponentModel;
#if LAUNCHDEBUGGER
using System.Diagnostics;
#endif
using System.IO;
using System.Linq;
using System.Xml;
Expand Down Expand Up @@ -57,11 +54,8 @@ public sealed class NUnit3TestDiscoverer : NUnitTestAdapter, ITestDiscoverer

public void DiscoverTests(IEnumerable<string> sources, IDiscoveryContext discoveryContext, IMessageLogger messageLogger, ITestCaseDiscoverySink discoverySink)
{
#if LAUNCHDEBUGGER
if (!Debugger.IsAttached)
Debugger.Launch();
#endif
Initialize(discoveryContext, messageLogger);
CheckIfDebug();
TestLog.Info($"NUnit Adapter {AdapterVersion}: Test discovery starting");

// Ensure any channels registered by other adapters are unregistered
Expand Down Expand Up @@ -182,10 +176,6 @@ private int ProcessTestCases(NUnitResults results, ITestCaseDiscoverySink discov
{
try
{
#if LAUNCHDEBUGGER
if (!Debugger.IsAttached)
Debugger.Launch();
#endif
var testCase = testConverterForXml.ConvertTestCase(new NUnitEventTestCase(testNode));
discoverySink.SendTestCase(testCase);
cases += 1;
Expand All @@ -199,6 +189,13 @@ private int ProcessTestCases(NUnitResults results, ITestCaseDiscoverySink discov
return cases;
}

private void CheckIfDebug()
{
if (!Settings.DebugDiscovery)
return;
if (!Debugger.IsAttached)
Debugger.Launch();
}
#endregion
}
}
76 changes: 45 additions & 31 deletions src/NUnitTestAdapter/NUnit3TestExecutor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,17 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ***********************************************************************

// #define LAUNCHDEBUGGER

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;

using Microsoft.VisualStudio.TestPlatform.ObjectModel;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter;

using NUnit.Engine;
using NUnit.VisualStudio.TestAdapter.Dump;
using NUnit.VisualStudio.TestAdapter.Internal;
Expand All @@ -57,7 +58,8 @@ public enum RunType


[ExtensionUri(ExecutorUri)]
public sealed class NUnit3TestExecutor : NUnitTestAdapter, ITestExecutor, IDisposable, INUnit3TestExecutor, IExecutionContext
public sealed class NUnit3TestExecutor : NUnitTestAdapter, ITestExecutor, IDisposable, INUnit3TestExecutor,
IExecutionContext
{
#region Properties

Expand Down Expand Up @@ -96,17 +98,15 @@ public sealed class NUnit3TestExecutor : NUnitTestAdapter, ITestExecutor, IDispo
/// <param name="frameworkHandle">Test log to send results and messages through.</param>
public void RunTests(IEnumerable<string> sources, IRunContext runContext, IFrameworkHandle frameworkHandle)
{
#if LAUNCHDEBUGGER
if (!Debugger.IsAttached)
Debugger.Launch();
#endif
Initialize(runContext, frameworkHandle);
CheckIfDebug();
TestLog.Debug("RunTests by IEnumerable<string>");
InitializeForExecution(runContext, frameworkHandle);

if (Settings.InProcDataCollectorsAvailable && sources.Count() > 1)
{
TestLog.Error("Failed to run tests for multiple assemblies when InProcDataCollectors specified in run configuration.");
TestLog.Error(
"Failed to run tests for multiple assemblies when InProcDataCollectors specified in run configuration.");
Unload();
return;
}
Expand All @@ -119,18 +119,22 @@ public void RunTests(IEnumerable<string> sources, IRunContext runContext, IFrame
var vsTestFilter = VsTestFilterFactory.CreateVsTestFilter(Settings, runContext);
filter = builder.ConvertVsTestFilterToNUnitFilter(vsTestFilter);
}

filter ??= builder.FilterByWhere(Settings.Where);

foreach (string assemblyName in sources)
{
try
{
string assemblyPath = Path.IsPathRooted(assemblyName) ? assemblyName : Path.Combine(Directory.GetCurrentDirectory(), assemblyName);
string assemblyPath = Path.IsPathRooted(assemblyName)
? assemblyName
: Path.Combine(Directory.GetCurrentDirectory(), assemblyName);
RunAssembly(assemblyPath, null, filter);
}
catch (Exception ex)
{
if (ex is TargetInvocationException) { ex = ex.InnerException; }

TestLog.Warning("Exception thrown executing tests", ex);
}
}
Expand All @@ -156,11 +160,8 @@ private void SetRunTypeByStrings() =>
/// <param name="frameworkHandle">The FrameworkHandle.</param>
public void RunTests(IEnumerable<TestCase> tests, IRunContext runContext, IFrameworkHandle frameworkHandle)
{
#if LAUNCHDEBUGGER
if (!Debugger.IsAttached)
Debugger.Launch();
#endif
Initialize(runContext, frameworkHandle);
CheckIfDebug();
TestLog.Debug("RunTests by IEnumerable<TestCase>");
InitializeForExecution(runContext, frameworkHandle);
RunType = RunType.Ide;
Expand All @@ -170,7 +171,8 @@ public void RunTests(IEnumerable<TestCase> tests, IRunContext runContext, IFrame
var assemblyGroups = tests.GroupBy(tc => tc.Source);
if (IsInProcDataCollectorsSpecifiedWithMultipleAssemblies(assemblyGroups))
{
TestLog.Error("Failed to run tests for multiple assemblies when InProcDataCollectors specified in run configuration.");
TestLog.Error(
"Failed to run tests for multiple assemblies when InProcDataCollectors specified in run configuration.");
Unload();
return;
}
Expand All @@ -181,7 +183,9 @@ public void RunTests(IEnumerable<TestCase> tests, IRunContext runContext, IFrame
try
{
string assemblyName = assemblyGroup.Key;
string assemblyPath = Path.IsPathRooted(assemblyName) ? assemblyName : Path.Combine(Directory.GetCurrentDirectory(), assemblyName);
string assemblyPath = Path.IsPathRooted(assemblyName)
? assemblyName
: Path.Combine(Directory.GetCurrentDirectory(), assemblyName);

var filterBuilder = CreateTestFilterBuilder();
var filter = filterBuilder.FilterByList(assemblyGroup);
Expand All @@ -191,6 +195,7 @@ public void RunTests(IEnumerable<TestCase> tests, IRunContext runContext, IFrame
catch (Exception ex)
{
if (ex is TargetInvocationException) { ex = ex.InnerException; }

TestLog.Warning("Exception thrown executing tests", ex);
}

Expand All @@ -202,7 +207,8 @@ public void RunTests(IEnumerable<TestCase> tests, IRunContext runContext, IFrame
Unload();
}

private bool IsInProcDataCollectorsSpecifiedWithMultipleAssemblies(IEnumerable<IGrouping<string, TestCase>> assemblyGroups)
private bool IsInProcDataCollectorsSpecifiedWithMultipleAssemblies(
IEnumerable<IGrouping<string, TestCase>> assemblyGroups)
=> Settings.InProcDataCollectorsAvailable && assemblyGroups.Count() > 1;

void ITestExecutor.Cancel()
Expand Down Expand Up @@ -244,7 +250,9 @@ public void InitializeForExecution(IRunContext runContext, IFrameworkHandle fram

if (VsTestFilter.IsEmpty)
{
if (!(enableShutdown && !runContext.KeepAlive)) // Otherwise causes exception when run as commandline, illegal to enableshutdown when Keepalive is false, might be only VS2012
if (!(enableShutdown &&
!runContext
.KeepAlive)) // Otherwise causes exception when run as commandline, illegal to enableshutdown when Keepalive is false, might be only VS2012
frameworkHandle.EnableShutdownAfterTestRun = enableShutdown;
}

Expand All @@ -253,9 +261,7 @@ public void InitializeForExecution(IRunContext runContext, IFrameworkHandle fram

private void RunAssembly(string assemblyPath, IGrouping<string, TestCase> testCases, TestFilter filter)
{
string actionText = Debugger.IsAttached ? "Debugging " : "Running ";
string selectionText = filter == null || filter == TestFilter.Empty ? "all" : "selected";
TestLog.Info(actionText + selectionText + " tests in " + assemblyPath);
LogActionAndSelection(assemblyPath, filter);
RestoreRandomSeed(assemblyPath);
Dump = DumpXml.CreateDump(assemblyPath, testCases, Settings);

Expand All @@ -279,9 +285,7 @@ private void RunAssembly(string assemblyPath, IGrouping<string, TestCase> testCa
}
else
{
TestLog.Info(discoveryResults.HasNoNUnitTests
? " NUnit couldn't find any tests in " + assemblyPath
: " NUnit failed to load " + assemblyPath);
TestLog.InfoNoTests(discoveryResults.HasNoNUnitTests, assemblyPath);
}
}
catch (Exception ex) when (ex is BadImageFormatException || ex.InnerException is BadImageFormatException)
Expand All @@ -292,7 +296,8 @@ private void RunAssembly(string assemblyPath, IGrouping<string, TestCase> testCa
catch (FileNotFoundException ex)
{
// Probably from the GetExportedTypes in NUnit.core, attempting to find an assembly, not a problem if it is not NUnit here
TestLog.Warning(" Dependent Assembly " + ex.FileName + " of " + assemblyPath + " not found. Can be ignored if not an NUnit project.");
TestLog.Warning(" Dependent Assembly " + ex.FileName + " of " + assemblyPath +
" not found. Can be ignored if not an NUnit project.");
}
catch (Exception ex)
{
Expand All @@ -312,12 +317,18 @@ private void RunAssembly(string assemblyPath, IGrouping<string, TestCase> testCa
// can happen if CLR throws CannotUnloadAppDomainException, for example
// due to a long-lasting operation in a protected region (catch/finally clause).
if (ex is TargetInvocationException) { ex = ex.InnerException; }

TestLog.Warning($" Exception thrown unloading tests from {assemblyPath}", ex);
}
}
}


private void LogActionAndSelection(string assemblyPath, TestFilter filter)
{
string actionText = Debugger.IsAttached ? "Debugging " : "Running ";
string selectionText = filter == null || filter == TestFilter.Empty ? "all" : "selected";
TestLog.Info(actionText + selectionText + " tests in " + assemblyPath);
}


private void RestoreRandomSeed(string assemblyPath)
Expand All @@ -328,12 +339,7 @@ private void RestoreRandomSeed(string assemblyPath)
}


private NUnitTestFilterBuilder CreateTestFilterBuilder()
{
return new (NUnitEngineAdapter.GetService<ITestFilterService>(), Settings);
}


private NUnitTestFilterBuilder CreateTestFilterBuilder() => new (NUnitEngineAdapter.GetService<ITestFilterService>(), Settings);


private void CreateTestOutputFolder()
Expand Down Expand Up @@ -367,5 +373,13 @@ public void StopRun()
}

public IDumpXml Dump { get; private set; }

private void CheckIfDebug()
{
if (!Settings.DebugExecution)
return;
if (!Debugger.IsAttached)
Debugger.Launch();
}
}
}
}
Loading

0 comments on commit e80964e

Please sign in to comment.