Read "qtaguid" network stats, refactor templates.

Teach NMS to read qtaguid stats from kernel, but fall back to older
stats when kernel doesn't support.  Add "tags" to NetworkStats entries
to support qtaguid.  To work around double-reporting bug, subtract
tagged stats from TAG_NONE entry.

Flesh out stronger NetworkTemplate.  All NetworkStatsService requests
now require a template, and moved matching logic into template.

Record UID stats keyed on complete NetworkIdentitySet definition,
similar to how interface stats are stored.  Since previous UID stats
didn't have iface breakdown, discard during file format upgrade.

Change-Id: I0447b5e7d205d73d28e71c889c568e536e91b8e4
This commit is contained in:
Jeff Sharkey
2011-06-18 18:34:16 -07:00
parent a47d7a1a70
commit de450f98eb
2 changed files with 80 additions and 50 deletions

View File

@@ -16,6 +16,8 @@
package android.net;
import static android.net.NetworkStats.TAG_NONE;
import android.test.suitebuilder.annotation.SmallTest;
import junit.framework.TestCase;
@@ -29,14 +31,14 @@ public class NetworkStatsTest extends TestCase {
public void testFindIndex() throws Exception {
final NetworkStats stats = new NetworkStats(TEST_START, 3)
.addEntry(TEST_IFACE, 100, 1024, 0)
.addEntry(TEST_IFACE, 101, 0, 1024)
.addEntry(TEST_IFACE, 102, 1024, 1024);
.addEntry(TEST_IFACE, 100, TAG_NONE, 1024L, 0L)
.addEntry(TEST_IFACE, 101, TAG_NONE, 0L, 1024L)
.addEntry(TEST_IFACE, 102, TAG_NONE, 1024L, 1024L);
assertEquals(2, stats.findIndex(TEST_IFACE, 102));
assertEquals(2, stats.findIndex(TEST_IFACE, 102));
assertEquals(0, stats.findIndex(TEST_IFACE, 100));
assertEquals(-1, stats.findIndex(TEST_IFACE, 6));
assertEquals(2, stats.findIndex(TEST_IFACE, 102, TAG_NONE));
assertEquals(2, stats.findIndex(TEST_IFACE, 102, TAG_NONE));
assertEquals(0, stats.findIndex(TEST_IFACE, 100, TAG_NONE));
assertEquals(-1, stats.findIndex(TEST_IFACE, 6, TAG_NONE));
}
public void testAddEntryGrow() throws Exception {
@@ -45,15 +47,15 @@ public class NetworkStatsTest extends TestCase {
assertEquals(0, stats.size);
assertEquals(2, stats.iface.length);
stats.addEntry(TEST_IFACE, TEST_UID, 1L, 2L);
stats.addEntry(TEST_IFACE, TEST_UID, 2L, 2L);
stats.addEntry(TEST_IFACE, TEST_UID, TAG_NONE, 1L, 2L);
stats.addEntry(TEST_IFACE, TEST_UID, TAG_NONE, 2L, 2L);
assertEquals(2, stats.size);
assertEquals(2, stats.iface.length);
stats.addEntry(TEST_IFACE, TEST_UID, 3L, 4L);
stats.addEntry(TEST_IFACE, TEST_UID, 4L, 4L);
stats.addEntry(TEST_IFACE, TEST_UID, 5L, 5L);
stats.addEntry(TEST_IFACE, TEST_UID, TAG_NONE, 3L, 4L);
stats.addEntry(TEST_IFACE, TEST_UID, TAG_NONE, 4L, 4L);
stats.addEntry(TEST_IFACE, TEST_UID, TAG_NONE, 5L, 5L);
assertEquals(5, stats.size);
assertTrue(stats.iface.length >= 5);
@@ -65,14 +67,31 @@ public class NetworkStatsTest extends TestCase {
assertEquals(5L, stats.rx[4]);
}
public void testCombineExisting() throws Exception {
final NetworkStats stats = new NetworkStats(TEST_START, 10);
stats.addEntry(TEST_IFACE, 1001, TAG_NONE, 512L, 256L);
stats.addEntry(TEST_IFACE, 1001, 0xff, 128L, 128L);
stats.combineEntry(TEST_IFACE, 1001, TAG_NONE, -128L, -128L);
assertStatsEntry(stats, 0, TEST_IFACE, 1001, TAG_NONE, 384L, 128L);
assertStatsEntry(stats, 1, TEST_IFACE, 1001, 0xff, 128L, 128L);
// now try combining that should create row
stats.combineEntry(TEST_IFACE, 5005, TAG_NONE, 128L, 128L);
assertStatsEntry(stats, 2, TEST_IFACE, 5005, TAG_NONE, 128L, 128L);
stats.combineEntry(TEST_IFACE, 5005, TAG_NONE, 128L, 128L);
assertStatsEntry(stats, 2, TEST_IFACE, 5005, TAG_NONE, 256L, 256L);
}
public void testSubtractIdenticalData() throws Exception {
final NetworkStats before = new NetworkStats(TEST_START, 2)
.addEntry(TEST_IFACE, 100, 1024, 0)
.addEntry(TEST_IFACE, 101, 0, 1024);
.addEntry(TEST_IFACE, 100, TAG_NONE, 1024L, 0L)
.addEntry(TEST_IFACE, 101, TAG_NONE, 0L, 1024L);
final NetworkStats after = new NetworkStats(TEST_START, 2)
.addEntry(TEST_IFACE, 100, 1024, 0)
.addEntry(TEST_IFACE, 101, 0, 1024);
.addEntry(TEST_IFACE, 100, TAG_NONE, 1024L, 0L)
.addEntry(TEST_IFACE, 101, TAG_NONE, 0L, 1024L);
final NetworkStats result = after.subtract(before);
@@ -85,12 +104,12 @@ public class NetworkStatsTest extends TestCase {
public void testSubtractIdenticalRows() throws Exception {
final NetworkStats before = new NetworkStats(TEST_START, 2)
.addEntry(TEST_IFACE, 100, 1024, 0)
.addEntry(TEST_IFACE, 101, 0, 1024);
.addEntry(TEST_IFACE, 100, TAG_NONE, 1024L, 0L)
.addEntry(TEST_IFACE, 101, TAG_NONE, 0L, 1024L);
final NetworkStats after = new NetworkStats(TEST_START, 2)
.addEntry(TEST_IFACE, 100, 1025, 2)
.addEntry(TEST_IFACE, 101, 3, 1028);
.addEntry(TEST_IFACE, 100, TAG_NONE, 1025L, 2L)
.addEntry(TEST_IFACE, 101, TAG_NONE, 3L, 1028L);
final NetworkStats result = after.subtract(before);
@@ -103,13 +122,13 @@ public class NetworkStatsTest extends TestCase {
public void testSubtractNewRows() throws Exception {
final NetworkStats before = new NetworkStats(TEST_START, 2)
.addEntry(TEST_IFACE, 100, 1024, 0)
.addEntry(TEST_IFACE, 101, 0, 1024);
.addEntry(TEST_IFACE, 100, TAG_NONE, 1024L, 0L)
.addEntry(TEST_IFACE, 101, TAG_NONE, 0L, 1024L);
final NetworkStats after = new NetworkStats(TEST_START, 3)
.addEntry(TEST_IFACE, 100, 1024, 0)
.addEntry(TEST_IFACE, 101, 0, 1024)
.addEntry(TEST_IFACE, 102, 1024, 1024);
.addEntry(TEST_IFACE, 100, TAG_NONE, 1024L, 0L)
.addEntry(TEST_IFACE, 101, TAG_NONE, 0L, 1024L)
.addEntry(TEST_IFACE, 102, TAG_NONE, 1024L, 1024L);
final NetworkStats result = after.subtract(before);
@@ -122,4 +141,13 @@ public class NetworkStatsTest extends TestCase {
assertEquals(1024, result.tx[2]);
}
private static void assertStatsEntry(
NetworkStats stats, int i, String iface, int uid, int tag, long rx, long tx) {
assertEquals(iface, stats.iface[i]);
assertEquals(uid, stats.uid[i]);
assertEquals(tag, stats.tag[i]);
assertEquals(rx, stats.rx[i]);
assertEquals(tx, stats.tx[i]);
}
}

View File

@@ -18,9 +18,9 @@ package com.android.server;
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
import static android.net.ConnectivityManager.TYPE_WIFI;
import static android.net.NetworkStats.IFACE_ALL;
import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL;
import static android.net.TrafficStats.TEMPLATE_WIFI;
import static android.net.NetworkTemplate.MATCH_WIFI;
import static android.text.format.DateUtils.DAY_IN_MILLIS;
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
@@ -44,6 +44,7 @@ import android.net.NetworkInfo.DetailedState;
import android.net.NetworkState;
import android.net.NetworkStats;
import android.net.NetworkStatsHistory;
import android.net.NetworkTemplate;
import android.os.INetworkManagementService;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.LargeTest;
@@ -66,6 +67,8 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
private static final String TEST_IFACE = "test0";
private static final long TEST_START = 1194220800000L;
private static NetworkTemplate sTemplateWifi = new NetworkTemplate(MATCH_WIFI, null);
private static final int TEST_UID_1 = 1001;
private static final int TEST_UID_2 = 1002;
@@ -138,7 +141,7 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
// verify service has empty history for wifi
assertNetworkTotal(TEMPLATE_WIFI, 0L, 0L);
assertNetworkTotal(sTemplateWifi, 0L, 0L);
verifyAndReset();
// modify some number on wifi, and trigger poll event
@@ -146,14 +149,14 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectTime(TEST_START + elapsedRealtime);
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
.addEntry(TEST_IFACE, UID_ALL, 1024L, 2048L));
.addEntry(TEST_IFACE, UID_ALL, TAG_NONE, 1024L, 2048L));
expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime));
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify service recorded history
assertNetworkTotal(TEMPLATE_WIFI, 1024L, 2048L);
assertNetworkTotal(sTemplateWifi, 1024L, 2048L);
verifyAndReset();
// and bump forward again, with counters going higher. this is
@@ -162,14 +165,14 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectTime(TEST_START + elapsedRealtime);
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
.addEntry(TEST_IFACE, UID_ALL, 4096L, 8192L));
.addEntry(TEST_IFACE, UID_ALL, TAG_NONE, 4096L, 8192L));
expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime));
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify service recorded history
assertNetworkTotal(TEMPLATE_WIFI, 4096L, 8192L);
assertNetworkTotal(sTemplateWifi, 4096L, 8192L);
verifyAndReset();
}
@@ -189,7 +192,7 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
// verify service has empty history for wifi
assertNetworkTotal(TEMPLATE_WIFI, 0L, 0L);
assertNetworkTotal(sTemplateWifi, 0L, 0L);
verifyAndReset();
// modify some number on wifi, and trigger poll event
@@ -197,19 +200,18 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectTime(TEST_START + elapsedRealtime);
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
.addEntry(TEST_IFACE, UID_ALL, 1024L, 2048L));
// TODO: switch these stats to specific iface
.addEntry(TEST_IFACE, UID_ALL, TAG_NONE, 1024L, 2048L));
expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 2)
.addEntry(IFACE_ALL, TEST_UID_1, 512L, 256L)
.addEntry(IFACE_ALL, TEST_UID_2, 128L, 128L));
.addEntry(TEST_IFACE, TEST_UID_1, TAG_NONE, 512L, 256L)
.addEntry(TEST_IFACE, TEST_UID_2, TAG_NONE, 128L, 128L));
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify service recorded history
assertNetworkTotal(TEMPLATE_WIFI, 1024L, 2048L);
assertUidTotal(TEST_UID_1, TEMPLATE_WIFI, 512L, 256L);
assertUidTotal(TEST_UID_2, TEMPLATE_WIFI, 128L, 128L);
assertNetworkTotal(sTemplateWifi, 1024L, 2048L);
assertUidTotal(sTemplateWifi, TEST_UID_1, 512L, 256L);
assertUidTotal(sTemplateWifi, TEST_UID_2, 128L, 128L);
verifyAndReset();
// graceful shutdown system, which should trigger persist of stats, and
@@ -220,7 +222,7 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
// we persisted them to file.
expectDefaultSettings();
replay();
assertNetworkTotal(TEMPLATE_WIFI, 0L, 0L);
assertNetworkTotal(sTemplateWifi, 0L, 0L);
verifyAndReset();
assertStatsFilesExist(true);
@@ -233,9 +235,9 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
mService.systemReady();
// after systemReady(), we should have historical stats loaded again
assertNetworkTotal(TEMPLATE_WIFI, 1024L, 2048L);
assertUidTotal(TEST_UID_1, TEMPLATE_WIFI, 512L, 256L);
assertUidTotal(TEST_UID_2, TEMPLATE_WIFI, 128L, 128L);
assertNetworkTotal(sTemplateWifi, 1024L, 2048L);
assertUidTotal(sTemplateWifi, TEST_UID_1, 512L, 256L);
assertUidTotal(sTemplateWifi, TEST_UID_2, 128L, 128L);
verifyAndReset();
}
@@ -263,14 +265,14 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectTime(TEST_START + elapsedRealtime);
expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
.addEntry(TEST_IFACE, UID_ALL, 512L, 512L));
.addEntry(TEST_IFACE, UID_ALL, TAG_NONE, 512L, 512L));
expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime));
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify service recorded history
history = mService.getHistoryForNetwork(TEMPLATE_WIFI);
history = mService.getHistoryForNetwork(new NetworkTemplate(MATCH_WIFI, null));
total = history.getTotalData(Long.MIN_VALUE, Long.MAX_VALUE, null);
assertEquals(512L, total[0]);
assertEquals(512L, total[1]);
@@ -289,7 +291,7 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify identical stats, but spread across 4 buckets now
history = mService.getHistoryForNetwork(TEMPLATE_WIFI);
history = mService.getHistoryForNetwork(new NetworkTemplate(MATCH_WIFI, null));
total = history.getTotalData(Long.MIN_VALUE, Long.MAX_VALUE, null);
assertEquals(512L, total[0]);
assertEquals(512L, total[1]);
@@ -299,15 +301,15 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
}
private void assertNetworkTotal(int template, long rx, long tx) {
private void assertNetworkTotal(NetworkTemplate template, long rx, long tx) {
final NetworkStatsHistory history = mService.getHistoryForNetwork(template);
final long[] total = history.getTotalData(Long.MIN_VALUE, Long.MAX_VALUE, null);
assertEquals(rx, total[0]);
assertEquals(tx, total[1]);
}
private void assertUidTotal(int uid, int template, long rx, long tx) {
final NetworkStatsHistory history = mService.getHistoryForUid(uid, template);
private void assertUidTotal(NetworkTemplate template, int uid, long rx, long tx) {
final NetworkStatsHistory history = mService.getHistoryForUid(template, uid);
final long[] total = history.getTotalData(Long.MIN_VALUE, Long.MAX_VALUE, null);
assertEquals(rx, total[0]);
assertEquals(tx, total[1]);