Merge "Networking unit tests: fix some flaky tests"
This commit is contained in:
@@ -349,7 +349,6 @@ public class NsdManagerTest {
|
||||
chan.connect(mContext, this, msg.replyTo);
|
||||
chan.sendMessage(AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static MockServiceHandler create(Context context) {
|
||||
|
||||
@@ -33,8 +33,8 @@ import java.util.Vector;
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@SmallTest
|
||||
public class SharedLogTest {
|
||||
private static final String TIMESTAMP_PATTERN = "\\d{2}:\\d{2}:\\d{2}\\.\\d{3}";
|
||||
private static final String TIMESTAMP = "HH:MM:SS.xxx";
|
||||
private static final String TIMESTAMP_PATTERN = "\\d{2}:\\d{2}:\\d{2}";
|
||||
private static final String TIMESTAMP = "HH:MM:SS";
|
||||
|
||||
@Test
|
||||
public void testBasicOperation() {
|
||||
@@ -85,7 +85,7 @@ public class SharedLogTest {
|
||||
String got = lines[i];
|
||||
String want = expected[i];
|
||||
assertTrue(String.format("'%s' did not contain '%s'", got, want), got.endsWith(want));
|
||||
assertTrue(String.format("'%s' did not contain a HH:MM:SS.xxx timestamp", got),
|
||||
assertTrue(String.format("'%s' did not contain a %s timestamp", got, TIMESTAMP),
|
||||
got.replaceFirst(TIMESTAMP_PATTERN, TIMESTAMP).contains(TIMESTAMP));
|
||||
}
|
||||
}
|
||||
|
||||
54
tests/net/java/com/android/internal/util/TestUtils.java
Normal file
54
tests/net/java/com/android/internal/util/TestUtils.java
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.internal.util;
|
||||
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import android.os.ConditionVariable;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.Looper;
|
||||
|
||||
public final class TestUtils {
|
||||
private TestUtils() { }
|
||||
|
||||
/**
|
||||
* Block until the given Handler thread becomes idle, or until timeoutMs has passed.
|
||||
*/
|
||||
public static void waitForIdleHandler(HandlerThread handlerThread, long timeoutMs) {
|
||||
// TODO: convert to getThreadHandler once it is available on aosp
|
||||
waitForIdleLooper(handlerThread.getLooper(), timeoutMs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Block until the given Looper becomes idle, or until timeoutMs has passed.
|
||||
*/
|
||||
public static void waitForIdleLooper(Looper looper, long timeoutMs) {
|
||||
waitForIdleHandler(new Handler(looper), timeoutMs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Block until the given Handler becomes idle, or until timeoutMs has passed.
|
||||
*/
|
||||
public static void waitForIdleHandler(Handler handler, long timeoutMs) {
|
||||
final ConditionVariable cv = new ConditionVariable();
|
||||
handler.post(() -> cv.open());
|
||||
if (!cv.block(timeoutMs)) {
|
||||
fail(handler.toString() + " did not become idle after " + timeoutMs + " ms");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,8 @@ import static android.net.ConnectivityManager.TYPE_WIFI;
|
||||
import static android.net.ConnectivityManager.getNetworkTypeName;
|
||||
import static android.net.NetworkCapabilities.*;
|
||||
|
||||
import static com.android.internal.util.TestUtils.waitForIdleHandler;
|
||||
|
||||
import static org.mockito.Mockito.anyBoolean;
|
||||
import static org.mockito.Mockito.anyInt;
|
||||
import static org.mockito.Mockito.eq;
|
||||
@@ -211,20 +213,8 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Block until the given handler becomes idle, or until timeoutMs has passed.
|
||||
*/
|
||||
private static void waitForIdleHandler(HandlerThread handlerThread, int timeoutMs) {
|
||||
final ConditionVariable cv = new ConditionVariable();
|
||||
final Handler handler = new Handler(handlerThread.getLooper());
|
||||
handler.post(() -> cv.open());
|
||||
if (!cv.block(timeoutMs)) {
|
||||
fail("HandlerThread " + handlerThread.getName() +
|
||||
" did not become idle after " + timeoutMs + " ms");
|
||||
}
|
||||
}
|
||||
|
||||
public void waitForIdle(int timeoutMs) {
|
||||
public void waitForIdle(int timeoutMsAsInt) {
|
||||
long timeoutMs = timeoutMsAsInt;
|
||||
waitForIdleHandler(mService.mHandlerThread, timeoutMs);
|
||||
waitForIdle(mCellNetworkAgent, timeoutMs);
|
||||
waitForIdle(mWiFiNetworkAgent, timeoutMs);
|
||||
@@ -232,7 +222,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
||||
waitForIdleHandler(mService.mHandlerThread, timeoutMs);
|
||||
}
|
||||
|
||||
public void waitForIdle(MockNetworkAgent agent, int timeoutMs) {
|
||||
public void waitForIdle(MockNetworkAgent agent, long timeoutMs) {
|
||||
if (agent == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@ import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
|
||||
import static android.net.TrafficStats.MB_IN_BYTES;
|
||||
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
|
||||
|
||||
import static com.android.internal.util.TestUtils.waitForIdleHandler;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
@@ -56,7 +58,6 @@ import android.util.ArrayMap;
|
||||
|
||||
import com.android.internal.net.VpnInfo;
|
||||
import com.android.server.net.NetworkStatsService;
|
||||
import com.android.server.net.NetworkStatsServiceTest.IdleableHandlerThread;
|
||||
import com.android.server.net.NetworkStatsServiceTest.LatchedHandler;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -102,7 +103,7 @@ public class NetworkStatsObserversTest {
|
||||
|
||||
private long mElapsedRealtime;
|
||||
|
||||
private IdleableHandlerThread mObserverHandlerThread;
|
||||
private HandlerThread mObserverHandlerThread;
|
||||
private Handler mObserverNoopHandler;
|
||||
|
||||
private LatchedHandler mHandler;
|
||||
@@ -118,7 +119,7 @@ public class NetworkStatsObserversTest {
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mObserverHandlerThread = new IdleableHandlerThread("HandlerThread");
|
||||
mObserverHandlerThread = new HandlerThread("HandlerThread");
|
||||
mObserverHandlerThread.start();
|
||||
final Looper observerLooper = mObserverHandlerThread.getLooper();
|
||||
mStatsObservers = new NetworkStatsObservers() {
|
||||
@@ -319,7 +320,7 @@ public class NetworkStatsObserversTest {
|
||||
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
|
||||
VPN_INFO, TEST_START);
|
||||
waitForObserverToIdle();
|
||||
assertEquals(NetworkStatsManager.CALLBACK_LIMIT_REACHED, mHandler.mLastMessageType);
|
||||
assertEquals(NetworkStatsManager.CALLBACK_LIMIT_REACHED, mHandler.lastMessageType);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -356,7 +357,7 @@ public class NetworkStatsObserversTest {
|
||||
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
|
||||
VPN_INFO, TEST_START);
|
||||
waitForObserverToIdle();
|
||||
assertEquals(NetworkStatsManager.CALLBACK_LIMIT_REACHED, mHandler.mLastMessageType);
|
||||
assertEquals(NetworkStatsManager.CALLBACK_LIMIT_REACHED, mHandler.lastMessageType);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -429,7 +430,7 @@ public class NetworkStatsObserversTest {
|
||||
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
|
||||
VPN_INFO, TEST_START);
|
||||
waitForObserverToIdle();
|
||||
assertEquals(NetworkStatsManager.CALLBACK_LIMIT_REACHED, mHandler.mLastMessageType);
|
||||
assertEquals(NetworkStatsManager.CALLBACK_LIMIT_REACHED, mHandler.lastMessageType);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -470,19 +471,7 @@ public class NetworkStatsObserversTest {
|
||||
}
|
||||
|
||||
private void waitForObserverToIdle() {
|
||||
waitForIdleLooper(mObserverHandlerThread.getLooper(), WAIT_TIMEOUT_MS);
|
||||
waitForIdleLooper(mHandler.getLooper(), WAIT_TIMEOUT_MS);
|
||||
waitForIdleHandler(mObserverHandlerThread, WAIT_TIMEOUT_MS);
|
||||
waitForIdleHandler(mHandler, WAIT_TIMEOUT_MS);
|
||||
}
|
||||
|
||||
// TODO: unify with ConnectivityService.waitForIdleHandler and
|
||||
// NetworkServiceStatsTest.IdleableHandlerThread
|
||||
private static void waitForIdleLooper(Looper looper, long timeoutMs) {
|
||||
final ConditionVariable cv = new ConditionVariable();
|
||||
final Handler handler = new Handler(looper);
|
||||
handler.post(() -> cv.open());
|
||||
if (!cv.block(timeoutMs)) {
|
||||
fail("Looper did not become idle after " + timeoutMs + " ms");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
|
||||
import static android.text.format.DateUtils.WEEK_IN_MILLIS;
|
||||
|
||||
import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_POLL;
|
||||
import static com.android.internal.util.TestUtils.waitForIdleHandler;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
@@ -154,7 +155,7 @@ public class NetworkStatsServiceTest {
|
||||
private @Mock IConnectivityManager mConnManager;
|
||||
private @Mock IBinder mBinder;
|
||||
private @Mock AlarmManager mAlarmManager;
|
||||
private IdleableHandlerThread mHandlerThread;
|
||||
private HandlerThread mHandlerThread;
|
||||
private Handler mHandler;
|
||||
|
||||
private NetworkStatsService mService;
|
||||
@@ -181,7 +182,7 @@ public class NetworkStatsServiceTest {
|
||||
mServiceContext, mNetManager, mAlarmManager, wakeLock, mTime,
|
||||
TelephonyManager.getDefault(), mSettings, new NetworkStatsObservers(),
|
||||
mStatsDir, getBaseDir(mStatsDir));
|
||||
mHandlerThread = new IdleableHandlerThread("HandlerThread");
|
||||
mHandlerThread = new HandlerThread("HandlerThread");
|
||||
mHandlerThread.start();
|
||||
Handler.Callback callback = new NetworkStatsService.HandlerCallback(mService);
|
||||
mHandler = new Handler(mHandlerThread.getLooper(), callback);
|
||||
@@ -886,7 +887,7 @@ public class NetworkStatsServiceTest {
|
||||
|
||||
// Send dummy message to make sure that any previous message has been handled
|
||||
mHandler.sendMessage(mHandler.obtainMessage(-1));
|
||||
mHandlerThread.waitForIdle(WAIT_TIMEOUT);
|
||||
waitForIdleHandler(mHandler, WAIT_TIMEOUT);
|
||||
|
||||
|
||||
|
||||
@@ -908,7 +909,7 @@ public class NetworkStatsServiceTest {
|
||||
assertNetworkTotal(sTemplateWifi, 1024L, 1L, 2048L, 2L, 0);
|
||||
|
||||
// make sure callback has not being called
|
||||
assertEquals(INVALID_TYPE, latchedHandler.mLastMessageType);
|
||||
assertEquals(INVALID_TYPE, latchedHandler.lastMessageType);
|
||||
|
||||
// and bump forward again, with counters going higher. this is
|
||||
// important, since it will trigger the data usage callback
|
||||
@@ -926,7 +927,7 @@ public class NetworkStatsServiceTest {
|
||||
|
||||
// Wait for the caller to ack receipt of CALLBACK_LIMIT_REACHED
|
||||
assertTrue(cv.block(WAIT_TIMEOUT));
|
||||
assertEquals(NetworkStatsManager.CALLBACK_LIMIT_REACHED, latchedHandler.mLastMessageType);
|
||||
assertEquals(NetworkStatsManager.CALLBACK_LIMIT_REACHED, latchedHandler.lastMessageType);
|
||||
cv.close();
|
||||
|
||||
// Allow binder to disconnect
|
||||
@@ -937,7 +938,7 @@ public class NetworkStatsServiceTest {
|
||||
|
||||
// Wait for the caller to ack receipt of CALLBACK_RELEASED
|
||||
assertTrue(cv.block(WAIT_TIMEOUT));
|
||||
assertEquals(NetworkStatsManager.CALLBACK_RELEASED, latchedHandler.mLastMessageType);
|
||||
assertEquals(NetworkStatsManager.CALLBACK_RELEASED, latchedHandler.lastMessageType);
|
||||
|
||||
// Make sure that the caller binder gets disconnected
|
||||
verify(mBinder).unlinkToDeath(any(IBinder.DeathRecipient.class), anyInt());
|
||||
@@ -1203,12 +1204,12 @@ public class NetworkStatsServiceTest {
|
||||
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
|
||||
// Send dummy message to make sure that any previous message has been handled
|
||||
mHandler.sendMessage(mHandler.obtainMessage(-1));
|
||||
mHandlerThread.waitForIdle(WAIT_TIMEOUT);
|
||||
waitForIdleHandler(mHandler, WAIT_TIMEOUT);
|
||||
}
|
||||
|
||||
static class LatchedHandler extends Handler {
|
||||
private final ConditionVariable mCv;
|
||||
int mLastMessageType = INVALID_TYPE;
|
||||
int lastMessageType = INVALID_TYPE;
|
||||
|
||||
LatchedHandler(Looper looper, ConditionVariable cv) {
|
||||
super(looper);
|
||||
@@ -1217,49 +1218,9 @@ public class NetworkStatsServiceTest {
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
mLastMessageType = msg.what;
|
||||
lastMessageType = msg.what;
|
||||
mCv.open();
|
||||
super.handleMessage(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A subclass of HandlerThread that allows callers to wait for it to become idle. waitForIdle
|
||||
* will return immediately if the handler is already idle.
|
||||
*/
|
||||
static class IdleableHandlerThread extends HandlerThread {
|
||||
private IdleHandler mIdleHandler;
|
||||
|
||||
public IdleableHandlerThread(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public void waitForIdle(long timeoutMs) {
|
||||
final ConditionVariable cv = new ConditionVariable();
|
||||
final MessageQueue queue = getLooper().getQueue();
|
||||
|
||||
synchronized (queue) {
|
||||
if (queue.isIdle()) {
|
||||
return;
|
||||
}
|
||||
|
||||
assertNull("BUG: only one idle handler allowed", mIdleHandler);
|
||||
mIdleHandler = new IdleHandler() {
|
||||
public boolean queueIdle() {
|
||||
cv.open();
|
||||
mIdleHandler = null;
|
||||
return false; // Remove the handler.
|
||||
}
|
||||
};
|
||||
queue.addIdleHandler(mIdleHandler);
|
||||
}
|
||||
|
||||
if (!cv.block(timeoutMs)) {
|
||||
fail("HandlerThread " + getName() + " did not become idle after " + timeoutMs
|
||||
+ " ms");
|
||||
queue.removeIdleHandler(mIdleHandler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user