From fb5dc3ae5a814664e6f80b1ee9c538c8294370f8 Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Tue, 9 Oct 2018 10:38:56 +0200 Subject: [PATCH] [Tests] Make network tests a bit more resilient We often see networ test "failures" caused by unreachability of one of the servers those tests use. This creates false negatives since this is not really the test failing but rather the environment not being correct and preventing the test from performing its actual task. This commit catches the `WebException` thrown in connection failed cases and merely ignores the test instead of failing it. Full exception message and stack trace is printed as part of the ignore message. --- .../AndroidClientHandlerTests.cs | 55 ++++++++++++++++--- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/src/Mono.Android/Test/Xamarin.Android.Net/AndroidClientHandlerTests.cs b/src/Mono.Android/Test/Xamarin.Android.Net/AndroidClientHandlerTests.cs index a235427d8cc..d1457cdf198 100644 --- a/src/Mono.Android/Test/Xamarin.Android.Net/AndroidClientHandlerTests.cs +++ b/src/Mono.Android/Test/Xamarin.Android.Net/AndroidClientHandlerTests.cs @@ -34,6 +34,8 @@ using System.Net.Http; using System.Text; using System.Threading; +using System.Threading.Tasks; +using System.Web; using NUnit.Framework; @@ -132,12 +134,32 @@ public void Disposed () h.Dispose (); var c = new HttpClient (h); try { - c.GetAsync ("http://google.com").Wait (); + var t = ConnectIgnoreFailure (() => c.GetAsync ("http://google.com"), out bool connectionFailed); + if (connectionFailed) + return; + + t.Wait (); Assert.Fail ("#1"); } catch (AggregateException e) { Assert.IsTrue (e.InnerException is ObjectDisposedException, "#2"); } } + + protected Task ConnectIgnoreFailure (Func> connector, out bool connectionFailed) + { + connectionFailed = false; + try { + return connector (); + } catch (AggregateException ex) { + if (ex.InnerException is WebException wex && wex.Status == WebExceptionStatus.ConnectFailure) { + connectionFailed = true; + Assert.Ignore ($"Failed to connect to server. {wex}"); + return null; + } + + throw; + } + } } [TestFixture] @@ -184,7 +206,10 @@ public void Sanity_Tls_1_2_Url_WithMonoClientHandlerFails () var supportTls1_2 = tlsProvider.Equals ("btls", StringComparison.OrdinalIgnoreCase); using (var c = new HttpClient (new HttpClientHandler ())) { try { - var tr = c.GetAsync (Tls_1_2_Url); + var tr = ConnectIgnoreFailure (() => c.GetAsync (Tls_1_2_Url), out bool connectionFailed); + if (connectionFailed) + return; + tr.Wait (); tr.Result.EnsureSuccessStatusCode (); if (!supportTls1_2) { @@ -210,7 +235,10 @@ public void Cancel_Client_Works() var cts = new CancellationTokenSource (); cts.Cancel (); //Cancel immediately using (var c = new HttpClient (CreateHandler())) { - var tr = c.GetAsync ("http://10.255.255.1", cts.Token); + var tr = ConnectIgnoreFailure (() => c.GetAsync ("http://10.255.255.1", cts.Token), out bool connectionFailed); + if (connectionFailed) + return; + try { tr.Wait(); Assert.Fail ("SHOULD NOT HAPPEN: Request is expected to cancel"); @@ -227,7 +255,10 @@ public void Token_Timeout_Works() { var cts = new CancellationTokenSource (2000); //Cancel after 2000ms through token using (var c = new HttpClient (CreateHandler())){ - var tr = c.GetAsync ("http://10.255.255.1", cts.Token); + var tr = ConnectIgnoreFailure (() => c.GetAsync ("http://10.255.255.1", cts.Token), out bool connectionFailed); + if (connectionFailed) + return; + try { tr.Wait (); Assert.Fail ("SHOULD NOT HAPPEN: Request is expected to cancel"); @@ -245,7 +276,10 @@ public void Property_Timeout_Works() using (var c = new HttpClient (CreateHandler ())) { c.Timeout = TimeSpan.FromMilliseconds (2000); //Cancel after 2000ms through Timeout property - var tr = c.GetAsync ("http://10.255.255.1"); + var tr = ConnectIgnoreFailure (() => c.GetAsync ("http://10.255.255.1"), out bool connectionFailed); + if (connectionFailed) + return; + try { tr.Wait (); Assert.Fail ("SHOULD NOT HAPPEN: Request is expected to cancel"); @@ -263,7 +297,10 @@ public void Redirect_Without_Protocol_Works() var requestURI = new Uri ("http://tls-test.internalx.com/redirect.php"); var redirectedURI = new Uri ("http://tls-test.internalx.com/redirect-301.html"); using (var c = new HttpClient (CreateHandler ())) { - var tr = c.GetAsync (requestURI); + var tr = ConnectIgnoreFailure (() => c.GetAsync (requestURI), out bool connectionFailed); + if (connectionFailed) + return; + tr.Wait (); tr.Result.EnsureSuccessStatusCode (); Assert.AreEqual (redirectedURI, tr.Result.RequestMessage.RequestUri, "Invalid redirected URI"); @@ -278,7 +315,11 @@ public void Redirect_POST_With_Content_Works () using (var c = new HttpClient (CreateHandler ())) { var request = new HttpRequestMessage (HttpMethod.Post, requestURI); request.Content = new StringContent("{}", Encoding.UTF8, "application/json"); - var response = c.SendAsync(request).Result; + var t = ConnectIgnoreFailure (() => c.SendAsync(request), out bool connectionFailed); + if (connectionFailed) + return; + + var response = t.Result; response.EnsureSuccessStatusCode (); Assert.AreEqual (redirectedURI, response.RequestMessage.RequestUri, "Invalid redirected URI"); }