Skip to content

Commit c6045d3

Browse files
[tests] ignore transient "Broken pipe" network errors (#10681)
This should allow us to ignore failure cases like: Mono.Android.NET_Tests, Xamarin.Android.NetTests.AndroidMessageHandlerTests.HttpContentStreamIsRewoundAfterCancellation / Release Error message System.AggregateException : AggregateException_ctor_DefaultMessage (Broken pipe) ----> System.Net.WebException : Broken pipe ----> Java.Net.SocketException : Broken pipe Stack trace at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean) at System.Threading.Tasks.Task.Wait(Int32, CancellationToken) at System.Threading.Tasks.Task.Wait() at NUnit.Framework.Internal.AsyncInvocationRegion.AsyncTaskInvocationRegion.WaitForPendingOperationsToComplete(Object) at NUnit.Framework.Internal.Commands.TestMethodCommand.RunAsyncTestMethod(TestExecutionContext) --WebException at Xamarin.Android.Net.AndroidMessageHandler.DoSendAsync(HttpRequestMessage, CancellationToken) at Xamarin.Android.Net.AndroidMessageHandler.SendWithNegotiateAuthenticationAsync(HttpRequestMessage, CancellationToken) at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage, HttpCompletionOption, CancellationTokenSource, Boolean, CancellationTokenSource, CancellationToken) at Xamarin.Android.NetTests.AndroidMessageHandlerTests.HttpContentStreamIsRewoundAfterCancellation() --SocketException at Java.Interop.JniEnvironment.InstanceMethods.CallIntMethod(JniObjectReference, JniMethodInfo , JniArgumentValue*) at Java.Interop.JniPeerMembers.JniInstanceMethods.InvokeVirtualInt32Method(String, IJavaPeerable, JniArgumentValue* ) at Java.Net.HttpURLConnection.get_ResponseCode() at Xamarin.Android.Net.AndroidMessageHandler.<>c__DisplayClass140_0.<DoProcessRequest>b__2() at System.Threading.Tasks.Task`1[[System.Net.HttpStatusCode, System.Net.Primitives, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].InnerInvoke() at System.Threading.Tasks.Task.<>c.<.cctor>b__289_0(Object obj) at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread, ExecutionContext, ContextCallback, Object) --- End of stack trace from previous location --- at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread, ExecutionContext, ContextCallback, Object) at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task&, Thread ) --- End of stack trace from previous location --- at Xamarin.Android.Net.AndroidMessageHandler.DoProcessRequest(HttpRequestMessage, URL, HttpURLConnection, CancellationToken, RequestRedirectionState) at Xamarin.Android.Net.AndroidMessageHandler.DoSendAsync(HttpRequestMessage, CancellationToken) --- End of managed Java.Net.SocketException stack trace --- java.net.SocketException: Broken pipe at java.net.SocketOutputStream.socketWrite0(Native Method) at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:117) at java.net.SocketOutputStream.write(SocketOutputStream.java:161) at com.android.okhttp.okio.Okio$1.write(Okio.java:78) at com.android.okhttp.okio.AsyncTimeout$1.write(AsyncTimeout.java:157) at com.android.okhttp.okio.RealBufferedSink.flush(RealBufferedSink.java:222) at com.android.okhttp.internal.http.Http1xStream.finishRequest(Http1xStream.java:163) at com.android.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:748) at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:622) at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:475) at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:411) at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:542)
1 parent 93d598b commit c6045d3

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

tests/Mono.Android-Tests/Mono.Android-Tests/Xamarin.Android.Net/AndroidClientHandlerTests.cs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,12 +115,15 @@ protected void RunIgnoringNetworkIssues (Action runner, out bool connectionFaile
115115
}
116116
}
117117

118-
bool IgnoreIfConnectionFailed (AggregateException aex, out bool connectionFailed)
118+
protected bool IgnoreIfConnectionFailed (AggregateException aex, out bool connectionFailed)
119119
{
120120
if (IgnoreIfConnectionFailed (aex.InnerException as HttpRequestException, out connectionFailed))
121121
return true;
122122

123-
return IgnoreIfConnectionFailed (aex.InnerException as WebException, out connectionFailed);
123+
if (IgnoreIfConnectionFailed (aex.InnerException as WebException, out connectionFailed))
124+
return true;
125+
126+
return IgnoreIfSocketException (aex, out connectionFailed);
124127
}
125128

126129
bool IgnoreIfConnectionFailed (HttpRequestException hrex, out bool connectionFailed)
@@ -145,6 +148,26 @@ bool IgnoreIfConnectionFailed (WebException wex, out bool connectionFailed)
145148

146149
return false;
147150
}
151+
152+
bool IgnoreIfSocketException (Exception ex, out bool connectionFailed)
153+
{
154+
connectionFailed = false;
155+
// Check the exception and all inner exceptions for transient socket errors
156+
var current = ex;
157+
while (current != null) {
158+
if (current is Java.Net.SocketException socketEx) {
159+
var message = socketEx.Message ?? "";
160+
if (message.Contains ("Broken pipe", StringComparison.OrdinalIgnoreCase) ||
161+
message.Contains ("Connection reset", StringComparison.OrdinalIgnoreCase)) {
162+
connectionFailed = true;
163+
Assert.Ignore ($"Ignoring transient socket error: {socketEx}");
164+
return true;
165+
}
166+
}
167+
current = current.InnerException;
168+
}
169+
return false;
170+
}
148171
}
149172

150173
[Category ("AndroidClientHandler")]

tests/Mono.Android-Tests/Mono.Android-Tests/Xamarin.Android.Net/AndroidMessageHandlerTests.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,13 @@ public async Task HttpContentStreamIsRewoundAfterCancellation ()
385385
try {
386386
await client.SendAsync (request, tcs.Token).ConfigureAwait (false);
387387
// If we get here without exception, that's also OK for this test
388+
} catch (AggregateException ex) {
389+
if (IgnoreIfConnectionFailed (ex, out _))
390+
return;
391+
// Expected - cancellation or connection error
392+
// We catch all exceptions to ensure the test doesn't fail due to unhandled exceptions
393+
Console.WriteLine ($"Exception during first request (expected): {ex}");
394+
exceptionThrown = true;
388395
} catch (Exception ex) {
389396
// Expected - cancellation or connection error
390397
// We catch all exceptions to ensure the test doesn't fail due to unhandled exceptions

0 commit comments

Comments
 (0)