summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Hugo Benichi <hugobenichi@google.com> 2016-05-30 14:42:29 +0900
committer Hugo Benichi <hugobenichi@google.com> 2016-06-28 11:43:03 +0900
commit3bba249c4711b10b2ba5335c7b6653dc570aae64 (patch)
tree8f8fa8be3f0cf5fd24d5552322bf8236840ebe9c
parent2cd8281a236a9c58bfdb22ce1e2e37303fdcd987 (diff)
Tests for IpConnectivityMetricsLog
Bug: 28204408 Bug: 29035129 Change-Id: I429562a00904188947b11da9928ec5c01296ff97
-rw-r--r--core/java/android/net/ConnectivityMetricsLogger.java15
-rw-r--r--core/java/android/net/metrics/IpConnectivityLog.java13
-rw-r--r--services/tests/servicestests/src/android/net/metrics/IpConnectivityLogTest.java165
3 files changed, 188 insertions, 5 deletions
diff --git a/core/java/android/net/ConnectivityMetricsLogger.java b/core/java/android/net/ConnectivityMetricsLogger.java
index 73734958f512..029c5bdccd41 100644
--- a/core/java/android/net/ConnectivityMetricsLogger.java
+++ b/core/java/android/net/ConnectivityMetricsLogger.java
@@ -23,6 +23,8 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;
+import com.android.internal.annotations.VisibleForTesting;
+
/** {@hide} */
@SystemApi
public class ConnectivityMetricsLogger {
@@ -49,8 +51,14 @@ public class ConnectivityMetricsLogger {
private int mNumSkippedEvents;
public ConnectivityMetricsLogger() {
- mService = IConnectivityMetricsLogger.Stub.asInterface(ServiceManager.getService(
- CONNECTIVITY_METRICS_LOGGER_SERVICE));
+ this(IConnectivityMetricsLogger.Stub.asInterface(
+ ServiceManager.getService(CONNECTIVITY_METRICS_LOGGER_SERVICE)));
+ }
+
+ /** {@hide} */
+ @VisibleForTesting
+ public ConnectivityMetricsLogger(IConnectivityMetricsLogger service) {
+ mService = service;
}
/**
@@ -153,11 +161,10 @@ public class ConnectivityMetricsLogger {
public boolean unregister(PendingIntent newEventsIntent) {
try {
mService.unregister(newEventsIntent);
+ return true;
} catch (RemoteException e) {
Log.e(TAG, "IConnectivityMetricsLogger.unregister", e);
return false;
}
-
- return true;
}
}
diff --git a/core/java/android/net/metrics/IpConnectivityLog.java b/core/java/android/net/metrics/IpConnectivityLog.java
index 233ff74a145b..0126a8793111 100644
--- a/core/java/android/net/metrics/IpConnectivityLog.java
+++ b/core/java/android/net/metrics/IpConnectivityLog.java
@@ -18,18 +18,29 @@ package android.net.metrics;
import android.net.ConnectivityMetricsEvent;
import android.net.ConnectivityMetricsLogger;
+import android.net.IConnectivityMetricsLogger;
import android.os.Parcelable;
import android.os.RemoteException;
import android.util.Log;
+import com.android.internal.annotations.VisibleForTesting;
+
/**
* Specialization of the ConnectivityMetricsLogger class for recording IP connectivity events.
* {@hide}
*/
-class IpConnectivityLog extends ConnectivityMetricsLogger {
+public class IpConnectivityLog extends ConnectivityMetricsLogger {
private static String TAG = "IpConnectivityMetricsLogger";
private static final boolean DBG = false;
+ public IpConnectivityLog() {
+ }
+
+ @VisibleForTesting
+ public IpConnectivityLog(IConnectivityMetricsLogger service) {
+ super(service);
+ }
+
/**
* Log an IpConnectivity event. Contrary to logEvent(), this method does not
* keep track of skipped events and is thread-safe for callers.
diff --git a/services/tests/servicestests/src/android/net/metrics/IpConnectivityLogTest.java b/services/tests/servicestests/src/android/net/metrics/IpConnectivityLogTest.java
new file mode 100644
index 000000000000..17ac9fe3e282
--- /dev/null
+++ b/services/tests/servicestests/src/android/net/metrics/IpConnectivityLogTest.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2016, 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 android.net.metrics;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.net.ConnectivityMetricsEvent;
+import android.net.IConnectivityMetricsLogger;
+
+import junit.framework.TestCase;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.List;
+
+public class IpConnectivityLogTest extends TestCase {
+
+ static class FakeEvent extends IpConnectivityEvent implements Parcelable {
+ public int describeContents() { return 0; }
+ public void writeToParcel(Parcel p, int flag) { }
+ }
+ static final FakeEvent FAKE_EV = new FakeEvent();
+
+ @Mock IConnectivityMetricsLogger mService;
+ ArgumentCaptor<ConnectivityMetricsEvent> evCaptor;
+
+ IpConnectivityLog mLog;
+
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ evCaptor = ArgumentCaptor.forClass(ConnectivityMetricsEvent.class);
+ mLog = new IpConnectivityLog(mService);
+ }
+
+ public void testLogEvents() throws Exception {
+ assertTrue(mLog.log(1, FAKE_EV));
+ assertTrue(mLog.log(2, FAKE_EV));
+ assertTrue(mLog.log(3, FAKE_EV));
+
+ List<ConnectivityMetricsEvent> gotEvents = verifyEvents(3);
+ assertEventsEqual(expectedEvent(1), gotEvents.get(0));
+ assertEventsEqual(expectedEvent(2), gotEvents.get(1));
+ assertEventsEqual(expectedEvent(3), gotEvents.get(2));
+ }
+
+ public void testLogEventTriggerThrottling() throws Exception {
+ when(mService.logEvent(any())).thenReturn(1234L);
+
+ assertFalse(mLog.log(1, FAKE_EV));
+ }
+
+ public void testLogEventFails() throws Exception {
+ when(mService.logEvent(any())).thenReturn(-1L); // Error.
+
+ assertFalse(mLog.log(1, FAKE_EV));
+ }
+
+ public void testLogEventWhenThrottling() throws Exception {
+ when(mService.logEvent(any())).thenReturn(Long.MAX_VALUE); // Throttled
+
+ // No events are logged. The service is only called once
+ // After that, throttling state is maintained locally.
+ assertFalse(mLog.log(1, FAKE_EV));
+ assertFalse(mLog.log(2, FAKE_EV));
+
+ List<ConnectivityMetricsEvent> gotEvents = verifyEvents(1);
+ assertEventsEqual(expectedEvent(1), gotEvents.get(0));
+ }
+
+ public void testLogEventRecoverFromThrottling() throws Exception {
+ final long throttleTimeout = System.currentTimeMillis() + 50;
+ when(mService.logEvent(any())).thenReturn(throttleTimeout, 0L);
+
+ assertFalse(mLog.log(1, FAKE_EV));
+ new Thread() {
+ public void run() {
+ busySpinLog(FAKE_EV);
+ }
+ }.start();
+
+ List<ConnectivityMetricsEvent> gotEvents = verifyEvents(2, 200);
+ assertEventsEqual(expectedEvent(1), gotEvents.get(0));
+ assertEventsEqual(expectedEvent(2), gotEvents.get(1));
+ }
+
+ public void testLogEventRecoverFromThrottlingWithMultipleCallers() throws Exception {
+ final long throttleTimeout = System.currentTimeMillis() + 50;
+ when(mService.logEvent(any())).thenReturn(throttleTimeout, 0L);
+
+ assertFalse(mLog.log(1, FAKE_EV));
+ final int nCallers = 10;
+ for (int i = 0; i < nCallers; i++) {
+ new Thread() {
+ public void run() {
+ busySpinLog(FAKE_EV);
+ }
+ }.start();
+ }
+
+ List<ConnectivityMetricsEvent> gotEvents = verifyEvents(1 + nCallers, 200);
+ assertEventsEqual(expectedEvent(1), gotEvents.get(0));
+ for (int i = 0; i < nCallers; i++) {
+ assertEventsEqual(expectedEvent(2), gotEvents.get(1 + i));
+ }
+ }
+
+ void busySpinLog(Parcelable ev) {
+ final long timeout = 200;
+ final long stop = System.currentTimeMillis() + timeout;
+ try {
+ while (System.currentTimeMillis() < stop) {
+ if (mLog.log(2, FAKE_EV)) {
+ return;
+ }
+ Thread.sleep(10);
+ }
+ } catch (InterruptedException e) { }
+ }
+
+ List<ConnectivityMetricsEvent> verifyEvents(int n) throws Exception {
+ verify(mService, times(n)).logEvent(evCaptor.capture());
+ return evCaptor.getAllValues();
+ }
+
+ List<ConnectivityMetricsEvent> verifyEvents(int n, int timeoutMs) throws Exception {
+ verify(mService, timeout(timeoutMs).times(n)).logEvent(evCaptor.capture());
+ return evCaptor.getAllValues();
+ }
+
+ static ConnectivityMetricsEvent expectedEvent(int timestamp) {
+ return new ConnectivityMetricsEvent((long)timestamp, 0, 0, FAKE_EV);
+ }
+
+ /** Outer equality for ConnectivityMetricsEvent to avoid overriding equals() and hashCode(). */
+ static void assertEventsEqual(ConnectivityMetricsEvent expected, ConnectivityMetricsEvent got) {
+ assertEquals(expected.timestamp, got.timestamp);
+ assertEquals(expected.componentTag, got.componentTag);
+ assertEquals(expected.eventTag, got.eventTag);
+ assertEquals(expected.data, got.data);
+ }
+}