Merge changes Ied9d0cec,I3087f446,Ibe706872 into oc-mr1-dev

* changes:
  Wakeup packet events: addressing a few comments
  Connectivity metrics: add WakeupStats events
  Connectivity metrics: collect NFLOG wakeup events
This commit is contained in:
Hugo Benichi
2017-09-20 00:58:35 +00:00
committed by Android (Google) Code Review
3 changed files with 246 additions and 16 deletions

View File

@@ -16,6 +16,8 @@
package com.android.server.connectivity;
import static android.net.metrics.INetdEventListener.EVENT_GETADDRINFO;
import static android.net.metrics.INetdEventListener.EVENT_GETHOSTBYNAME;
import static com.android.server.connectivity.MetricsTestUtil.aBool;
import static com.android.server.connectivity.MetricsTestUtil.aByteArray;
import static com.android.server.connectivity.MetricsTestUtil.aLong;
@@ -31,29 +33,41 @@ import static com.android.server.connectivity.metrics.nano.IpConnectivityLogClas
import static com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.ETHERNET;
import static com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.MULTIPLE;
import static com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.WIFI;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import android.net.ConnectivityMetricsEvent;
import android.net.metrics.ApfProgramEvent;
import android.net.metrics.ApfStats;
import android.net.metrics.ConnectStats;
import android.net.metrics.DefaultNetworkEvent;
import android.net.metrics.DhcpClientEvent;
import android.net.metrics.DhcpErrorEvent;
import android.net.metrics.DnsEvent;
import android.net.metrics.DnsEvent;
import android.net.metrics.IpManagerEvent;
import android.net.metrics.IpReachabilityEvent;
import android.net.metrics.NetworkEvent;
import android.net.metrics.RaEvent;
import android.net.metrics.ValidationProbeEvent;
import android.net.metrics.WakeupStats;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityEvent;
import java.util.Arrays;
import java.util.List;
import junit.framework.TestCase;
import org.junit.runner.RunWith;
import org.junit.Test;
// TODO: instead of comparing textpb to textpb, parse textpb and compare proto to proto.
public class IpConnectivityEventBuilderTest extends TestCase {
@RunWith(AndroidJUnit4.class)
@SmallTest
public class IpConnectivityEventBuilderTest {
@SmallTest
@Test
public void testLinkLayerInferrence() {
ConnectivityMetricsEvent ev = describeIpEvent(
aType(IpReachabilityEvent.class),
@@ -182,7 +196,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
verifySerialization(want, ev);
}
@SmallTest
@Test
public void testDefaultNetworkEventSerialization() {
ConnectivityMetricsEvent ev = describeIpEvent(
aType(DefaultNetworkEvent.class),
@@ -223,7 +237,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
verifySerialization(want, ev);
}
@SmallTest
@Test
public void testDhcpClientEventSerialization() {
ConnectivityMetricsEvent ev = describeIpEvent(
aType(DhcpClientEvent.class),
@@ -249,7 +263,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
verifySerialization(want, ev);
}
@SmallTest
@Test
public void testDhcpErrorEventSerialization() {
ConnectivityMetricsEvent ev = describeIpEvent(
aType(DhcpErrorEvent.class),
@@ -274,7 +288,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
verifySerialization(want, ev);
}
@SmallTest
@Test
public void testIpManagerEventSerialization() {
ConnectivityMetricsEvent ev = describeIpEvent(
aType(IpManagerEvent.class),
@@ -300,7 +314,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
verifySerialization(want, ev);
}
@SmallTest
@Test
public void testIpReachabilityEventSerialization() {
ConnectivityMetricsEvent ev = describeIpEvent(
aType(IpReachabilityEvent.class),
@@ -324,7 +338,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
verifySerialization(want, ev);
}
@SmallTest
@Test
public void testNetworkEventSerialization() {
ConnectivityMetricsEvent ev = describeIpEvent(
aType(NetworkEvent.class),
@@ -353,7 +367,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
verifySerialization(want, ev);
}
@SmallTest
@Test
public void testValidationProbeEventSerialization() {
ConnectivityMetricsEvent ev = describeIpEvent(
aType(ValidationProbeEvent.class),
@@ -380,7 +394,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
verifySerialization(want, ev);
}
@SmallTest
@Test
public void testApfProgramEventSerialization() {
ConnectivityMetricsEvent ev = describeIpEvent(
aType(ApfProgramEvent.class),
@@ -414,7 +428,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
verifySerialization(want, ev);
}
@SmallTest
@Test
public void testApfStatsSerialization() {
ConnectivityMetricsEvent ev = describeIpEvent(
aType(ApfStats.class),
@@ -457,7 +471,7 @@ public class IpConnectivityEventBuilderTest extends TestCase {
verifySerialization(want, ev);
}
@SmallTest
@Test
public void testRaEventSerialization() {
ConnectivityMetricsEvent ev = describeIpEvent(
aType(RaEvent.class),
@@ -490,11 +504,49 @@ public class IpConnectivityEventBuilderTest extends TestCase {
verifySerialization(want, ev);
}
@Test
public void testWakeupStatsSerialization() {
WakeupStats stats = new WakeupStats("wlan0");
stats.totalWakeups = 14;
stats.applicationWakeups = 5;
stats.nonApplicationWakeups = 1;
stats.rootWakeups = 2;
stats.systemWakeups = 3;
stats.noUidWakeups = 3;
IpConnectivityEvent got = IpConnectivityEventBuilder.toProto(stats);
String want = String.join("\n",
"dropped_events: 0",
"events <",
" if_name: \"\"",
" link_layer: 4",
" network_id: 0",
" time_ms: 0",
" transports: 0",
" wakeup_stats <",
" application_wakeups: 5",
" duration_sec: 0",
" no_uid_wakeups: 3",
" non_application_wakeups: 1",
" root_wakeups: 2",
" system_wakeups: 3",
" total_wakeups: 14",
" >",
">",
"version: 2\n");
verifySerialization(want, got);
}
static void verifySerialization(String want, ConnectivityMetricsEvent... input) {
List<IpConnectivityEvent> protoInput =
IpConnectivityEventBuilder.toProto(Arrays.asList(input));
verifySerialization(want, protoInput.toArray(new IpConnectivityEvent[0]));
}
static void verifySerialization(String want, IpConnectivityEvent... input) {
try {
List<IpConnectivityEvent> proto =
IpConnectivityEventBuilder.toProto(Arrays.asList(input));
byte[] got = IpConnectivityEventBuilder.serialize(0, proto);
byte[] got = IpConnectivityEventBuilder.serialize(0, Arrays.asList(input));
IpConnectivityLog log = IpConnectivityLog.parseFrom(got);
assertEquals(want, log.toString());
} catch (Exception e) {

View File

@@ -224,6 +224,15 @@ public class IpConnectivityMetricsTest {
dnsEvent(101, EVENT_GETADDRINFO, 0, 56);
dnsEvent(101, EVENT_GETHOSTBYNAME, 0, 34);
// iface, uid
wakeupEvent("wlan0", 1000);
wakeupEvent("rmnet0", 10123);
wakeupEvent("wlan0", 1000);
wakeupEvent("rmnet0", 10008);
wakeupEvent("wlan0", -1);
wakeupEvent("wlan0", 10008);
wakeupEvent("rmnet0", 1000);
String want = String.join("\n",
"dropped_events: 0",
"events <",
@@ -405,6 +414,38 @@ public class IpConnectivityMetricsTest {
" return_codes: 0",
" >",
">",
"events <",
" if_name: \"\"",
" link_layer: 2",
" network_id: 0",
" time_ms: 0",
" transports: 0",
" wakeup_stats <",
" application_wakeups: 2",
" duration_sec: 0",
" no_uid_wakeups: 0",
" non_application_wakeups: 0",
" root_wakeups: 0",
" system_wakeups: 1",
" total_wakeups: 3",
" >",
">",
"events <",
" if_name: \"\"",
" link_layer: 4",
" network_id: 0",
" time_ms: 0",
" transports: 0",
" wakeup_stats <",
" application_wakeups: 1",
" duration_sec: 0",
" no_uid_wakeups: 1",
" non_application_wakeups: 0",
" root_wakeups: 0",
" system_wakeups: 2",
" total_wakeups: 4",
" >",
">",
"version: 2\n");
verifySerialization(want, getdump("flush"));
@@ -425,6 +466,11 @@ public class IpConnectivityMetricsTest {
mNetdListener.onDnsEvent(netId, type, result, latency, "", null, 0, 0);
}
void wakeupEvent(String iface, int uid) throws Exception {
String prefix = NetdEventListenerService.WAKEUP_EVENT_IFACE_PREFIX + iface;
mNetdListener.onWakeupEvent(prefix, uid, uid, 0);
}
List<ConnectivityMetricsEvent> verifyEvents(int n, int timeoutMs) throws Exception {
ArgumentCaptor<ConnectivityMetricsEvent> captor =
ArgumentCaptor.forClass(ConnectivityMetricsEvent.class);

View File

@@ -19,6 +19,7 @@ package com.android.server.connectivity;
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.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
@@ -37,9 +38,11 @@ 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;
@@ -47,6 +50,7 @@ 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;
@@ -74,6 +78,118 @@ public class NetdEventListenerServiceTest {
mNetdEventListenerService = new NetdEventListenerService(mCm);
}
@Test
public void testWakeupEventLogging() throws Exception {
final int BUFFER_LENGTH = NetdEventListenerService.WAKEUP_EVENT_BUFFER_LENGTH;
// Assert no events
String[] events1 = listNetdEvent();
assertEquals(new String[]{""}, events1);
long now = System.currentTimeMillis();
String prefix = "iface:wlan0";
int[] uids = { 10001, 10002, 10004, 1000, 10052, 10023, 10002, 10123, 10004 };
for (int uid : uids) {
mNetdEventListenerService.onWakeupEvent(prefix, uid, uid, now);
}
String[] events2 = listNetdEvent();
int expectedLength2 = uids.length + 1; // +1 for the WakeupStats line
assertEquals(expectedLength2, events2.length);
assertContains(events2[0], "WakeupStats");
assertContains(events2[0], "wlan0");
for (int i = 0; i < uids.length; i++) {
String got = events2[i+1];
assertContains(got, "WakeupEvent");
assertContains(got, "wlan0");
assertContains(got, "uid: " + uids[i]);
}
int uid = 20000;
for (int i = 0; i < BUFFER_LENGTH * 2; i++) {
long ts = now + 10;
mNetdEventListenerService.onWakeupEvent(prefix, uid, uid, ts);
}
String[] events3 = listNetdEvent();
int expectedLength3 = BUFFER_LENGTH + 1; // +1 for the WakeupStats line
assertEquals(expectedLength3, events3.length);
assertContains(events2[0], "WakeupStats");
assertContains(events2[0], "wlan0");
for (int i = 1; i < expectedLength3; i++) {
String got = events3[i];
assertContains(got, "WakeupEvent");
assertContains(got, "wlan0");
assertContains(got, "uid: " + uid);
}
uid = 45678;
mNetdEventListenerService.onWakeupEvent(prefix, uid, uid, now);
String[] events4 = listNetdEvent();
String lastEvent = events4[events4.length - 1];
assertContains(lastEvent, "WakeupEvent");
assertContains(lastEvent, "wlan0");
assertContains(lastEvent, "uid: " + uid);
}
@Test
public void testWakeupStatsLogging() throws Exception {
wakeupEvent("wlan0", 1000);
wakeupEvent("rmnet0", 10123);
wakeupEvent("wlan0", 1000);
wakeupEvent("rmnet0", 10008);
wakeupEvent("wlan0", -1);
wakeupEvent("wlan0", 10008);
wakeupEvent("rmnet0", 1000);
wakeupEvent("wlan0", 10004);
wakeupEvent("wlan0", 1000);
wakeupEvent("wlan0", 0);
wakeupEvent("wlan0", -1);
wakeupEvent("rmnet0", 10052);
wakeupEvent("wlan0", 0);
wakeupEvent("rmnet0", 1000);
wakeupEvent("wlan0", 1010);
String got = flushStatistics();
String want = String.join("\n",
"dropped_events: 0",
"events <",
" if_name: \"\"",
" link_layer: 2",
" network_id: 0",
" time_ms: 0",
" transports: 0",
" wakeup_stats <",
" application_wakeups: 3",
" duration_sec: 0",
" no_uid_wakeups: 0",
" non_application_wakeups: 0",
" root_wakeups: 0",
" system_wakeups: 2",
" total_wakeups: 5",
" >",
">",
"events <",
" if_name: \"\"",
" link_layer: 4",
" network_id: 0",
" time_ms: 0",
" transports: 0",
" wakeup_stats <",
" application_wakeups: 2",
" duration_sec: 0",
" no_uid_wakeups: 2",
" non_application_wakeups: 1",
" root_wakeups: 2",
" system_wakeups: 3",
" total_wakeups: 10",
" >",
">",
"version: 2\n");
assertEquals(want, got);
}
@Test
public void testDnsLogging() throws Exception {
asyncDump(100);
@@ -297,6 +413,11 @@ public class NetdEventListenerServiceTest {
mNetdEventListenerService.onDnsEvent(netId, type, result, latency, "", null, 0, 0);
}
void wakeupEvent(String iface, int uid) throws Exception {
String prefix = NetdEventListenerService.WAKEUP_EVENT_IFACE_PREFIX + iface;
mNetdEventListenerService.onWakeupEvent(prefix, uid, uid, 0);
}
void asyncDump(long durationMs) throws Exception {
final long stop = System.currentTimeMillis() + durationMs;
final PrintWriter pw = new PrintWriter(new FileOutputStream("/dev/null"));
@@ -329,4 +450,15 @@ public class NetdEventListenerServiceTest {
}
return log.toString();
}
String[] listNetdEvent() throws Exception {
StringWriter buffer = new StringWriter();
PrintWriter writer = new PrintWriter(buffer);
mNetdEventListenerService.list(writer);
return buffer.toString().split("\\n");
}
static void assertContains(String got, String want) {
assertTrue(got + " did not contain \"" + want + "\"", got.contains(want));
}
}