diff --git a/services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityEventBuilderTest.java b/services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityEventBuilderTest.java index 84f0f9040b..011e505c46 100644 --- a/services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityEventBuilderTest.java +++ b/services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityEventBuilderTest.java @@ -16,6 +16,17 @@ package com.android.server.connectivity; +import static com.android.server.connectivity.MetricsTestUtil.aBool; +import static com.android.server.connectivity.MetricsTestUtil.aByteArray; +import static com.android.server.connectivity.MetricsTestUtil.aLong; +import static com.android.server.connectivity.MetricsTestUtil.aString; +import static com.android.server.connectivity.MetricsTestUtil.aType; +import static com.android.server.connectivity.MetricsTestUtil.anInt; +import static com.android.server.connectivity.MetricsTestUtil.anIntArray; +import static com.android.server.connectivity.MetricsTestUtil.b; +import static com.android.server.connectivity.MetricsTestUtil.describeIpEvent; +import static com.android.server.connectivity.metrics.IpConnectivityLogClass.IpConnectivityLog; + import android.net.ConnectivityMetricsEvent; import android.net.metrics.ApfProgramEvent; import android.net.metrics.ApfStats; @@ -28,24 +39,13 @@ import android.net.metrics.IpReachabilityEvent; import android.net.metrics.NetworkEvent; import android.net.metrics.RaEvent; import android.net.metrics.ValidationProbeEvent; -import com.google.protobuf.nano.MessageNano; +import android.test.suitebuilder.annotation.SmallTest; import java.util.Arrays; import junit.framework.TestCase; -import static com.android.server.connectivity.metrics.IpConnectivityLogClass.IpConnectivityLog; -import static com.android.server.connectivity.MetricsTestUtil.aBool; -import static com.android.server.connectivity.MetricsTestUtil.aByteArray; -import static com.android.server.connectivity.MetricsTestUtil.aLong; -import static com.android.server.connectivity.MetricsTestUtil.aString; -import static com.android.server.connectivity.MetricsTestUtil.aType; -import static com.android.server.connectivity.MetricsTestUtil.anInt; -import static com.android.server.connectivity.MetricsTestUtil.anIntArray; -import static com.android.server.connectivity.MetricsTestUtil.b; -import static com.android.server.connectivity.MetricsTestUtil.describeIpEvent; -import static com.android.server.connectivity.MetricsTestUtil.ipEv; - public class IpConnectivityEventBuilderTest extends TestCase { + @SmallTest public void testDefaultNetworkEventSerialization() { ConnectivityMetricsEvent ev = describeIpEvent( aType(DefaultNetworkEvent.class), @@ -58,6 +58,8 @@ public class IpConnectivityEventBuilderTest extends TestCase { String want = joinLines( "dropped_events: 0", "events <", + " time_ms: 1", + " transport: 0", " default_network_event <", " network_id <", " network_id: 102", @@ -70,13 +72,13 @@ public class IpConnectivityEventBuilderTest extends TestCase { " transport_types: 2", " transport_types: 3", " >", - " time_ms: 1", ">", "version: 2"); verifySerialization(want, ev); } + @SmallTest public void testDhcpClientEventSerialization() { ConnectivityMetricsEvent ev = describeIpEvent( aType(DhcpClientEvent.class), @@ -87,19 +89,20 @@ public class IpConnectivityEventBuilderTest extends TestCase { String want = joinLines( "dropped_events: 0", "events <", + " time_ms: 1", + " transport: 0", " dhcp_event <", " duration_ms: 192", - " error_code: 0", " if_name: \"wlan0\"", " state_transition: \"SomeState\"", " >", - " time_ms: 1", ">", "version: 2"); verifySerialization(want, ev); } + @SmallTest public void testDhcpErrorEventSerialization() { ConnectivityMetricsEvent ev = describeIpEvent( aType(DhcpErrorEvent.class), @@ -109,19 +112,20 @@ public class IpConnectivityEventBuilderTest extends TestCase { String want = joinLines( "dropped_events: 0", "events <", + " time_ms: 1", + " transport: 0", " dhcp_event <", " duration_ms: 0", - " error_code: 50397184", " if_name: \"wlan0\"", - " state_transition: \"\"", + " error_code: 50397184", " >", - " time_ms: 1", ">", "version: 2"); verifySerialization(want, ev); } + @SmallTest public void testDnsEventSerialization() { ConnectivityMetricsEvent ev = describeIpEvent( aType(DnsEvent.class), @@ -133,6 +137,8 @@ public class IpConnectivityEventBuilderTest extends TestCase { String want = joinLines( "dropped_events: 0", "events <", + " time_ms: 1", + " transport: 0", " dns_lookup_batch <", " event_types: 1", " event_types: 1", @@ -162,13 +168,13 @@ public class IpConnectivityEventBuilderTest extends TestCase { " return_codes: 200", " return_codes: 178", " >", - " time_ms: 1", ">", "version: 2"); verifySerialization(want, ev); } + @SmallTest public void testIpManagerEventSerialization() { ConnectivityMetricsEvent ev = describeIpEvent( aType(IpManagerEvent.class), @@ -179,18 +185,20 @@ public class IpConnectivityEventBuilderTest extends TestCase { String want = joinLines( "dropped_events: 0", "events <", + " time_ms: 1", + " transport: 0", " ip_provisioning_event <", " event_type: 1", " if_name: \"wlan0\"", " latency_ms: 5678", " >", - " time_ms: 1", ">", "version: 2"); verifySerialization(want, ev); } + @SmallTest public void testIpReachabilityEventSerialization() { ConnectivityMetricsEvent ev = describeIpEvent( aType(IpReachabilityEvent.class), @@ -200,17 +208,19 @@ public class IpConnectivityEventBuilderTest extends TestCase { String want = joinLines( "dropped_events: 0", "events <", + " time_ms: 1", + " transport: 0", " ip_reachability_event <", " event_type: 512", " if_name: \"wlan0\"", " >", - " time_ms: 1", ">", "version: 2"); verifySerialization(want, ev); } + @SmallTest public void testNetworkEventSerialization() { ConnectivityMetricsEvent ev = describeIpEvent( aType(NetworkEvent.class), @@ -221,6 +231,8 @@ public class IpConnectivityEventBuilderTest extends TestCase { String want = joinLines( "dropped_events: 0", "events <", + " time_ms: 1", + " transport: 0", " network_event <", " event_type: 5", " latency_ms: 20410", @@ -228,13 +240,13 @@ public class IpConnectivityEventBuilderTest extends TestCase { " network_id: 100", " >", " >", - " time_ms: 1", ">", "version: 2"); verifySerialization(want, ev); } + @SmallTest public void testValidationProbeEventSerialization() { ConnectivityMetricsEvent ev = describeIpEvent( aType(ValidationProbeEvent.class), @@ -247,6 +259,7 @@ public class IpConnectivityEventBuilderTest extends TestCase { "dropped_events: 0", "events <", " time_ms: 1", + " transport: 0", " validation_probe_event <", " latency_ms: 40730", " network_id <", @@ -261,6 +274,7 @@ public class IpConnectivityEventBuilderTest extends TestCase { verifySerialization(want, ev); } + @SmallTest public void testApfProgramEventSerialization() { ConnectivityMetricsEvent ev = describeIpEvent( aType(ApfProgramEvent.class), @@ -273,6 +287,8 @@ public class IpConnectivityEventBuilderTest extends TestCase { String want = joinLines( "dropped_events: 0", "events <", + " time_ms: 1", + " transport: 0", " apf_program_event <", " current_ras: 9", " drop_multicast: true", @@ -281,13 +297,13 @@ public class IpConnectivityEventBuilderTest extends TestCase { " lifetime: 200", " program_length: 2048", " >", - " time_ms: 1", ">", "version: 2"); verifySerialization(want, ev); } + @SmallTest public void testApfStatsSerialization() { ConnectivityMetricsEvent ev = describeIpEvent( aType(ApfStats.class), @@ -303,6 +319,8 @@ public class IpConnectivityEventBuilderTest extends TestCase { String want = joinLines( "dropped_events: 0", "events <", + " time_ms: 1", + " transport: 0", " apf_statistics <", " dropped_ras: 2", " duration_ms: 45000", @@ -313,13 +331,13 @@ public class IpConnectivityEventBuilderTest extends TestCase { " received_ras: 10", " zero_lifetime_ras: 1", " >", - " time_ms: 1", ">", "version: 2"); verifySerialization(want, ev); } + @SmallTest public void testRaEventSerialization() { ConnectivityMetricsEvent ev = describeIpEvent( aType(RaEvent.class), @@ -333,6 +351,8 @@ public class IpConnectivityEventBuilderTest extends TestCase { String want = joinLines( "dropped_events: 0", "events <", + " time_ms: 1", + " transport: 0", " ra_event <", " dnssl_lifetime: -1", " prefix_preferred_lifetime: 300", @@ -341,7 +361,6 @@ public class IpConnectivityEventBuilderTest extends TestCase { " route_info_lifetime: -1", " router_lifetime: 2000", " >", - " time_ms: 1", ">", "version: 2"); @@ -350,9 +369,9 @@ public class IpConnectivityEventBuilderTest extends TestCase { static void verifySerialization(String want, ConnectivityMetricsEvent... input) { try { - byte[] got = IpConnectivityEventBuilder.serialize(0, Arrays.asList(input)); - IpConnectivityLog log = new IpConnectivityLog(); - MessageNano.mergeFrom(log, got); + byte[] got = IpConnectivityEventBuilder.serialize(0, + IpConnectivityEventBuilder.toProto(Arrays.asList(input))); + IpConnectivityLog log = IpConnectivityLog.parseFrom(got); assertEquals(want, log.toString()); } catch (Exception e) { fail(e.toString()); diff --git a/services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityMetricsTest.java b/services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityMetricsTest.java index aa491bbabd..450653cdb0 100644 --- a/services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityMetricsTest.java +++ b/services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityMetricsTest.java @@ -16,6 +16,9 @@ package com.android.server.connectivity; +import static org.mockito.Mockito.timeout; +import static org.mockito.Mockito.verify; + import android.content.Context; import android.net.ConnectivityMetricsEvent; import android.net.IIpConnectivityMetrics; @@ -29,9 +32,9 @@ import android.net.metrics.IpReachabilityEvent; import android.net.metrics.RaEvent; import android.net.metrics.ValidationProbeEvent; import android.os.Parcelable; +import android.test.suitebuilder.annotation.SmallTest; import android.util.Base64; import com.android.server.connectivity.metrics.IpConnectivityLogClass; -import com.google.protobuf.nano.MessageNano; import java.io.PrintWriter; import java.io.StringWriter; import java.util.Collections; @@ -43,10 +46,6 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import static org.mockito.Mockito.timeout; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - public class IpConnectivityMetricsTest extends TestCase { static final IpReachabilityEvent FAKE_EV = new IpReachabilityEvent("wlan0", IpReachabilityEvent.NUD_FAILED); @@ -61,6 +60,7 @@ public class IpConnectivityMetricsTest extends TestCase { mService = new IpConnectivityMetrics(mCtx, (ctx) -> 2000); } + @SmallTest public void testLoggingEvents() throws Exception { IpConnectivityLog logger = new IpConnectivityLog(mMockService); @@ -74,6 +74,7 @@ public class IpConnectivityMetricsTest extends TestCase { assertEventsEqual(expectedEvent(3), got.get(2)); } + @SmallTest public void testLoggingEventsWithMultipleCallers() throws Exception { IpConnectivityLog logger = new IpConnectivityLog(mMockService); @@ -101,6 +102,7 @@ public class IpConnectivityMetricsTest extends TestCase { } } + @SmallTest public void testBufferFlushing() { String output1 = getdump("flush"); assertEquals("", output1); @@ -113,6 +115,7 @@ public class IpConnectivityMetricsTest extends TestCase { assertEquals("", output3); } + @SmallTest public void testRateLimiting() { final IpConnectivityLog logger = new IpConnectivityLog(mService.impl); final ApfProgramEvent ev = new ApfProgramEvent(0, 0, 0, 0, 0); @@ -134,6 +137,7 @@ public class IpConnectivityMetricsTest extends TestCase { assertEquals("", output2); } + @SmallTest public void testEndToEndLogging() { IpConnectivityLog logger = new IpConnectivityLog(mService.impl); @@ -154,22 +158,25 @@ public class IpConnectivityMetricsTest extends TestCase { String want = joinLines( "dropped_events: 0", "events <", + " time_ms: 100", + " transport: 0", " ip_reachability_event <", " event_type: 512", " if_name: \"wlan0\"", " >", - " time_ms: 100", ">", "events <", + " time_ms: 200", + " transport: 0", " dhcp_event <", " duration_ms: 192", - " error_code: 0", " if_name: \"wlan0\"", " state_transition: \"SomeState\"", " >", - " time_ms: 200", ">", "events <", + " time_ms: 300", + " transport: 0", " default_network_event <", " network_id <", " network_id: 102", @@ -182,18 +189,19 @@ public class IpConnectivityMetricsTest extends TestCase { " transport_types: 2", " transport_types: 3", " >", - " time_ms: 300", ">", "events <", + " time_ms: 400", + " transport: 0", " ip_provisioning_event <", " event_type: 1", " if_name: \"wlan0\"", " latency_ms: 5678", " >", - " time_ms: 400", ">", "events <", " time_ms: 500", + " transport: 0", " validation_probe_event <", " latency_ms: 40730", " network_id <", @@ -204,6 +212,8 @@ public class IpConnectivityMetricsTest extends TestCase { " >", ">", "events <", + " time_ms: 600", + " transport: 0", " apf_statistics <", " dropped_ras: 2", " duration_ms: 45000", @@ -214,9 +224,10 @@ public class IpConnectivityMetricsTest extends TestCase { " received_ras: 10", " zero_lifetime_ras: 1", " >", - " time_ms: 600", ">", "events <", + " time_ms: 700", + " transport: 0", " ra_event <", " dnssl_lifetime: -1", " prefix_preferred_lifetime: 300", @@ -225,7 +236,6 @@ public class IpConnectivityMetricsTest extends TestCase { " route_info_lifetime: -1", " router_lifetime: 2000", " >", - " time_ms: 700", ">", "version: 2"); @@ -254,8 +264,7 @@ public class IpConnectivityMetricsTest extends TestCase { try { byte[] got = Base64.decode(output, Base64.DEFAULT); IpConnectivityLogClass.IpConnectivityLog log = - new IpConnectivityLogClass.IpConnectivityLog(); - MessageNano.mergeFrom(log, got); + IpConnectivityLogClass.IpConnectivityLog.parseFrom(got); assertEquals(want, log.toString()); } catch (Exception e) { fail(e.toString()); @@ -283,10 +292,5 @@ public class IpConnectivityMetricsTest extends TestCase { } static final Comparator EVENT_COMPARATOR = - new Comparator() { - @Override - public int compare(ConnectivityMetricsEvent ev1, ConnectivityMetricsEvent ev2) { - return (int) (ev1.timestamp - ev2.timestamp); - } - }; + Comparator.comparingLong((ev) -> ev.timestamp); } diff --git a/services/tests/servicestests/src/com/android/server/connectivity/NetdEventListenerServiceTest.java b/services/tests/servicestests/src/com/android/server/connectivity/NetdEventListenerServiceTest.java index af4a374bff..97afa60f0c 100644 --- a/services/tests/servicestests/src/com/android/server/connectivity/NetdEventListenerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/connectivity/NetdEventListenerServiceTest.java @@ -16,24 +16,34 @@ package com.android.server.connectivity; -import android.net.ConnectivityManager.NetworkCallback; import android.net.ConnectivityManager; +import android.net.ConnectivityManager.NetworkCallback; import android.net.Network; import android.net.metrics.DnsEvent; import android.net.metrics.INetdEventListener; import android.net.metrics.IpConnectivityLog; import android.os.RemoteException; - +import android.system.OsConstants; +import android.test.suitebuilder.annotation.SmallTest; +import com.android.server.connectivity.metrics.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 static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertTrue; - 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 org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.eq; @@ -41,13 +51,6 @@ import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import java.io.FileOutputStream; -import java.io.PrintWriter; -import java.util.Arrays; -import java.util.List; -import java.util.OptionalInt; -import java.util.stream.IntStream; - public class NetdEventListenerServiceTest extends TestCase { // TODO: read from NetdEventListenerService after this constant is read from system property @@ -67,50 +70,56 @@ public class NetdEventListenerServiceTest extends TestCase { } } + private static final String EXAMPLE_IPV4 = "192.0.2.1"; + private static final String EXAMPLE_IPV6 = "2001:db8:1200::2:1"; + NetdEventListenerService mNetdEventListenerService; @Mock ConnectivityManager mCm; @Mock IpConnectivityLog mLog; ArgumentCaptor mCallbackCaptor; - ArgumentCaptor mEvCaptor; + ArgumentCaptor mDnsEvCaptor; public void setUp() { MockitoAnnotations.initMocks(this); mCallbackCaptor = ArgumentCaptor.forClass(NetworkCallback.class); - mEvCaptor = ArgumentCaptor.forClass(DnsEvent.class); + mDnsEvCaptor = ArgumentCaptor.forClass(DnsEvent.class); mNetdEventListenerService = new NetdEventListenerService(mCm, mLog); verify(mCm, times(1)).registerNetworkCallback(any(), mCallbackCaptor.capture()); } - public void testOneBatch() throws Exception { + @SmallTest + public void testOneDnsBatch() throws Exception { log(105, LATENCIES); log(106, Arrays.copyOf(LATENCIES, BATCH_SIZE - 1)); // one lookup short of a batch event - verifyLoggedEvents(new DnsEvent(105, EVENT_TYPES, RETURN_CODES, LATENCIES)); + verifyLoggedDnsEvents(new DnsEvent(105, EVENT_TYPES, RETURN_CODES, LATENCIES)); log(106, Arrays.copyOfRange(LATENCIES, BATCH_SIZE - 1, BATCH_SIZE)); - mEvCaptor = ArgumentCaptor.forClass(DnsEvent.class); // reset argument captor - verifyLoggedEvents( + 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)); } - public void testSeveralBatches() throws Exception { + @SmallTest + public void testSeveralDmsBatches() throws Exception { log(105, LATENCIES); log(106, LATENCIES); log(105, LATENCIES); log(107, LATENCIES); - verifyLoggedEvents( + 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)); } - public void testBatchAndNetworkLost() throws Exception { + @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); @@ -120,13 +129,14 @@ public class NetdEventListenerServiceTest extends TestCase { mCallbackCaptor.getValue().onLost(new Network(105)); log(105, LATENCIES); - verifyLoggedEvents( + verifyLoggedDnsEvents( new DnsEvent(105, eventTypes, returnCodes, latencies), new DnsEvent(105, EVENT_TYPES, RETURN_CODES, LATENCIES), new DnsEvent(105, EVENT_TYPES, RETURN_CODES, LATENCIES)); } - public void testConcurrentBatchesAndDumps() throws Exception { + @SmallTest + public void testConcurrentDnsBatchesAndDumps() throws Exception { final long stop = System.currentTimeMillis() + 100; final PrintWriter pw = new PrintWriter(new FileOutputStream("/dev/null")); new Thread() { @@ -137,26 +147,120 @@ public class NetdEventListenerServiceTest extends TestCase { } }.start(); - logAsync(105, LATENCIES); - logAsync(106, LATENCIES); - logAsync(107, LATENCIES); + logDnsAsync(105, LATENCIES); + logDnsAsync(106, LATENCIES); + logDnsAsync(107, LATENCIES); - verifyLoggedEvents(500, + 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)); } - public void testConcurrentBatchesAndNetworkLoss() throws Exception { - logAsync(105, LATENCIES); + @SmallTest + public void testConcurrentDnsBatchesAndNetworkLoss() throws Exception { + logDnsAsync(105, LATENCIES); Thread.sleep(10L); - // call onLost() asynchronously to logAsync's onDnsEvent() calls. + // call onLost() asynchronously to logDnsAsync's onDnsEvent() calls. mCallbackCaptor.getValue().onLost(new Network(105)); // do not verify unpredictable batch verify(mLog, timeout(500).times(1)).log(any()); } + @SmallTest + public void testConnectLogging() throws Exception { + final int OK = 0; + Thread[] logActions = { + // ignored + connectEventAction(OsConstants.EALREADY, 0, EXAMPLE_IPV4), + connectEventAction(OsConstants.EALREADY, 0, EXAMPLE_IPV6), + connectEventAction(OsConstants.EINPROGRESS, 0, EXAMPLE_IPV4), + connectEventAction(OsConstants.EINPROGRESS, 0, EXAMPLE_IPV6), + connectEventAction(OsConstants.EINPROGRESS, 0, EXAMPLE_IPV6), + // valid latencies + connectEventAction(OK, 110, EXAMPLE_IPV4), + connectEventAction(OK, 23, EXAMPLE_IPV4), + connectEventAction(OK, 45, EXAMPLE_IPV4), + connectEventAction(OK, 56, EXAMPLE_IPV4), + connectEventAction(OK, 523, EXAMPLE_IPV6), + connectEventAction(OK, 214, EXAMPLE_IPV6), + connectEventAction(OK, 67, EXAMPLE_IPV6), + // errors + connectEventAction(OsConstants.EPERM, 0, EXAMPLE_IPV4), + connectEventAction(OsConstants.EPERM, 0, EXAMPLE_IPV4), + connectEventAction(OsConstants.EAGAIN, 0, EXAMPLE_IPV4), + connectEventAction(OsConstants.EACCES, 0, EXAMPLE_IPV4), + connectEventAction(OsConstants.EACCES, 0, EXAMPLE_IPV4), + connectEventAction(OsConstants.EACCES, 0, EXAMPLE_IPV6), + connectEventAction(OsConstants.EADDRINUSE, 0, EXAMPLE_IPV4), + connectEventAction(OsConstants.ETIMEDOUT, 0, EXAMPLE_IPV4), + connectEventAction(OsConstants.ETIMEDOUT, 0, EXAMPLE_IPV6), + connectEventAction(OsConstants.ETIMEDOUT, 0, EXAMPLE_IPV6), + connectEventAction(OsConstants.ECONNREFUSED, 0, EXAMPLE_IPV4), + }; + + for (Thread t : logActions) { + t.start(); + } + for (Thread t : logActions) { + t.join(); + } + + List events = new ArrayList<>(); + mNetdEventListenerService.flushStatistics(events); + + IpConnectivityEvent got = events.get(0); + String want = joinLines( + "time_ms: 0", + "transport: 0", + "connect_statistics <", + " connect_count: 12", + " errnos_counters <", + " key: 1", + " value: 2", + " >", + " errnos_counters <", + " key: 11", + " value: 1", + " >", + " errnos_counters <", + " key: 13", + " value: 3", + " >", + " errnos_counters <", + " key: 98", + " value: 1", + " >", + " errnos_counters <", + " key: 110", + " value: 3", + " >", + " errnos_counters <", + " key: 111", + " value: 1", + " >", + " ipv6_addr_count: 6", + " latencies_ms: 23", + " latencies_ms: 45", + " latencies_ms: 56", + " latencies_ms: 67", + " latencies_ms: 110", + " latencies_ms: 214", + " latencies_ms: 523"); + verifyConnectEvent(want, got); + } + + Thread connectEventAction(int error, int latencyMs, String ipAddr) { + return new Thread(() -> { + try { + mNetdEventListenerService.onConnectEvent(100, error, latencyMs, ipAddr, 80, 1); + } catch (Exception e) { + fail(e.toString()); + } + }); + } + void log(int netId, int[] latencies) { try { for (int l : latencies) { @@ -168,7 +272,7 @@ public class NetdEventListenerServiceTest extends TestCase { } } - void logAsync(int netId, int[] latencies) { + void logDnsAsync(int netId, int[] latencies) { new Thread() { public void run() { log(netId, latencies); @@ -176,15 +280,15 @@ public class NetdEventListenerServiceTest extends TestCase { }.start(); } - void verifyLoggedEvents(DnsEvent... expected) { - verifyLoggedEvents(0, expected); + void verifyLoggedDnsEvents(DnsEvent... expected) { + verifyLoggedDnsEvents(0, expected); } - void verifyLoggedEvents(int wait, DnsEvent... expectedEvents) { - verify(mLog, timeout(wait).times(expectedEvents.length)).log(mEvCaptor.capture()); - for (DnsEvent got : mEvCaptor.getAllValues()) { + 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 -> eventsEqual(expectedEvents[i], got)) + .filter(i -> dnsEventsEqual(expectedEvents[i], got)) .findFirst(); // Don't match same expected event more than once. index.ifPresent(i -> expectedEvents[i] = null); @@ -193,11 +297,30 @@ public class NetdEventListenerServiceTest extends TestCase { } /** equality function for DnsEvent to avoid overriding equals() and hashCode(). */ - static boolean eventsEqual(DnsEvent expected, DnsEvent got) { + 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 String joinLines(String ... elems) { + StringBuilder b = new StringBuilder(); + for (String s : elems) { + b.append(s).append("\n"); + } + return b.toString(); + } + + static void verifyConnectEvent(String expected, IpConnectivityEvent got) { + try { + Arrays.sort(got.connectStatistics.latenciesMs); + Arrays.sort(got.connectStatistics.errnosCounters, + Comparator.comparingInt((p) -> p.key)); + assertEquals(expected, got.toString()); + } catch (Exception e) { + fail(e.toString()); + } + } }