From 7c3c5b6a41a1f6d77d11c3452072ca990b232426 Mon Sep 17 00:00:00 2001 From: eunwoo song Date: Sun, 6 Sep 2026 00:45:53 +0900 Subject: [PATCH] feat(netcli): expose VSTest crash diagnostics across supported wrappers --- README.md | 1 + docs/dotnet-test-diagnostics.md | 28 +++++++++++ src/Tamp.NetCli.V10/DotNetTestSettings.cs | 35 +++++++++++++ src/Tamp.NetCli.V8/DotNetTestSettings.cs | 35 +++++++++++++ src/Tamp.NetCli.V9/DotNetTestSettings.cs | 35 +++++++++++++ tests/Tamp.NetCli.V10.Tests/DotNetTests.cs | 57 ++++++++++++++++++++++ tests/Tamp.NetCli.V8.Tests/DotNetTests.cs | 57 ++++++++++++++++++++++ tests/Tamp.NetCli.V9.Tests/DotNetTests.cs | 57 ++++++++++++++++++++++ 8 files changed, 305 insertions(+) create mode 100644 docs/dotnet-test-diagnostics.md diff --git a/README.md b/README.md index 1ec49fa..6bfc951 100644 --- a/README.md +++ b/README.md @@ -133,6 +133,7 @@ Full rationale: [ADR 0002 — Package naming convention](docs/adr/0002-package-n The wiki's **[Module Catalog](https://github.com/tamp-build/tamp/wiki/Module-Catalog)** is the canonical reference for every published `Tamp.*` package — what it wraps, latest version, and source repo. Categories include: - **.NET toolchain** — `Tamp.NetCli.V8/9/10`, `Tamp.EFCore.V8/9/10`, `Tamp.Coverlet.V6`, `Tamp.ReportGenerator.V5`, `Tamp.DotNetCoverage.V18`, `Tamp.GitVersion.V6` + See [test-host crash diagnostics](docs/dotnet-test-diagnostics.md) for typed VSTest crash-dump options. - **Containers + cluster ops** — `Tamp.Docker.V27`, `Tamp.Helm.V3`, `Tamp.Kubectl`, `Tamp.Sccache`, `Tamp.AdjacentContainer(.Local/.Provisioning)`, `Tamp.Testcontainers.V4` - **JavaScript / TypeScript** — `Tamp.Yarn.V4`, `Tamp.Npm.V10`, `Tamp.Turbo.V2`, `Tamp.Vite.V5`, `Tamp.Playwright.V1`, `Tamp.GraphQLCodegen.V5`, `Tamp.Eslint.V9` - **Rust + desktop ship chain** — `Tamp.Cargo`, `Tamp.Tauri.V2`, `Tamp.Msix`, `Tamp.MicrosoftStoreCli` diff --git a/docs/dotnet-test-diagnostics.md b/docs/dotnet-test-diagnostics.md new file mode 100644 index 0000000..3450690 --- /dev/null +++ b/docs/dotnet-test-diagnostics.md @@ -0,0 +1,28 @@ +# Diagnosing test-host crashes + +The `Tamp.NetCli.V8`, `V9`, and `V10` test settings expose VSTest crash diagnostics +alongside the existing hang diagnostics: + +```csharp +using Tamp.NetCli.V10; + +var plan = DotNet.Test(s => s + .SetProject("Tests.csproj") + .SetBlameCrash(true) + .SetBlameCrashDumpType(DotNetCrashDumpType.Mini)); +``` + +This emits `test Tests.csproj --blame-crash --blame-crash-dump-type mini`. +Choose `DotNetCrashDumpType.Full` for a full dump. The nullable dump-type setting +is validated when assigned, including direct property assignments; undefined +enum values are rejected rather than emitted as numeric CLI arguments. + +Both options are omitted by default. `SetBlameCrash(false)` omits the explicit +crash flag, and `SetBlameCrashDumpType(null)` omits the dump-type flag. As in the +underlying CLI, specifying a dump type still implies crash diagnostics even +without the explicit crash flag. Crash and hang settings can be combined. + +These flags target **VSTest**, not Microsoft.Testing.Platform. Dump availability +still depends on the runtime, operating system, and crash type. See Microsoft's +[dotnet test VSTest reference](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-test-vstest#options) +for the underlying behavior and platform requirements. diff --git a/src/Tamp.NetCli.V10/DotNetTestSettings.cs b/src/Tamp.NetCli.V10/DotNetTestSettings.cs index a35555c..f4cf3c0 100644 --- a/src/Tamp.NetCli.V10/DotNetTestSettings.cs +++ b/src/Tamp.NetCli.V10/DotNetTestSettings.cs @@ -1,5 +1,14 @@ namespace Tamp.NetCli.V10; +/// Crash dump sizes accepted by VSTest's --blame-crash-dump-type. +public enum DotNetCrashDumpType +{ + /// Collect a small crash dump. + Mini, + /// Collect a full crash dump. + Full, +} + public sealed class DotNetTestSettings : DotNetSettingsBase { public Configuration? Configuration { get; set; } @@ -12,6 +21,22 @@ public sealed class DotNetTestSettings : DotNetSettingsBase public string? Settings { get; set; } public string? Runtime { get; set; } public string? Framework { get; set; } + /// Collect crash diagnostics when the VSTest test host exits unexpectedly. + public bool BlameCrash { get; set; } + + private DotNetCrashDumpType? _blameCrashDumpType; + /// Crash dump size. Null uses the CLI default; specifying a size implies crash diagnostics. + public DotNetCrashDumpType? BlameCrashDumpType + { + get => _blameCrashDumpType; + set + { + if (value is { } type && !Enum.IsDefined(type)) + throw new ArgumentOutOfRangeException(nameof(value), value, "Unsupported crash dump type."); + _blameCrashDumpType = value; + } + } + public bool BlameHang { get; set; } public TimeSpan? BlameHangTimeout { get; set; } public Dictionary Properties { get; } = new(); @@ -36,6 +61,10 @@ public sealed class DotNetTestSettings : DotNetSettingsBase public DotNetTestSettings SetSettings(string? path) { Settings = path; return this; } public DotNetTestSettings SetRuntime(string? runtime) { Runtime = runtime; return this; } public DotNetTestSettings SetFramework(string? tfm) { Framework = tfm; return this; } + /// Enable or disable VSTest crash diagnostics. + public DotNetTestSettings SetBlameCrash(bool v) { BlameCrash = v; return this; } + /// Set the crash dump size, or null to omit the dump-type flag. + public DotNetTestSettings SetBlameCrashDumpType(DotNetCrashDumpType? v) { BlameCrashDumpType = v; return this; } public DotNetTestSettings SetBlameHang(bool v) { BlameHang = v; return this; } public DotNetTestSettings SetBlameHangTimeout(TimeSpan? t) { BlameHangTimeout = t; return this; } public DotNetTestSettings SetProperty(string name, string value) { Properties[name] = value; return this; } @@ -57,6 +86,12 @@ protected override IEnumerable BuildVerbArguments() if (!string.IsNullOrEmpty(Settings)) { yield return "--settings"; yield return Settings!; } if (!string.IsNullOrEmpty(Runtime)) { yield return "--runtime"; yield return Runtime!; } if (!string.IsNullOrEmpty(Framework)) { yield return "--framework"; yield return Framework!; } + if (BlameCrash) yield return "--blame-crash"; + if (BlameCrashDumpType is { } dumpType) + { + yield return "--blame-crash-dump-type"; + yield return dumpType.ToString().ToLowerInvariant(); + } if (BlameHang) yield return "--blame-hang"; if (BlameHangTimeout is { } t) { yield return "--blame-hang-timeout"; yield return $"{(int)t.TotalMilliseconds}ms"; } foreach (var (k, v) in Properties) diff --git a/src/Tamp.NetCli.V8/DotNetTestSettings.cs b/src/Tamp.NetCli.V8/DotNetTestSettings.cs index 9c354d4..a26419b 100644 --- a/src/Tamp.NetCli.V8/DotNetTestSettings.cs +++ b/src/Tamp.NetCli.V8/DotNetTestSettings.cs @@ -1,5 +1,14 @@ namespace Tamp.NetCli.V8; +/// Crash dump sizes accepted by VSTest's --blame-crash-dump-type. +public enum DotNetCrashDumpType +{ + /// Collect a small crash dump. + Mini, + /// Collect a full crash dump. + Full, +} + public sealed class DotNetTestSettings : DotNetSettingsBase { public Configuration? Configuration { get; set; } @@ -12,6 +21,22 @@ public sealed class DotNetTestSettings : DotNetSettingsBase public string? Settings { get; set; } public string? Runtime { get; set; } public string? Framework { get; set; } + /// Collect crash diagnostics when the VSTest test host exits unexpectedly. + public bool BlameCrash { get; set; } + + private DotNetCrashDumpType? _blameCrashDumpType; + /// Crash dump size. Null uses the CLI default; specifying a size implies crash diagnostics. + public DotNetCrashDumpType? BlameCrashDumpType + { + get => _blameCrashDumpType; + set + { + if (value is { } type && !Enum.IsDefined(type)) + throw new ArgumentOutOfRangeException(nameof(value), value, "Unsupported crash dump type."); + _blameCrashDumpType = value; + } + } + public bool BlameHang { get; set; } public TimeSpan? BlameHangTimeout { get; set; } public Dictionary Properties { get; } = new(); @@ -36,6 +61,10 @@ public sealed class DotNetTestSettings : DotNetSettingsBase public DotNetTestSettings SetSettings(string? path) { Settings = path; return this; } public DotNetTestSettings SetRuntime(string? runtime) { Runtime = runtime; return this; } public DotNetTestSettings SetFramework(string? tfm) { Framework = tfm; return this; } + /// Enable or disable VSTest crash diagnostics. + public DotNetTestSettings SetBlameCrash(bool v) { BlameCrash = v; return this; } + /// Set the crash dump size, or null to omit the dump-type flag. + public DotNetTestSettings SetBlameCrashDumpType(DotNetCrashDumpType? v) { BlameCrashDumpType = v; return this; } public DotNetTestSettings SetBlameHang(bool v) { BlameHang = v; return this; } public DotNetTestSettings SetBlameHangTimeout(TimeSpan? t) { BlameHangTimeout = t; return this; } public DotNetTestSettings SetProperty(string name, string value) { Properties[name] = value; return this; } @@ -57,6 +86,12 @@ protected override IEnumerable BuildVerbArguments() if (!string.IsNullOrEmpty(Settings)) { yield return "--settings"; yield return Settings!; } if (!string.IsNullOrEmpty(Runtime)) { yield return "--runtime"; yield return Runtime!; } if (!string.IsNullOrEmpty(Framework)) { yield return "--framework"; yield return Framework!; } + if (BlameCrash) yield return "--blame-crash"; + if (BlameCrashDumpType is { } dumpType) + { + yield return "--blame-crash-dump-type"; + yield return dumpType.ToString().ToLowerInvariant(); + } if (BlameHang) yield return "--blame-hang"; if (BlameHangTimeout is { } t) { yield return "--blame-hang-timeout"; yield return $"{(int)t.TotalMilliseconds}ms"; } foreach (var (k, v) in Properties) diff --git a/src/Tamp.NetCli.V9/DotNetTestSettings.cs b/src/Tamp.NetCli.V9/DotNetTestSettings.cs index e2f714e..5d95df3 100644 --- a/src/Tamp.NetCli.V9/DotNetTestSettings.cs +++ b/src/Tamp.NetCli.V9/DotNetTestSettings.cs @@ -1,5 +1,14 @@ namespace Tamp.NetCli.V9; +/// Crash dump sizes accepted by VSTest's --blame-crash-dump-type. +public enum DotNetCrashDumpType +{ + /// Collect a small crash dump. + Mini, + /// Collect a full crash dump. + Full, +} + public sealed class DotNetTestSettings : DotNetSettingsBase { public Configuration? Configuration { get; set; } @@ -12,6 +21,22 @@ public sealed class DotNetTestSettings : DotNetSettingsBase public string? Settings { get; set; } public string? Runtime { get; set; } public string? Framework { get; set; } + /// Collect crash diagnostics when the VSTest test host exits unexpectedly. + public bool BlameCrash { get; set; } + + private DotNetCrashDumpType? _blameCrashDumpType; + /// Crash dump size. Null uses the CLI default; specifying a size implies crash diagnostics. + public DotNetCrashDumpType? BlameCrashDumpType + { + get => _blameCrashDumpType; + set + { + if (value is { } type && !Enum.IsDefined(type)) + throw new ArgumentOutOfRangeException(nameof(value), value, "Unsupported crash dump type."); + _blameCrashDumpType = value; + } + } + public bool BlameHang { get; set; } public TimeSpan? BlameHangTimeout { get; set; } public Dictionary Properties { get; } = new(); @@ -36,6 +61,10 @@ public sealed class DotNetTestSettings : DotNetSettingsBase public DotNetTestSettings SetSettings(string? path) { Settings = path; return this; } public DotNetTestSettings SetRuntime(string? runtime) { Runtime = runtime; return this; } public DotNetTestSettings SetFramework(string? tfm) { Framework = tfm; return this; } + /// Enable or disable VSTest crash diagnostics. + public DotNetTestSettings SetBlameCrash(bool v) { BlameCrash = v; return this; } + /// Set the crash dump size, or null to omit the dump-type flag. + public DotNetTestSettings SetBlameCrashDumpType(DotNetCrashDumpType? v) { BlameCrashDumpType = v; return this; } public DotNetTestSettings SetBlameHang(bool v) { BlameHang = v; return this; } public DotNetTestSettings SetBlameHangTimeout(TimeSpan? t) { BlameHangTimeout = t; return this; } public DotNetTestSettings SetProperty(string name, string value) { Properties[name] = value; return this; } @@ -57,6 +86,12 @@ protected override IEnumerable BuildVerbArguments() if (!string.IsNullOrEmpty(Settings)) { yield return "--settings"; yield return Settings!; } if (!string.IsNullOrEmpty(Runtime)) { yield return "--runtime"; yield return Runtime!; } if (!string.IsNullOrEmpty(Framework)) { yield return "--framework"; yield return Framework!; } + if (BlameCrash) yield return "--blame-crash"; + if (BlameCrashDumpType is { } dumpType) + { + yield return "--blame-crash-dump-type"; + yield return dumpType.ToString().ToLowerInvariant(); + } if (BlameHang) yield return "--blame-hang"; if (BlameHangTimeout is { } t) { yield return "--blame-hang-timeout"; yield return $"{(int)t.TotalMilliseconds}ms"; } foreach (var (k, v) in Properties) diff --git a/tests/Tamp.NetCli.V10.Tests/DotNetTests.cs b/tests/Tamp.NetCli.V10.Tests/DotNetTests.cs index 635f425..01d0415 100644 --- a/tests/Tamp.NetCli.V10.Tests/DotNetTests.cs +++ b/tests/Tamp.NetCli.V10.Tests/DotNetTests.cs @@ -189,6 +189,63 @@ public void Test_BlameHang_With_Timeout_Emits_Milliseconds() Assert.Equal("45000ms", args[IndexOf(args, "--blame-hang-timeout") + 1]); } + [Theory] + [InlineData(false)] + [InlineData(true)] + public void Test_BlameCrash_Flag_Does_Not_Require_A_Dump_Type(bool enabled) + { + var args = DotNet.Test(s => s.SetBlameCrash(enabled)).Arguments; + Assert.Equal(enabled, args.Contains("--blame-crash")); + Assert.DoesNotContain("--blame-crash-dump-type", args); + } + + [Theory] + [InlineData(DotNetCrashDumpType.Mini, "mini")] + [InlineData(DotNetCrashDumpType.Full, "full")] + public void Test_BlameCrash_Emits_Requested_Dump_Alongside_Hang_Diagnostics( + DotNetCrashDumpType dumpType, string token) + { + var plan = DotNet.Test(s => s.SetBlameCrash(true).SetBlameCrashDumpType(dumpType) + .SetBlameHang(true).SetBlameHangTimeout(TimeSpan.FromSeconds(45))); + var args = plan.Arguments; + Assert.Contains("--blame-crash", args); + Assert.Equal(token, args[IndexOf(args, "--blame-crash-dump-type") + 1]); + Assert.Contains("--blame-hang", args); + Assert.Equal("45000ms", args[IndexOf(args, "--blame-hang-timeout") + 1]); + } + + [Fact] + public void Test_BlameCrash_Defaults_And_Reset_Omit_Crash_Flags() + { + Assert.DoesNotContain("--blame-crash", DotNet.Test().Arguments); + Assert.DoesNotContain("--blame-crash-dump-type", DotNet.Test().Arguments); + var plan = DotNet.Test(s => s.SetBlameCrash(true).SetBlameCrashDumpType(DotNetCrashDumpType.Mini) + .SetBlameCrash(false).SetBlameCrashDumpType(null)); + Assert.DoesNotContain("--blame-crash", plan.Arguments); + Assert.DoesNotContain("--blame-crash-dump-type", plan.Arguments); + } + + [Fact] + public void Test_Crash_Dump_Type_Can_Be_Used_Without_Explicit_Blame_Flag() + { + var settings = new DotNetTestSettings { BlameCrashDumpType = DotNetCrashDumpType.Mini }; + var args = settings.ToCommandPlan().Arguments; + Assert.Equal("mini", args[IndexOf(args, "--blame-crash-dump-type") + 1]); + Assert.DoesNotContain("--blame-crash", args); // VSTest implies it from dump type. + } + + [Theory] + [InlineData(-1)] + [InlineData(2)] + [InlineData(int.MaxValue)] + public void Test_Invalid_Crash_Dump_Type_Is_Rejected_Before_It_Becomes_State(int value) + { + var settings = new DotNetTestSettings { BlameCrashDumpType = DotNetCrashDumpType.Full }; + Assert.Throws(() => settings.BlameCrashDumpType = (DotNetCrashDumpType)value); + Assert.Throws(() => settings.SetBlameCrashDumpType((DotNetCrashDumpType)value)); + Assert.Equal(DotNetCrashDumpType.Full, settings.BlameCrashDumpType); + } + // ---- Pack ---- [Fact] diff --git a/tests/Tamp.NetCli.V8.Tests/DotNetTests.cs b/tests/Tamp.NetCli.V8.Tests/DotNetTests.cs index 2f8184a..4b205a0 100644 --- a/tests/Tamp.NetCli.V8.Tests/DotNetTests.cs +++ b/tests/Tamp.NetCli.V8.Tests/DotNetTests.cs @@ -189,6 +189,63 @@ public void Test_BlameHang_With_Timeout_Emits_Milliseconds() Assert.Equal("45000ms", args[IndexOf(args, "--blame-hang-timeout") + 1]); } + [Theory] + [InlineData(false)] + [InlineData(true)] + public void Test_BlameCrash_Flag_Does_Not_Require_A_Dump_Type(bool enabled) + { + var args = DotNet.Test(s => s.SetBlameCrash(enabled)).Arguments; + Assert.Equal(enabled, args.Contains("--blame-crash")); + Assert.DoesNotContain("--blame-crash-dump-type", args); + } + + [Theory] + [InlineData(DotNetCrashDumpType.Mini, "mini")] + [InlineData(DotNetCrashDumpType.Full, "full")] + public void Test_BlameCrash_Emits_Requested_Dump_Alongside_Hang_Diagnostics( + DotNetCrashDumpType dumpType, string token) + { + var plan = DotNet.Test(s => s.SetBlameCrash(true).SetBlameCrashDumpType(dumpType) + .SetBlameHang(true).SetBlameHangTimeout(TimeSpan.FromSeconds(45))); + var args = plan.Arguments; + Assert.Contains("--blame-crash", args); + Assert.Equal(token, args[IndexOf(args, "--blame-crash-dump-type") + 1]); + Assert.Contains("--blame-hang", args); + Assert.Equal("45000ms", args[IndexOf(args, "--blame-hang-timeout") + 1]); + } + + [Fact] + public void Test_BlameCrash_Defaults_And_Reset_Omit_Crash_Flags() + { + Assert.DoesNotContain("--blame-crash", DotNet.Test().Arguments); + Assert.DoesNotContain("--blame-crash-dump-type", DotNet.Test().Arguments); + var plan = DotNet.Test(s => s.SetBlameCrash(true).SetBlameCrashDumpType(DotNetCrashDumpType.Mini) + .SetBlameCrash(false).SetBlameCrashDumpType(null)); + Assert.DoesNotContain("--blame-crash", plan.Arguments); + Assert.DoesNotContain("--blame-crash-dump-type", plan.Arguments); + } + + [Fact] + public void Test_Crash_Dump_Type_Can_Be_Used_Without_Explicit_Blame_Flag() + { + var settings = new DotNetTestSettings { BlameCrashDumpType = DotNetCrashDumpType.Mini }; + var args = settings.ToCommandPlan().Arguments; + Assert.Equal("mini", args[IndexOf(args, "--blame-crash-dump-type") + 1]); + Assert.DoesNotContain("--blame-crash", args); // VSTest implies it from dump type. + } + + [Theory] + [InlineData(-1)] + [InlineData(2)] + [InlineData(int.MaxValue)] + public void Test_Invalid_Crash_Dump_Type_Is_Rejected_Before_It_Becomes_State(int value) + { + var settings = new DotNetTestSettings { BlameCrashDumpType = DotNetCrashDumpType.Full }; + Assert.Throws(() => settings.BlameCrashDumpType = (DotNetCrashDumpType)value); + Assert.Throws(() => settings.SetBlameCrashDumpType((DotNetCrashDumpType)value)); + Assert.Equal(DotNetCrashDumpType.Full, settings.BlameCrashDumpType); + } + // ---- Pack ---- [Fact] diff --git a/tests/Tamp.NetCli.V9.Tests/DotNetTests.cs b/tests/Tamp.NetCli.V9.Tests/DotNetTests.cs index 4bbb03d..0b6e46e 100644 --- a/tests/Tamp.NetCli.V9.Tests/DotNetTests.cs +++ b/tests/Tamp.NetCli.V9.Tests/DotNetTests.cs @@ -189,6 +189,63 @@ public void Test_BlameHang_With_Timeout_Emits_Milliseconds() Assert.Equal("45000ms", args[IndexOf(args, "--blame-hang-timeout") + 1]); } + [Theory] + [InlineData(false)] + [InlineData(true)] + public void Test_BlameCrash_Flag_Does_Not_Require_A_Dump_Type(bool enabled) + { + var args = DotNet.Test(s => s.SetBlameCrash(enabled)).Arguments; + Assert.Equal(enabled, args.Contains("--blame-crash")); + Assert.DoesNotContain("--blame-crash-dump-type", args); + } + + [Theory] + [InlineData(DotNetCrashDumpType.Mini, "mini")] + [InlineData(DotNetCrashDumpType.Full, "full")] + public void Test_BlameCrash_Emits_Requested_Dump_Alongside_Hang_Diagnostics( + DotNetCrashDumpType dumpType, string token) + { + var plan = DotNet.Test(s => s.SetBlameCrash(true).SetBlameCrashDumpType(dumpType) + .SetBlameHang(true).SetBlameHangTimeout(TimeSpan.FromSeconds(45))); + var args = plan.Arguments; + Assert.Contains("--blame-crash", args); + Assert.Equal(token, args[IndexOf(args, "--blame-crash-dump-type") + 1]); + Assert.Contains("--blame-hang", args); + Assert.Equal("45000ms", args[IndexOf(args, "--blame-hang-timeout") + 1]); + } + + [Fact] + public void Test_BlameCrash_Defaults_And_Reset_Omit_Crash_Flags() + { + Assert.DoesNotContain("--blame-crash", DotNet.Test().Arguments); + Assert.DoesNotContain("--blame-crash-dump-type", DotNet.Test().Arguments); + var plan = DotNet.Test(s => s.SetBlameCrash(true).SetBlameCrashDumpType(DotNetCrashDumpType.Mini) + .SetBlameCrash(false).SetBlameCrashDumpType(null)); + Assert.DoesNotContain("--blame-crash", plan.Arguments); + Assert.DoesNotContain("--blame-crash-dump-type", plan.Arguments); + } + + [Fact] + public void Test_Crash_Dump_Type_Can_Be_Used_Without_Explicit_Blame_Flag() + { + var settings = new DotNetTestSettings { BlameCrashDumpType = DotNetCrashDumpType.Mini }; + var args = settings.ToCommandPlan().Arguments; + Assert.Equal("mini", args[IndexOf(args, "--blame-crash-dump-type") + 1]); + Assert.DoesNotContain("--blame-crash", args); // VSTest implies it from dump type. + } + + [Theory] + [InlineData(-1)] + [InlineData(2)] + [InlineData(int.MaxValue)] + public void Test_Invalid_Crash_Dump_Type_Is_Rejected_Before_It_Becomes_State(int value) + { + var settings = new DotNetTestSettings { BlameCrashDumpType = DotNetCrashDumpType.Full }; + Assert.Throws(() => settings.BlameCrashDumpType = (DotNetCrashDumpType)value); + Assert.Throws(() => settings.SetBlameCrashDumpType((DotNetCrashDumpType)value)); + Assert.Equal(DotNetCrashDumpType.Full, settings.BlameCrashDumpType); + } + // ---- Pack ---- [Fact]