Connectivity metrics: log DnsEvents in-band

This patch changes how DnsEvents are logged in IpConnectivityMetrics.
The following changes are made:
 - DnsEventBatch are not logged after 100 queries on the same network
    - this allows to merge DnsEvent and DnsEventBatch into one class
 - DnsEventBatch are not logged after a network disconnect
    - this allows to remove the NetworkCallback
 - DnsEvent are now logged similarly to ConnectStats when statistics are
   flushed, in a direct call from IpConnectivityMetrics into
   NetdEventListenerService, in a direct call from IpConnectivityMetrics
   into NetdEventListenerService.
    - this allows to remove the Parcelable implementation of DnsEvent
 - transports information is added to DnsEvent.

Test: - simplified NetdEventListenerServiceTest covering dns logging
      - updated IpConnectivityEventBuilderTest
      - updated IpConnectivityMetricsTest
      - $ runtest frameworks-net passes
      - manually verified $ adb shell dumpsys connmetrics list proto
Bug: 34901696
Change-Id: I4fcd0ad7a7b85d587647f471a90c1e53a18fc95a
Merged-In: Ia4b33fd4212741152662a2adbb0533bd1b4902ee

(cherry picked from commit 0699cf98042a64e41ee076c464eb115a6579be08)
This commit is contained in:
Hugo Benichi
2017-03-22 22:21:44 +09:00
parent 45670bb37d
commit c8ed8fba88
3 changed files with 195 additions and 268 deletions

View File

