blob: 9a08f4147ebc282825132caaae3ad743bc1ba617 [file] [log] [blame]
Jeff Sharkey75279902011-05-24 18:39:45 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.net;
18
Jeff Sharkey63d27a92011-08-03 17:04:22 -070019import static android.net.NetworkStatsHistory.FIELD_ALL;
20import static android.net.NetworkStatsHistory.FIELD_OPERATIONS;
21import static android.net.NetworkStatsHistory.FIELD_RX_BYTES;
22import static android.net.NetworkStatsHistory.FIELD_RX_PACKETS;
23import static android.net.NetworkStatsHistory.FIELD_TX_BYTES;
24import static android.net.NetworkStatsHistory.DataStreamUtils.readVarLong;
25import static android.net.NetworkStatsHistory.DataStreamUtils.writeVarLong;
26import static android.net.NetworkStatsHistory.Entry.UNKNOWN;
Jeff Sharkey241dde22012-02-03 14:50:07 -080027import static android.net.TrafficStats.GB_IN_BYTES;
28import static android.net.TrafficStats.MB_IN_BYTES;
Jeff Sharkey75279902011-05-24 18:39:45 -070029import static android.text.format.DateUtils.DAY_IN_MILLIS;
30import static android.text.format.DateUtils.HOUR_IN_MILLIS;
31import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
32import static android.text.format.DateUtils.SECOND_IN_MILLIS;
33import static android.text.format.DateUtils.WEEK_IN_MILLIS;
34import static android.text.format.DateUtils.YEAR_IN_MILLIS;
35
Jeff Sharkeya63ba592011-07-19 23:47:12 -070036import android.test.AndroidTestCase;
Jeff Sharkey75279902011-05-24 18:39:45 -070037import android.test.suitebuilder.annotation.SmallTest;
38import android.test.suitebuilder.annotation.Suppress;
39import android.util.Log;
40
Jeff Sharkeya63ba592011-07-19 23:47:12 -070041import com.android.frameworks.coretests.R;
Jeff Sharkey75279902011-05-24 18:39:45 -070042
Jeff Sharkey63d27a92011-08-03 17:04:22 -070043import java.io.ByteArrayInputStream;
44import java.io.ByteArrayOutputStream;
Jeff Sharkeya63ba592011-07-19 23:47:12 -070045import java.io.DataInputStream;
Jeff Sharkey63d27a92011-08-03 17:04:22 -070046import java.io.DataOutputStream;
Jeff Sharkey75279902011-05-24 18:39:45 -070047import java.util.Random;
48
49@SmallTest
Jeff Sharkeya63ba592011-07-19 23:47:12 -070050public class NetworkStatsHistoryTest extends AndroidTestCase {
Jeff Sharkey75279902011-05-24 18:39:45 -070051 private static final String TAG = "NetworkStatsHistoryTest";
52
53 private static final long TEST_START = 1194220800000L;
54
55 private NetworkStatsHistory stats;
56
57 @Override
58 protected void tearDown() throws Exception {
59 super.tearDown();
60 if (stats != null) {
61 assertConsistent(stats);
62 }
63 }
64
Jeff Sharkeya63ba592011-07-19 23:47:12 -070065 public void testReadOriginalVersion() throws Exception {
66 final DataInputStream in = new DataInputStream(
67 getContext().getResources().openRawResource(R.raw.history_v1));
68
69 NetworkStatsHistory.Entry entry = null;
70 try {
71 final NetworkStatsHistory history = new NetworkStatsHistory(in);
72 assertEquals(15 * SECOND_IN_MILLIS, history.getBucketDuration());
73
74 entry = history.getValues(0, entry);
75 assertEquals(29143L, entry.rxBytes);
76 assertEquals(6223L, entry.txBytes);
77
78 entry = history.getValues(history.size() - 1, entry);
79 assertEquals(1476L, entry.rxBytes);
80 assertEquals(838L, entry.txBytes);
81
82 entry = history.getValues(Long.MIN_VALUE, Long.MAX_VALUE, entry);
83 assertEquals(332401L, entry.rxBytes);
84 assertEquals(64314L, entry.txBytes);
85
86 } finally {
87 in.close();
88 }
89 }
90
Jeff Sharkey75279902011-05-24 18:39:45 -070091 public void testRecordSingleBucket() throws Exception {
92 final long BUCKET_SIZE = HOUR_IN_MILLIS;
Jeff Sharkeyd2a45872011-05-28 20:56:34 -070093 stats = new NetworkStatsHistory(BUCKET_SIZE);
Jeff Sharkey75279902011-05-24 18:39:45 -070094
95 // record data into narrow window to get single bucket
Jeff Sharkey63d27a92011-08-03 17:04:22 -070096 stats.recordData(TEST_START, TEST_START + SECOND_IN_MILLIS,
97 new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 2L));
Jeff Sharkey75279902011-05-24 18:39:45 -070098
Jeff Sharkeyd37948f2011-07-12 13:57:00 -070099 assertEquals(1, stats.size());
Jeff Sharkey558a2322011-08-24 15:42:09 -0700100 assertValues(stats, 0, SECOND_IN_MILLIS, 1024L, 10L, 2048L, 20L, 2L);
Jeff Sharkey75279902011-05-24 18:39:45 -0700101 }
102
103 public void testRecordEqualBuckets() throws Exception {
104 final long bucketDuration = HOUR_IN_MILLIS;
Jeff Sharkeyd2a45872011-05-28 20:56:34 -0700105 stats = new NetworkStatsHistory(bucketDuration);
Jeff Sharkey75279902011-05-24 18:39:45 -0700106
107 // split equally across two buckets
108 final long recordStart = TEST_START + (bucketDuration / 2);
Jeff Sharkey63d27a92011-08-03 17:04:22 -0700109 stats.recordData(recordStart, recordStart + bucketDuration,
110 new NetworkStats.Entry(1024L, 10L, 128L, 2L, 2L));
Jeff Sharkey75279902011-05-24 18:39:45 -0700111
Jeff Sharkeyd37948f2011-07-12 13:57:00 -0700112 assertEquals(2, stats.size());
Jeff Sharkey558a2322011-08-24 15:42:09 -0700113 assertValues(stats, 0, HOUR_IN_MILLIS / 2, 512L, 5L, 64L, 1L, 1L);
114 assertValues(stats, 1, HOUR_IN_MILLIS / 2, 512L, 5L, 64L, 1L, 1L);
Jeff Sharkey75279902011-05-24 18:39:45 -0700115 }
116
117 public void testRecordTouchingBuckets() throws Exception {
118 final long BUCKET_SIZE = 15 * MINUTE_IN_MILLIS;
Jeff Sharkeyd2a45872011-05-28 20:56:34 -0700119 stats = new NetworkStatsHistory(BUCKET_SIZE);
Jeff Sharkey75279902011-05-24 18:39:45 -0700120
121 // split almost completely into middle bucket, but with a few minutes
122 // overlap into neighboring buckets. total record is 20 minutes.
123 final long recordStart = (TEST_START + BUCKET_SIZE) - MINUTE_IN_MILLIS;
124 final long recordEnd = (TEST_START + (BUCKET_SIZE * 2)) + (MINUTE_IN_MILLIS * 4);
Jeff Sharkey63d27a92011-08-03 17:04:22 -0700125 stats.recordData(recordStart, recordEnd,
126 new NetworkStats.Entry(1000L, 2000L, 5000L, 10000L, 100L));
Jeff Sharkey75279902011-05-24 18:39:45 -0700127
Jeff Sharkeyd37948f2011-07-12 13:57:00 -0700128 assertEquals(3, stats.size());
Jeff Sharkey75279902011-05-24 18:39:45 -0700129 // first bucket should have (1/20 of value)
Jeff Sharkey558a2322011-08-24 15:42:09 -0700130 assertValues(stats, 0, MINUTE_IN_MILLIS, 50L, 100L, 250L, 500L, 5L);
Jeff Sharkey75279902011-05-24 18:39:45 -0700131 // second bucket should have (15/20 of value)
Jeff Sharkey558a2322011-08-24 15:42:09 -0700132 assertValues(stats, 1, 15 * MINUTE_IN_MILLIS, 750L, 1500L, 3750L, 7500L, 75L);
Jeff Sharkey75279902011-05-24 18:39:45 -0700133 // final bucket should have (4/20 of value)
Jeff Sharkey558a2322011-08-24 15:42:09 -0700134 assertValues(stats, 2, 4 * MINUTE_IN_MILLIS, 200L, 400L, 1000L, 2000L, 20L);
Jeff Sharkey75279902011-05-24 18:39:45 -0700135 }
136
137 public void testRecordGapBuckets() throws Exception {
138 final long BUCKET_SIZE = HOUR_IN_MILLIS;
Jeff Sharkeyd2a45872011-05-28 20:56:34 -0700139 stats = new NetworkStatsHistory(BUCKET_SIZE);
Jeff Sharkey75279902011-05-24 18:39:45 -0700140
141 // record some data today and next week with large gap
142 final long firstStart = TEST_START;
143 final long lastStart = TEST_START + WEEK_IN_MILLIS;
Jeff Sharkey63d27a92011-08-03 17:04:22 -0700144 stats.recordData(firstStart, firstStart + SECOND_IN_MILLIS,
145 new NetworkStats.Entry(128L, 2L, 256L, 4L, 1L));
146 stats.recordData(lastStart, lastStart + SECOND_IN_MILLIS,
147 new NetworkStats.Entry(64L, 1L, 512L, 8L, 2L));
Jeff Sharkey75279902011-05-24 18:39:45 -0700148
149 // we should have two buckets, far apart from each other
Jeff Sharkeyd37948f2011-07-12 13:57:00 -0700150 assertEquals(2, stats.size());
Jeff Sharkey558a2322011-08-24 15:42:09 -0700151 assertValues(stats, 0, SECOND_IN_MILLIS, 128L, 2L, 256L, 4L, 1L);
152 assertValues(stats, 1, SECOND_IN_MILLIS, 64L, 1L, 512L, 8L, 2L);
Jeff Sharkey75279902011-05-24 18:39:45 -0700153
154 // now record something in middle, spread across two buckets
155 final long middleStart = TEST_START + DAY_IN_MILLIS;
156 final long middleEnd = middleStart + (HOUR_IN_MILLIS * 2);
Jeff Sharkey63d27a92011-08-03 17:04:22 -0700157 stats.recordData(middleStart, middleEnd,
158 new NetworkStats.Entry(2048L, 4L, 2048L, 4L, 2L));
Jeff Sharkey75279902011-05-24 18:39:45 -0700159
160 // now should have four buckets, with new record in middle two buckets
Jeff Sharkeyd37948f2011-07-12 13:57:00 -0700161 assertEquals(4, stats.size());
Jeff Sharkey558a2322011-08-24 15:42:09 -0700162 assertValues(stats, 0, SECOND_IN_MILLIS, 128L, 2L, 256L, 4L, 1L);
163 assertValues(stats, 1, HOUR_IN_MILLIS, 1024L, 2L, 1024L, 2L, 1L);
164 assertValues(stats, 2, HOUR_IN_MILLIS, 1024L, 2L, 1024L, 2L, 1L);
165 assertValues(stats, 3, SECOND_IN_MILLIS, 64L, 1L, 512L, 8L, 2L);
Jeff Sharkey75279902011-05-24 18:39:45 -0700166 }
167
168 public void testRecordOverlapBuckets() throws Exception {
169 final long BUCKET_SIZE = HOUR_IN_MILLIS;
Jeff Sharkeyd2a45872011-05-28 20:56:34 -0700170 stats = new NetworkStatsHistory(BUCKET_SIZE);
Jeff Sharkey75279902011-05-24 18:39:45 -0700171
172 // record some data in one bucket, and another overlapping buckets
Jeff Sharkey63d27a92011-08-03 17:04:22 -0700173 stats.recordData(TEST_START, TEST_START + SECOND_IN_MILLIS,
174 new NetworkStats.Entry(256L, 2L, 256L, 2L, 1L));
Jeff Sharkey75279902011-05-24 18:39:45 -0700175 final long midStart = TEST_START + (HOUR_IN_MILLIS / 2);
Jeff Sharkey63d27a92011-08-03 17:04:22 -0700176 stats.recordData(midStart, midStart + HOUR_IN_MILLIS,
177 new NetworkStats.Entry(1024L, 10L, 1024L, 10L, 10L));
Jeff Sharkey75279902011-05-24 18:39:45 -0700178
179 // should have two buckets, with some data mixed together
Jeff Sharkeyd37948f2011-07-12 13:57:00 -0700180 assertEquals(2, stats.size());
Jeff Sharkey558a2322011-08-24 15:42:09 -0700181 assertValues(stats, 0, SECOND_IN_MILLIS + (HOUR_IN_MILLIS / 2), 768L, 7L, 768L, 7L, 6L);
182 assertValues(stats, 1, (HOUR_IN_MILLIS / 2), 512L, 5L, 512L, 5L, 5L);
Jeff Sharkey75279902011-05-24 18:39:45 -0700183 }
184
Jeff Sharkey19862bf2011-06-02 17:38:22 -0700185 public void testRecordEntireGapIdentical() throws Exception {
Jeff Sharkey19862bf2011-06-02 17:38:22 -0700186 // first, create two separate histories far apart
187 final NetworkStatsHistory stats1 = new NetworkStatsHistory(HOUR_IN_MILLIS);
188 stats1.recordData(TEST_START, TEST_START + 2 * HOUR_IN_MILLIS, 2000L, 1000L);
189
190 final long TEST_START_2 = TEST_START + DAY_IN_MILLIS;
191 final NetworkStatsHistory stats2 = new NetworkStatsHistory(HOUR_IN_MILLIS);
192 stats2.recordData(TEST_START_2, TEST_START_2 + 2 * HOUR_IN_MILLIS, 1000L, 500L);
193
194 // combine together with identical bucket size
195 stats = new NetworkStatsHistory(HOUR_IN_MILLIS);
196 stats.recordEntireHistory(stats1);
197 stats.recordEntireHistory(stats2);
198
199 // first verify that totals match up
Jeff Sharkey434962e2011-07-12 20:20:56 -0700200 assertValues(stats, TEST_START - WEEK_IN_MILLIS, TEST_START + WEEK_IN_MILLIS, 3000L, 1500L);
Jeff Sharkey19862bf2011-06-02 17:38:22 -0700201
202 // now inspect internal buckets
Jeff Sharkey434962e2011-07-12 20:20:56 -0700203 assertValues(stats, 0, 1000L, 500L);
204 assertValues(stats, 1, 1000L, 500L);
205 assertValues(stats, 2, 500L, 250L);
206 assertValues(stats, 3, 500L, 250L);
Jeff Sharkey19862bf2011-06-02 17:38:22 -0700207 }
208
209 public void testRecordEntireOverlapVaryingBuckets() throws Exception {
Jeff Sharkey19862bf2011-06-02 17:38:22 -0700210 // create history just over hour bucket boundary
211 final NetworkStatsHistory stats1 = new NetworkStatsHistory(HOUR_IN_MILLIS);
212 stats1.recordData(TEST_START, TEST_START + MINUTE_IN_MILLIS * 60, 600L, 600L);
213
214 final long TEST_START_2 = TEST_START + MINUTE_IN_MILLIS;
215 final NetworkStatsHistory stats2 = new NetworkStatsHistory(MINUTE_IN_MILLIS);
216 stats2.recordData(TEST_START_2, TEST_START_2 + MINUTE_IN_MILLIS * 5, 50L, 50L);
217
218 // combine together with minute bucket size
219 stats = new NetworkStatsHistory(MINUTE_IN_MILLIS);
220 stats.recordEntireHistory(stats1);
221 stats.recordEntireHistory(stats2);
222
223 // first verify that totals match up
Jeff Sharkey434962e2011-07-12 20:20:56 -0700224 assertValues(stats, TEST_START - WEEK_IN_MILLIS, TEST_START + WEEK_IN_MILLIS, 650L, 650L);
Jeff Sharkey19862bf2011-06-02 17:38:22 -0700225
226 // now inspect internal buckets
Jeff Sharkey434962e2011-07-12 20:20:56 -0700227 assertValues(stats, 0, 10L, 10L);
228 assertValues(stats, 1, 20L, 20L);
229 assertValues(stats, 2, 20L, 20L);
230 assertValues(stats, 3, 20L, 20L);
231 assertValues(stats, 4, 20L, 20L);
232 assertValues(stats, 5, 20L, 20L);
233 assertValues(stats, 6, 10L, 10L);
Jeff Sharkey19862bf2011-06-02 17:38:22 -0700234
235 // now combine using 15min buckets
236 stats = new NetworkStatsHistory(HOUR_IN_MILLIS / 4);
237 stats.recordEntireHistory(stats1);
238 stats.recordEntireHistory(stats2);
239
240 // first verify that totals match up
Jeff Sharkey434962e2011-07-12 20:20:56 -0700241 assertValues(stats, TEST_START - WEEK_IN_MILLIS, TEST_START + WEEK_IN_MILLIS, 650L, 650L);
Jeff Sharkey19862bf2011-06-02 17:38:22 -0700242
243 // and inspect buckets
Jeff Sharkey434962e2011-07-12 20:20:56 -0700244 assertValues(stats, 0, 200L, 200L);
245 assertValues(stats, 1, 150L, 150L);
246 assertValues(stats, 2, 150L, 150L);
247 assertValues(stats, 3, 150L, 150L);
Jeff Sharkey19862bf2011-06-02 17:38:22 -0700248 }
249
Jeff Sharkey75279902011-05-24 18:39:45 -0700250 public void testRemove() throws Exception {
Jeff Sharkey19862bf2011-06-02 17:38:22 -0700251 stats = new NetworkStatsHistory(HOUR_IN_MILLIS);
Jeff Sharkey75279902011-05-24 18:39:45 -0700252
253 // record some data across 24 buckets
254 stats.recordData(TEST_START, TEST_START + DAY_IN_MILLIS, 24L, 24L);
Jeff Sharkeyd37948f2011-07-12 13:57:00 -0700255 assertEquals(24, stats.size());
Jeff Sharkey75279902011-05-24 18:39:45 -0700256
Jeff Sharkey7ee86582011-11-14 18:02:21 -0800257 // try removing invalid data; should be no change
258 stats.removeBucketsBefore(0 - DAY_IN_MILLIS);
259 assertEquals(24, stats.size());
260
Jeff Sharkey75279902011-05-24 18:39:45 -0700261 // try removing far before buckets; should be no change
262 stats.removeBucketsBefore(TEST_START - YEAR_IN_MILLIS);
Jeff Sharkeyd37948f2011-07-12 13:57:00 -0700263 assertEquals(24, stats.size());
Jeff Sharkey75279902011-05-24 18:39:45 -0700264
265 // try removing just moments into first bucket; should be no change
266 // since that bucket contains data beyond the cutoff
267 stats.removeBucketsBefore(TEST_START + SECOND_IN_MILLIS);
Jeff Sharkeyd37948f2011-07-12 13:57:00 -0700268 assertEquals(24, stats.size());
Jeff Sharkey75279902011-05-24 18:39:45 -0700269
270 // try removing single bucket
271 stats.removeBucketsBefore(TEST_START + HOUR_IN_MILLIS);
Jeff Sharkeyd37948f2011-07-12 13:57:00 -0700272 assertEquals(23, stats.size());
Jeff Sharkey75279902011-05-24 18:39:45 -0700273
274 // try removing multiple buckets
275 stats.removeBucketsBefore(TEST_START + (4 * HOUR_IN_MILLIS));
Jeff Sharkeyd37948f2011-07-12 13:57:00 -0700276 assertEquals(20, stats.size());
Jeff Sharkey75279902011-05-24 18:39:45 -0700277
278 // try removing all buckets
279 stats.removeBucketsBefore(TEST_START + YEAR_IN_MILLIS);
Jeff Sharkeyd37948f2011-07-12 13:57:00 -0700280 assertEquals(0, stats.size());
Jeff Sharkey75279902011-05-24 18:39:45 -0700281 }
282
Jeff Sharkey19862bf2011-06-02 17:38:22 -0700283 public void testTotalData() throws Exception {
284 final long BUCKET_SIZE = HOUR_IN_MILLIS;
285 stats = new NetworkStatsHistory(BUCKET_SIZE);
286
287 // record uniform data across day
288 stats.recordData(TEST_START, TEST_START + DAY_IN_MILLIS, 2400L, 4800L);
289
Jeff Sharkey19862bf2011-06-02 17:38:22 -0700290 // verify that total outside range is 0
Jeff Sharkey434962e2011-07-12 20:20:56 -0700291 assertValues(stats, TEST_START - WEEK_IN_MILLIS, TEST_START - DAY_IN_MILLIS, 0L, 0L);
Jeff Sharkey19862bf2011-06-02 17:38:22 -0700292
293 // verify total in first hour
Jeff Sharkey434962e2011-07-12 20:20:56 -0700294 assertValues(stats, TEST_START, TEST_START + HOUR_IN_MILLIS, 100L, 200L);
Jeff Sharkey19862bf2011-06-02 17:38:22 -0700295
296 // verify total across 1.5 hours
Jeff Sharkey434962e2011-07-12 20:20:56 -0700297 assertValues(stats, TEST_START, TEST_START + (long) (1.5 * HOUR_IN_MILLIS), 150L, 300L);
Jeff Sharkey19862bf2011-06-02 17:38:22 -0700298
299 // verify total beyond end
Jeff Sharkey434962e2011-07-12 20:20:56 -0700300 assertValues(stats, TEST_START + (23 * HOUR_IN_MILLIS), TEST_START + WEEK_IN_MILLIS, 100L, 200L);
Jeff Sharkey19862bf2011-06-02 17:38:22 -0700301
302 // verify everything total
Jeff Sharkey434962e2011-07-12 20:20:56 -0700303 assertValues(stats, TEST_START - WEEK_IN_MILLIS, TEST_START + WEEK_IN_MILLIS, 2400L, 4800L);
Jeff Sharkey19862bf2011-06-02 17:38:22 -0700304
305 }
306
Jeff Sharkey75279902011-05-24 18:39:45 -0700307 @Suppress
308 public void testFuzzing() throws Exception {
309 try {
310 // fuzzing with random events, looking for crashes
Jeff Sharkey63d27a92011-08-03 17:04:22 -0700311 final NetworkStats.Entry entry = new NetworkStats.Entry();
Jeff Sharkey75279902011-05-24 18:39:45 -0700312 final Random r = new Random();
313 for (int i = 0; i < 500; i++) {
Jeff Sharkeyd2a45872011-05-28 20:56:34 -0700314 stats = new NetworkStatsHistory(r.nextLong());
Jeff Sharkey75279902011-05-24 18:39:45 -0700315 for (int j = 0; j < 10000; j++) {
316 if (r.nextBoolean()) {
317 // add range
318 final long start = r.nextLong();
319 final long end = start + r.nextInt();
Jeff Sharkey63d27a92011-08-03 17:04:22 -0700320 entry.rxBytes = nextPositiveLong(r);
321 entry.rxPackets = nextPositiveLong(r);
322 entry.txBytes = nextPositiveLong(r);
323 entry.txPackets = nextPositiveLong(r);
324 entry.operations = nextPositiveLong(r);
325 stats.recordData(start, end, entry);
Jeff Sharkey75279902011-05-24 18:39:45 -0700326 } else {
327 // trim something
328 stats.removeBucketsBefore(r.nextLong());
329 }
330 }
331 assertConsistent(stats);
332 }
333 } catch (Throwable e) {
334 Log.e(TAG, String.valueOf(stats));
335 throw new RuntimeException(e);
336 }
337 }
338
Jeff Sharkey63d27a92011-08-03 17:04:22 -0700339 private static long nextPositiveLong(Random r) {
340 final long value = r.nextLong();
341 return value < 0 ? -value : value;
342 }
343
344 public void testIgnoreFields() throws Exception {
345 final NetworkStatsHistory history = new NetworkStatsHistory(
346 MINUTE_IN_MILLIS, 0, FIELD_RX_BYTES | FIELD_TX_BYTES);
347
348 history.recordData(0, MINUTE_IN_MILLIS,
349 new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 4L));
Jeff Sharkey558a2322011-08-24 15:42:09 -0700350 history.recordData(0, 2 * MINUTE_IN_MILLIS,
Jeff Sharkey63d27a92011-08-03 17:04:22 -0700351 new NetworkStats.Entry(2L, 2L, 2L, 2L, 2L));
352
Jeff Sharkey558a2322011-08-24 15:42:09 -0700353 assertFullValues(history, UNKNOWN, 1026L, UNKNOWN, 2050L, UNKNOWN, UNKNOWN);
Jeff Sharkey63d27a92011-08-03 17:04:22 -0700354 }
355
356 public void testIgnoreFieldsRecordIn() throws Exception {
357 final NetworkStatsHistory full = new NetworkStatsHistory(MINUTE_IN_MILLIS, 0, FIELD_ALL);
358 final NetworkStatsHistory partial = new NetworkStatsHistory(
359 MINUTE_IN_MILLIS, 0, FIELD_RX_PACKETS | FIELD_OPERATIONS);
360
361 full.recordData(0, MINUTE_IN_MILLIS,
362 new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 4L));
363 partial.recordEntireHistory(full);
364
Jeff Sharkey558a2322011-08-24 15:42:09 -0700365 assertFullValues(partial, UNKNOWN, UNKNOWN, 10L, UNKNOWN, UNKNOWN, 4L);
Jeff Sharkey63d27a92011-08-03 17:04:22 -0700366 }
367
368 public void testIgnoreFieldsRecordOut() throws Exception {
369 final NetworkStatsHistory full = new NetworkStatsHistory(MINUTE_IN_MILLIS, 0, FIELD_ALL);
370 final NetworkStatsHistory partial = new NetworkStatsHistory(
371 MINUTE_IN_MILLIS, 0, FIELD_RX_PACKETS | FIELD_OPERATIONS);
372
373 partial.recordData(0, MINUTE_IN_MILLIS,
374 new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 4L));
375 full.recordEntireHistory(partial);
376
Jeff Sharkey558a2322011-08-24 15:42:09 -0700377 assertFullValues(full, MINUTE_IN_MILLIS, 0L, 10L, 0L, 0L, 4L);
Jeff Sharkey63d27a92011-08-03 17:04:22 -0700378 }
379
380 public void testSerialize() throws Exception {
381 final NetworkStatsHistory before = new NetworkStatsHistory(MINUTE_IN_MILLIS, 40, FIELD_ALL);
Jeff Sharkey558a2322011-08-24 15:42:09 -0700382 before.recordData(0, 4 * MINUTE_IN_MILLIS,
Jeff Sharkey63d27a92011-08-03 17:04:22 -0700383 new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 4L));
384 before.recordData(DAY_IN_MILLIS, DAY_IN_MILLIS + MINUTE_IN_MILLIS,
385 new NetworkStats.Entry(10L, 20L, 30L, 40L, 50L));
386
387 final ByteArrayOutputStream out = new ByteArrayOutputStream();
388 before.writeToStream(new DataOutputStream(out));
389 out.close();
390
391 final ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
392 final NetworkStatsHistory after = new NetworkStatsHistory(new DataInputStream(in));
393
394 // must have identical totals before and after
Jeff Sharkey558a2322011-08-24 15:42:09 -0700395 assertFullValues(before, 5 * MINUTE_IN_MILLIS, 1034L, 30L, 2078L, 60L, 54L);
396 assertFullValues(after, 5 * MINUTE_IN_MILLIS, 1034L, 30L, 2078L, 60L, 54L);
Jeff Sharkey63d27a92011-08-03 17:04:22 -0700397 }
398
399 public void testVarLong() throws Exception {
400 assertEquals(0L, performVarLong(0L));
401 assertEquals(-1L, performVarLong(-1L));
402 assertEquals(1024L, performVarLong(1024L));
403 assertEquals(-1024L, performVarLong(-1024L));
404 assertEquals(40 * MB_IN_BYTES, performVarLong(40 * MB_IN_BYTES));
405 assertEquals(512 * GB_IN_BYTES, performVarLong(512 * GB_IN_BYTES));
406 assertEquals(Long.MIN_VALUE, performVarLong(Long.MIN_VALUE));
407 assertEquals(Long.MAX_VALUE, performVarLong(Long.MAX_VALUE));
408 assertEquals(Long.MIN_VALUE + 40, performVarLong(Long.MIN_VALUE + 40));
409 assertEquals(Long.MAX_VALUE - 40, performVarLong(Long.MAX_VALUE - 40));
410 }
411
Jeff Sharkey69b0f632011-09-11 17:33:14 -0700412 public void testIndexBeforeAfter() throws Exception {
413 final long BUCKET_SIZE = HOUR_IN_MILLIS;
414 stats = new NetworkStatsHistory(BUCKET_SIZE);
415
416 final long FIRST_START = TEST_START;
417 final long FIRST_END = FIRST_START + (2 * HOUR_IN_MILLIS);
418 final long SECOND_START = TEST_START + WEEK_IN_MILLIS;
419 final long SECOND_END = SECOND_START + HOUR_IN_MILLIS;
420 final long THIRD_START = TEST_START + (2 * WEEK_IN_MILLIS);
421 final long THIRD_END = THIRD_START + (2 * HOUR_IN_MILLIS);
422
423 stats.recordData(FIRST_START, FIRST_END,
424 new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 2L));
425 stats.recordData(SECOND_START, SECOND_END,
426 new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 2L));
427 stats.recordData(THIRD_START, THIRD_END,
428 new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 2L));
429
430 // should have buckets: 2+1+2
431 assertEquals(5, stats.size());
432
433 assertIndexBeforeAfter(stats, 0, 0, Long.MIN_VALUE);
434 assertIndexBeforeAfter(stats, 0, 1, FIRST_START);
435 assertIndexBeforeAfter(stats, 0, 1, FIRST_START + MINUTE_IN_MILLIS);
436 assertIndexBeforeAfter(stats, 0, 2, FIRST_START + HOUR_IN_MILLIS);
437 assertIndexBeforeAfter(stats, 1, 2, FIRST_START + HOUR_IN_MILLIS + MINUTE_IN_MILLIS);
438 assertIndexBeforeAfter(stats, 1, 2, FIRST_END - MINUTE_IN_MILLIS);
439 assertIndexBeforeAfter(stats, 1, 2, FIRST_END);
440 assertIndexBeforeAfter(stats, 1, 2, FIRST_END + MINUTE_IN_MILLIS);
441 assertIndexBeforeAfter(stats, 1, 2, SECOND_START - MINUTE_IN_MILLIS);
442 assertIndexBeforeAfter(stats, 1, 3, SECOND_START);
443 assertIndexBeforeAfter(stats, 2, 3, SECOND_END);
444 assertIndexBeforeAfter(stats, 2, 3, SECOND_END + MINUTE_IN_MILLIS);
445 assertIndexBeforeAfter(stats, 2, 3, THIRD_START - MINUTE_IN_MILLIS);
446 assertIndexBeforeAfter(stats, 2, 4, THIRD_START);
447 assertIndexBeforeAfter(stats, 3, 4, THIRD_START + MINUTE_IN_MILLIS);
448 assertIndexBeforeAfter(stats, 3, 4, THIRD_START + HOUR_IN_MILLIS);
449 assertIndexBeforeAfter(stats, 4, 4, THIRD_END);
450 assertIndexBeforeAfter(stats, 4, 4, THIRD_END + MINUTE_IN_MILLIS);
451 assertIndexBeforeAfter(stats, 4, 4, Long.MAX_VALUE);
452 }
453
Jeff Sharkey55a442e2014-11-18 18:22:21 -0800454 public void testIntersects() throws Exception {
455 final long BUCKET_SIZE = HOUR_IN_MILLIS;
456 stats = new NetworkStatsHistory(BUCKET_SIZE);
457
458 final long FIRST_START = TEST_START;
459 final long FIRST_END = FIRST_START + (2 * HOUR_IN_MILLIS);
460 final long SECOND_START = TEST_START + WEEK_IN_MILLIS;
461 final long SECOND_END = SECOND_START + HOUR_IN_MILLIS;
462 final long THIRD_START = TEST_START + (2 * WEEK_IN_MILLIS);
463 final long THIRD_END = THIRD_START + (2 * HOUR_IN_MILLIS);
464
465 stats.recordData(FIRST_START, FIRST_END,
466 new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 2L));
467 stats.recordData(SECOND_START, SECOND_END,
468 new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 2L));
469 stats.recordData(THIRD_START, THIRD_END,
470 new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 2L));
471
472 assertFalse(stats.intersects(10, 20));
473 assertFalse(stats.intersects(TEST_START + YEAR_IN_MILLIS, TEST_START + YEAR_IN_MILLIS + 1));
474 assertFalse(stats.intersects(Long.MAX_VALUE, Long.MIN_VALUE));
475
476 assertTrue(stats.intersects(Long.MIN_VALUE, Long.MAX_VALUE));
477 assertTrue(stats.intersects(10, TEST_START + YEAR_IN_MILLIS));
478 assertTrue(stats.intersects(TEST_START, TEST_START));
479 assertTrue(stats.intersects(TEST_START + DAY_IN_MILLIS, TEST_START + DAY_IN_MILLIS + 1));
480 assertTrue(stats.intersects(TEST_START + DAY_IN_MILLIS, Long.MAX_VALUE));
481 assertTrue(stats.intersects(TEST_START + 1, Long.MAX_VALUE));
482
483 assertFalse(stats.intersects(Long.MIN_VALUE, TEST_START - 1));
484 assertTrue(stats.intersects(Long.MIN_VALUE, TEST_START));
485 assertTrue(stats.intersects(Long.MIN_VALUE, TEST_START + 1));
486 }
487
Jeff Sharkey69b0f632011-09-11 17:33:14 -0700488 private static void assertIndexBeforeAfter(
489 NetworkStatsHistory stats, int before, int after, long time) {
490 assertEquals("unexpected before", before, stats.getIndexBefore(time));
491 assertEquals("unexpected after", after, stats.getIndexAfter(time));
492 }
493
Jeff Sharkey63d27a92011-08-03 17:04:22 -0700494 private static long performVarLong(long before) throws Exception {
495 final ByteArrayOutputStream out = new ByteArrayOutputStream();
496 writeVarLong(new DataOutputStream(out), before);
497
498 final ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
499 return readVarLong(new DataInputStream(in));
500 }
501
Jeff Sharkey75279902011-05-24 18:39:45 -0700502 private static void assertConsistent(NetworkStatsHistory stats) {
503 // verify timestamps are monotonic
Jeff Sharkeyd37948f2011-07-12 13:57:00 -0700504 long lastStart = Long.MIN_VALUE;
505 NetworkStatsHistory.Entry entry = null;
506 for (int i = 0; i < stats.size(); i++) {
507 entry = stats.getValues(i, entry);
508 assertTrue(lastStart < entry.bucketStart);
509 lastStart = entry.bucketStart;
Jeff Sharkey75279902011-05-24 18:39:45 -0700510 }
511 }
512
Jeff Sharkey434962e2011-07-12 20:20:56 -0700513 private static void assertValues(
Jeff Sharkeyd37948f2011-07-12 13:57:00 -0700514 NetworkStatsHistory stats, int index, long rxBytes, long txBytes) {
515 final NetworkStatsHistory.Entry entry = stats.getValues(index, null);
516 assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
517 assertEquals("unexpected txBytes", txBytes, entry.txBytes);
Jeff Sharkey75279902011-05-24 18:39:45 -0700518 }
519
Jeff Sharkey434962e2011-07-12 20:20:56 -0700520 private static void assertValues(
521 NetworkStatsHistory stats, long start, long end, long rxBytes, long txBytes) {
522 final NetworkStatsHistory.Entry entry = stats.getValues(start, end, null);
523 assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
524 assertEquals("unexpected txBytes", txBytes, entry.txBytes);
525 }
526
Jeff Sharkey558a2322011-08-24 15:42:09 -0700527 private static void assertValues(NetworkStatsHistory stats, int index, long activeTime,
528 long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) {
Jeff Sharkey63d27a92011-08-03 17:04:22 -0700529 final NetworkStatsHistory.Entry entry = stats.getValues(index, null);
Jeff Sharkey558a2322011-08-24 15:42:09 -0700530 assertEquals("unexpected activeTime", activeTime, entry.activeTime);
Jeff Sharkey63d27a92011-08-03 17:04:22 -0700531 assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
532 assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
533 assertEquals("unexpected txBytes", txBytes, entry.txBytes);
534 assertEquals("unexpected txPackets", txPackets, entry.txPackets);
535 assertEquals("unexpected operations", operations, entry.operations);
536 }
537
Jeff Sharkey558a2322011-08-24 15:42:09 -0700538 private static void assertFullValues(NetworkStatsHistory stats, long activeTime, long rxBytes,
Jeff Sharkey63d27a92011-08-03 17:04:22 -0700539 long rxPackets, long txBytes, long txPackets, long operations) {
Jeff Sharkey558a2322011-08-24 15:42:09 -0700540 assertValues(stats, Long.MIN_VALUE, Long.MAX_VALUE, activeTime, rxBytes, rxPackets, txBytes,
541 txPackets, operations);
542 }
543
544 private static void assertValues(NetworkStatsHistory stats, long start, long end,
545 long activeTime, long rxBytes, long rxPackets, long txBytes, long txPackets,
546 long operations) {
Jeff Sharkey63d27a92011-08-03 17:04:22 -0700547 final NetworkStatsHistory.Entry entry = stats.getValues(start, end, null);
Jeff Sharkey558a2322011-08-24 15:42:09 -0700548 assertEquals("unexpected activeTime", activeTime, entry.activeTime);
Jeff Sharkey63d27a92011-08-03 17:04:22 -0700549 assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
550 assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
551 assertEquals("unexpected txBytes", txBytes, entry.txBytes);
552 assertEquals("unexpected txPackets", txPackets, entry.txPackets);
553 assertEquals("unexpected operations", operations, entry.operations);
554 }
Jeff Sharkey75279902011-05-24 18:39:45 -0700555}