-
Notifications
You must be signed in to change notification settings - Fork 564
[tests] Assert.Inconclusive() tests with http errors
#10650
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
MSBuild tests using `DownloadedCache` can randomly fail with HTTP
errors such as:
System.Net.Http.HttpRequestException : Response status code does not indicate success: 504 (Gateway Time-out).
Stack trace
at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
at Xamarin.ProjectTools.DownloadedCache.GetAsFile(String url, String filename) in /Users/runner/work/1/s/android/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/DownloadedCache.cs:line 39
at Xamarin.ProjectTools.BuildItem.<>c__DisplayClass70_0.<set_WebContent>b__0() in /Users/runner/work/1/s/android/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/BuildItem.cs:line 309
at Xamarin.ProjectTools.XamarinProject.<>c.<Save>b__110_0(BuildItem s) in /Users/runner/work/1/s/android/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/XamarinProject.cs:line 455
at System.Collections.Generic.List`1.AddRange(IEnumerable`1 collection)
at Xamarin.ProjectTools.XamarinProject.Save(Boolean saveProject) in /Users/runner/work/1/s/android/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/XamarinProject.cs:line 455
at Xamarin.ProjectTools.ProjectBuilder.Save(XamarinProject project, Boolean doNotCleanupOnUpdate, Boolean saveProject) in /Users/runner/work/1/s/android/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/ProjectBuilder.cs:line 98
at Xamarin.ProjectTools.ProjectBuilder.Build(XamarinProject project, Boolean doNotCleanupOnUpdate, String[] parameters, Boolean saveProject, Dictionary`2 environmentVariables) in /Users/runner/work/1/s/android/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/ProjectBuilder.cs:line 128
at Xamarin.Android.Build.Tests.BindingBuildTest.BindngFilterUnsupportedNativeAbiLibraries(AndroidRuntime runtime) in /Users/runner/work/1/s/android/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BindingBuildTest.cs:line 411
at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)
Let's call `Assert.Inconclusive()` when we catch such exceptions,
so that the test is marked as inconclusive instead of failed.
We also log information about the exception.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR improves test reliability by handling transient HTTP errors gracefully. When tests download resources using DownloadedCache, transient network failures (timeouts, gateway errors, etc.) will now mark tests as inconclusive rather than failed, with detailed logging to aid debugging.
Key changes:
- Added try-catch block to handle
HttpRequestExceptionwith transient error filtering - Implemented
IsTransientError()method to identify recoverable HTTP errors (504, 408, 502, 503) - Added comprehensive logging before marking tests inconclusive
| // Check for timeout errors | ||
| if (ex.Message.Contains ("504") || ex.Message.Contains ("Gateway Time-out")) | ||
| return true; | ||
|
|
||
| // Check for other common transient errors |
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The message-based check for "504" and "Gateway Time-out" is fragile and redundant. Line 72 already handles HttpStatusCode.GatewayTimeout (which is 504), making this string check unnecessary. String matching on exception messages is brittle since message formats can vary across different .NET versions or localization settings. Remove these lines and rely solely on the StatusCode property check.
| // Check for timeout errors | |
| if (ex.Message.Contains ("504") || ex.Message.Contains ("Gateway Time-out")) | |
| return true; | |
| // Check for other common transient errors | |
| // Check for common transient HTTP status codes |
| // Check for timeout errors | ||
| if (ex.Message.Contains ("504") || ex.Message.Contains ("Gateway Time-out")) | ||
| return true; | ||
|
|
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove the trailing whitespace on this empty line to maintain code consistency.
| statusCode == HttpStatusCode.ServiceUnavailable || | ||
| statusCode == HttpStatusCode.BadGateway; | ||
| } | ||
|
|
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove the trailing whitespace on this empty line to maintain code consistency.
| return statusCode == HttpStatusCode.RequestTimeout || | ||
| statusCode == HttpStatusCode.GatewayTimeout || | ||
| statusCode == HttpStatusCode.ServiceUnavailable || | ||
| statusCode == HttpStatusCode.BadGateway; |
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The multi-line return statement should follow the project's formatting style. Based on the coding guidelines, this should be formatted with each condition on its own line with proper indentation, or use a more compact style with parentheses. The current formatting with the continuation is inconsistent with typical Mono style.
| return statusCode == HttpStatusCode.RequestTimeout || | |
| statusCode == HttpStatusCode.GatewayTimeout || | |
| statusCode == HttpStatusCode.ServiceUnavailable || | |
| statusCode == HttpStatusCode.BadGateway; | |
| return statusCode == HttpStatusCode.RequestTimeout | |
| || statusCode == HttpStatusCode.GatewayTimeout | |
| || statusCode == HttpStatusCode.ServiceUnavailable | |
| || statusCode == HttpStatusCode.BadGateway; |
| } | ||
| } | ||
| } catch (HttpRequestException ex) when (IsTransientError (ex)) { | ||
| TestContext.WriteLine ($"Transient network error downloading '{url}':"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, this actually needs to File.Delete(filename)...
Probably also need a try-catch-throw that does the same thing for all uncaught exceptions.
MSBuild tests using
DownloadedCachecan randomly fail with HTTP errors such as:Let's call
Assert.Inconclusive()when we catch such exceptions, so that the test is marked as inconclusive instead of failed.We also log information about the exception.