@@ -57,7 +57,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
aType(IpReachabilityEvent.class),
anInt(IpReachabilityEvent.NUD_FAILED));
String want = joinLines(
String want = String.join("\n",
"dropped_events: 0",
"events <",
" if_name: \"\"",
@@ -70,13 +70,13 @@ public class IpConnectivityEventBuilderTest extends TestCase {
" if_name: \"\"",
" >",
">",
"version: 2");
"version: 2\n");
verifySerialization(want, ev);
ev.netId = 123;
ev.transports = 3; // transports have priority for inferrence of link layer
ev.ifname = "wlan0";
want = joinLines(
want = String.join("\n",
"dropped_events: 0",
"events <",
" if_name: \"\"",
@@ -89,12 +89,12 @@ public class IpConnectivityEventBuilderTest extends TestCase {
" if_name: \"\"",
" >",
">",
"version: 2");
"version: 2\n");
verifySerialization(want, ev);
ev.transports = 1;
ev.ifname = null;
want = joinLines(
want = String.join("\n",
"dropped_events: 0",
"events <",
" if_name: \"\"",
@@ -107,12 +107,12 @@ public class IpConnectivityEventBuilderTest extends TestCase {
" if_name: \"\"",
" >",
">",
"version: 2");
"version: 2\n");
verifySerialization(want, ev);
ev.transports = 0;
ev.ifname = "not_inferred";
want = joinLines(
want = String.join("\n",
"dropped_events: 0",
"events <",
" if_name: \"not_inferred\"",
@@ -125,11 +125,11 @@ public class IpConnectivityEventBuilderTest extends TestCase {
" if_name: \"\"",
" >",
">",
"version: 2");
"version: 2\n");
verifySerialization(want, ev);
ev.ifname = "bt-pan";
want = joinLines(
want = String.join("\n",
"dropped_events: 0",
"events <",
" if_name: \"\"",
@@ -142,11 +142,11 @@ public class IpConnectivityEventBuilderTest extends TestCase {
" if_name: \"\"",
" >",
">",
"version: 2");
"version: 2\n");
verifySerialization(want, ev);
ev.ifname = "rmnet_ipa0";
want = joinLines(
want = String.join("\n",
"dropped_events: 0",
"events <",
" if_name: \"\"",
@@ -159,11 +159,11 @@ public class IpConnectivityEventBuilderTest extends TestCase {
" if_name: \"\"",
" >",
">",
"version: 2");
"version: 2\n");
verifySerialization(want, ev);
ev.ifname = "wlan0";
want = joinLines(
want = String.join("\n",
"dropped_events: 0",
"events <",
" if_name: \"\"",
@@ -176,7 +176,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
" if_name: \"\"",
" >",
">",
"version: 2");
"version: 2\n");
verifySerialization(want, ev);
}
@@ -190,7 +190,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
aBool(true),
aBool(false));
String want = joinLines(
String want = String.join("\n",
"dropped_events: 0",
"events <",
" if_name: \"\"",
@@ -211,7 +211,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
" transport_types: 3",
" >",
">",
"version: 2");
"version: 2\n");
verifySerialization(want, ev);
}
@@ -223,7 +223,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
aString("SomeState"),
anInt(192));
String want = joinLines(
String want = String.join("\n",
"dropped_events: 0",
"events <",
" if_name: \"\"",
@@ -237,7 +237,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
" state_transition: \"SomeState\"",
" >",
">",
"version: 2");
"version: 2\n");
verifySerialization(want, ev);
}
@@ -248,7 +248,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
aType(DhcpErrorEvent.class),
anInt(DhcpErrorEvent.L4_NOT_UDP));
String want = joinLines(
String want = String.join("\n",
"dropped_events: 0",
"events <",
" if_name: \"\"",
@@ -262,59 +262,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
" error_code: 50397184",
" >",
">",
"version: 2");
verifySerialization(want, ev);
}
@SmallTest
public void testDnsEventSerialization() {
ConnectivityMetricsEvent ev = describeIpEvent(
aType(DnsEvent.class),
anInt(101),
aByteArray(b(1), b(1), b(2), b(1), b(1), b(1), b(2), b(2)),
aByteArray(b(0), b(0), b(22), b(3), b(1), b(0), b(200), b(178)),
anIntArray(3456, 267, 1230, 45, 2111, 450, 638, 1300));
String want = joinLines(
"dropped_events: 0",
"events <",
" if_name: \"\"",
" link_layer: 0",
" network_id: 0",
" time_ms: 1",
" transports: 0",
" dns_lookup_batch <",
" event_types: 1",
" event_types: 1",
" event_types: 2",
" event_types: 1",
" event_types: 1",
" event_types: 1",
" event_types: 2",
" event_types: 2",
" latencies_ms: 3456",
" latencies_ms: 267",
" latencies_ms: 1230",
" latencies_ms: 45",
" latencies_ms: 2111",
" latencies_ms: 450",
" latencies_ms: 638",
" latencies_ms: 1300",
" network_id <",
" network_id: 101",
" >",
" return_codes: 0",
" return_codes: 0",
" return_codes: 22",
" return_codes: 3",
" return_codes: 1",
" return_codes: 0",
" return_codes: 200",
" return_codes: 178",
" >",
">",
"version: 2");
"version: 2\n");
verifySerialization(want, ev);
}
@@ -326,7 +274,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
anInt(IpManagerEvent.PROVISIONING_OK),
aLong(5678));
String want = joinLines(
String want = String.join("\n",
"dropped_events: 0",
"events <",
" if_name: \"\"",
@@ -340,7 +288,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
" latency_ms: 5678",
" >",
">",
"version: 2");
"version: 2\n");
verifySerialization(want, ev);
}
@@ -351,7 +299,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
aType(IpReachabilityEvent.class),
anInt(IpReachabilityEvent.NUD_FAILED));
String want = joinLines(
String want = String.join("\n",
"dropped_events: 0",
"events <",
" if_name: \"\"",
@@ -364,7 +312,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
" if_name: \"\"",
" >",
">",
"version: 2");
"version: 2\n");
verifySerialization(want, ev);
}
@@ -377,7 +325,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
anInt(5),
aLong(20410));
String want = joinLines(
String want = String.join("\n",
"dropped_events: 0",
"events <",
" if_name: \"\"",
@@ -393,7 +341,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
" >",
" >",
">",
"version: 2");
"version: 2\n");
verifySerialization(want, ev);
}
@@ -406,7 +354,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
anInt(ValidationProbeEvent.PROBE_HTTP),
anInt(204));
String want = joinLines(
String want = String.join("\n",
"dropped_events: 0",
"events <",
" if_name: \"\"",
@@ -420,7 +368,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
" probe_type: 1",
" >",
">",
"version: 2");
"version: 2\n");
verifySerialization(want, ev);
}
@@ -436,7 +384,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
anInt(2048),
anInt(3));
String want = joinLines(
String want = String.join("\n",
"dropped_events: 0",
"events <",
" if_name: \"\"",
@@ -454,7 +402,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
" program_length: 2048",
" >",
">",
"version: 2");
"version: 2\n");
verifySerialization(want, ev);
}
@@ -474,7 +422,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
anInt(3),
anInt(2048));
String want = joinLines(
String want = String.join("\n",
"dropped_events: 0",
"events <",
" if_name: \"\"",
@@ -495,7 +443,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
" zero_lifetime_ras: 1",
" >",
">",
"version: 2");
"version: 2\n");
verifySerialization(want, ev);
}
@@ -511,7 +459,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
aLong(1000),
aLong(-1));
String want = joinLines(
String want = String.join("\n",
"dropped_events: 0",
"events <",
" if_name: \"\"",
@@ -528,7 +476,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
" router_lifetime: 2000",
" >",
">",
"version: 2");
"version: 2\n");
verifySerialization(want, ev);
}
@@ -543,13 +491,4 @@ public class IpConnectivityEventBuilderTest extends TestCase {
fail(e.toString());
}
}
static String joinLines(String ... elems) {
StringBuilder b = new StringBuilder();
for (String s : elems) {
b.append(s);
b.append("\n");
}
return b.toString();
}
}

