diff --git a/src/BuiltInTools/dotnet-watch/Internal/ProcessRunner.cs b/src/BuiltInTools/dotnet-watch/Internal/ProcessRunner.cs index 6551d37c8a06..e53942a662bc 100644 --- a/src/BuiltInTools/dotnet-watch/Internal/ProcessRunner.cs +++ b/src/BuiltInTools/dotnet-watch/Internal/ProcessRunner.cs @@ -257,7 +257,7 @@ private static void TerminateProcess(Process process, ProcessState state, IRepor } else { - TerminateUnixProcess(state, reporter); + TerminateUnixProcess(process, state, reporter); } reporter.Verbose($"Process {state.ProcessId} killed."); @@ -305,17 +305,21 @@ private static void TerminateWindowsProcess(Process process, ProcessState state, process.Kill(); } - private static void TerminateUnixProcess(ProcessState state, IReporter reporter) + private static void TerminateUnixProcess(Process process, ProcessState state, IReporter reporter) { - [DllImport("libc", SetLastError = true, EntryPoint = "kill")] - static extern int sys_kill(int pid, int sig); + // Signals no longer work on Linux https://github.com/dotnet/sdk/issues/49307 - var result = sys_kill(state.ProcessId, state.ForceExit ? SIGKILL : SIGTERM); - if (result != 0) - { - var error = Marshal.GetLastPInvokeError(); - reporter.Verbose($"Error while sending SIGTERM to process {state.ProcessId}: {Marshal.GetPInvokeErrorMessage(error)} (code {error})."); - } + //[DllImport("libc", SetLastError = true, EntryPoint = "kill")] + //static extern int sys_kill(int pid, int sig); + + //var result = sys_kill(state.ProcessId, state.ForceExit ? SIGKILL : SIGTERM); + //if (result != 0) + //{ + // var error = Marshal.GetLastPInvokeError(); + // reporter.Verbose($"Error while sending SIGTERM to process {state.ProcessId}: {Marshal.GetPInvokeErrorMessage(error)} (code {error})."); + //} + + process.Kill(entireProcessTree: true); } } } diff --git a/test/dotnet-watch.Tests/HotReload/ApplyDeltaTests.cs b/test/dotnet-watch.Tests/HotReload/ApplyDeltaTests.cs index 2fef1c0e6dff..b4a23558560a 100644 --- a/test/dotnet-watch.Tests/HotReload/ApplyDeltaTests.cs +++ b/test/dotnet-watch.Tests/HotReload/ApplyDeltaTests.cs @@ -420,7 +420,7 @@ class AppUpdateHandler } } - [Theory(Skip = "https://github.com/dotnet/sdk/issues/45299")] + [Theory] [CombinatorialData] public async Task BlazorWasm(bool projectSpecifiesCapabilities) { @@ -502,7 +502,7 @@ public async Task BlazorWasm_MSBuildWarning() await App.AssertWaitingForChanges(); } - [Fact(Skip = "https://github.com/dotnet/sdk/issues/49307")] + [Fact] public async Task BlazorWasm_Restart() { var testAsset = TestAssets.CopyTestAsset("WatchBlazorWasm") @@ -757,7 +757,7 @@ public static void PrintDirectoryName([CallerFilePathAttribute] string filePath await App.AssertOutputLineStartsWith("> NewSubdir"); } - [Fact] + [Fact(Skip = "https://github.com/dotnet/sdk/issues/49307")] public async Task Aspire() { var tfm = ToolsetInfo.CurrentTargetFramework; @@ -817,9 +817,13 @@ public async Task Aspire() } else { + App.AssertOutputContains($"dotnet watch ❌ [WatchAspire.ApiService ({tfm})] Exited"); + + // TODO: SIGTERM no longer works on Linux https://github.com/dotnet/sdk/issues/49307 // Unix process may return exit code = 128 + SIGTERM + // Exited with error code 143 - App.AssertOutputContains($"[WatchAspire.ApiService ({tfm})] Exited"); + // App.AssertOutputContains($"[WatchAspire.ApiService ({tfm})] Exited"); } App.AssertOutputContains($"dotnet watch ⌚ Building {serviceProjectPath} ..."); @@ -834,7 +838,7 @@ public async Task Aspire() await App.AssertOutputLineStartsWith($"dotnet watch ⌚ [WatchAspire.ApiService ({tfm})] Capabilities"); App.AssertOutputContains($"dotnet watch 🔨 Build succeeded: {serviceProjectPath}"); - App.AssertOutputContains("dotnet watch 🔥 Project baselines updated."); + App.AssertOutputContains("dotnet watch 🔥 Projects rebuilt"); App.AssertOutputContains($"dotnet watch ⭐ Starting project: {serviceProjectPath}"); // Note: sending Ctrl+C via standard input is not the same as sending real Ctrl+C. @@ -843,6 +847,8 @@ public async Task Aspire() await App.AssertOutputLineStartsWith("dotnet watch 🛑 Shutdown requested. Press Ctrl+C again to force exit."); + // SIGTERM no longer works on Linux https://github.com/dotnet/sdk/issues/49307 + // We don't have means to gracefully terminate process on Windows, see https://github.com/dotnet/runtime/issues/109432 if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { @@ -851,10 +857,15 @@ public async Task Aspire() } else { + // TODO: SIGTERM no longer works on Linux https://github.com/dotnet/sdk/issues/49307 + + await App.AssertOutputLineStartsWith($"dotnet watch ❌ [WatchAspire.ApiService ({tfm})] Exited"); + await App.AssertOutputLineStartsWith($"dotnet watch ❌ [WatchAspire.AppHost ({tfm})] Exited"); + // Unix process may return exit code = 128 + SIGTERM // Exited with error code 143 - await App.AssertOutputLine(line => line.Contains($"[WatchAspire.ApiService ({tfm})] Exited")); - await App.AssertOutputLine(line => line.Contains($"[WatchAspire.AppHost ({tfm})] Exited")); + // await App.AssertOutputLine(line => line.Contains($"[WatchAspire.ApiService ({tfm})] Exited")); + // await App.AssertOutputLine(line => line.Contains($"[WatchAspire.AppHost ({tfm})] Exited")); } await App.AssertOutputLineStartsWith("dotnet watch ⭐ Waiting for server to shutdown ...");