1 /* 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 17 package android.net; 18 19 import static android.net.NetworkStatsHistory.FIELD_ALL; 20 import static android.net.NetworkStatsHistory.FIELD_OPERATIONS; 21 import static android.net.NetworkStatsHistory.FIELD_RX_BYTES; 22 import static android.net.NetworkStatsHistory.FIELD_RX_PACKETS; 23 import static android.net.NetworkStatsHistory.FIELD_TX_BYTES; 24 import static android.net.NetworkStatsHistory.DataStreamUtils.readVarLong; 25 import static android.net.NetworkStatsHistory.DataStreamUtils.writeVarLong; 26 import static android.net.NetworkStatsHistory.Entry.UNKNOWN; 27 import static android.text.format.DateUtils.DAY_IN_MILLIS; 28 import static android.text.format.DateUtils.HOUR_IN_MILLIS; 29 import static android.text.format.DateUtils.MINUTE_IN_MILLIS; 30 import static android.text.format.DateUtils.SECOND_IN_MILLIS; 31 import static android.text.format.DateUtils.WEEK_IN_MILLIS; 32 import static android.text.format.DateUtils.YEAR_IN_MILLIS; 33 34 import android.test.AndroidTestCase; 35 import android.test.suitebuilder.annotation.SmallTest; 36 import android.test.suitebuilder.annotation.Suppress; 37 import android.util.Log; 38 39 import com.android.frameworks.coretests.R; 40 41 import java.io.ByteArrayInputStream; 42 import java.io.ByteArrayOutputStream; 43 import java.io.DataInputStream; 44 import java.io.DataOutputStream; 45 import java.util.Random; 46 47 @SmallTest 48 public class NetworkStatsHistoryTest extends AndroidTestCase { 49 private static final String TAG = "NetworkStatsHistoryTest"; 50 51 private static final long TEST_START = 1194220800000L; 52 53 private static final long KB_IN_BYTES = 1024; 54 private static final long MB_IN_BYTES = KB_IN_BYTES * 1024; 55 private static final long GB_IN_BYTES = MB_IN_BYTES * 1024; 56 57 private NetworkStatsHistory stats; 58 59 @Override 60 protected void tearDown() throws Exception { 61 super.tearDown(); 62 if (stats != null) { 63 assertConsistent(stats); 64 } 65 } 66 67 public void testReadOriginalVersion() throws Exception { 68 final DataInputStream in = new DataInputStream( 69 getContext().getResources().openRawResource(R.raw.history_v1)); 70 71 NetworkStatsHistory.Entry entry = null; 72 try { 73 final NetworkStatsHistory history = new NetworkStatsHistory(in); 74 assertEquals(15 * SECOND_IN_MILLIS, history.getBucketDuration()); 75 76 entry = history.getValues(0, entry); 77 assertEquals(29143L, entry.rxBytes); 78 assertEquals(6223L, entry.txBytes); 79 80 entry = history.getValues(history.size() - 1, entry); 81 assertEquals(1476L, entry.rxBytes); 82 assertEquals(838L, entry.txBytes); 83 84 entry = history.getValues(Long.MIN_VALUE, Long.MAX_VALUE, entry); 85 assertEquals(332401L, entry.rxBytes); 86 assertEquals(64314L, entry.txBytes); 87 88 } finally { 89 in.close(); 90 } 91 } 92 93 public void testRecordSingleBucket() throws Exception { 94 final long BUCKET_SIZE = HOUR_IN_MILLIS; 95 stats = new NetworkStatsHistory(BUCKET_SIZE); 96 97 // record data into narrow window to get single bucket 98 stats.recordData(TEST_START, TEST_START + SECOND_IN_MILLIS, 99 new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 2L)); 100 101 assertEquals(1, stats.size()); 102 assertValues(stats, 0, SECOND_IN_MILLIS, 1024L, 10L, 2048L, 20L, 2L); 103 } 104 105 public void testRecordEqualBuckets() throws Exception { 106 final long bucketDuration = HOUR_IN_MILLIS; 107 stats = new NetworkStatsHistory(bucketDuration); 108 109 // split equally across two buckets 110 final long recordStart = TEST_START + (bucketDuration / 2); 111 stats.recordData(recordStart, recordStart + bucketDuration, 112 new NetworkStats.Entry(1024L, 10L, 128L, 2L, 2L)); 113 114 assertEquals(2, stats.size()); 115 assertValues(stats, 0, HOUR_IN_MILLIS / 2, 512L, 5L, 64L, 1L, 1L); 116 assertValues(stats, 1, HOUR_IN_MILLIS / 2, 512L, 5L, 64L, 1L, 1L); 117 } 118 119 public void testRecordTouchingBuckets() throws Exception { 120 final long BUCKET_SIZE = 15 * MINUTE_IN_MILLIS; 121 stats = new NetworkStatsHistory(BUCKET_SIZE); 122 123 // split almost completely into middle bucket, but with a few minutes 124 // overlap into neighboring buckets. total record is 20 minutes. 125 final long recordStart = (TEST_START + BUCKET_SIZE) - MINUTE_IN_MILLIS; 126 final long recordEnd = (TEST_START + (BUCKET_SIZE * 2)) + (MINUTE_IN_MILLIS * 4); 127 stats.recordData(recordStart, recordEnd, 128 new NetworkStats.Entry(1000L, 2000L, 5000L, 10000L, 100L)); 129 130 assertEquals(3, stats.size()); 131 // first bucket should have (1/20 of value) 132 assertValues(stats, 0, MINUTE_IN_MILLIS, 50L, 100L, 250L, 500L, 5L); 133 // second bucket should have (15/20 of value) 134 assertValues(stats, 1, 15 * MINUTE_IN_MILLIS, 750L, 1500L, 3750L, 7500L, 75L); 135 // final bucket should have (4/20 of value) 136 assertValues(stats, 2, 4 * MINUTE_IN_MILLIS, 200L, 400L, 1000L, 2000L, 20L); 137 } 138 139 public void testRecordGapBuckets() throws Exception { 140 final long BUCKET_SIZE = HOUR_IN_MILLIS; 141 stats = new NetworkStatsHistory(BUCKET_SIZE); 142 143 // record some data today and next week with large gap 144 final long firstStart = TEST_START; 145 final long lastStart = TEST_START + WEEK_IN_MILLIS; 146 stats.recordData(firstStart, firstStart + SECOND_IN_MILLIS, 147 new NetworkStats.Entry(128L, 2L, 256L, 4L, 1L)); 148 stats.recordData(lastStart, lastStart + SECOND_IN_MILLIS, 149 new NetworkStats.Entry(64L, 1L, 512L, 8L, 2L)); 150 151 // we should have two buckets, far apart from each other 152 assertEquals(2, stats.size()); 153 assertValues(stats, 0, SECOND_IN_MILLIS, 128L, 2L, 256L, 4L, 1L); 154 assertValues(stats, 1, SECOND_IN_MILLIS, 64L, 1L, 512L, 8L, 2L); 155 156 // now record something in middle, spread across two buckets 157 final long middleStart = TEST_START + DAY_IN_MILLIS; 158 final long middleEnd = middleStart + (HOUR_IN_MILLIS * 2); 159 stats.recordData(middleStart, middleEnd, 160 new NetworkStats.Entry(2048L, 4L, 2048L, 4L, 2L)); 161 162 // now should have four buckets, with new record in middle two buckets 163 assertEquals(4, stats.size()); 164 assertValues(stats, 0, SECOND_IN_MILLIS, 128L, 2L, 256L, 4L, 1L); 165 assertValues(stats, 1, HOUR_IN_MILLIS, 1024L, 2L, 1024L, 2L, 1L); 166 assertValues(stats, 2, HOUR_IN_MILLIS, 1024L, 2L, 1024L, 2L, 1L); 167 assertValues(stats, 3, SECOND_IN_MILLIS, 64L, 1L, 512L, 8L, 2L); 168 } 169 170 public void testRecordOverlapBuckets() throws Exception { 171 final long BUCKET_SIZE = HOUR_IN_MILLIS; 172 stats = new NetworkStatsHistory(BUCKET_SIZE); 173 174 // record some data in one bucket, and another overlapping buckets 175 stats.recordData(TEST_START, TEST_START + SECOND_IN_MILLIS, 176 new NetworkStats.Entry(256L, 2L, 256L, 2L, 1L)); 177 final long midStart = TEST_START + (HOUR_IN_MILLIS / 2); 178 stats.recordData(midStart, midStart + HOUR_IN_MILLIS, 179 new NetworkStats.Entry(1024L, 10L, 1024L, 10L, 10L)); 180 181 // should have two buckets, with some data mixed together 182 assertEquals(2, stats.size()); 183 assertValues(stats, 0, SECOND_IN_MILLIS + (HOUR_IN_MILLIS / 2), 768L, 7L, 768L, 7L, 6L); 184 assertValues(stats, 1, (HOUR_IN_MILLIS / 2), 512L, 5L, 512L, 5L, 5L); 185 } 186 187 public void testRecordEntireGapIdentical() throws Exception { 188 // first, create two separate histories far apart 189 final NetworkStatsHistory stats1 = new NetworkStatsHistory(HOUR_IN_MILLIS); 190 stats1.recordData(TEST_START, TEST_START + 2 * HOUR_IN_MILLIS, 2000L, 1000L); 191 192 final long TEST_START_2 = TEST_START + DAY_IN_MILLIS; 193 final NetworkStatsHistory stats2 = new NetworkStatsHistory(HOUR_IN_MILLIS); 194 stats2.recordData(TEST_START_2, TEST_START_2 + 2 * HOUR_IN_MILLIS, 1000L, 500L); 195 196 // combine together with identical bucket size 197 stats = new NetworkStatsHistory(HOUR_IN_MILLIS); 198 stats.recordEntireHistory(stats1); 199 stats.recordEntireHistory(stats2); 200 201 // first verify that totals match up 202 assertValues(stats, TEST_START - WEEK_IN_MILLIS, TEST_START + WEEK_IN_MILLIS, 3000L, 1500L); 203 204 // now inspect internal buckets 205 assertValues(stats, 0, 1000L, 500L); 206 assertValues(stats, 1, 1000L, 500L); 207 assertValues(stats, 2, 500L, 250L); 208 assertValues(stats, 3, 500L, 250L); 209 } 210 211 public void testRecordEntireOverlapVaryingBuckets() throws Exception { 212 // create history just over hour bucket boundary 213 final NetworkStatsHistory stats1 = new NetworkStatsHistory(HOUR_IN_MILLIS); 214 stats1.recordData(TEST_START, TEST_START + MINUTE_IN_MILLIS * 60, 600L, 600L); 215 216 final long TEST_START_2 = TEST_START + MINUTE_IN_MILLIS; 217 final NetworkStatsHistory stats2 = new NetworkStatsHistory(MINUTE_IN_MILLIS); 218 stats2.recordData(TEST_START_2, TEST_START_2 + MINUTE_IN_MILLIS * 5, 50L, 50L); 219 220 // combine together with minute bucket size 221 stats = new NetworkStatsHistory(MINUTE_IN_MILLIS); 222 stats.recordEntireHistory(stats1); 223 stats.recordEntireHistory(stats2); 224 225 // first verify that totals match up 226 assertValues(stats, TEST_START - WEEK_IN_MILLIS, TEST_START + WEEK_IN_MILLIS, 650L, 650L); 227 228 // now inspect internal buckets 229 assertValues(stats, 0, 10L, 10L); 230 assertValues(stats, 1, 20L, 20L); 231 assertValues(stats, 2, 20L, 20L); 232 assertValues(stats, 3, 20L, 20L); 233 assertValues(stats, 4, 20L, 20L); 234 assertValues(stats, 5, 20L, 20L); 235 assertValues(stats, 6, 10L, 10L); 236 237 // now combine using 15min buckets 238 stats = new NetworkStatsHistory(HOUR_IN_MILLIS / 4); 239 stats.recordEntireHistory(stats1); 240 stats.recordEntireHistory(stats2); 241 242 // first verify that totals match up 243 assertValues(stats, TEST_START - WEEK_IN_MILLIS, TEST_START + WEEK_IN_MILLIS, 650L, 650L); 244 245 // and inspect buckets 246 assertValues(stats, 0, 200L, 200L); 247 assertValues(stats, 1, 150L, 150L); 248 assertValues(stats, 2, 150L, 150L); 249 assertValues(stats, 3, 150L, 150L); 250 } 251 252 public void testRemove() throws Exception { 253 stats = new NetworkStatsHistory(HOUR_IN_MILLIS); 254 255 // record some data across 24 buckets 256 stats.recordData(TEST_START, TEST_START + DAY_IN_MILLIS, 24L, 24L); 257 assertEquals(24, stats.size()); 258 259 // try removing invalid data; should be no change 260 stats.removeBucketsBefore(0 - DAY_IN_MILLIS); 261 assertEquals(24, stats.size()); 262 263 // try removing far before buckets; should be no change 264 stats.removeBucketsBefore(TEST_START - YEAR_IN_MILLIS); 265 assertEquals(24, stats.size()); 266 267 // try removing just moments into first bucket; should be no change 268 // since that bucket contains data beyond the cutoff 269 stats.removeBucketsBefore(TEST_START + SECOND_IN_MILLIS); 270 assertEquals(24, stats.size()); 271 272 // try removing single bucket 273 stats.removeBucketsBefore(TEST_START + HOUR_IN_MILLIS); 274 assertEquals(23, stats.size()); 275 276 // try removing multiple buckets 277 stats.removeBucketsBefore(TEST_START + (4 * HOUR_IN_MILLIS)); 278 assertEquals(20, stats.size()); 279 280 // try removing all buckets 281 stats.removeBucketsBefore(TEST_START + YEAR_IN_MILLIS); 282 assertEquals(0, stats.size()); 283 } 284 285 public void testTotalData() throws Exception { 286 final long BUCKET_SIZE = HOUR_IN_MILLIS; 287 stats = new NetworkStatsHistory(BUCKET_SIZE); 288 289 // record uniform data across day 290 stats.recordData(TEST_START, TEST_START + DAY_IN_MILLIS, 2400L, 4800L); 291 292 // verify that total outside range is 0 293 assertValues(stats, TEST_START - WEEK_IN_MILLIS, TEST_START - DAY_IN_MILLIS, 0L, 0L); 294 295 // verify total in first hour 296 assertValues(stats, TEST_START, TEST_START + HOUR_IN_MILLIS, 100L, 200L); 297 298 // verify total across 1.5 hours 299 assertValues(stats, TEST_START, TEST_START + (long) (1.5 * HOUR_IN_MILLIS), 150L, 300L); 300 301 // verify total beyond end 302 assertValues(stats, TEST_START + (23 * HOUR_IN_MILLIS), TEST_START + WEEK_IN_MILLIS, 100L, 200L); 303 304 // verify everything total 305 assertValues(stats, TEST_START - WEEK_IN_MILLIS, TEST_START + WEEK_IN_MILLIS, 2400L, 4800L); 306 307 } 308 309 @Suppress 310 public void testFuzzing() throws Exception { 311 try { 312 // fuzzing with random events, looking for crashes 313 final NetworkStats.Entry entry = new NetworkStats.Entry(); 314 final Random r = new Random(); 315 for (int i = 0; i < 500; i++) { 316 stats = new NetworkStatsHistory(r.nextLong()); 317 for (int j = 0; j < 10000; j++) { 318 if (r.nextBoolean()) { 319 // add range 320 final long start = r.nextLong(); 321 final long end = start + r.nextInt(); 322 entry.rxBytes = nextPositiveLong(r); 323 entry.rxPackets = nextPositiveLong(r); 324 entry.txBytes = nextPositiveLong(r); 325 entry.txPackets = nextPositiveLong(r); 326 entry.operations = nextPositiveLong(r); 327 stats.recordData(start, end, entry); 328 } else { 329 // trim something 330 stats.removeBucketsBefore(r.nextLong()); 331 } 332 } 333 assertConsistent(stats); 334 } 335 } catch (Throwable e) { 336 Log.e(TAG, String.valueOf(stats)); 337 throw new RuntimeException(e); 338 } 339 } 340 341 private static long nextPositiveLong(Random r) { 342 final long value = r.nextLong(); 343 return value < 0 ? -value : value; 344 } 345 346 public void testIgnoreFields() throws Exception { 347 final NetworkStatsHistory history = new NetworkStatsHistory( 348 MINUTE_IN_MILLIS, 0, FIELD_RX_BYTES | FIELD_TX_BYTES); 349 350 history.recordData(0, MINUTE_IN_MILLIS, 351 new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 4L)); 352 history.recordData(0, 2 * MINUTE_IN_MILLIS, 353 new NetworkStats.Entry(2L, 2L, 2L, 2L, 2L)); 354 355 assertFullValues(history, UNKNOWN, 1026L, UNKNOWN, 2050L, UNKNOWN, UNKNOWN); 356 } 357 358 public void testIgnoreFieldsRecordIn() throws Exception { 359 final NetworkStatsHistory full = new NetworkStatsHistory(MINUTE_IN_MILLIS, 0, FIELD_ALL); 360 final NetworkStatsHistory partial = new NetworkStatsHistory( 361 MINUTE_IN_MILLIS, 0, FIELD_RX_PACKETS | FIELD_OPERATIONS); 362 363 full.recordData(0, MINUTE_IN_MILLIS, 364 new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 4L)); 365 partial.recordEntireHistory(full); 366 367 assertFullValues(partial, UNKNOWN, UNKNOWN, 10L, UNKNOWN, UNKNOWN, 4L); 368 } 369 370 public void testIgnoreFieldsRecordOut() throws Exception { 371 final NetworkStatsHistory full = new NetworkStatsHistory(MINUTE_IN_MILLIS, 0, FIELD_ALL); 372 final NetworkStatsHistory partial = new NetworkStatsHistory( 373 MINUTE_IN_MILLIS, 0, FIELD_RX_PACKETS | FIELD_OPERATIONS); 374 375 partial.recordData(0, MINUTE_IN_MILLIS, 376 new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 4L)); 377 full.recordEntireHistory(partial); 378 379 assertFullValues(full, MINUTE_IN_MILLIS, 0L, 10L, 0L, 0L, 4L); 380 } 381 382 public void testSerialize() throws Exception { 383 final NetworkStatsHistory before = new NetworkStatsHistory(MINUTE_IN_MILLIS, 40, FIELD_ALL); 384 before.recordData(0, 4 * MINUTE_IN_MILLIS, 385 new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 4L)); 386 before.recordData(DAY_IN_MILLIS, DAY_IN_MILLIS + MINUTE_IN_MILLIS, 387 new NetworkStats.Entry(10L, 20L, 30L, 40L, 50L)); 388 389 final ByteArrayOutputStream out = new ByteArrayOutputStream(); 390 before.writeToStream(new DataOutputStream(out)); 391 out.close(); 392 393 final ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); 394 final NetworkStatsHistory after = new NetworkStatsHistory(new DataInputStream(in)); 395 396 // must have identical totals before and after 397 assertFullValues(before, 5 * MINUTE_IN_MILLIS, 1034L, 30L, 2078L, 60L, 54L); 398 assertFullValues(after, 5 * MINUTE_IN_MILLIS, 1034L, 30L, 2078L, 60L, 54L); 399 } 400 401 public void testVarLong() throws Exception { 402 assertEquals(0L, performVarLong(0L)); 403 assertEquals(-1L, performVarLong(-1L)); 404 assertEquals(1024L, performVarLong(1024L)); 405 assertEquals(-1024L, performVarLong(-1024L)); 406 assertEquals(40 * MB_IN_BYTES, performVarLong(40 * MB_IN_BYTES)); 407 assertEquals(512 * GB_IN_BYTES, performVarLong(512 * GB_IN_BYTES)); 408 assertEquals(Long.MIN_VALUE, performVarLong(Long.MIN_VALUE)); 409 assertEquals(Long.MAX_VALUE, performVarLong(Long.MAX_VALUE)); 410 assertEquals(Long.MIN_VALUE + 40, performVarLong(Long.MIN_VALUE + 40)); 411 assertEquals(Long.MAX_VALUE - 40, performVarLong(Long.MAX_VALUE - 40)); 412 } 413 414 public void testIndexBeforeAfter() throws Exception { 415 final long BUCKET_SIZE = HOUR_IN_MILLIS; 416 stats = new NetworkStatsHistory(BUCKET_SIZE); 417 418 final long FIRST_START = TEST_START; 419 final long FIRST_END = FIRST_START + (2 * HOUR_IN_MILLIS); 420 final long SECOND_START = TEST_START + WEEK_IN_MILLIS; 421 final long SECOND_END = SECOND_START + HOUR_IN_MILLIS; 422 final long THIRD_START = TEST_START + (2 * WEEK_IN_MILLIS); 423 final long THIRD_END = THIRD_START + (2 * HOUR_IN_MILLIS); 424 425 stats.recordData(FIRST_START, FIRST_END, 426 new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 2L)); 427 stats.recordData(SECOND_START, SECOND_END, 428 new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 2L)); 429 stats.recordData(THIRD_START, THIRD_END, 430 new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 2L)); 431 432 // should have buckets: 2+1+2 433 assertEquals(5, stats.size()); 434 435 assertIndexBeforeAfter(stats, 0, 0, Long.MIN_VALUE); 436 assertIndexBeforeAfter(stats, 0, 1, FIRST_START); 437 assertIndexBeforeAfter(stats, 0, 1, FIRST_START + MINUTE_IN_MILLIS); 438 assertIndexBeforeAfter(stats, 0, 2, FIRST_START + HOUR_IN_MILLIS); 439 assertIndexBeforeAfter(stats, 1, 2, FIRST_START + HOUR_IN_MILLIS + MINUTE_IN_MILLIS); 440 assertIndexBeforeAfter(stats, 1, 2, FIRST_END - MINUTE_IN_MILLIS); 441 assertIndexBeforeAfter(stats, 1, 2, FIRST_END); 442 assertIndexBeforeAfter(stats, 1, 2, FIRST_END + MINUTE_IN_MILLIS); 443 assertIndexBeforeAfter(stats, 1, 2, SECOND_START - MINUTE_IN_MILLIS); 444 assertIndexBeforeAfter(stats, 1, 3, SECOND_START); 445 assertIndexBeforeAfter(stats, 2, 3, SECOND_END); 446 assertIndexBeforeAfter(stats, 2, 3, SECOND_END + MINUTE_IN_MILLIS); 447 assertIndexBeforeAfter(stats, 2, 3, THIRD_START - MINUTE_IN_MILLIS); 448 assertIndexBeforeAfter(stats, 2, 4, THIRD_START); 449 assertIndexBeforeAfter(stats, 3, 4, THIRD_START + MINUTE_IN_MILLIS); 450 assertIndexBeforeAfter(stats, 3, 4, THIRD_START + HOUR_IN_MILLIS); 451 assertIndexBeforeAfter(stats, 4, 4, THIRD_END); 452 assertIndexBeforeAfter(stats, 4, 4, THIRD_END + MINUTE_IN_MILLIS); 453 assertIndexBeforeAfter(stats, 4, 4, Long.MAX_VALUE); 454 } 455 456 private static void assertIndexBeforeAfter( 457 NetworkStatsHistory stats, int before, int after, long time) { 458 assertEquals("unexpected before", before, stats.getIndexBefore(time)); 459 assertEquals("unexpected after", after, stats.getIndexAfter(time)); 460 } 461 462 private static long performVarLong(long before) throws Exception { 463 final ByteArrayOutputStream out = new ByteArrayOutputStream(); 464 writeVarLong(new DataOutputStream(out), before); 465 466 final ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); 467 return readVarLong(new DataInputStream(in)); 468 } 469 470 private static void assertConsistent(NetworkStatsHistory stats) { 471 // verify timestamps are monotonic 472 long lastStart = Long.MIN_VALUE; 473 NetworkStatsHistory.Entry entry = null; 474 for (int i = 0; i < stats.size(); i++) { 475 entry = stats.getValues(i, entry); 476 assertTrue(lastStart < entry.bucketStart); 477 lastStart = entry.bucketStart; 478 } 479 } 480 481 private static void assertValues( 482 NetworkStatsHistory stats, int index, long rxBytes, long txBytes) { 483 final NetworkStatsHistory.Entry entry = stats.getValues(index, null); 484 assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes); 485 assertEquals("unexpected txBytes", txBytes, entry.txBytes); 486 } 487 488 private static void assertValues( 489 NetworkStatsHistory stats, long start, long end, long rxBytes, long txBytes) { 490 final NetworkStatsHistory.Entry entry = stats.getValues(start, end, null); 491 assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes); 492 assertEquals("unexpected txBytes", txBytes, entry.txBytes); 493 } 494 495 private static void assertValues(NetworkStatsHistory stats, int index, long activeTime, 496 long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) { 497 final NetworkStatsHistory.Entry entry = stats.getValues(index, null); 498 assertEquals("unexpected activeTime", activeTime, entry.activeTime); 499 assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes); 500 assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets); 501 assertEquals("unexpected txBytes", txBytes, entry.txBytes); 502 assertEquals("unexpected txPackets", txPackets, entry.txPackets); 503 assertEquals("unexpected operations", operations, entry.operations); 504 } 505 506 private static void assertFullValues(NetworkStatsHistory stats, long activeTime, long rxBytes, 507 long rxPackets, long txBytes, long txPackets, long operations) { 508 assertValues(stats, Long.MIN_VALUE, Long.MAX_VALUE, activeTime, rxBytes, rxPackets, txBytes, 509 txPackets, operations); 510 } 511 512 private static void assertValues(NetworkStatsHistory stats, long start, long end, 513 long activeTime, long rxBytes, long rxPackets, long txBytes, long txPackets, 514 long operations) { 515 final NetworkStatsHistory.Entry entry = stats.getValues(start, end, null); 516 assertEquals("unexpected activeTime", activeTime, entry.activeTime); 517 assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes); 518 assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets); 519 assertEquals("unexpected txBytes", txBytes, entry.txBytes); 520 assertEquals("unexpected txPackets", txPackets, entry.txPackets); 521 assertEquals("unexpected operations", operations, entry.operations); 522 } 523 } 524