Skip to content

Commit 97ce3b0

Browse files
committed
test: preserve CLI smoke cleanup failures
1 parent c422ee2 commit 97ce3b0

1 file changed

Lines changed: 71 additions & 13 deletions

File tree

‎ClaudeCodeSharpSDK.Tests/Integration/ClaudeCliSmokeTests.cs‎

Lines changed: 71 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Diagnostics;
2+
using System.Runtime.ExceptionServices;
23
using System.Text.Json;
34
using ManagedCode.ClaudeCodeSharpSDK.Client;
45
using ManagedCode.ClaudeCodeSharpSDK.Configuration;
@@ -38,6 +39,7 @@ public class ClaudeCliSmokeTests
3839
private const string CarriageReturn = "\r";
3940
private const string CouldNotLocateRepositoryRootMessage = "Could not locate repository root from test execution directory.";
4041
private const string StartProcessFailedMessagePrefix = "Failed to start Claude Code CLI at";
42+
private const string SmokeCleanupFailedMessage = "Claude CLI smoke process cleanup could not be fully confirmed.";
4143
private const string ClaudeCodeNestingEnvironmentVariable = "CLAUDECODE";
4244
private const string Space = " ";
4345
private const string MessageQuote = "'";
@@ -220,6 +222,8 @@ private static async Task<ClaudeProcessResult> RunClaudeAsync(
220222

221223
Task<string>? standardOutputTask = null;
222224
Task<string>? standardErrorTask = null;
225+
ClaudeProcessResult? result = null;
226+
Exception? invocationFailure = null;
223227
try
224228
{
225229
process.StandardInput.Close();
@@ -228,34 +232,88 @@ private static async Task<ClaudeProcessResult> RunClaudeAsync(
228232
await process.WaitForExitAsync(cancellationToken);
229233
var output = await Task.WhenAll(standardOutputTask, standardErrorTask)
230234
.WaitAsync(TestCleanupTimeout, cancellationToken);
231-
return new ClaudeProcessResult(process.ExitCode, output[0], output[1]);
235+
result = new ClaudeProcessResult(process.ExitCode, output[0], output[1]);
232236
}
233-
finally
237+
catch (Exception exception)
234238
{
235-
if (!process.HasExited)
239+
invocationFailure = exception;
240+
}
241+
242+
var cleanupFailures = new List<Exception>();
243+
if (!process.HasExited)
244+
{
245+
try
246+
{
247+
process.Kill(entireProcessTree: true);
248+
}
249+
catch (InvalidOperationException) when (process.HasExited)
250+
{
251+
// The CLI exited between the state check and the kill request.
252+
}
253+
catch (Exception exception)
236254
{
237-
try
238-
{
239-
process.Kill(entireProcessTree: true);
240-
}
241-
catch (InvalidOperationException) when (process.HasExited)
242-
{
243-
// The CLI exited between the state check and the kill request.
244-
}
255+
cleanupFailures.Add(exception);
245256
}
257+
}
246258

247-
if (!process.HasExited)
259+
if (!process.HasExited)
260+
{
261+
try
248262
{
249263
await process.WaitForExitAsync().WaitAsync(TestCleanupTimeout);
250264
}
265+
catch (Exception exception)
266+
{
267+
cleanupFailures.Add(exception);
268+
}
269+
}
251270

271+
try
272+
{
252273
process.StandardOutput.Dispose();
274+
}
275+
catch (Exception exception)
276+
{
277+
cleanupFailures.Add(exception);
278+
}
279+
280+
try
281+
{
253282
process.StandardError.Dispose();
254-
if (standardOutputTask is not null && standardErrorTask is not null)
283+
}
284+
catch (Exception exception)
285+
{
286+
cleanupFailures.Add(exception);
287+
}
288+
289+
if (standardOutputTask is not null && standardErrorTask is not null)
290+
{
291+
try
255292
{
256293
await ObserveReadersAsync(standardOutputTask, standardErrorTask, cancellationToken);
257294
}
295+
catch (Exception exception)
296+
{
297+
cleanupFailures.Add(exception);
298+
}
258299
}
300+
301+
if (cleanupFailures.Count != 0)
302+
{
303+
if (invocationFailure is not null)
304+
{
305+
cleanupFailures.Insert(0, invocationFailure);
306+
}
307+
308+
throw new AggregateException(SmokeCleanupFailedMessage, cleanupFailures);
309+
}
310+
311+
if (invocationFailure is not null)
312+
{
313+
ExceptionDispatchInfo.Capture(invocationFailure).Throw();
314+
}
315+
316+
return result!;
259317
}
260318

261319
private static async Task ObserveReadersAsync(

0 commit comments

Comments
 (0)