View File

@@ -138,6 +138,7 @@ public class IpConnectivityMetricsTest extends TestCase {
}
@SmallTest
// TODO: add NetdEventListenerService coverage too
public void testEndToEndLogging() {
// TODO: instead of comparing textpb to textpb, parse textpb and compare proto to proto.
IpConnectivityLog logger = new IpConnectivityLog(mService.impl);
@@ -177,7 +178,7 @@ public class IpConnectivityMetricsTest extends TestCase {
logger.log(ev);
}
String want = joinLines(
String want = String.join("\n",
"dropped_events: 0",
"events <",
" if_name: \"\"",
@@ -279,7 +280,7 @@ public class IpConnectivityMetricsTest extends TestCase {
" router_lifetime: 2000",
" >",
">",
"version: 2");
"version: 2\n");
verifySerialization(want, getdump("flush"));
}

View File

@@ -16,161 +16,161 @@
package com.android.server.connectivity;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback;
import android.net.Network;
import android.net.metrics.ConnectStats;
import android.net.metrics.DnsEvent;
import android.net.metrics.INetdEventListener;
import android.net.metrics.IpConnectivityLog;
import android.os.Parcelable;
import android.os.RemoteException;
import android.system.OsConstants;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityEvent;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.OptionalInt;
import java.util.stream.IntStream;
import junit.framework.TestCase;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertTrue;
import static android.net.metrics.INetdEventListener.EVENT_GETADDRINFO;
import static android.net.metrics.INetdEventListener.EVENT_GETHOSTBYNAME;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.anyInt;
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;
public class NetdEventListenerServiceTest extends TestCase {
// TODO: read from NetdEventListenerService after this constant is read from system property
static final int BATCH_SIZE = 100;
static final int EVENT_TYPE = INetdEventListener.EVENT_GETADDRINFO;
// TODO: read from INetdEventListener
static final int RETURN_CODE = 1;
static final byte[] EVENT_TYPES = new byte[BATCH_SIZE];
static final byte[] RETURN_CODES = new byte[BATCH_SIZE];
static final int[] LATENCIES = new int[BATCH_SIZE];
static {
for (int i = 0; i < BATCH_SIZE; i++) {
EVENT_TYPES[i] = EVENT_TYPE;
RETURN_CODES[i] = RETURN_CODE;
LATENCIES[i] = i;
}
}
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.support.test.runner.AndroidJUnit4;
import android.system.OsConstants;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Base64;
import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.DNSLookupBatch;
import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityEvent;
import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityLog;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class NetdEventListenerServiceTest {
private static final String EXAMPLE_IPV4 = "192.0.2.1";
private static final String EXAMPLE_IPV6 = "2001:db8:1200::2:1";
NetdEventListenerService mNetdEventListenerService;
ConnectivityManager mCm;
@Mock ConnectivityManager mCm;
@Mock IpConnectivityLog mLog;
ArgumentCaptor<NetworkCallback> mCallbackCaptor;
ArgumentCaptor<DnsEvent> mDnsEvCaptor;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mCallbackCaptor = ArgumentCaptor.forClass(NetworkCallback.class);
mDnsEvCaptor = ArgumentCaptor.forClass(DnsEvent.class);
mNetdEventListenerService = new NetdEventListenerService(mCm, mLog);
verify(mCm, times(1)).registerNetworkCallback(any(), mCallbackCaptor.capture());
mCm = mock(ConnectivityManager.class);
mNetdEventListenerService = new NetdEventListenerService(mCm);
}
@SmallTest
public void testOneDnsBatch() throws Exception {
log(105, LATENCIES);
log(106, Arrays.copyOf(LATENCIES, BATCH_SIZE - 1)); // one lookup short of a batch event
@Test
public void testDnsLogging() throws Exception {
NetworkCapabilities ncWifi = new NetworkCapabilities();
NetworkCapabilities ncCell = new NetworkCapabilities();
ncWifi.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
ncCell.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
verifyLoggedDnsEvents(new DnsEvent(105, EVENT_TYPES, RETURN_CODES, LATENCIES));
when(mCm.getNetworkCapabilities(new Network(100))).thenReturn(ncWifi);
when(mCm.getNetworkCapabilities(new Network(101))).thenReturn(ncCell);
log(106, Arrays.copyOfRange(LATENCIES, BATCH_SIZE - 1, BATCH_SIZE));
dnsEvent(100, EVENT_GETADDRINFO, 0, 3456);
dnsEvent(100, EVENT_GETADDRINFO, 0, 267);
dnsEvent(100, EVENT_GETHOSTBYNAME, 22, 1230);
dnsEvent(100, EVENT_GETADDRINFO, 3, 45);
dnsEvent(100, EVENT_GETADDRINFO, 1, 2111);
dnsEvent(100, EVENT_GETADDRINFO, 0, 450);
dnsEvent(100, EVENT_GETHOSTBYNAME, 200, 638);
dnsEvent(100, EVENT_GETHOSTBYNAME, 178, 1300);
dnsEvent(101, EVENT_GETADDRINFO, 0, 56);
dnsEvent(101, EVENT_GETADDRINFO, 0, 78);
dnsEvent(101, EVENT_GETADDRINFO, 0, 14);
dnsEvent(101, EVENT_GETHOSTBYNAME, 0, 56);
dnsEvent(101, EVENT_GETADDRINFO, 0, 78);
dnsEvent(101, EVENT_GETADDRINFO, 0, 14);
mDnsEvCaptor = ArgumentCaptor.forClass(DnsEvent.class); // reset argument captor
verifyLoggedDnsEvents(
new DnsEvent(105, EVENT_TYPES, RETURN_CODES, LATENCIES),
new DnsEvent(106, EVENT_TYPES, RETURN_CODES, LATENCIES));
String got = flushStatistics();
String want = String.join("\n",
"dropped_events: 0",
"events <",
" if_name: \"\"",
" link_layer: 0",
" network_id: 0",
" time_ms: 0",
" transports: 0",
" connect_statistics <",
" connect_blocking_count: 0",
" connect_count: 0",
" ipv6_addr_count: 0",
" >",
">",
"events <",
" if_name: \"\"",
" link_layer: 4",
" network_id: 100",
" time_ms: 0",
" transports: 2",
" dns_lookup_batch <",
" event_types: 1",
" event_types: 1",
" event_types: 2",
" event_types: 1",
" event_types: 1",
" event_types: 1",
" event_types: 2",
" event_types: 2",
" latencies_ms: 3456",
" latencies_ms: 267",
" latencies_ms: 1230",
" latencies_ms: 45",
" latencies_ms: 2111",
" latencies_ms: 450",
" latencies_ms: 638",
" latencies_ms: 1300",
" return_codes: 0",
" return_codes: 0",
" return_codes: 22",
" return_codes: 3",
" return_codes: 1",
" return_codes: 0",
" return_codes: 200",
" return_codes: 178",
" >",
">",
"events <",
" if_name: \"\"",
" link_layer: 2",
" network_id: 101",
" time_ms: 0",
" transports: 1",
" dns_lookup_batch <",
" event_types: 1",
" event_types: 1",
" event_types: 1",
" event_types: 2",
" event_types: 1",
" event_types: 1",
" latencies_ms: 56",
" latencies_ms: 78",
" latencies_ms: 14",
" latencies_ms: 56",
" latencies_ms: 78",
" latencies_ms: 14",
" return_codes: 0",
" return_codes: 0",
" return_codes: 0",
" return_codes: 0",
" return_codes: 0",
" return_codes: 0",
" >",
">",
"version: 2\n");
assertEquals(want, got);
}
@SmallTest
public void testSeveralDmsBatches() throws Exception {
log(105, LATENCIES);
log(106, LATENCIES);
log(105, LATENCIES);
log(107, LATENCIES);
verifyLoggedDnsEvents(
new DnsEvent(105, EVENT_TYPES, RETURN_CODES, LATENCIES),
new DnsEvent(106, EVENT_TYPES, RETURN_CODES, LATENCIES),
new DnsEvent(105, EVENT_TYPES, RETURN_CODES, LATENCIES),
new DnsEvent(107, EVENT_TYPES, RETURN_CODES, LATENCIES));
}
@SmallTest
public void testDnsBatchAndNetworkLost() throws Exception {
byte[] eventTypes = Arrays.copyOf(EVENT_TYPES, 20);
byte[] returnCodes = Arrays.copyOf(RETURN_CODES, 20);
int[] latencies = Arrays.copyOf(LATENCIES, 20);
log(105, LATENCIES);
log(105, latencies);
mCallbackCaptor.getValue().onLost(new Network(105));
log(105, LATENCIES);
verifyLoggedDnsEvents(
new DnsEvent(105, eventTypes, returnCodes, latencies),
new DnsEvent(105, EVENT_TYPES, RETURN_CODES, LATENCIES),
new DnsEvent(105, EVENT_TYPES, RETURN_CODES, LATENCIES));
}
@SmallTest
public void testConcurrentDnsBatchesAndDumps() throws Exception {
final long stop = System.currentTimeMillis() + 100;
final PrintWriter pw = new PrintWriter(new FileOutputStream("/dev/null"));
new Thread() {
public void run() {
while (System.currentTimeMillis() < stop) {
mNetdEventListenerService.dump(pw);
}
}
}.start();
logDnsAsync(105, LATENCIES);
logDnsAsync(106, LATENCIES);
logDnsAsync(107, LATENCIES);
verifyLoggedDnsEvents(500,
new DnsEvent(105, EVENT_TYPES, RETURN_CODES, LATENCIES),
new DnsEvent(106, EVENT_TYPES, RETURN_CODES, LATENCIES),
new DnsEvent(107, EVENT_TYPES, RETURN_CODES, LATENCIES));
}
@SmallTest
public void testConcurrentDnsBatchesAndNetworkLoss() throws Exception {
logDnsAsync(105, LATENCIES);
Thread.sleep(10L);
// call onLost() asynchronously to logDnsAsync's onDnsEvent() calls.
mCallbackCaptor.getValue().onLost(new Network(105));
// do not verify batch with unpredictable length
verify(mLog, timeout(500).times(1)).log(any(Parcelable.class));
}
@SmallTest
@Test
public void testConnectLogging() throws Exception {
final int OK = 0;
Thread[] logActions = {
@@ -268,44 +268,18 @@ public class NetdEventListenerServiceTest extends TestCase {
});
}
void log(int netId, int[] latencies) {
try {
for (int l : latencies) {
mNetdEventListenerService.onDnsEvent(netId, EVENT_TYPE, RETURN_CODE, l, null, null,
0, 0);
}
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
void dnsEvent(int netId, int type, int result, int latency) throws Exception {
mNetdEventListenerService.onDnsEvent(netId, type, result, latency, "", null, 0, 0);
}
void logDnsAsync(int netId, int[] latencies) {
new Thread(() -> log(netId, latencies)).start();
Thread dumpAction(long durationMs) throws Exception {
final long stop = System.currentTimeMillis() + durationMs;
final PrintWriter pw = new PrintWriter(new FileOutputStream("/dev/null"));
return new Thread(() -> {
while (System.currentTimeMillis() < stop) {
mNetdEventListenerService.dump(pw);
}
void verifyLoggedDnsEvents(DnsEvent... expected) {
verifyLoggedDnsEvents(0, expected);
}
void verifyLoggedDnsEvents(int wait, DnsEvent... expectedEvents) {
verify(mLog, timeout(wait).times(expectedEvents.length)).log(mDnsEvCaptor.capture());
for (DnsEvent got : mDnsEvCaptor.getAllValues()) {
OptionalInt index = IntStream.range(0, expectedEvents.length)
.filter(i -> dnsEventsEqual(expectedEvents[i], got))
.findFirst();
// Don't match same expected event more than once.
index.ifPresent(i -> expectedEvents[i] = null);
assertTrue(index.isPresent());
}
}
/** equality function for DnsEvent to avoid overriding equals() and hashCode(). */
static boolean dnsEventsEqual(DnsEvent expected, DnsEvent got) {
return (expected == got) || ((expected != null) && (got != null)
&& (expected.netId == got.netId)
&& Arrays.equals(expected.eventTypes, got.eventTypes)
&& Arrays.equals(expected.returnCodes, got.returnCodes)
&& Arrays.equals(expected.latenciesMs, got.latenciesMs));
});
}
static void verifyConnectEvent(String expected, IpConnectivityEvent got) {
@@ -318,4 +292,17 @@ public class NetdEventListenerServiceTest extends TestCase {
fail(e.toString());
}
}
// TODO: instead of comparing textpb to textpb, parse textpb and compare proto to proto.
String flushStatistics() throws Exception {
IpConnectivityMetrics metricsService =
new IpConnectivityMetrics(mock(Context.class), (ctx) -> 2000);
metricsService.mNetdListener = mNetdEventListenerService;
StringWriter buffer = new StringWriter();
PrintWriter writer = new PrintWriter(buffer);
metricsService.impl.dump(null, writer, new String[]{"flush"});
byte[] bytes = Base64.decode(buffer.toString(), Base64.DEFAULT);
return IpConnectivityLog.parseFrom(bytes).toString();
}
}