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.net.TrafficStats.GB_IN_BYTES; 28 import static android.net.TrafficStats.MB_IN_BYTES; 29 import static android.text.format.DateUtils.DAY_IN_MILLIS; 30 import static android.text.format.DateUtils.HOUR_IN_MILLIS; 31 import static android.text.format.DateUtils.MINUTE_IN_MILLIS; 32 import static android.text.format.DateUtils.SECOND_IN_MILLIS; 33 import static android.text.format.DateUtils.WEEK_IN_MILLIS; 34 import static android.text.format.DateUtils.YEAR_IN_MILLIS; 35 36 import android.test.AndroidTestCase; 37 import android.test.suitebuilder.annotation.SmallTest; 38 import android.test.suitebuilder.annotation.Suppress; 39 import android.util.Log; 40 41 import com.android.frameworks.coretests.R; 42 43 import java.io.ByteArrayInputStream; 44 import java.io.ByteArrayOutputStream; 45 import java.io.DataInputStream; 46 import java.io.DataOutputStream; 47 import java.util.Random; 48 49 @SmallTest 50 public class NetworkStatsHistoryTest extends AndroidTestCase { 51 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 65 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 91 public void testRecordSingleBucket() throws Exception { 92 final long BUCKET_SIZE = HOUR_IN_MILLIS; 93 stats = new NetworkStatsHistory(BUCKET_SIZE); 94 95 // record data into narrow window to get single bucket 96 stats.recordData(TEST_START, TEST_START + SECOND_IN_MILLIS, 97 new NetworkStats.Entry(1024L, 10L, 2048L, 20L, 2L)); 98 99 assertEquals(1, stats.size()); 100 assertValues(stats, 0, SECOND_IN_MILLIS, 1024L, 10L, 2048L, 20L, 2L); 101 } 102 103 public void testRecordEqualBuckets() throws Exception { 104 final long bucketDuration = HOUR_IN_MILLIS; 105 stats = new NetworkStatsHistory(bucketDuration); 106 107 // split equally across two buckets 108 final long recordStart = TEST_START + (bucketDuration / 2); 109 stats.recordData(recordStart, recordStart + bucketDuration, 110 new NetworkStats.Entry(1024L, 10L, 128L, 2L, 2L)); 111 112 assertEquals(2, stats.size()); 113 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); 115 } 116 117 public void testRecordTouchingBuckets() throws Exception { 118 final long BUCKET_SIZE = 15 * MINUTE_IN_MILLIS; 119 stats = new NetworkStatsHistory(BUCKET_SIZE); 120 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); 125 stats.recordData(recordStart, recordEnd, 126 new NetworkStats.Entry(1000L, 2000L, 5000L, 10000L, 100L)); 127 128 assertEquals(3, stats.size()); 129 // first bucket should have (1/20 of value) 130 assertValues(stats, 0, MINUTE_IN_MILLIS, 50L, 100L, 250L, 500L, 5L); 131 // second bucket should have (15/20 of value) 132 assertValues(stats, 1, 15 * MINUTE_IN_MILLIS, 750L, 1500L, 3750L, 7500L, 75L); 133 // final bucket should have (4/20 of value) 134 assertValues(stats, 2, 4 * MINUTE_IN_MILLIS, 200L, 400L, 1000L, 2000L, 20L); 135 } 136 137 public void testRecordGapBuckets() throws Exception { 138 final long BUCKET_SIZE = HOUR_IN_MILLIS; 139 stats = new NetworkStatsHistory(BUCKET_SIZE); 140 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; 144 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)); 148 149 // we should have two buckets, far apart from each other 150 assertEquals(2, stats.size()); 151 assertValues(stats, 0, SECOND_IN_MILLIS, 128L, 2L, 256L, 4L, 1L); 152 assertValues(stats, 1, SECOND_IN_MILLIS, 64L, 1L, 512L, 8L, 2L); 153 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); 157 stats.recordData(middleStart, middleEnd, 158 new NetworkStats.Entry(2048L, 4L, 2048L, 4L, 2L)); 159 160 // now should have four buckets, with new record in middle two buckets 161 assertEquals(4, stats.size()); 162 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); 166 } 167 168 public void testRecordOverlapBuckets() throws Exception { 169 final long BUCKET_SIZE = HOUR_IN_MILLIS; 170 stats = new NetworkStatsHistory(BUCKET_SIZE); 171 172 // record some data in one bucket, and another overlapping buckets 173 stats.recordData(TEST_START, TEST_START + SECOND_IN_MILLIS, 174 new NetworkStats.Entry(256L, 2L, 256L, 2L, 1L)); 175 final long midStart = TEST_START + (HOUR_IN_MILLIS / 2); 176 stats.recordData(midStart, midStart + HOUR_IN_MILLIS, 177 new NetworkStats.Entry(1024L, 10L, 1024L, 10L, 10L)); 178 179 // should have two buckets, with some data mixed together 180 assertEquals(2, stats.size()); 181 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); 183 } 184 185 public void testRecordEntireGapIdentical() throws Exception { 186 // 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 200 assertValues(stats, TEST_START - WEEK_IN_MILLIS, TEST_START + WEEK_IN_MILLIS, 3000L, 1500L); 201 202 // now inspect internal buckets 203 assertValues(stats, 0, 1000L, 500L); 204 assertValues(stats, 1, 1000L, 500L); 205 assertValues(stats, 2, 500L, 250L); 206 assertValues(stats, 3, 500L, 250L); 207 } 208 209 public void testRecordEntireOverlapVaryingBuckets() throws Exception { 210 // 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 224 assertValues(stats, TEST_START - WEEK_IN_MILLIS, TEST_START + WEEK_IN_MILLIS, 650L, 650L); 225 226 // now inspect internal buckets 227 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); 234 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 241 assertValues(stats, TEST_START - WEEK_IN_MILLIS, TEST_START + WEEK_IN_MILLIS, 650L, 650L); 242 243 // and inspect buckets 244 assertValues(stats, 0, 200L, 200L); 245 assertValues(stats, 1, 150L, 150L); 246 assertValues(stats, 2, 150L, 150L); 247 assertValues(stats, 3, 150L, 150L); 248 } 249 250 public void testRemove() throws Exception { 251 stats = new NetworkStatsHistory(HOUR_IN_MILLIS); 252 253 // record some data across 24 buckets 254 stats.recordData(TEST_START, TEST_START + DAY_IN_MILLIS, 24L, 24L); 255 assertEquals(24, stats.size()); 256 257 // try removing invalid data; should be no change 258 stats.removeBucketsBefore(0 - DAY_IN_MILLIS); 259 assertEquals(24, stats.size()); 260 261 // try removing far before buckets; should be no change 262 stats.removeBucketsBefore(TEST_START - YEAR_IN_MILLIS); 263 assertEquals(24, stats.size()); 264 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); 268 assertEquals(24, stats.size()); 269 270 // try removing single bucket 271 stats.removeBucketsBefore(TEST_START + HOUR_IN_MILLIS); 272 assertEquals(23, stats.size()); 273 274 // try removing multiple buckets 275 stats.removeBucketsBefore(TEST_START + (4 * HOUR_IN_MILLIS)); 276 assertEquals(20, stats.size()); 277 278 // try removing all buckets 279 stats.removeBucketsBefore(TEST_START + YEAR_IN_MILLIS); 280 assertEquals(0, stats.size()); 281 } 282 283 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 290 // verify that total outside range is 0 291 assertValues(stats, TEST_START - WEEK_IN_MILLIS, TEST_START - DAY_IN_MILLIS, 0L, 0L); 292 293 // verify total in first hour 294 assertValues(stats, TEST_START, TEST_START + HOUR_IN_MILLIS, 100L, 200L); 295 296 // verify total across 1.5 hours 297 assertValues(stats, TEST_START, TEST_START + (long) (1.5 * HOUR_IN_MILLIS), 150L, 300L); 298 299 // verify total beyond end 300 assertValues(stats, TEST_START + (23 * HOUR_IN_MILLIS), TEST_START + WEEK_IN_MILLIS, 100L, 200L); 301 302 // verify everything total 303 assertValues(stats, TEST_START - WEEK_IN_MILLIS, TEST_START + WEEK_IN_MILLIS, 2400L, 4800L); 304 305 } 306 307 @Suppress 308 public void testFuzzing() throws Exception { 309 try { 310 // fuzzing with random events, looking for crashes 311 final NetworkStats.Entry entry = new NetworkStats.Entry(); 312 final Random r = new Random(); 313 for (int i = 0; i < 500; i++) { 314 stats = new NetworkStatsHistory(r.nextLong()); 315 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(); 320 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); 326 } 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 339 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)); 350 history.recordData(0, 2 * MINUTE_IN_MILLIS, 351 new NetworkStats.Entry(2L, 2L, 2L, 2L, 2L)); 352 353 assertFullValues(history, UNKNOWN, 1026L, UNKNOWN, 2050L, UNKNOWN, UNKNOWN); 354 } 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 365 assertFullValues(partial, UNKNOWN, UNKNOWN, 10L, UNKNOWN, UNKNOWN, 4L); 366 } 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 377 assertFullValues(full, MINUTE_IN_MILLIS, 0L, 10L, 0L, 0L, 4L); 378 } 379 380 public void testSerialize() throws Exception { 381 final NetworkStatsHistory before = new NetworkStatsHistory(MINUTE_IN_MILLIS, 40, FIELD_ALL); 382 before.recordData(0, 4 * MINUTE_IN_MILLIS, 383 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 395 assertFullValues(before, 5 * MINUTE_IN_MILLIS, 1034L, 30L, 2078L, 60L, 54L); 396 assertFullValues(after, 5 * MINUTE_IN_MILLIS, 1034L, 30L, 2078L, 60L, 54L); 397 } 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 412 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 454 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 488 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 494 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 502 private static void assertConsistent(NetworkStatsHistory stats) { 503 // verify timestamps are monotonic 504 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; 510 } 511 } 512 513 private static void assertValues( 514 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); 518 } 519 520 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 527 private static void assertValues(NetworkStatsHistory stats, int index, long activeTime, 528 long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) { 529 final NetworkStatsHistory.Entry entry = stats.getValues(index, null); 530 assertEquals("unexpected activeTime", activeTime, entry.activeTime); 531 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 538 private static void assertFullValues(NetworkStatsHistory stats, long activeTime, long rxBytes, 539 long rxPackets, long txBytes, long txPackets, long operations) { 540 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) { 547 final NetworkStatsHistory.Entry entry = stats.getValues(start, end, null); 548 assertEquals("unexpected activeTime", activeTime, entry.activeTime); 549 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 } 555 } 556