Fix TetheringServiceTest#testTetheringManagerLeak flaky
The clearance of the weak reference to TetheringManager can't be a
confirmation check of the completion running of its finalization.
The weak references to a weakly-reachable object will be cleared
before it becomes eligible for finalization. Calling of
System.runFinalization() method doesn't guarantee finalizers are
executed synchronously. In fact, finalizer of TetheringManager is
running in a different thread in this test.
GCs and finalizers behaviors could be vary on different JVMs.
Due to the unsynchronization, besides the weak reference of
TetheringManager, we need to add retries to the checking of
unregister Tethering internal callback as well.
Bug: 243340454
Test: atest TetheringServiceTest#testTetheringManagerLeak --iterations 10000
Change-Id: I8231146f26deb0825dadb70d8d0dbdc963989558
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java
index e114cb5..38f1e9c 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java
@@ -664,17 +664,17 @@
assertEquals("Internal callback is not registered", 1, callbacks.size());
assertNotNull(weakTm.get());
+ // Calling System.gc() or System.runFinalization() doesn't guarantee GCs or finalizers
+ // are executed synchronously. The finalizer is called after GC on a separate thread.
final int attempts = 100;
final long waitIntervalMs = 50;
for (int i = 0; i < attempts; i++) {
forceGc();
- if (weakTm.get() == null) break;
+ if (weakTm.get() == null && callbacks.size() == 0) break;
Thread.sleep(waitIntervalMs);
}
- assertNull("TetheringManager weak reference still not null after " + attempts
- + " attempts", weakTm.get());
-
+ assertNull("TetheringManager weak reference is not null", weakTm.get());
assertEquals("Internal callback is not unregistered", 0, callbacks.size());
});
}