Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,59 @@ public void AssertHasDevices (bool fail = true)
}
}

/// <summary>
/// Probes the Android package manager service the same way `bundletool build-apks
/// --connected-device` (which runs `pm list features`) and `adb install` do. On CI the
/// emulator's system_server sometimes wedges while `adb shell echo OK` still succeeds, so
/// <see cref="IsDeviceAttached"/> reports the device as healthy even though every subsequent
/// build/install fails deep inside a test with a cryptic
/// "Failure calling service package: Broken pipe" (XABAS0000). Retries a few times so a
/// momentary hiccup does not trigger an unnecessary emulator restart.
/// </summary>
protected static bool IsPackageManagerResponsive (out string diagnostic)
{
string output = "";
for (int attempt = 0; attempt < 3; attempt++) {
output = (RunAdbCommand ("shell pm list features", timeout: 30) ?? "").Trim ();
bool broken = output.Contains ("Failure calling service", StringComparison.OrdinalIgnoreCase) ||
output.Contains ("Broken pipe", StringComparison.OrdinalIgnoreCase) ||
output.Contains ("Can't find service", StringComparison.OrdinalIgnoreCase);
// A responsive package service always lists the framework's own features.
if (!broken && output.Contains ("feature:", StringComparison.OrdinalIgnoreCase)) {
diagnostic = output;
return true;
}
WaitFor ((int) TimeSpan.FromSeconds (2).TotalMilliseconds);
}
Comment thread
simonrozsival marked this conversation as resolved.
diagnostic = output;
return false;
}

/// <summary>
/// Fails fast, with a clear reason, when the emulator's package manager service is
/// unusable — instead of letting the app build/install fail cryptically later and
/// reporting an emulator crash as N unrelated test failures. Attempts one emulator
/// restart first; if the service is still broken the run is marked inconclusive
/// (an infrastructure problem, not a product regression).
/// </summary>
protected void AssertPackageManagerResponsive ()
{
if (IsPackageManagerResponsive (out _)) {
return;
}

TestContext.Out.WriteLine ("Android package manager service is unresponsive; restarting the emulator.");
RestartDevice ();
AssertHasDevices ();

if (!IsPackageManagerResponsive (out string diagnostic)) {
Assert.Inconclusive (
"Android package manager service is unresponsive even after restarting the emulator " +
"(system_server likely crashed). Skipping so an emulator failure is not reported as a test failure. " +
$"Last 'adb shell pm list features' output: {diagnostic}");
}
Comment thread
simonrozsival marked this conversation as resolved.
}

[OneTimeSetUp]
public void DeviceSetup ()
{
Expand Down Expand Up @@ -126,6 +179,11 @@ public virtual void SetupTest ()
AssertHasDevices ();
}

// `adb shell echo OK` can succeed while the package manager service is wedged, so
// verify it is responsive before a test wastes time building/installing an app that
// would otherwise fail with a cryptic "Failure calling service package" error.
AssertPackageManagerResponsive ();

// We want to start with a clean logcat buffer for each test
ClearAdbLogcat ();
}
Expand Down