Fix testKeyValue_Concurrency flakyness
Bug: 131132243
Test: atest 'LockSettingsStorageTests#testKeyValue_Concurrency'
Change-Id: If14b6fe63ea57837ac3d594c5219b4eb5839002a
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
index 8af4edd..18453aa 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
@@ -27,6 +27,7 @@
import android.content.pm.UserInfo;
import android.database.sqlite.SQLiteDatabase;
import android.os.FileUtils;
+import android.os.SystemClock;
import android.os.UserManager;
import android.os.storage.StorageManager;
import android.platform.test.annotations.Presubmit;
@@ -125,7 +126,7 @@
List<Thread> threads = new ArrayList<>();
for (int i = 0; i < 100; i++) {
final int threadId = i;
- threads.add(new Thread() {
+ threads.add(new Thread("testKeyValue_Concurrency_" + i) {
@Override
public void run() {
synchronized (monitor) {
@@ -134,17 +135,17 @@
} catch (InterruptedException e) {
return;
}
- mStorage.writeKeyValue("key", "1 from thread " + threadId, 0);
- mStorage.readKeyValue("key", "default", 0);
- mStorage.writeKeyValue("key", "2 from thread " + threadId, 0);
- mStorage.readKeyValue("key", "default", 0);
- mStorage.writeKeyValue("key", "3 from thread " + threadId, 0);
- mStorage.readKeyValue("key", "default", 0);
- mStorage.writeKeyValue("key", "4 from thread " + threadId, 0);
- mStorage.readKeyValue("key", "default", 0);
- mStorage.writeKeyValue("key", "5 from thread " + threadId, 0);
- mStorage.readKeyValue("key", "default", 0);
}
+ mStorage.writeKeyValue("key", "1 from thread " + threadId, 0);
+ mStorage.readKeyValue("key", "default", 0);
+ mStorage.writeKeyValue("key", "2 from thread " + threadId, 0);
+ mStorage.readKeyValue("key", "default", 0);
+ mStorage.writeKeyValue("key", "3 from thread " + threadId, 0);
+ mStorage.readKeyValue("key", "default", 0);
+ mStorage.writeKeyValue("key", "4 from thread " + threadId, 0);
+ mStorage.readKeyValue("key", "default", 0);
+ mStorage.writeKeyValue("key", "5 from thread " + threadId, 0);
+ mStorage.readKeyValue("key", "default", 0);
}
});
threads.get(i).start();
@@ -153,12 +154,7 @@
synchronized (monitor) {
monitor.notifyAll();
}
- for (int i = 0; i < threads.size(); i++) {
- try {
- threads.get(i).join();
- } catch (InterruptedException e) {
- }
- }
+ joinAll(threads, 10000);
assertEquals('5', mStorage.readKeyValue("key", "default", 0).charAt(0));
mStorage.clearCache();
assertEquals('5', mStorage.readKeyValue("key", "default", 0).charAt(0));
@@ -515,4 +511,29 @@
}
return captured[0];
}
+
+ private static void joinAll(List<Thread> threads, long timeoutMillis) {
+ long deadline = SystemClock.uptimeMillis() + timeoutMillis;
+ for (Thread t : threads) {
+ try {
+ t.join(deadline - SystemClock.uptimeMillis());
+ if (t.isAlive()) {
+ t.interrupt();
+ throw new RuntimeException(
+ "Joining " + t + " timed out. Stack: \n" + getStack(t));
+ }
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Interrupted while joining " + t, e);
+ }
+ }
+ }
+
+ private static String getStack(Thread t) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(t.toString()).append('\n');
+ for (StackTraceElement ste : t.getStackTrace()) {
+ sb.append("\tat ").append(ste.toString()).append('\n');
+ }
+ return sb.toString();
+ }
}