From cedf0f758d5f16e137006a2dca9c2b92533bff44 Mon Sep 17 00:00:00 2001 From: Simon Rozsival Date: Fri, 3 Jul 2026 23:15:24 +0200 Subject: [PATCH] [Tests] Retry flaky InstallAndroidDependenciesTest download InstallAndroidDependenciesTest exercises the InstallAndroidDependencies target, which downloads the Android SDK and JDK over the network. These downloads fail intermittently in CI, causing the ("GoogleV2", CoreCLR) and ("Xamarin", CoreCLR) cases to fail randomly across unrelated PRs. Retry the install build up to 3 times, waiting 10 seconds between attempts and starting from a clean SDK/JDK directory each time so a partial download does not affect the next attempt. Mitigates #11973 --- .../AndroidDependenciesTests.cs | 31 +++++++++++++++---- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidDependenciesTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidDependenciesTests.cs index baad82d7013..15fcb7aed23 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidDependenciesTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidDependenciesTests.cs @@ -3,6 +3,7 @@ using System.IO; using System.Linq; using System.Text; +using System.Threading; using System.Xml; using System.Xml.Linq; using NUnit.Framework; @@ -43,11 +44,6 @@ public void InstallAndroidDependenciesTest ([Values ("GoogleV2", "Xamarin")] str string jdkPath = Path.Combine (Root, "temp", TestName, "android-jdk"); Environment.SetEnvironmentVariable ("TEST_ANDROID_SDK_PATH", sdkPath); Environment.SetEnvironmentVariable ("TEST_ANDROID_JDK_PATH", jdkPath); - foreach (var path in new [] { sdkPath, jdkPath }) { - if (Directory.Exists (path)) - Directory.Delete (path, recursive: true); - Directory.CreateDirectory (path); - } var proj = new XamarinAndroidApplicationProject { IsRelease = isRelease, @@ -69,7 +65,30 @@ public void InstallAndroidDependenciesTest ([Values ("GoogleV2", "Xamarin")] str string defaultTarget = b.Target; b.Target = "InstallAndroidDependencies"; b.BuildLogFile = "install-deps.log"; - Assert.IsTrue (b.Build (proj, parameters: buildArgs.ToArray ()), "InstallAndroidDependencies should have succeeded."); + + // InstallAndroidDependencies downloads the Android SDK and JDK over the network, which + // can fail intermittently in CI. Retry a few times before giving up, starting from a + // clean SDK/JDK directory each attempt so a partial download does not affect the next. + // See https://github.com/dotnet/android/issues/11973 + const int maxInstallAttempts = 3; + bool installSucceeded = false; + for (int attempt = 1; attempt <= maxInstallAttempts; attempt++) { + foreach (var path in new [] { sdkPath, jdkPath }) { + if (Directory.Exists (path)) + Directory.Delete (path, recursive: true); + Directory.CreateDirectory (path); + } + + if (b.Build (proj, parameters: buildArgs.ToArray ())) { + installSucceeded = true; + break; + } + + TestContext.WriteLine ($"InstallAndroidDependencies attempt {attempt} of {maxInstallAttempts} failed. Please check the task output in 'install-deps.log'."); + if (attempt < maxInstallAttempts) + Thread.Sleep (TimeSpan.FromSeconds (10)); + } + Assert.IsTrue (installSucceeded, $"InstallAndroidDependencies should have succeeded within {maxInstallAttempts} attempts."); // When dependencies can not be resolved/installed a warning will be present in build output: // Dependency `platform-tools` should have been installed but could not be resolved.