Include full network history around current time.

When requesting historical values with time ranges, always include
full values for buckets that span current time.  (It doesn't make
sense to interpolate partial data.)  Move getTotalData() to return
full Entry objects to prepare for packet counts.

Bug: 4691901
Change-Id: I717bd721be9f1d4a47c4121e46e07a56cb15bbf1
This commit is contained in:
Jeff Sharkey
2011-07-12 20:20:56 -07:00
parent aa731e75a9
commit 26f35e29cd
2 changed files with 63 additions and 77 deletions

View File

@@ -55,7 +55,7 @@ public class NetworkStatsHistoryTest extends TestCase {
stats.recordData(TEST_START, TEST_START + SECOND_IN_MILLIS, 1024L, 2048L); stats.recordData(TEST_START, TEST_START + SECOND_IN_MILLIS, 1024L, 2048L);
assertEquals(1, stats.size()); assertEquals(1, stats.size());
assertEntry(stats, 0, 1024L, 2048L); assertValues(stats, 0, 1024L, 2048L);
} }
public void testRecordEqualBuckets() throws Exception { public void testRecordEqualBuckets() throws Exception {
@@ -67,8 +67,8 @@ public class NetworkStatsHistoryTest extends TestCase {
stats.recordData(recordStart, recordStart + bucketDuration, 1024L, 128L); stats.recordData(recordStart, recordStart + bucketDuration, 1024L, 128L);
assertEquals(2, stats.size()); assertEquals(2, stats.size());
assertEntry(stats, 0, 512L, 64L); assertValues(stats, 0, 512L, 64L);
assertEntry(stats, 1, 512L, 64L); assertValues(stats, 1, 512L, 64L);
} }
public void testRecordTouchingBuckets() throws Exception { public void testRecordTouchingBuckets() throws Exception {
@@ -83,11 +83,11 @@ public class NetworkStatsHistoryTest extends TestCase {
assertEquals(3, stats.size()); assertEquals(3, stats.size());
// first bucket should have (1/20 of value) // first bucket should have (1/20 of value)
assertEntry(stats, 0, 50L, 250L); assertValues(stats, 0, 50L, 250L);
// second bucket should have (15/20 of value) // second bucket should have (15/20 of value)
assertEntry(stats, 1, 750L, 3750L); assertValues(stats, 1, 750L, 3750L);
// final bucket should have (4/20 of value) // final bucket should have (4/20 of value)
assertEntry(stats, 2, 200L, 1000L); assertValues(stats, 2, 200L, 1000L);
} }
public void testRecordGapBuckets() throws Exception { public void testRecordGapBuckets() throws Exception {
@@ -102,8 +102,8 @@ public class NetworkStatsHistoryTest extends TestCase {
// we should have two buckets, far apart from each other // we should have two buckets, far apart from each other
assertEquals(2, stats.size()); assertEquals(2, stats.size());
assertEntry(stats, 0, 128L, 256L); assertValues(stats, 0, 128L, 256L);
assertEntry(stats, 1, 64L, 512L); assertValues(stats, 1, 64L, 512L);
// now record something in middle, spread across two buckets // now record something in middle, spread across two buckets
final long middleStart = TEST_START + DAY_IN_MILLIS; final long middleStart = TEST_START + DAY_IN_MILLIS;
@@ -112,10 +112,10 @@ public class NetworkStatsHistoryTest extends TestCase {
// now should have four buckets, with new record in middle two buckets // now should have four buckets, with new record in middle two buckets
assertEquals(4, stats.size()); assertEquals(4, stats.size());
assertEntry(stats, 0, 128L, 256L); assertValues(stats, 0, 128L, 256L);
assertEntry(stats, 1, 1024L, 1024L); assertValues(stats, 1, 1024L, 1024L);
assertEntry(stats, 2, 1024L, 1024L); assertValues(stats, 2, 1024L, 1024L);
assertEntry(stats, 3, 64L, 512L); assertValues(stats, 3, 64L, 512L);
} }
public void testRecordOverlapBuckets() throws Exception { public void testRecordOverlapBuckets() throws Exception {
@@ -129,13 +129,11 @@ public class NetworkStatsHistoryTest extends TestCase {
// should have two buckets, with some data mixed together // should have two buckets, with some data mixed together
assertEquals(2, stats.size()); assertEquals(2, stats.size());
assertEntry(stats, 0, 768L, 768L); assertValues(stats, 0, 768L, 768L);
assertEntry(stats, 1, 512L, 512L); assertValues(stats, 1, 512L, 512L);
} }
public void testRecordEntireGapIdentical() throws Exception { public void testRecordEntireGapIdentical() throws Exception {
final long[] total = new long[2];
// first, create two separate histories far apart // first, create two separate histories far apart
final NetworkStatsHistory stats1 = new NetworkStatsHistory(HOUR_IN_MILLIS); final NetworkStatsHistory stats1 = new NetworkStatsHistory(HOUR_IN_MILLIS);
stats1.recordData(TEST_START, TEST_START + 2 * HOUR_IN_MILLIS, 2000L, 1000L); stats1.recordData(TEST_START, TEST_START + 2 * HOUR_IN_MILLIS, 2000L, 1000L);
@@ -150,19 +148,16 @@ public class NetworkStatsHistoryTest extends TestCase {
stats.recordEntireHistory(stats2); stats.recordEntireHistory(stats2);
// first verify that totals match up // first verify that totals match up
stats.getTotalData(TEST_START - WEEK_IN_MILLIS, TEST_START + WEEK_IN_MILLIS, total); assertValues(stats, TEST_START - WEEK_IN_MILLIS, TEST_START + WEEK_IN_MILLIS, 3000L, 1500L);
assertTotalEquals(total, 3000L, 1500L);
// now inspect internal buckets // now inspect internal buckets
assertEntry(stats, 0, 1000L, 500L); assertValues(stats, 0, 1000L, 500L);
assertEntry(stats, 1, 1000L, 500L); assertValues(stats, 1, 1000L, 500L);
assertEntry(stats, 2, 500L, 250L); assertValues(stats, 2, 500L, 250L);
assertEntry(stats, 3, 500L, 250L); assertValues(stats, 3, 500L, 250L);
} }
public void testRecordEntireOverlapVaryingBuckets() throws Exception { public void testRecordEntireOverlapVaryingBuckets() throws Exception {
final long[] total = new long[2];
// create history just over hour bucket boundary // create history just over hour bucket boundary
final NetworkStatsHistory stats1 = new NetworkStatsHistory(HOUR_IN_MILLIS); final NetworkStatsHistory stats1 = new NetworkStatsHistory(HOUR_IN_MILLIS);
stats1.recordData(TEST_START, TEST_START + MINUTE_IN_MILLIS * 60, 600L, 600L); stats1.recordData(TEST_START, TEST_START + MINUTE_IN_MILLIS * 60, 600L, 600L);
@@ -177,17 +172,16 @@ public class NetworkStatsHistoryTest extends TestCase {
stats.recordEntireHistory(stats2); stats.recordEntireHistory(stats2);
// first verify that totals match up // first verify that totals match up
stats.getTotalData(TEST_START - WEEK_IN_MILLIS, TEST_START + WEEK_IN_MILLIS, total); assertValues(stats, TEST_START - WEEK_IN_MILLIS, TEST_START + WEEK_IN_MILLIS, 650L, 650L);
assertTotalEquals(total, 650L, 650L);
// now inspect internal buckets // now inspect internal buckets
assertEntry(stats, 0, 10L, 10L); assertValues(stats, 0, 10L, 10L);
assertEntry(stats, 1, 20L, 20L); assertValues(stats, 1, 20L, 20L);
assertEntry(stats, 2, 20L, 20L); assertValues(stats, 2, 20L, 20L);
assertEntry(stats, 3, 20L, 20L); assertValues(stats, 3, 20L, 20L);
assertEntry(stats, 4, 20L, 20L); assertValues(stats, 4, 20L, 20L);
assertEntry(stats, 5, 20L, 20L); assertValues(stats, 5, 20L, 20L);
assertEntry(stats, 6, 10L, 10L); assertValues(stats, 6, 10L, 10L);
// now combine using 15min buckets // now combine using 15min buckets
stats = new NetworkStatsHistory(HOUR_IN_MILLIS / 4); stats = new NetworkStatsHistory(HOUR_IN_MILLIS / 4);
@@ -195,14 +189,13 @@ public class NetworkStatsHistoryTest extends TestCase {
stats.recordEntireHistory(stats2); stats.recordEntireHistory(stats2);
// first verify that totals match up // first verify that totals match up
stats.getTotalData(TEST_START - WEEK_IN_MILLIS, TEST_START + WEEK_IN_MILLIS, total); assertValues(stats, TEST_START - WEEK_IN_MILLIS, TEST_START + WEEK_IN_MILLIS, 650L, 650L);
assertTotalEquals(total, 650L, 650L);
// and inspect buckets // and inspect buckets
assertEntry(stats, 0, 200L, 200L); assertValues(stats, 0, 200L, 200L);
assertEntry(stats, 1, 150L, 150L); assertValues(stats, 1, 150L, 150L);
assertEntry(stats, 2, 150L, 150L); assertValues(stats, 2, 150L, 150L);
assertEntry(stats, 3, 150L, 150L); assertValues(stats, 3, 150L, 150L);
} }
public void testRemove() throws Exception { public void testRemove() throws Exception {
@@ -241,27 +234,20 @@ public class NetworkStatsHistoryTest extends TestCase {
// record uniform data across day // record uniform data across day
stats.recordData(TEST_START, TEST_START + DAY_IN_MILLIS, 2400L, 4800L); stats.recordData(TEST_START, TEST_START + DAY_IN_MILLIS, 2400L, 4800L);
final long[] total = new long[2];
// verify that total outside range is 0 // verify that total outside range is 0
stats.getTotalData(TEST_START - WEEK_IN_MILLIS, TEST_START - DAY_IN_MILLIS, total); assertValues(stats, TEST_START - WEEK_IN_MILLIS, TEST_START - DAY_IN_MILLIS, 0L, 0L);
assertTotalEquals(total, 0, 0);
// verify total in first hour // verify total in first hour
stats.getTotalData(TEST_START, TEST_START + HOUR_IN_MILLIS, total); assertValues(stats, TEST_START, TEST_START + HOUR_IN_MILLIS, 100L, 200L);
assertTotalEquals(total, 100, 200);
// verify total across 1.5 hours // verify total across 1.5 hours
stats.getTotalData(TEST_START, TEST_START + (long) (1.5 * HOUR_IN_MILLIS), total); assertValues(stats, TEST_START, TEST_START + (long) (1.5 * HOUR_IN_MILLIS), 150L, 300L);
assertTotalEquals(total, 150, 300);
// verify total beyond end // verify total beyond end
stats.getTotalData(TEST_START + (23 * HOUR_IN_MILLIS), TEST_START + WEEK_IN_MILLIS, total); assertValues(stats, TEST_START + (23 * HOUR_IN_MILLIS), TEST_START + WEEK_IN_MILLIS, 100L, 200L);
assertTotalEquals(total, 100, 200);
// verify everything total // verify everything total
stats.getTotalData(TEST_START - WEEK_IN_MILLIS, TEST_START + WEEK_IN_MILLIS, total); assertValues(stats, TEST_START - WEEK_IN_MILLIS, TEST_START + WEEK_IN_MILLIS, 2400L, 4800L);
assertTotalEquals(total, 2400, 4800);
} }
@@ -302,16 +288,18 @@ public class NetworkStatsHistoryTest extends TestCase {
} }
} }
private static void assertTotalEquals(long[] total, long rxBytes, long txBytes) { private static void assertValues(
assertEquals("unexpected rxBytes", rxBytes, total[0]);
assertEquals("unexpected txBytes", txBytes, total[1]);
}
private static void assertEntry(
NetworkStatsHistory stats, int index, long rxBytes, long txBytes) { NetworkStatsHistory stats, int index, long rxBytes, long txBytes) {
final NetworkStatsHistory.Entry entry = stats.getValues(index, null); final NetworkStatsHistory.Entry entry = stats.getValues(index, null);
assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes); assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
assertEquals("unexpected txBytes", txBytes, entry.txBytes); assertEquals("unexpected txBytes", txBytes, entry.txBytes);
} }
private static void assertValues(
NetworkStatsHistory stats, long start, long end, long rxBytes, long txBytes) {
final NetworkStatsHistory.Entry entry = stats.getValues(start, end, null);
assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
assertEquals("unexpected txBytes", txBytes, entry.txBytes);
}
} }

View File

@@ -264,7 +264,6 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
public void testStatsBucketResize() throws Exception { public void testStatsBucketResize() throws Exception {
long elapsedRealtime = 0; long elapsedRealtime = 0;
NetworkStatsHistory history = null; NetworkStatsHistory history = null;
long[] total = null;
assertStatsFilesExist(false); assertStatsFilesExist(false);
@@ -292,9 +291,7 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
// verify service recorded history // verify service recorded history
history = mService.getHistoryForNetwork(new NetworkTemplate(MATCH_WIFI, null)); history = mService.getHistoryForNetwork(new NetworkTemplate(MATCH_WIFI, null));
total = history.getTotalData(Long.MIN_VALUE, Long.MAX_VALUE, null); assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, 512L, 512L);
assertEquals(512L, total[0]);
assertEquals(512L, total[1]);
assertEquals(HOUR_IN_MILLIS, history.getBucketDuration()); assertEquals(HOUR_IN_MILLIS, history.getBucketDuration());
assertEquals(2, history.size()); assertEquals(2, history.size());
verifyAndReset(); verifyAndReset();
@@ -311,9 +308,7 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
// verify identical stats, but spread across 4 buckets now // verify identical stats, but spread across 4 buckets now
history = mService.getHistoryForNetwork(new NetworkTemplate(MATCH_WIFI, null)); history = mService.getHistoryForNetwork(new NetworkTemplate(MATCH_WIFI, null));
total = history.getTotalData(Long.MIN_VALUE, Long.MAX_VALUE, null); assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, 512L, 512L);
assertEquals(512L, total[0]);
assertEquals(512L, total[1]);
assertEquals(30 * MINUTE_IN_MILLIS, history.getBucketDuration()); assertEquals(30 * MINUTE_IN_MILLIS, history.getBucketDuration());
assertEquals(4, history.size()); assertEquals(4, history.size());
verifyAndReset(); verifyAndReset();
@@ -575,32 +570,28 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
NetworkStats stats = mService.getSummaryForAllUid( NetworkStats stats = mService.getSummaryForAllUid(
sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true); sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true);
assertEquals(3, stats.size()); assertEquals(3, stats.size());
assertEntry(stats, 0, IFACE_ALL, UID_RED, TAG_NONE, 50L, 5L, 50L, 5L); assertValues(stats, 0, IFACE_ALL, UID_RED, TAG_NONE, 50L, 5L, 50L, 5L);
assertEntry(stats, 1, IFACE_ALL, UID_RED, 0xF00D, 10L, 1L, 10L, 1L); assertValues(stats, 1, IFACE_ALL, UID_RED, 0xF00D, 10L, 1L, 10L, 1L);
assertEntry(stats, 2, IFACE_ALL, UID_BLUE, TAG_NONE, 2048L, 16L, 1024L, 8L); assertValues(stats, 2, IFACE_ALL, UID_BLUE, TAG_NONE, 2048L, 16L, 1024L, 8L);
// now verify that recent history only contains one uid // now verify that recent history only contains one uid
final long currentTime = TEST_START + elapsedRealtime; final long currentTime = TEST_START + elapsedRealtime;
stats = mService.getSummaryForAllUid( stats = mService.getSummaryForAllUid(
sTemplateWifi, currentTime - HOUR_IN_MILLIS, currentTime, true); sTemplateWifi, currentTime - HOUR_IN_MILLIS, currentTime, true);
assertEquals(1, stats.size()); assertEquals(1, stats.size());
assertEntry(stats, 0, IFACE_ALL, UID_BLUE, TAG_NONE, 1024L, 8L, 512L, 4L); assertValues(stats, 0, IFACE_ALL, UID_BLUE, TAG_NONE, 1024L, 8L, 512L, 4L);
verifyAndReset(); verifyAndReset();
} }
private void assertNetworkTotal(NetworkTemplate template, long rx, long tx) { private void assertNetworkTotal(NetworkTemplate template, long rxBytes, long txBytes) {
final NetworkStatsHistory history = mService.getHistoryForNetwork(template); final NetworkStatsHistory history = mService.getHistoryForNetwork(template);
final long[] total = history.getTotalData(Long.MIN_VALUE, Long.MAX_VALUE, null); assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, rxBytes, txBytes);
assertEquals(rx, total[0]);
assertEquals(tx, total[1]);
} }
private void assertUidTotal(NetworkTemplate template, int uid, long rx, long tx) { private void assertUidTotal(NetworkTemplate template, int uid, long rxBytes, long txBytes) {
final NetworkStatsHistory history = mService.getHistoryForUid(template, uid, TAG_NONE); final NetworkStatsHistory history = mService.getHistoryForUid(template, uid, TAG_NONE);
final long[] total = history.getTotalData(Long.MIN_VALUE, Long.MAX_VALUE, null); assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, rxBytes, txBytes);
assertEquals(rx, total[0]);
assertEquals(tx, total[1]);
} }
private void expectSystemReady() throws Exception { private void expectSystemReady() throws Exception {
@@ -660,7 +651,7 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
} }
} }
private static void assertEntry(NetworkStats stats, int i, String iface, int uid, int tag, private static void assertValues(NetworkStats stats, int i, String iface, int uid, int tag,
long rxBytes, long rxPackets, long txBytes, long txPackets) { long rxBytes, long rxPackets, long txBytes, long txPackets) {
final NetworkStats.Entry entry = stats.getValues(i, null); final NetworkStats.Entry entry = stats.getValues(i, null);
assertEquals(iface, entry.iface); assertEquals(iface, entry.iface);
@@ -673,6 +664,13 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
// assertEquals(txPackets, entry.txPackets); // assertEquals(txPackets, entry.txPackets);
} }
private static void assertValues(
NetworkStatsHistory stats, long start, long end, long rxBytes, long txBytes) {
final NetworkStatsHistory.Entry entry = stats.getValues(start, end, null);
assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
assertEquals("unexpected txBytes", txBytes, entry.txBytes);
}
private static NetworkState buildWifiState() { private static NetworkState buildWifiState() {
final NetworkInfo info = new NetworkInfo(TYPE_WIFI, 0, null, null); final NetworkInfo info = new NetworkInfo(TYPE_WIFI, 0, null, null);
info.setDetailedState(DetailedState.CONNECTED, null, null); info.setDetailedState(DetailedState.CONNECTED, null, null);