Skip to content

No Popups from test crashes#745

Open
johnml1135 wants to merge 1 commit intomainfrom
no-popups-from-test-crashes
Open

No Popups from test crashes#745
johnml1135 wants to merge 1 commit intomainfrom
no-popups-from-test-crashes

Conversation

@johnml1135
Copy link
Contributor

@johnml1135 johnml1135 commented Mar 6, 2026

Summary

  • suppress popup-based assertion behavior in managed and native test runs
  • mirror assertion and last-chance managed exception details to console output
  • ensure test failures fail fast instead of blocking or silently continuing
  • cover installer test projects that opt out of the shared test assembly bootstrap
  • fix TestGeneric debug include paths so native tests build with the new DebugProcs dependency

Validation

  • ./build.ps1
  • ./test.ps1
  • ./test.ps1 -Native

Notes

  • managed test suite passed across 43 test assemblies
  • native test executables passed: testGenericLib.exe and TestViews.exe

This change is Reviewable

Copilot AI review requested due to automatic review settings March 6, 2026 20:07
@johnml1135 johnml1135 changed the title No Popups from test branches No Popups from test crashes Mar 6, 2026
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR aims to prevent modal popups during managed and native test runs by enforcing “test mode” assertion behavior, and by ensuring assertion/exception details are visible in console output so CI fails fast and diagnosably.

Changes:

  • Add FW_TEST_MODE=1 to managed/native test runners and runsettings to bypass assertion dialog behavior (including registry overrides).
  • Introduce NUnit assembly-level attributes to suppress assert dialogs and log last-chance exceptions to console for projects that don’t use the shared bootstrap.
  • Update native test project includes to build with the DebugProcs dependency and disable assertion dialogs in testGeneric.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
test.ps1 Sets FW_TEST_MODE for managed test runs outside .runsettings.
Test.runsettings Adds FW_TEST_MODE to test environment variables.
Src/InstallValidator/InstallerArtifactsTests/TestAssemblyInfo.cs Adds assembly-level unhandled-exception logging for installer artifact tests.
Src/InstallValidator/InstallerArtifactsTests/InstallerArtifactsTests.csproj Links AppForTests.config and compiles the logging attribute for tests opting out of shared bootstrap.
Src/InstallValidator/InstallValidatorTests/TestAssemblyInfo.cs Adds assembly-level unhandled-exception logging for installer validator tests.
Src/InstallValidator/InstallValidatorTests/InstallValidatorTests.csproj Compiles the logging attribute for tests opting out of shared bootstrap.
Src/Generic/Test/testGeneric.cpp Disables native assert dialogs during global test setup.
Src/Generic/Test/TestGeneric.vcxproj Fixes include paths for DebugProcs dependency.
Src/DebugProcs/DebugProcs.cpp Adds FW_TEST_MODE override for assert-dialog behavior; mirrors asserts to stderr.
Src/Common/FwUtils/FwUtilsTests/Attributes/SuppressAssertDialogsAttribute.cs New NUnit attribute to suppress assert UI and mirror trace/assert output to console.
Src/Common/FwUtils/FwUtilsTests/Attributes/LogUnhandledExceptionsAttribute.cs New NUnit attribute to log last-chance exceptions to console.
Src/Common/FwUtils/FwUtilsTests/Attributes/HandleApplicationThreadExceptionAttribute.cs Writes WinForms thread exceptions to console before rethrowing.
Src/AssemblyInfoForUiIndependentTests.cs Enables last-chance exception logging for UI-independent test assemblies.
Src/AssemblyInfoForTests.cs Enables last-chance exception logging and assert-dialog suppression for most test assemblies.
Src/AppForTests.config Adds ConsoleTraceListener to mirror trace output to console.
Build/scripts/Invoke-CppTest.ps1 Sets FW_TEST_MODE for native test runner execution.

Comment on lines +65 to +67
m_listener = new ConsoleErrorTraceListener(throwOnFail: !hasEnvVarListener);
Trace.Listeners.Insert(0, m_listener);
}
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BeforeTest unconditionally inserts a new ConsoleErrorTraceListener into Trace.Listeners, which can result in multiple listeners (duplicate output and extra overhead) if BeforeTest runs more than once per process or if another console listener is already configured (e.g., via AppForTests.config). Add a guard to avoid inserting a duplicate listener (or reuse a static singleton) and consider skipping when an existing console/EnvVar listener already provides the desired output.

