Merge changes Id0d536ff,I4fcd0ad7 into oc-dev
am: 0e8090b10e Change-Id: I0b432e9d7aa5654a0aeac1d3d0a09e624bcbc9bc
This commit is contained in:
@@ -45,7 +45,9 @@ import android.net.metrics.NetworkEvent;
|
|||||||
import android.net.metrics.RaEvent;
|
import android.net.metrics.RaEvent;
|
||||||
import android.net.metrics.ValidationProbeEvent;
|
import android.net.metrics.ValidationProbeEvent;
|
||||||
import android.test.suitebuilder.annotation.SmallTest;
|
import android.test.suitebuilder.annotation.SmallTest;
|
||||||
|
import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityEvent;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
// TODO: instead of comparing textpb to textpb, parse textpb and compare proto to proto.
|
// TODO: instead of comparing textpb to textpb, parse textpb and compare proto to proto.
|
||||||
@@ -57,7 +59,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
|
|||||||
aType(IpReachabilityEvent.class),
|
aType(IpReachabilityEvent.class),
|
||||||
anInt(IpReachabilityEvent.NUD_FAILED));
|
anInt(IpReachabilityEvent.NUD_FAILED));
|
||||||
|
|
||||||
String want = joinLines(
|
String want = String.join("\n",
|
||||||
"dropped_events: 0",
|
"dropped_events: 0",
|
||||||
"events <",
|
"events <",
|
||||||
" if_name: \"\"",
|
" if_name: \"\"",
|
||||||
@@ -70,13 +72,13 @@ public class IpConnectivityEventBuilderTest extends TestCase {
|
|||||||
" if_name: \"\"",
|
" if_name: \"\"",
|
||||||
" >",
|
" >",
|
||||||
">",
|
">",
|
||||||
"version: 2");
|
"version: 2\n");
|
||||||
verifySerialization(want, ev);
|
verifySerialization(want, ev);
|
||||||
|
|
||||||
ev.netId = 123;
|
ev.netId = 123;
|
||||||
ev.transports = 3; // transports have priority for inferrence of link layer
|
ev.transports = 3; // transports have priority for inferrence of link layer
|
||||||
ev.ifname = "wlan0";
|
ev.ifname = "wlan0";
|
||||||
want = joinLines(
|
want = String.join("\n",
|
||||||
"dropped_events: 0",
|
"dropped_events: 0",
|
||||||
"events <",
|
"events <",
|
||||||
" if_name: \"\"",
|
" if_name: \"\"",
|
||||||
@@ -89,12 +91,12 @@ public class IpConnectivityEventBuilderTest extends TestCase {
|
|||||||
" if_name: \"\"",
|
" if_name: \"\"",
|
||||||
" >",
|
" >",
|
||||||
">",
|
">",
|
||||||
"version: 2");
|
"version: 2\n");
|
||||||
verifySerialization(want, ev);
|
verifySerialization(want, ev);
|
||||||
|
|
||||||
ev.transports = 1;
|
ev.transports = 1;
|
||||||
ev.ifname = null;
|
ev.ifname = null;
|
||||||
want = joinLines(
|
want = String.join("\n",
|
||||||
"dropped_events: 0",
|
"dropped_events: 0",
|
||||||
"events <",
|
"events <",
|
||||||
" if_name: \"\"",
|
" if_name: \"\"",
|
||||||
@@ -107,12 +109,12 @@ public class IpConnectivityEventBuilderTest extends TestCase {
|
|||||||
" if_name: \"\"",
|
" if_name: \"\"",
|
||||||
" >",
|
" >",
|
||||||
">",
|
">",
|
||||||
"version: 2");
|
"version: 2\n");
|
||||||
verifySerialization(want, ev);
|
verifySerialization(want, ev);
|
||||||
|
|
||||||
ev.transports = 0;
|
ev.transports = 0;
|
||||||
ev.ifname = "not_inferred";
|
ev.ifname = "not_inferred";
|
||||||
want = joinLines(
|
want = String.join("\n",
|
||||||
"dropped_events: 0",
|
"dropped_events: 0",
|
||||||
"events <",
|
"events <",
|
||||||
" if_name: \"not_inferred\"",
|
" if_name: \"not_inferred\"",
|
||||||
@@ -125,11 +127,11 @@ public class IpConnectivityEventBuilderTest extends TestCase {
|
|||||||
" if_name: \"\"",
|
" if_name: \"\"",
|
||||||
" >",
|
" >",
|
||||||
">",
|
">",
|
||||||
"version: 2");
|
"version: 2\n");
|
||||||
verifySerialization(want, ev);
|
verifySerialization(want, ev);
|
||||||
|
|
||||||
ev.ifname = "bt-pan";
|
ev.ifname = "bt-pan";
|
||||||
want = joinLines(
|
want = String.join("\n",
|
||||||
"dropped_events: 0",
|
"dropped_events: 0",
|
||||||
"events <",
|
"events <",
|
||||||
" if_name: \"\"",
|
" if_name: \"\"",
|
||||||
@@ -142,11 +144,11 @@ public class IpConnectivityEventBuilderTest extends TestCase {
|
|||||||
" if_name: \"\"",
|
" if_name: \"\"",
|
||||||
" >",
|
" >",
|
||||||
">",
|
">",
|
||||||
"version: 2");
|
"version: 2\n");
|
||||||
verifySerialization(want, ev);
|
verifySerialization(want, ev);
|
||||||
|
|
||||||
ev.ifname = "rmnet_ipa0";
|
ev.ifname = "rmnet_ipa0";
|
||||||
want = joinLines(
|
want = String.join("\n",
|
||||||
"dropped_events: 0",
|
"dropped_events: 0",
|
||||||
"events <",
|
"events <",
|
||||||
" if_name: \"\"",
|
" if_name: \"\"",
|
||||||
@@ -159,11 +161,11 @@ public class IpConnectivityEventBuilderTest extends TestCase {
|
|||||||
" if_name: \"\"",
|
" if_name: \"\"",
|
||||||
" >",
|
" >",
|
||||||
">",
|
">",
|
||||||
"version: 2");
|
"version: 2\n");
|
||||||
verifySerialization(want, ev);
|
verifySerialization(want, ev);
|
||||||
|
|
||||||
ev.ifname = "wlan0";
|
ev.ifname = "wlan0";
|
||||||
want = joinLines(
|
want = String.join("\n",
|
||||||
"dropped_events: 0",
|
"dropped_events: 0",
|
||||||
"events <",
|
"events <",
|
||||||
" if_name: \"\"",
|
" if_name: \"\"",
|
||||||
@@ -176,7 +178,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
|
|||||||
" if_name: \"\"",
|
" if_name: \"\"",
|
||||||
" >",
|
" >",
|
||||||
">",
|
">",
|
||||||
"version: 2");
|
"version: 2\n");
|
||||||
verifySerialization(want, ev);
|
verifySerialization(want, ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,7 +192,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
|
|||||||
aBool(true),
|
aBool(true),
|
||||||
aBool(false));
|
aBool(false));
|
||||||
|
|
||||||
String want = joinLines(
|
String want = String.join("\n",
|
||||||
"dropped_events: 0",
|
"dropped_events: 0",
|
||||||
"events <",
|
"events <",
|
||||||
" if_name: \"\"",
|
" if_name: \"\"",
|
||||||
@@ -211,7 +213,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
|
|||||||
" transport_types: 3",
|
" transport_types: 3",
|
||||||
" >",
|
" >",
|
||||||
">",
|
">",
|
||||||
"version: 2");
|
"version: 2\n");
|
||||||
|
|
||||||
verifySerialization(want, ev);
|
verifySerialization(want, ev);
|
||||||
}
|
}
|
||||||
@@ -223,7 +225,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
|
|||||||
aString("SomeState"),
|
aString("SomeState"),
|
||||||
anInt(192));
|
anInt(192));
|
||||||
|
|
||||||
String want = joinLines(
|
String want = String.join("\n",
|
||||||
"dropped_events: 0",
|
"dropped_events: 0",
|
||||||
"events <",
|
"events <",
|
||||||
" if_name: \"\"",
|
" if_name: \"\"",
|
||||||
@@ -237,7 +239,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
|
|||||||
" state_transition: \"SomeState\"",
|
" state_transition: \"SomeState\"",
|
||||||
" >",
|
" >",
|
||||||
">",
|
">",
|
||||||
"version: 2");
|
"version: 2\n");
|
||||||
|
|
||||||
verifySerialization(want, ev);
|
verifySerialization(want, ev);
|
||||||
}
|
}
|
||||||
@@ -248,7 +250,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
|
|||||||
aType(DhcpErrorEvent.class),
|
aType(DhcpErrorEvent.class),
|
||||||
anInt(DhcpErrorEvent.L4_NOT_UDP));
|
anInt(DhcpErrorEvent.L4_NOT_UDP));
|
||||||
|
|
||||||
String want = joinLines(
|
String want = String.join("\n",
|
||||||
"dropped_events: 0",
|
"dropped_events: 0",
|
||||||
"events <",
|
"events <",
|
||||||
" if_name: \"\"",
|
" if_name: \"\"",
|
||||||
@@ -262,59 +264,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
|
|||||||
" error_code: 50397184",
|
" error_code: 50397184",
|
||||||
" >",
|
" >",
|
||||||
">",
|
">",
|
||||||
"version: 2");
|
"version: 2\n");
|
||||||
|
|
||||||
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");
|
|
||||||
|
|
||||||
verifySerialization(want, ev);
|
verifySerialization(want, ev);
|
||||||
}
|
}
|
||||||
@@ -326,7 +276,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
|
|||||||
anInt(IpManagerEvent.PROVISIONING_OK),
|
anInt(IpManagerEvent.PROVISIONING_OK),
|
||||||
aLong(5678));
|
aLong(5678));
|
||||||
|
|
||||||
String want = joinLines(
|
String want = String.join("\n",
|
||||||
"dropped_events: 0",
|
"dropped_events: 0",
|
||||||
"events <",
|
"events <",
|
||||||
" if_name: \"\"",
|
" if_name: \"\"",
|
||||||
@@ -340,7 +290,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
|
|||||||
" latency_ms: 5678",
|
" latency_ms: 5678",
|
||||||
" >",
|
" >",
|
||||||
">",
|
">",
|
||||||
"version: 2");
|
"version: 2\n");
|
||||||
|
|
||||||
verifySerialization(want, ev);
|
verifySerialization(want, ev);
|
||||||
}
|
}
|
||||||
@@ -351,7 +301,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
|
|||||||
aType(IpReachabilityEvent.class),
|
aType(IpReachabilityEvent.class),
|
||||||
anInt(IpReachabilityEvent.NUD_FAILED));
|
anInt(IpReachabilityEvent.NUD_FAILED));
|
||||||
|
|
||||||
String want = joinLines(
|
String want = String.join("\n",
|
||||||
"dropped_events: 0",
|
"dropped_events: 0",
|
||||||
"events <",
|
"events <",
|
||||||
" if_name: \"\"",
|
" if_name: \"\"",
|
||||||
@@ -364,7 +314,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
|
|||||||
" if_name: \"\"",
|
" if_name: \"\"",
|
||||||
" >",
|
" >",
|
||||||
">",
|
">",
|
||||||
"version: 2");
|
"version: 2\n");
|
||||||
|
|
||||||
verifySerialization(want, ev);
|
verifySerialization(want, ev);
|
||||||
}
|
}
|
||||||
@@ -377,7 +327,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
|
|||||||
anInt(5),
|
anInt(5),
|
||||||
aLong(20410));
|
aLong(20410));
|
||||||
|
|
||||||
String want = joinLines(
|
String want = String.join("\n",
|
||||||
"dropped_events: 0",
|
"dropped_events: 0",
|
||||||
"events <",
|
"events <",
|
||||||
" if_name: \"\"",
|
" if_name: \"\"",
|
||||||
@@ -393,7 +343,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
|
|||||||
" >",
|
" >",
|
||||||
" >",
|
" >",
|
||||||
">",
|
">",
|
||||||
"version: 2");
|
"version: 2\n");
|
||||||
|
|
||||||
verifySerialization(want, ev);
|
verifySerialization(want, ev);
|
||||||
}
|
}
|
||||||
@@ -406,7 +356,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
|
|||||||
anInt(ValidationProbeEvent.PROBE_HTTP),
|
anInt(ValidationProbeEvent.PROBE_HTTP),
|
||||||
anInt(204));
|
anInt(204));
|
||||||
|
|
||||||
String want = joinLines(
|
String want = String.join("\n",
|
||||||
"dropped_events: 0",
|
"dropped_events: 0",
|
||||||
"events <",
|
"events <",
|
||||||
" if_name: \"\"",
|
" if_name: \"\"",
|
||||||
@@ -420,7 +370,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
|
|||||||
" probe_type: 1",
|
" probe_type: 1",
|
||||||
" >",
|
" >",
|
||||||
">",
|
">",
|
||||||
"version: 2");
|
"version: 2\n");
|
||||||
|
|
||||||
verifySerialization(want, ev);
|
verifySerialization(want, ev);
|
||||||
}
|
}
|
||||||
@@ -436,7 +386,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
|
|||||||
anInt(2048),
|
anInt(2048),
|
||||||
anInt(3));
|
anInt(3));
|
||||||
|
|
||||||
String want = joinLines(
|
String want = String.join("\n",
|
||||||
"dropped_events: 0",
|
"dropped_events: 0",
|
||||||
"events <",
|
"events <",
|
||||||
" if_name: \"\"",
|
" if_name: \"\"",
|
||||||
@@ -454,7 +404,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
|
|||||||
" program_length: 2048",
|
" program_length: 2048",
|
||||||
" >",
|
" >",
|
||||||
">",
|
">",
|
||||||
"version: 2");
|
"version: 2\n");
|
||||||
|
|
||||||
verifySerialization(want, ev);
|
verifySerialization(want, ev);
|
||||||
}
|
}
|
||||||
@@ -474,7 +424,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
|
|||||||
anInt(3),
|
anInt(3),
|
||||||
anInt(2048));
|
anInt(2048));
|
||||||
|
|
||||||
String want = joinLines(
|
String want = String.join("\n",
|
||||||
"dropped_events: 0",
|
"dropped_events: 0",
|
||||||
"events <",
|
"events <",
|
||||||
" if_name: \"\"",
|
" if_name: \"\"",
|
||||||
@@ -495,7 +445,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
|
|||||||
" zero_lifetime_ras: 1",
|
" zero_lifetime_ras: 1",
|
||||||
" >",
|
" >",
|
||||||
">",
|
">",
|
||||||
"version: 2");
|
"version: 2\n");
|
||||||
|
|
||||||
verifySerialization(want, ev);
|
verifySerialization(want, ev);
|
||||||
}
|
}
|
||||||
@@ -511,7 +461,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
|
|||||||
aLong(1000),
|
aLong(1000),
|
||||||
aLong(-1));
|
aLong(-1));
|
||||||
|
|
||||||
String want = joinLines(
|
String want = String.join("\n",
|
||||||
"dropped_events: 0",
|
"dropped_events: 0",
|
||||||
"events <",
|
"events <",
|
||||||
" if_name: \"\"",
|
" if_name: \"\"",
|
||||||
@@ -528,28 +478,20 @@ public class IpConnectivityEventBuilderTest extends TestCase {
|
|||||||
" router_lifetime: 2000",
|
" router_lifetime: 2000",
|
||||||
" >",
|
" >",
|
||||||
">",
|
">",
|
||||||
"version: 2");
|
"version: 2\n");
|
||||||
|
|
||||||
verifySerialization(want, ev);
|
verifySerialization(want, ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void verifySerialization(String want, ConnectivityMetricsEvent... input) {
|
static void verifySerialization(String want, ConnectivityMetricsEvent... input) {
|
||||||
try {
|
try {
|
||||||
byte[] got = IpConnectivityEventBuilder.serialize(0,
|
List<IpConnectivityEvent> proto =
|
||||||
IpConnectivityEventBuilder.toProto(Arrays.asList(input)));
|
IpConnectivityEventBuilder.toProto(Arrays.asList(input));
|
||||||
|
byte[] got = IpConnectivityEventBuilder.serialize(0, proto);
|
||||||
IpConnectivityLog log = IpConnectivityLog.parseFrom(got);
|
IpConnectivityLog log = IpConnectivityLog.parseFrom(got);
|
||||||
assertEquals(want, log.toString());
|
assertEquals(want, log.toString());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
fail(e.toString());
|
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,12 +16,22 @@
|
|||||||
|
|
||||||
package com.android.server.connectivity;
|
package com.android.server.connectivity;
|
||||||
|
|
||||||
|
import static android.net.metrics.INetdEventListener.EVENT_GETADDRINFO;
|
||||||
|
import static android.net.metrics.INetdEventListener.EVENT_GETHOSTBYNAME;
|
||||||
import static org.mockito.Mockito.timeout;
|
import static org.mockito.Mockito.timeout;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
import android.net.ConnectivityMetricsEvent;
|
import android.net.ConnectivityMetricsEvent;
|
||||||
import android.net.IIpConnectivityMetrics;
|
import android.net.IIpConnectivityMetrics;
|
||||||
|
import android.net.Network;
|
||||||
|
import android.net.NetworkCapabilities;
|
||||||
import android.net.metrics.ApfProgramEvent;
|
import android.net.metrics.ApfProgramEvent;
|
||||||
import android.net.metrics.ApfStats;
|
import android.net.metrics.ApfStats;
|
||||||
import android.net.metrics.DefaultNetworkEvent;
|
import android.net.metrics.DefaultNetworkEvent;
|
||||||
@@ -31,7 +41,9 @@ import android.net.metrics.IpManagerEvent;
|
|||||||
import android.net.metrics.IpReachabilityEvent;
|
import android.net.metrics.IpReachabilityEvent;
|
||||||
import android.net.metrics.RaEvent;
|
import android.net.metrics.RaEvent;
|
||||||
import android.net.metrics.ValidationProbeEvent;
|
import android.net.metrics.ValidationProbeEvent;
|
||||||
|
import android.system.OsConstants;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
|
import android.support.test.runner.AndroidJUnit4;
|
||||||
import android.test.suitebuilder.annotation.SmallTest;
|
import android.test.suitebuilder.annotation.SmallTest;
|
||||||
import android.util.Base64;
|
import android.util.Base64;
|
||||||
import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass;
|
import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass;
|
||||||
@@ -41,26 +53,38 @@ import java.util.Collections;
|
|||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import junit.framework.TestCase;
|
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
public class IpConnectivityMetricsTest extends TestCase {
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
@SmallTest
|
||||||
|
public class IpConnectivityMetricsTest {
|
||||||
static final IpReachabilityEvent FAKE_EV =
|
static final IpReachabilityEvent FAKE_EV =
|
||||||
new IpReachabilityEvent(IpReachabilityEvent.NUD_FAILED);
|
new IpReachabilityEvent(IpReachabilityEvent.NUD_FAILED);
|
||||||
|
|
||||||
|
private static final String EXAMPLE_IPV4 = "192.0.2.1";
|
||||||
|
private static final String EXAMPLE_IPV6 = "2001:db8:1200::2:1";
|
||||||
|
|
||||||
@Mock Context mCtx;
|
@Mock Context mCtx;
|
||||||
@Mock IIpConnectivityMetrics mMockService;
|
@Mock IIpConnectivityMetrics mMockService;
|
||||||
|
@Mock ConnectivityManager mCm;
|
||||||
|
|
||||||
IpConnectivityMetrics mService;
|
IpConnectivityMetrics mService;
|
||||||
|
NetdEventListenerService mNetdListener;
|
||||||
|
|
||||||
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mService = new IpConnectivityMetrics(mCtx, (ctx) -> 2000);
|
mService = new IpConnectivityMetrics(mCtx, (ctx) -> 2000);
|
||||||
|
mNetdListener = new NetdEventListenerService(mCm);
|
||||||
|
mService.mNetdListener = mNetdListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SmallTest
|
@Test
|
||||||
public void testLoggingEvents() throws Exception {
|
public void testLoggingEvents() throws Exception {
|
||||||
IpConnectivityLog logger = new IpConnectivityLog(mMockService);
|
IpConnectivityLog logger = new IpConnectivityLog(mMockService);
|
||||||
|
|
||||||
@@ -74,7 +98,7 @@ public class IpConnectivityMetricsTest extends TestCase {
|
|||||||
assertEventsEqual(expectedEvent(3), got.get(2));
|
assertEventsEqual(expectedEvent(3), got.get(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SmallTest
|
@Test
|
||||||
public void testLoggingEventsWithMultipleCallers() throws Exception {
|
public void testLoggingEventsWithMultipleCallers() throws Exception {
|
||||||
IpConnectivityLog logger = new IpConnectivityLog(mMockService);
|
IpConnectivityLog logger = new IpConnectivityLog(mMockService);
|
||||||
|
|
||||||
@@ -91,7 +115,7 @@ public class IpConnectivityMetricsTest extends TestCase {
|
|||||||
}.start();
|
}.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
List<ConnectivityMetricsEvent> got = verifyEvents(nCallers * nEvents, 100);
|
List<ConnectivityMetricsEvent> got = verifyEvents(nCallers * nEvents, 200);
|
||||||
Collections.sort(got, EVENT_COMPARATOR);
|
Collections.sort(got, EVENT_COMPARATOR);
|
||||||
Iterator<ConnectivityMetricsEvent> iter = got.iterator();
|
Iterator<ConnectivityMetricsEvent> iter = got.iterator();
|
||||||
for (int i = 0; i < nCallers; i++) {
|
for (int i = 0; i < nCallers; i++) {
|
||||||
@@ -102,7 +126,7 @@ public class IpConnectivityMetricsTest extends TestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SmallTest
|
@Test
|
||||||
public void testBufferFlushing() {
|
public void testBufferFlushing() {
|
||||||
String output1 = getdump("flush");
|
String output1 = getdump("flush");
|
||||||
assertEquals("", output1);
|
assertEquals("", output1);
|
||||||
@@ -115,7 +139,7 @@ public class IpConnectivityMetricsTest extends TestCase {
|
|||||||
assertEquals("", output3);
|
assertEquals("", output3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SmallTest
|
@Test
|
||||||
public void testRateLimiting() {
|
public void testRateLimiting() {
|
||||||
final IpConnectivityLog logger = new IpConnectivityLog(mService.impl);
|
final IpConnectivityLog logger = new IpConnectivityLog(mService.impl);
|
||||||
final ApfProgramEvent ev = new ApfProgramEvent();
|
final ApfProgramEvent ev = new ApfProgramEvent();
|
||||||
@@ -137,11 +161,19 @@ public class IpConnectivityMetricsTest extends TestCase {
|
|||||||
assertEquals("", output2);
|
assertEquals("", output2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SmallTest
|
@Test
|
||||||
public void testEndToEndLogging() {
|
public void testEndToEndLogging() throws Exception {
|
||||||
// TODO: instead of comparing textpb to textpb, parse textpb and compare proto to proto.
|
// TODO: instead of comparing textpb to textpb, parse textpb and compare proto to proto.
|
||||||
IpConnectivityLog logger = new IpConnectivityLog(mService.impl);
|
IpConnectivityLog logger = new IpConnectivityLog(mService.impl);
|
||||||
|
|
||||||
|
NetworkCapabilities ncWifi = new NetworkCapabilities();
|
||||||
|
NetworkCapabilities ncCell = new NetworkCapabilities();
|
||||||
|
ncWifi.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
|
||||||
|
ncCell.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
|
||||||
|
|
||||||
|
when(mCm.getNetworkCapabilities(new Network(100))).thenReturn(ncWifi);
|
||||||
|
when(mCm.getNetworkCapabilities(new Network(101))).thenReturn(ncCell);
|
||||||
|
|
||||||
ApfStats apfStats = new ApfStats();
|
ApfStats apfStats = new ApfStats();
|
||||||
apfStats.durationMs = 45000;
|
apfStats.durationMs = 45000;
|
||||||
apfStats.receivedRas = 10;
|
apfStats.receivedRas = 10;
|
||||||
@@ -177,7 +209,22 @@ public class IpConnectivityMetricsTest extends TestCase {
|
|||||||
logger.log(ev);
|
logger.log(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
String want = joinLines(
|
// netId, errno, latency, destination
|
||||||
|
connectEvent(100, OsConstants.EALREADY, 0, EXAMPLE_IPV4);
|
||||||
|
connectEvent(100, OsConstants.EINPROGRESS, 0, EXAMPLE_IPV6);
|
||||||
|
connectEvent(100, 0, 110, EXAMPLE_IPV4);
|
||||||
|
connectEvent(101, 0, 23, EXAMPLE_IPV4);
|
||||||
|
connectEvent(101, 0, 45, EXAMPLE_IPV6);
|
||||||
|
connectEvent(100, OsConstants.EAGAIN, 0, EXAMPLE_IPV4);
|
||||||
|
|
||||||
|
// netId, type, return code, latency
|
||||||
|
dnsEvent(100, EVENT_GETADDRINFO, 0, 3456);
|
||||||
|
dnsEvent(100, EVENT_GETADDRINFO, 3, 45);
|
||||||
|
dnsEvent(100, EVENT_GETHOSTBYNAME, 0, 638);
|
||||||
|
dnsEvent(101, EVENT_GETADDRINFO, 0, 56);
|
||||||
|
dnsEvent(101, EVENT_GETHOSTBYNAME, 0, 34);
|
||||||
|
|
||||||
|
String want = String.join("\n",
|
||||||
"dropped_events: 0",
|
"dropped_events: 0",
|
||||||
"events <",
|
"events <",
|
||||||
" if_name: \"\"",
|
" if_name: \"\"",
|
||||||
@@ -279,7 +326,71 @@ public class IpConnectivityMetricsTest extends TestCase {
|
|||||||
" router_lifetime: 2000",
|
" router_lifetime: 2000",
|
||||||
" >",
|
" >",
|
||||||
">",
|
">",
|
||||||
"version: 2");
|
"events <",
|
||||||
|
" if_name: \"\"",
|
||||||
|
" link_layer: 4",
|
||||||
|
" network_id: 100",
|
||||||
|
" time_ms: 0",
|
||||||
|
" transports: 2",
|
||||||
|
" connect_statistics <",
|
||||||
|
" connect_blocking_count: 1",
|
||||||
|
" connect_count: 3",
|
||||||
|
" errnos_counters <",
|
||||||
|
" key: 11",
|
||||||
|
" value: 1",
|
||||||
|
" >",
|
||||||
|
" ipv6_addr_count: 1",
|
||||||
|
" latencies_ms: 110",
|
||||||
|
" >",
|
||||||
|
">",
|
||||||
|
"events <",
|
||||||
|
" if_name: \"\"",
|
||||||
|
" link_layer: 2",
|
||||||
|
" network_id: 101",
|
||||||
|
" time_ms: 0",
|
||||||
|
" transports: 1",
|
||||||
|
" connect_statistics <",
|
||||||
|
" connect_blocking_count: 2",
|
||||||
|
" connect_count: 2",
|
||||||
|
" ipv6_addr_count: 1",
|
||||||
|
" latencies_ms: 23",
|
||||||
|
" latencies_ms: 45",
|
||||||
|
" >",
|
||||||
|
">",
|
||||||
|
"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",
|
||||||
|
" latencies_ms: 3456",
|
||||||
|
" latencies_ms: 45",
|
||||||
|
" latencies_ms: 638",
|
||||||
|
" return_codes: 0",
|
||||||
|
" return_codes: 3",
|
||||||
|
" return_codes: 0",
|
||||||
|
" >",
|
||||||
|
">",
|
||||||
|
"events <",
|
||||||
|
" if_name: \"\"",
|
||||||
|
" link_layer: 2",
|
||||||
|
" network_id: 101",
|
||||||
|
" time_ms: 0",
|
||||||
|
" transports: 1",
|
||||||
|
" dns_lookup_batch <",
|
||||||
|
" event_types: 1",
|
||||||
|
" event_types: 2",
|
||||||
|
" latencies_ms: 56",
|
||||||
|
" latencies_ms: 34",
|
||||||
|
" return_codes: 0",
|
||||||
|
" return_codes: 0",
|
||||||
|
" >",
|
||||||
|
">",
|
||||||
|
"version: 2\n");
|
||||||
|
|
||||||
verifySerialization(want, getdump("flush"));
|
verifySerialization(want, getdump("flush"));
|
||||||
}
|
}
|
||||||
@@ -291,6 +402,14 @@ public class IpConnectivityMetricsTest extends TestCase {
|
|||||||
return buffer.toString();
|
return buffer.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void connectEvent(int netid, int error, int latencyMs, String ipAddr) throws Exception {
|
||||||
|
mNetdListener.onConnectEvent(netid, error, latencyMs, ipAddr, 80, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dnsEvent(int netId, int type, int result, int latency) throws Exception {
|
||||||
|
mNetdListener.onDnsEvent(netId, type, result, latency, "", null, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
List<ConnectivityMetricsEvent> verifyEvents(int n, int timeoutMs) throws Exception {
|
List<ConnectivityMetricsEvent> verifyEvents(int n, int timeoutMs) throws Exception {
|
||||||
ArgumentCaptor<ConnectivityMetricsEvent> captor =
|
ArgumentCaptor<ConnectivityMetricsEvent> captor =
|
||||||
ArgumentCaptor.forClass(ConnectivityMetricsEvent.class);
|
ArgumentCaptor.forClass(ConnectivityMetricsEvent.class);
|
||||||
|
|||||||
@@ -16,190 +16,182 @@
|
|||||||
|
|
||||||
package com.android.server.connectivity;
|
package com.android.server.connectivity;
|
||||||
|
|
||||||
import android.net.ConnectivityManager;
|
import static android.net.metrics.INetdEventListener.EVENT_GETADDRINFO;
|
||||||
import android.net.ConnectivityManager.NetworkCallback;
|
import static android.net.metrics.INetdEventListener.EVENT_GETHOSTBYNAME;
|
||||||
import android.net.Network;
|
import static org.junit.Assert.assertEquals;
|
||||||
import android.net.metrics.ConnectStats;
|
import static org.junit.Assert.fail;
|
||||||
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 org.mockito.Mockito.any;
|
import static org.mockito.Mockito.any;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.anyInt;
|
import static org.mockito.Mockito.anyInt;
|
||||||
import static org.mockito.Mockito.eq;
|
import static org.mockito.Mockito.eq;
|
||||||
import static org.mockito.Mockito.timeout;
|
import static org.mockito.Mockito.timeout;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
public class NetdEventListenerServiceTest extends TestCase {
|
import android.content.Context;
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
// TODO: read from NetdEventListenerService after this constant is read from system property
|
import android.net.Network;
|
||||||
static final int BATCH_SIZE = 100;
|
import android.net.NetworkCapabilities;
|
||||||
static final int EVENT_TYPE = INetdEventListener.EVENT_GETADDRINFO;
|
import android.support.test.runner.AndroidJUnit4;
|
||||||
// TODO: read from INetdEventListener
|
import android.system.OsConstants;
|
||||||
static final int RETURN_CODE = 1;
|
import android.test.suitebuilder.annotation.SmallTest;
|
||||||
|
import android.util.Base64;
|
||||||
static final byte[] EVENT_TYPES = new byte[BATCH_SIZE];
|
import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.DNSLookupBatch;
|
||||||
static final byte[] RETURN_CODES = new byte[BATCH_SIZE];
|
import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityEvent;
|
||||||
static final int[] LATENCIES = new int[BATCH_SIZE];
|
import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityLog;
|
||||||
static {
|
import java.io.FileOutputStream;
|
||||||
for (int i = 0; i < BATCH_SIZE; i++) {
|
import java.io.PrintWriter;
|
||||||
EVENT_TYPES[i] = EVENT_TYPE;
|
import java.io.StringWriter;
|
||||||
RETURN_CODES[i] = RETURN_CODE;
|
import java.util.ArrayList;
|
||||||
LATENCIES[i] = i;
|
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_IPV4 = "192.0.2.1";
|
||||||
private static final String EXAMPLE_IPV6 = "2001:db8:1200::2:1";
|
private static final String EXAMPLE_IPV6 = "2001:db8:1200::2:1";
|
||||||
|
|
||||||
NetdEventListenerService mNetdEventListenerService;
|
NetdEventListenerService mNetdEventListenerService;
|
||||||
|
ConnectivityManager mCm;
|
||||||
|
|
||||||
@Mock ConnectivityManager mCm;
|
@Before
|
||||||
@Mock IpConnectivityLog mLog;
|
|
||||||
ArgumentCaptor<NetworkCallback> mCallbackCaptor;
|
|
||||||
ArgumentCaptor<DnsEvent> mDnsEvCaptor;
|
|
||||||
|
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
NetworkCapabilities ncWifi = new NetworkCapabilities();
|
||||||
mCallbackCaptor = ArgumentCaptor.forClass(NetworkCallback.class);
|
NetworkCapabilities ncCell = new NetworkCapabilities();
|
||||||
mDnsEvCaptor = ArgumentCaptor.forClass(DnsEvent.class);
|
ncWifi.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
|
||||||
mNetdEventListenerService = new NetdEventListenerService(mCm, mLog);
|
ncCell.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
|
||||||
|
|
||||||
verify(mCm, times(1)).registerNetworkCallback(any(), mCallbackCaptor.capture());
|
mCm = mock(ConnectivityManager.class);
|
||||||
|
when(mCm.getNetworkCapabilities(new Network(100))).thenReturn(ncWifi);
|
||||||
|
when(mCm.getNetworkCapabilities(new Network(101))).thenReturn(ncCell);
|
||||||
|
|
||||||
|
mNetdEventListenerService = new NetdEventListenerService(mCm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SmallTest
|
@Test
|
||||||
public void testOneDnsBatch() throws Exception {
|
public void testDnsLogging() throws Exception {
|
||||||
log(105, LATENCIES);
|
asyncDump(100);
|
||||||
log(106, Arrays.copyOf(LATENCIES, BATCH_SIZE - 1)); // one lookup short of a batch event
|
|
||||||
|
|
||||||
verifyLoggedDnsEvents(new DnsEvent(105, EVENT_TYPES, RETURN_CODES, LATENCIES));
|
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);
|
||||||
|
|
||||||
log(106, Arrays.copyOfRange(LATENCIES, BATCH_SIZE - 1, BATCH_SIZE));
|
String got = flushStatistics();
|
||||||
|
String want = String.join("\n",
|
||||||
mDnsEvCaptor = ArgumentCaptor.forClass(DnsEvent.class); // reset argument captor
|
"dropped_events: 0",
|
||||||
verifyLoggedDnsEvents(
|
"events <",
|
||||||
new DnsEvent(105, EVENT_TYPES, RETURN_CODES, LATENCIES),
|
" if_name: \"\"",
|
||||||
new DnsEvent(106, EVENT_TYPES, RETURN_CODES, LATENCIES));
|
" 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
|
@Test
|
||||||
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
|
|
||||||
public void testConnectLogging() throws Exception {
|
public void testConnectLogging() throws Exception {
|
||||||
|
asyncDump(100);
|
||||||
|
|
||||||
final int OK = 0;
|
final int OK = 0;
|
||||||
Thread[] logActions = {
|
Thread[] logActions = {
|
||||||
// ignored
|
// ignored
|
||||||
connectEventAction(OsConstants.EALREADY, 0, EXAMPLE_IPV4),
|
connectEventAction(100, OsConstants.EALREADY, 0, EXAMPLE_IPV4),
|
||||||
connectEventAction(OsConstants.EALREADY, 0, EXAMPLE_IPV6),
|
connectEventAction(100, OsConstants.EALREADY, 0, EXAMPLE_IPV6),
|
||||||
connectEventAction(OsConstants.EINPROGRESS, 0, EXAMPLE_IPV4),
|
connectEventAction(100, OsConstants.EINPROGRESS, 0, EXAMPLE_IPV4),
|
||||||
connectEventAction(OsConstants.EINPROGRESS, 0, EXAMPLE_IPV6),
|
connectEventAction(101, OsConstants.EINPROGRESS, 0, EXAMPLE_IPV6),
|
||||||
connectEventAction(OsConstants.EINPROGRESS, 0, EXAMPLE_IPV6),
|
connectEventAction(101, OsConstants.EINPROGRESS, 0, EXAMPLE_IPV6),
|
||||||
// valid latencies
|
// valid latencies
|
||||||
connectEventAction(OK, 110, EXAMPLE_IPV4),
|
connectEventAction(100, OK, 110, EXAMPLE_IPV4),
|
||||||
connectEventAction(OK, 23, EXAMPLE_IPV4),
|
connectEventAction(100, OK, 23, EXAMPLE_IPV4),
|
||||||
connectEventAction(OK, 45, EXAMPLE_IPV4),
|
connectEventAction(100, OK, 45, EXAMPLE_IPV4),
|
||||||
connectEventAction(OK, 56, EXAMPLE_IPV4),
|
connectEventAction(101, OK, 56, EXAMPLE_IPV4),
|
||||||
connectEventAction(OK, 523, EXAMPLE_IPV6),
|
connectEventAction(101, OK, 523, EXAMPLE_IPV6),
|
||||||
connectEventAction(OK, 214, EXAMPLE_IPV6),
|
connectEventAction(101, OK, 214, EXAMPLE_IPV6),
|
||||||
connectEventAction(OK, 67, EXAMPLE_IPV6),
|
connectEventAction(101, OK, 67, EXAMPLE_IPV6),
|
||||||
// errors
|
// errors
|
||||||
connectEventAction(OsConstants.EPERM, 0, EXAMPLE_IPV4),
|
connectEventAction(100, OsConstants.EPERM, 0, EXAMPLE_IPV4),
|
||||||
connectEventAction(OsConstants.EPERM, 0, EXAMPLE_IPV4),
|
connectEventAction(101, OsConstants.EPERM, 0, EXAMPLE_IPV4),
|
||||||
connectEventAction(OsConstants.EAGAIN, 0, EXAMPLE_IPV4),
|
connectEventAction(100, OsConstants.EAGAIN, 0, EXAMPLE_IPV4),
|
||||||
connectEventAction(OsConstants.EACCES, 0, EXAMPLE_IPV4),
|
connectEventAction(100, OsConstants.EACCES, 0, EXAMPLE_IPV4),
|
||||||
connectEventAction(OsConstants.EACCES, 0, EXAMPLE_IPV4),
|
connectEventAction(101, OsConstants.EACCES, 0, EXAMPLE_IPV4),
|
||||||
connectEventAction(OsConstants.EACCES, 0, EXAMPLE_IPV6),
|
connectEventAction(101, OsConstants.EACCES, 0, EXAMPLE_IPV6),
|
||||||
connectEventAction(OsConstants.EADDRINUSE, 0, EXAMPLE_IPV4),
|
connectEventAction(100, OsConstants.EADDRINUSE, 0, EXAMPLE_IPV4),
|
||||||
connectEventAction(OsConstants.ETIMEDOUT, 0, EXAMPLE_IPV4),
|
connectEventAction(101, OsConstants.ETIMEDOUT, 0, EXAMPLE_IPV4),
|
||||||
connectEventAction(OsConstants.ETIMEDOUT, 0, EXAMPLE_IPV6),
|
connectEventAction(100, OsConstants.ETIMEDOUT, 0, EXAMPLE_IPV6),
|
||||||
connectEventAction(OsConstants.ETIMEDOUT, 0, EXAMPLE_IPV6),
|
connectEventAction(100, OsConstants.ETIMEDOUT, 0, EXAMPLE_IPV6),
|
||||||
connectEventAction(OsConstants.ECONNREFUSED, 0, EXAMPLE_IPV4),
|
connectEventAction(101, OsConstants.ECONNREFUSED, 0, EXAMPLE_IPV4),
|
||||||
};
|
};
|
||||||
|
|
||||||
for (Thread t : logActions) {
|
for (Thread t : logActions) {
|
||||||
@@ -209,113 +201,124 @@ public class NetdEventListenerServiceTest extends TestCase {
|
|||||||
t.join();
|
t.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
List<IpConnectivityEvent> events = new ArrayList<>();
|
String got = flushStatistics();
|
||||||
mNetdEventListenerService.flushStatistics(events);
|
|
||||||
|
|
||||||
IpConnectivityEvent got = events.get(0);
|
|
||||||
String want = String.join("\n",
|
String want = String.join("\n",
|
||||||
"if_name: \"\"",
|
"dropped_events: 0",
|
||||||
"link_layer: 0",
|
"events <",
|
||||||
"network_id: 0",
|
" if_name: \"\"",
|
||||||
"time_ms: 0",
|
" link_layer: 4",
|
||||||
"transports: 0",
|
" network_id: 100",
|
||||||
"connect_statistics <",
|
" time_ms: 0",
|
||||||
" connect_blocking_count: 7",
|
" transports: 2",
|
||||||
" connect_count: 12",
|
" connect_statistics <",
|
||||||
" errnos_counters <",
|
" connect_blocking_count: 3",
|
||||||
" key: 1",
|
" connect_count: 6",
|
||||||
" value: 2",
|
" errnos_counters <",
|
||||||
|
" key: 1",
|
||||||
|
" value: 1",
|
||||||
|
" >",
|
||||||
|
" errnos_counters <",
|
||||||
|
" key: 11",
|
||||||
|
" value: 1",
|
||||||
|
" >",
|
||||||
|
" errnos_counters <",
|
||||||
|
" key: 13",
|
||||||
|
" value: 1",
|
||||||
|
" >",
|
||||||
|
" errnos_counters <",
|
||||||
|
" key: 98",
|
||||||
|
" value: 1",
|
||||||
|
" >",
|
||||||
|
" errnos_counters <",
|
||||||
|
" key: 110",
|
||||||
|
" value: 2",
|
||||||
|
" >",
|
||||||
|
" ipv6_addr_count: 1",
|
||||||
|
" latencies_ms: 23",
|
||||||
|
" latencies_ms: 45",
|
||||||
|
" latencies_ms: 110",
|
||||||
" >",
|
" >",
|
||||||
" errnos_counters <",
|
">",
|
||||||
" key: 11",
|
"events <",
|
||||||
" value: 1",
|
" if_name: \"\"",
|
||||||
|
" link_layer: 2",
|
||||||
|
" network_id: 101",
|
||||||
|
" time_ms: 0",
|
||||||
|
" transports: 1",
|
||||||
|
" connect_statistics <",
|
||||||
|
" connect_blocking_count: 4",
|
||||||
|
" connect_count: 6",
|
||||||
|
" errnos_counters <",
|
||||||
|
" key: 1",
|
||||||
|
" value: 1",
|
||||||
|
" >",
|
||||||
|
" errnos_counters <",
|
||||||
|
" key: 13",
|
||||||
|
" value: 2",
|
||||||
|
" >",
|
||||||
|
" errnos_counters <",
|
||||||
|
" key: 110",
|
||||||
|
" value: 1",
|
||||||
|
" >",
|
||||||
|
" errnos_counters <",
|
||||||
|
" key: 111",
|
||||||
|
" value: 1",
|
||||||
|
" >",
|
||||||
|
" ipv6_addr_count: 5",
|
||||||
|
" latencies_ms: 56",
|
||||||
|
" latencies_ms: 67",
|
||||||
|
" latencies_ms: 214",
|
||||||
|
" latencies_ms: 523",
|
||||||
" >",
|
" >",
|
||||||
" errnos_counters <",
|
">",
|
||||||
" key: 13",
|
"version: 2\n");
|
||||||
" value: 3",
|
assertEquals(want, got);
|
||||||
" >",
|
|
||||||
" 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",
|
|
||||||
">\n");
|
|
||||||
verifyConnectEvent(want, got);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread connectEventAction(int error, int latencyMs, String ipAddr) {
|
Thread connectEventAction(int netId, int error, int latencyMs, String ipAddr) {
|
||||||
return new Thread(() -> {
|
return new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
mNetdEventListenerService.onConnectEvent(100, error, latencyMs, ipAddr, 80, 1);
|
mNetdEventListenerService.onConnectEvent(netId, error, latencyMs, ipAddr, 80, 1);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
fail(e.toString());
|
fail(e.toString());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void log(int netId, int[] latencies) {
|
void dnsEvent(int netId, int type, int result, int latency) throws Exception {
|
||||||
try {
|
mNetdEventListenerService.onDnsEvent(netId, type, result, latency, "", null, 0, 0);
|
||||||
for (int l : latencies) {
|
}
|
||||||
mNetdEventListenerService.onDnsEvent(netId, EVENT_TYPE, RETURN_CODE, l, null, null,
|
|
||||||
0, 0);
|
void asyncDump(long durationMs) throws Exception {
|
||||||
|
final long stop = System.currentTimeMillis() + durationMs;
|
||||||
|
final PrintWriter pw = new PrintWriter(new FileOutputStream("/dev/null"));
|
||||||
|
new Thread(() -> {
|
||||||
|
while (System.currentTimeMillis() < stop) {
|
||||||
|
mNetdEventListenerService.dump(pw);
|
||||||
}
|
}
|
||||||
} catch (RemoteException re) {
|
}).start();
|
||||||
throw re.rethrowFromSystemServer();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void logDnsAsync(int netId, int[] latencies) {
|
// TODO: instead of comparing textpb to textpb, parse textpb and compare proto to proto.
|
||||||
new Thread(() -> log(netId, latencies)).start();
|
String flushStatistics() throws Exception {
|
||||||
}
|
IpConnectivityMetrics metricsService =
|
||||||
|
new IpConnectivityMetrics(mock(Context.class), (ctx) -> 2000);
|
||||||
|
metricsService.mNetdListener = mNetdEventListenerService;
|
||||||
|
|
||||||
void verifyLoggedDnsEvents(DnsEvent... expected) {
|
StringWriter buffer = new StringWriter();
|
||||||
verifyLoggedDnsEvents(0, expected);
|
PrintWriter writer = new PrintWriter(buffer);
|
||||||
}
|
metricsService.impl.dump(null, writer, new String[]{"flush"});
|
||||||
|
byte[] bytes = Base64.decode(buffer.toString(), Base64.DEFAULT);
|
||||||
void verifyLoggedDnsEvents(int wait, DnsEvent... expectedEvents) {
|
IpConnectivityLog log = IpConnectivityLog.parseFrom(bytes);
|
||||||
verify(mLog, timeout(wait).times(expectedEvents.length)).log(mDnsEvCaptor.capture());
|
for (IpConnectivityEvent ev : log.events) {
|
||||||
for (DnsEvent got : mDnsEvCaptor.getAllValues()) {
|
if (ev.getConnectStatistics() == null) {
|
||||||
OptionalInt index = IntStream.range(0, expectedEvents.length)
|
continue;
|
||||||
.filter(i -> dnsEventsEqual(expectedEvents[i], got))
|
}
|
||||||
.findFirst();
|
// Sort repeated fields of connect() events arriving in non-deterministic order.
|
||||||
// Don't match same expected event more than once.
|
Arrays.sort(ev.getConnectStatistics().latenciesMs);
|
||||||
index.ifPresent(i -> expectedEvents[i] = null);
|
Arrays.sort(ev.getConnectStatistics().errnosCounters,
|
||||||
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) {
|
|
||||||
try {
|
|
||||||
Arrays.sort(got.getConnectStatistics().latenciesMs);
|
|
||||||
Arrays.sort(got.getConnectStatistics().errnosCounters,
|
|
||||||
Comparator.comparingInt((p) -> p.key));
|
Comparator.comparingInt((p) -> p.key));
|
||||||
assertEquals(expected, got.toString());
|
|
||||||
} catch (Exception e) {
|
|
||||||
fail(e.toString());
|
|
||||||
}
|
}
|
||||||
|
return log.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user