Copilot uses AI. Check for mistakes.
Comment on lines +105 to +115
public override void Write(string message)
{
Console.Error.Write(message);
Console.Error.Flush();
}

public override void WriteLine(string message)
{
Console.Error.WriteLine(message);
Console.Error.Flush();
}
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ConsoleErrorTraceListener mirrors all Trace output to Console.Error and flushes on every write. In large test runs this can significantly slow execution and flood CI logs, even when there are no assertion failures. Consider limiting console output to Fail/assert paths (or buffering/conditional flushing) so only actionable failure details are emitted by default.

Copilot uses AI. Check for mistakes.
Comment on lines +72 to +73
// Escalate instead of allowing the exception to be quietly ignored at finalization time.
throw new UnobservedTaskExceptionLoggedException(e.Exception);
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The XML comment says this attribute is “logging-only”, but OnUnobservedTaskException throws a new exception from the TaskScheduler.UnobservedTaskException event handler. Exceptions thrown on the finalizer thread can terminate the process unpredictably and may not surface as a clean test failure. Consider logging and then using a deterministic fail-fast mechanism (or mark the exception observed and report it through the test framework in a controlled way) rather than throwing from this event.

Suggested change
// Escalate instead of allowing the exception to be quietly ignored at finalization time.
throw new UnobservedTaskExceptionLoggedException(e.Exception);
// Mark the exception as observed so it is not rethrown on the finalizer thread.
e.SetObserved();

Copilot uses AI. Check for mistakes.
Comment on lines +594 to +598
// Always mirror assertion text to the process error stream so test runners,
// humans, and automation can see the failure details without a debugger.
fprintf(stderr, "%s\n", assertbuf);
fflush(stderr);

Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SilAssert now always writes the full assertion text to stderr. This affects all consumers of DebugProcs.dll (not just tests) and may create noisy output/perf overhead for interactive apps. If the intent is test-only visibility, consider gating the fprintf/fflush on FW_TEST_MODE (or a similar opt-in env var) so normal runs aren’t impacted.

Copilot uses AI. Check for mistakes.
<trace autoflush="false" indentsize="4">
<listeners>
<clear/>
<add name="ConsoleTraceListener" type="System.Diagnostics.ConsoleTraceListener"/>
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding ConsoleTraceListener will mirror all System.Diagnostics.Trace output to stdout for every test using this config, which can significantly increase log volume. Given this PR also installs a console trace listener via SuppressAssertDialogsAttribute, consider whether you need both (and whether you can restrict console output to assertion/failure details only).

Suggested change
<add name="ConsoleTraceListener" type="System.Diagnostics.ConsoleTraceListener"/>

Copilot uses AI. Check for mistakes.
Comment on lines +34 to +39
// Force environment variables that control native (DebugProcs.dll) and
// managed (EnvVarTraceListener) assertion behavior.
Environment.SetEnvironmentVariable("AssertUiEnabled", "false");
Environment.SetEnvironmentVariable("AssertExceptionEnabled", "true");
Environment.SetEnvironmentVariable("FW_TEST_MODE", "1");

Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SuppressAssertDialogsAttribute sets process-wide environment variables in BeforeTest but never restores the previous values. This can leak into subsequent test assemblies that run in the same testhost process and make failures harder to diagnose. Consider capturing the prior values (AssertUiEnabled/AssertExceptionEnabled/FW_TEST_MODE) and restoring them in AfterTest.

Copilot uses AI. Check for mistakes.
@github-actions
Copy link

github-actions bot commented Mar 6, 2026

NUnit Tests

    1 files  ±0      1 suites  ±0   5m 49s ⏱️ +9s
4 407 tests ±0  4 320 ✅ ±0  87 💤 ±0  0 ❌ ±0 
4 416 runs  ±0  4 329 ✅ ±0  87 💤 ±0  0 ❌ ±0 

Results for commit 917324f. ± Comparison against base commit 0d6dace.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants