1 /* 2 * Copyright (C) 2017 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 com.android.server.wifi.aware; 18 19 import static com.android.server.wifi.aware.WifiAwareMetrics.addNanHalStatusToHistogram; 20 import static com.android.server.wifi.aware.WifiAwareMetrics.histogramToProtoArray; 21 22 import static org.hamcrest.core.IsEqual.equalTo; 23 import static org.mockito.Mockito.when; 24 25 import android.app.AppOpsManager; 26 import android.content.Context; 27 import android.hardware.wifi.V1_0.NanStatusType; 28 import android.net.wifi.aware.WifiAwareNetworkSpecifier; 29 import android.util.Log; 30 import android.util.SparseArray; 31 import android.util.SparseIntArray; 32 33 import com.android.server.wifi.Clock; 34 import com.android.server.wifi.nano.WifiMetricsProto; 35 import com.android.server.wifi.util.MetricsUtils; 36 37 import org.junit.Before; 38 import org.junit.Rule; 39 import org.junit.Test; 40 import org.junit.rules.ErrorCollector; 41 import org.mockito.Mock; 42 import org.mockito.MockitoAnnotations; 43 44 import java.io.PrintWriter; 45 import java.io.StringWriter; 46 import java.util.HashMap; 47 import java.util.Map; 48 49 /** 50 * Unit test harness for WifiAwareMetrics 51 */ 52 public class WifiAwareMetricsTest { 53 @Mock Clock mClock; 54 @Mock private Context mMockContext; 55 @Mock private AppOpsManager mMockAppOpsManager; 56 @Rule public ErrorCollector collector = new ErrorCollector(); 57 58 private WifiAwareMetrics mDut; 59 60 // Histogram definition: start[i] = b + p * m^i with s sub-buckets, i=0,...,n-1 61 62 /** 63 * Histogram of following buckets, start[i] = 0 + 1 * 10^i with 9 sub-buckets, i=0,...,5 64 * 1 - 10: 9 sub-buckets each of width 1 65 * 10 - 100: 10 66 * 100 - 10e3: 10^2 67 * 10e3 - 10e4: 10^3 68 * 10e4 - 10e5: 10^4 69 * 10e5 - 10e6: 10^5 70 */ 71 private static final MetricsUtils.LogHistParms HIST1 = new MetricsUtils.LogHistParms(0, 1, 72 10, 9, 6); 73 74 /** 75 * Histogram of following buckets, start[i] = -20 + 2 * 5^i with 40 sub-buckets, i=0,...,2 76 * -18 - -10: 40 sub-bucket each of width 0.2 77 * -10 - 30: 1 78 * 30 - 230: 5 79 */ 80 private static final MetricsUtils.LogHistParms HIST2 = new MetricsUtils.LogHistParms(-20, 2, 81 5, 40, 3); 82 83 // Linear histogram of following buckets: 84 // <10 85 // [10, 30) 86 // [30, 60) 87 // [60, 100) 88 // >100 89 private static final int[] HIST_LINEAR = { 10, 30, 60, 100 }; 90 91 /** 92 * Pre-test configuration. Initialize and install mocks. 93 */ 94 @Before 95 public void setUp() throws Exception { 96 MockitoAnnotations.initMocks(this); 97 when(mMockContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mMockAppOpsManager); 98 setTime(0); 99 100 mDut = new WifiAwareMetrics(mClock); 101 } 102 103 /** 104 * Validates that recordEnableUsage() and recordDisableUsage() record valid metrics. 105 */ 106 @Test 107 public void testEnableDisableUsageMetrics() { 108 WifiMetricsProto.WifiAwareLog log; 109 110 // create 2 records 111 setTime(5); 112 mDut.recordEnableUsage(); 113 setTime(10); 114 mDut.recordDisableUsage(); 115 setTime(11); 116 mDut.recordEnableUsage(); 117 setTime(12); 118 mDut.recordDisableUsage(); 119 120 setTime(14); 121 log = mDut.consolidateProto(); 122 collector.checkThat(countAllHistogramSamples(log.histogramAwareAvailableDurationMs), 123 equalTo(2)); 124 validateProtoHistBucket("Duration[0] #1", log.histogramAwareAvailableDurationMs[0], 1, 2, 125 1); 126 validateProtoHistBucket("Duration[1] #1", log.histogramAwareAvailableDurationMs[1], 5, 6, 127 1); 128 collector.checkThat(log.availableTimeMs, equalTo(6L)); 129 130 // create another partial record 131 setTime(15); 132 mDut.recordEnableUsage(); 133 134 setTime(17); 135 log = mDut.consolidateProto(); 136 collector.checkThat(countAllHistogramSamples(log.histogramAwareAvailableDurationMs), 137 equalTo(2)); 138 validateProtoHistBucket("Duration[0] #2", log.histogramAwareAvailableDurationMs[0], 1, 2, 139 1); 140 validateProtoHistBucket("Duration[1] #2", log.histogramAwareAvailableDurationMs[1], 5, 6, 141 1); 142 collector.checkThat(log.availableTimeMs, equalTo(8L)); // the partial record of 2ms 143 144 145 // clear and continue that partial record (verify completed) 146 mDut.clear(); 147 setTime(23); 148 mDut.recordDisableUsage(); 149 150 log = mDut.consolidateProto(); 151 collector.checkThat(countAllHistogramSamples(log.histogramAwareAvailableDurationMs), 152 equalTo(1)); 153 validateProtoHistBucket("Duration[0] #3", log.histogramAwareAvailableDurationMs[0], 8, 9, 154 1); 155 collector.checkThat(log.availableTimeMs, equalTo(6L)); // the remnant record of 6ms 156 157 // clear and verify empty records 158 mDut.clear(); 159 log = mDut.consolidateProto(); 160 collector.checkThat(countAllHistogramSamples(log.histogramAwareAvailableDurationMs), 161 equalTo(0)); 162 } 163 164 /** 165 * Validates that recordEnableAware() and recordDisableAware() record valid metrics. 166 */ 167 @Test 168 public void testEnableDisableAwareMetrics() { 169 WifiMetricsProto.WifiAwareLog log; 170 171 // create 2 records 172 setTime(5); 173 mDut.recordEnableAware(); 174 setTime(10); 175 mDut.recordDisableAware(); 176 setTime(11); 177 mDut.recordEnableAware(); 178 setTime(12); 179 mDut.recordDisableAware(); 180 181 setTime(14); 182 log = mDut.consolidateProto(); 183 collector.checkThat(countAllHistogramSamples(log.histogramAwareEnabledDurationMs), 184 equalTo(2)); 185 validateProtoHistBucket("Duration[0] #1", log.histogramAwareEnabledDurationMs[0], 1, 2, 186 1); 187 validateProtoHistBucket("Duration[1] #1", log.histogramAwareEnabledDurationMs[1], 5, 6, 188 1); 189 collector.checkThat(log.enabledTimeMs, equalTo(6L)); 190 191 // create another partial record 192 setTime(15); 193 mDut.recordEnableAware(); 194 195 setTime(17); 196 log = mDut.consolidateProto(); 197 collector.checkThat(countAllHistogramSamples(log.histogramAwareEnabledDurationMs), 198 equalTo(2)); 199 validateProtoHistBucket("Duration[0] #2", log.histogramAwareEnabledDurationMs[0], 1, 2, 200 1); 201 validateProtoHistBucket("Duration[1] #2", log.histogramAwareEnabledDurationMs[1], 5, 6, 202 1); 203 collector.checkThat(log.enabledTimeMs, equalTo(8L)); // the partial record of 2ms 204 205 206 // clear and continue that partial record (verify completed) 207 mDut.clear(); 208 setTime(23); 209 mDut.recordDisableAware(); 210 211 log = mDut.consolidateProto(); 212 collector.checkThat(countAllHistogramSamples(log.histogramAwareEnabledDurationMs), 213 equalTo(1)); 214 validateProtoHistBucket("Duration[0] #3", log.histogramAwareEnabledDurationMs[0], 8, 9, 215 1); 216 collector.checkThat(log.enabledTimeMs, equalTo(6L)); // the remnant record of 6ms 217 218 // clear and verify empty records 219 mDut.clear(); 220 log = mDut.consolidateProto(); 221 collector.checkThat(countAllHistogramSamples(log.histogramAwareEnabledDurationMs), 222 equalTo(0)); 223 } 224 225 @Test 226 public void testAttachSessionMetrics() { 227 final int uid1 = 1005; 228 final int uid2 = 1006; 229 final SparseArray<WifiAwareClientState> clients = new SparseArray<>(); 230 WifiMetricsProto.WifiAwareLog log; 231 232 setTime(5); 233 234 // uid1: session 1 235 clients.put(10, 236 new WifiAwareClientState(mMockContext, 10, uid1, 0, null, null, null, false, 237 mClock.getElapsedSinceBootMillis())); 238 mDut.recordAttachSession(uid1, false, clients); 239 240 // uid1: session 2 241 clients.put(11, 242 new WifiAwareClientState(mMockContext, 11, uid1, 0, null, null, null, false, 243 mClock.getElapsedSinceBootMillis())); 244 mDut.recordAttachSession(uid1, false, clients); 245 246 // uid2: session 1 247 clients.put(12, 248 new WifiAwareClientState(mMockContext, 12, uid2, 0, null, null, null, false, 249 mClock.getElapsedSinceBootMillis())); 250 mDut.recordAttachSession(uid2, false, clients); 251 252 // uid2: session 2 253 clients.put(13, 254 new WifiAwareClientState(mMockContext, 13, uid2, 0, null, null, null, true, 255 mClock.getElapsedSinceBootMillis())); 256 mDut.recordAttachSession(uid2, true, clients); 257 258 // uid2: delete session 1 259 setTime(10); 260 mDut.recordAttachSessionDuration(clients.get(12).getCreationTime()); 261 clients.delete(12); 262 263 // uid2: delete session 2 264 setTime(15); 265 mDut.recordAttachSessionDuration(clients.get(13).getCreationTime()); 266 clients.delete(13); 267 268 // uid2: session 3 269 clients.put(14, 270 new WifiAwareClientState(mMockContext, 14, uid2, 0, null, null, null, false, 271 mClock.getElapsedSinceBootMillis())); 272 mDut.recordAttachSession(uid2, false, clients); 273 274 // a few failures 275 mDut.recordAttachStatus(NanStatusType.INTERNAL_FAILURE); 276 mDut.recordAttachStatus(NanStatusType.INTERNAL_FAILURE); 277 mDut.recordAttachStatus(-5); // invalid 278 279 // verify 280 log = mDut.consolidateProto(); 281 282 collector.checkThat("numApps", log.numApps, equalTo(2)); 283 collector.checkThat("numAppsUsingIdentityCallback", log.numAppsUsingIdentityCallback, 284 equalTo(1)); 285 collector.checkThat("maxConcurrentAttachSessionsInApp", 286 log.maxConcurrentAttachSessionsInApp, equalTo(2)); 287 collector.checkThat("histogramAttachSessionStatus.length", 288 log.histogramAttachSessionStatus.length, equalTo(3)); // 3 buckets 289 collector.checkThat("histogramAttachDurationMs.length", 290 log.histogramAttachDurationMs.length, equalTo(2)); 291 validateProtoHistBucket("Duration[0]", log.histogramAttachDurationMs[0], 5, 6, 1); 292 validateProtoHistBucket("Duration[1]", log.histogramAttachDurationMs[1], 10, 20, 1); 293 } 294 295 @Test 296 public void testDiscoverySessionMetrics() { 297 final int uid1 = 1005; 298 final int uid2 = 1006; 299 final int uid3 = 1007; 300 final SparseArray<WifiAwareClientState> clients = new SparseArray<>(); 301 WifiMetricsProto.WifiAwareLog log; 302 303 setTime(5); 304 WifiAwareClientState client1 = new WifiAwareClientState(mMockContext, 10, uid1, 0, null, 305 null, null, false, 0); 306 WifiAwareClientState client2 = new WifiAwareClientState(mMockContext, 11, uid2, 0, null, 307 null, null, false, 0); 308 WifiAwareClientState client3 = new WifiAwareClientState(mMockContext, 12, uid3, 0, null, 309 null, null, false, 0); 310 clients.put(10, client1); 311 clients.put(11, client2); 312 clients.put(12, client3); 313 314 // uid1: publish session 1 315 client1.addSession(new WifiAwareDiscoverySessionState(null, 100, (byte) 0, null, true, 316 false, mClock.getElapsedSinceBootMillis())); 317 mDut.recordDiscoverySession(uid1, clients); 318 mDut.recordDiscoveryStatus(uid1, NanStatusType.SUCCESS, true); 319 320 // uid1: publish session 2 321 client1.addSession(new WifiAwareDiscoverySessionState(null, 101, (byte) 0, null, true, 322 false, mClock.getElapsedSinceBootMillis())); 323 mDut.recordDiscoverySession(uid1, clients); 324 mDut.recordDiscoveryStatus(uid1, NanStatusType.SUCCESS, true); 325 326 // uid3: publish session 3 with ranging 327 client3.addSession(new WifiAwareDiscoverySessionState(null, 111, (byte) 0, null, true, 328 true, mClock.getElapsedSinceBootMillis())); 329 mDut.recordDiscoverySessionWithRanging(uid3, false, -1, -1, clients); 330 mDut.recordDiscoveryStatus(uid3, NanStatusType.SUCCESS, true); 331 332 // uid2: subscribe session 1 333 client2.addSession(new WifiAwareDiscoverySessionState(null, 102, (byte) 0, null, false, 334 false, mClock.getElapsedSinceBootMillis())); 335 mDut.recordDiscoverySession(uid2, clients); 336 mDut.recordDiscoveryStatus(uid2, NanStatusType.SUCCESS, false); 337 338 // uid2: publish session 2 339 client2.addSession(new WifiAwareDiscoverySessionState(null, 103, (byte) 0, null, true, 340 false, mClock.getElapsedSinceBootMillis())); 341 mDut.recordDiscoverySession(uid2, clients); 342 mDut.recordDiscoveryStatus(uid2, NanStatusType.SUCCESS, false); 343 344 // uid3: subscribe session 3 with ranging: min 345 client3.addSession(new WifiAwareDiscoverySessionState(null, 112, (byte) 0, null, false, 346 true, mClock.getElapsedSinceBootMillis())); 347 mDut.recordDiscoverySessionWithRanging(uid3, true, 10, -1, clients); 348 mDut.recordDiscoveryStatus(uid3, NanStatusType.SUCCESS, false); 349 350 // uid3: subscribe session 3 with ranging: max 351 client3.addSession(new WifiAwareDiscoverySessionState(null, 113, (byte) 0, null, false, 352 true, mClock.getElapsedSinceBootMillis())); 353 mDut.recordDiscoverySessionWithRanging(uid3, true, -1, 50, clients); 354 mDut.recordDiscoveryStatus(uid3, NanStatusType.SUCCESS, false); 355 356 // uid3: subscribe session 3 with ranging: minmax 357 client3.addSession(new WifiAwareDiscoverySessionState(null, 114, (byte) 0, null, false, 358 true, mClock.getElapsedSinceBootMillis())); 359 mDut.recordDiscoverySessionWithRanging(uid3, true, 0, 110, clients); 360 mDut.recordDiscoveryStatus(uid3, NanStatusType.SUCCESS, false); 361 362 // uid1: delete session 1 363 setTime(10); 364 mDut.recordDiscoverySessionDuration(client1.getSession(100).getCreationTime(), 365 client1.getSession(100).isPublishSession()); 366 client1.removeSession(100); 367 368 // uid2: delete session 1 369 setTime(15); 370 mDut.recordDiscoverySessionDuration(client2.getSession(102).getCreationTime(), 371 client2.getSession(102).isPublishSession()); 372 client2.removeSession(102); 373 374 // uid2: subscribe session 3 375 mDut.recordDiscoverySession(uid2, clients); 376 client2.addSession(new WifiAwareDiscoverySessionState(null, 104, (byte) 0, null, false, 377 false, mClock.getElapsedSinceBootMillis())); 378 379 // a few failures 380 mDut.recordDiscoveryStatus(uid1, NanStatusType.INTERNAL_FAILURE, true); 381 mDut.recordDiscoveryStatus(uid2, NanStatusType.INTERNAL_FAILURE, false); 382 mDut.recordDiscoveryStatus(uid2, NanStatusType.NO_RESOURCES_AVAILABLE, false); 383 mDut.recordAttachStatus(-5); // invalid 384 385 // verify 386 log = mDut.consolidateProto(); 387 388 collector.checkThat("maxConcurrentPublishInApp", log.maxConcurrentPublishInApp, equalTo(2)); 389 collector.checkThat("maxConcurrentSubscribeInApp", log.maxConcurrentSubscribeInApp, 390 equalTo(3)); 391 collector.checkThat("maxConcurrentDiscoverySessionsInApp", 392 log.maxConcurrentDiscoverySessionsInApp, equalTo(4)); 393 collector.checkThat("maxConcurrentPublishInSystem", log.maxConcurrentPublishInSystem, 394 equalTo(4)); 395 collector.checkThat("maxConcurrentSubscribeInSystem", log.maxConcurrentSubscribeInSystem, 396 equalTo(4)); 397 collector.checkThat("maxConcurrentDiscoverySessionsInSystem", 398 log.maxConcurrentDiscoverySessionsInSystem, equalTo(8)); 399 collector.checkThat("histogramPublishStatus.length", 400 log.histogramPublishStatus.length, equalTo(2)); // 2 buckets 401 collector.checkThat("histogramSubscribeStatus.length", 402 log.histogramSubscribeStatus.length, equalTo(3)); // 3 buckets 403 collector.checkThat("numAppsWithDiscoverySessionFailureOutOfResources", 404 log.numAppsWithDiscoverySessionFailureOutOfResources, equalTo(1)); 405 validateProtoHistBucket("Publish Duration[0]", log.histogramPublishSessionDurationMs[0], 5, 406 6, 1); 407 validateProtoHistBucket("Subscribe Duration[0]", log.histogramSubscribeSessionDurationMs[0], 408 10, 20, 1); 409 410 collector.checkThat("maxConcurrentPublishWithRangingInApp", 411 log.maxConcurrentPublishWithRangingInApp, equalTo(1)); 412 collector.checkThat("maxConcurrentSubscribeWithRangingInApp", 413 log.maxConcurrentSubscribeWithRangingInApp, equalTo(3)); 414 collector.checkThat("maxConcurrentPublishWithRangingInSystem", 415 log.maxConcurrentPublishWithRangingInSystem, equalTo(1)); 416 collector.checkThat("maxConcurrentSubscribeWithRangingInSystem", 417 log.maxConcurrentSubscribeWithRangingInSystem, equalTo(3)); 418 collector.checkThat("numSubscribesWithRanging", log.numSubscribesWithRanging, equalTo(3)); 419 collector.checkThat("histogramSubscribeGeofenceMin.length", 420 log.histogramSubscribeGeofenceMin.length, equalTo(2)); 421 collector.checkThat("histogramSubscribeGeofenceMax.length", 422 log.histogramSubscribeGeofenceMax.length, equalTo(2)); 423 validateProtoHistBucket("histogramSubscribeGeofenceMin[0]", 424 log.histogramSubscribeGeofenceMin[0], Integer.MIN_VALUE, 10, 1); 425 validateProtoHistBucket("histogramSubscribeGeofenceMin[1]", 426 log.histogramSubscribeGeofenceMin[1], 10, 30, 1); 427 validateProtoHistBucket("histogramSubscribeGeofenceMax[0]", 428 log.histogramSubscribeGeofenceMax[0], 30, 60, 1); 429 validateProtoHistBucket("histogramSubscribeGeofenceMax[1]", 430 log.histogramSubscribeGeofenceMax[1], 100, Integer.MAX_VALUE, 1); 431 } 432 433 /** 434 * Validate the data-path (NDP & NDI) metrics. 435 */ 436 @Test 437 public void testDataPathMetrics() { 438 final int uid1 = 1005; 439 final int uid2 = 1006; 440 final String ndi0 = "aware_data0"; 441 final String ndi1 = "aware_data1"; 442 Map<WifiAwareNetworkSpecifier, WifiAwareDataPathStateManager.AwareNetworkRequestInformation> 443 networkRequestCache = new HashMap<>(); 444 WifiMetricsProto.WifiAwareLog log; 445 446 setTime(5); 447 448 // uid1: ndp (non-secure) on ndi0 449 addNetworkInfoToCache(networkRequestCache, 10, uid1, ndi0, null); 450 mDut.recordNdpCreation(uid1, networkRequestCache); 451 setTime(7); // 2ms creation time 452 mDut.recordNdpStatus(NanStatusType.SUCCESS, false, 5); 453 454 // uid2: ndp (non-secure) on ndi0 455 WifiAwareNetworkSpecifier ns = addNetworkInfoToCache(networkRequestCache, 11, uid2, ndi0, 456 null); 457 mDut.recordNdpCreation(uid2, networkRequestCache); 458 setTime(10); // 3 ms creation time 459 mDut.recordNdpStatus(NanStatusType.SUCCESS, false, 7); 460 461 // uid2: ndp (secure) on ndi1 (OOB) 462 addNetworkInfoToCache(networkRequestCache, 12, uid2, ndi1, "passphrase of some kind"); 463 mDut.recordNdpCreation(uid2, networkRequestCache); 464 setTime(25); // 15 ms creation time 465 mDut.recordNdpStatus(NanStatusType.SUCCESS, true, 10); 466 467 // uid2: ndp (secure) on ndi0 (OOB) 468 addNetworkInfoToCache(networkRequestCache, 13, uid2, ndi0, "super secret password"); 469 mDut.recordNdpCreation(uid2, networkRequestCache); 470 setTime(36); // 11 ms creation time 471 mDut.recordNdpStatus(NanStatusType.SUCCESS, true, 25); 472 473 // uid2: delete the first NDP 474 networkRequestCache.remove(ns); 475 476 // uid2: ndp (non-secure) on ndi0 477 addNetworkInfoToCache(networkRequestCache, 14, uid2, ndi0, null); 478 mDut.recordNdpCreation(uid2, networkRequestCache); 479 setTime(37); // 1 ms creation time! 480 mDut.recordNdpStatus(NanStatusType.SUCCESS, false, 36); 481 482 // a few error codes 483 mDut.recordNdpStatus(NanStatusType.INTERNAL_FAILURE, false, 0); 484 mDut.recordNdpStatus(NanStatusType.INTERNAL_FAILURE, false, 0); 485 mDut.recordNdpStatus(NanStatusType.NO_RESOURCES_AVAILABLE, false, 0); 486 487 // and some durations 488 setTime(150); 489 mDut.recordNdpSessionDuration(7); // 143ms 490 mDut.recordNdpSessionDuration(10); // 140ms 491 mDut.recordNdpSessionDuration(25); // 125ms 492 mDut.recordNdpSessionDuration(140); // 10ms 493 494 //verify 495 log = mDut.consolidateProto(); 496 497 collector.checkThat("maxConcurrentNdiInApp", log.maxConcurrentNdiInApp, equalTo(2)); 498 collector.checkThat("maxConcurrentNdiInSystem", log.maxConcurrentNdiInSystem, equalTo(2)); 499 collector.checkThat("maxConcurrentNdpInApp", log.maxConcurrentNdpInApp, equalTo(3)); 500 collector.checkThat("maxConcurrentNdpInSystem", log.maxConcurrentNdpInSystem, equalTo(4)); 501 collector.checkThat("maxConcurrentSecureNdpInApp", log.maxConcurrentSecureNdpInApp, 502 equalTo(2)); 503 collector.checkThat("maxConcurrentSecureNdpInSystem", log.maxConcurrentSecureNdpInSystem, 504 equalTo(2)); 505 collector.checkThat("maxConcurrentNdpPerNdi", log.maxConcurrentNdpPerNdi, equalTo(3)); 506 collector.checkThat("histogramRequestNdpStatus.length", 507 log.histogramRequestNdpStatus.length, equalTo(3)); 508 collector.checkThat("histogramRequestNdpOobStatus.length", 509 log.histogramRequestNdpOobStatus.length, equalTo(1)); 510 511 collector.checkThat("ndpCreationTimeMsMin", log.ndpCreationTimeMsMin, equalTo(1L)); 512 collector.checkThat("ndpCreationTimeMsMax", log.ndpCreationTimeMsMax, equalTo(15L)); 513 collector.checkThat("ndpCreationTimeMsSum", log.ndpCreationTimeMsSum, equalTo(32L)); 514 collector.checkThat("ndpCreationTimeMsSumOfSq", log.ndpCreationTimeMsSumOfSq, 515 equalTo(360L)); 516 collector.checkThat("ndpCreationTimeMsNumSamples", log.ndpCreationTimeMsNumSamples, 517 equalTo(5L)); 518 validateProtoHistBucket("Creation[0]", log.histogramNdpCreationTimeMs[0], 1, 2, 1); 519 validateProtoHistBucket("Creation[1]", log.histogramNdpCreationTimeMs[1], 2, 3, 1); 520 validateProtoHistBucket("Creation[2]", log.histogramNdpCreationTimeMs[2], 3, 4, 1); 521 validateProtoHistBucket("Creation[3]", log.histogramNdpCreationTimeMs[3], 10, 20, 2); 522 523 validateProtoHistBucket("Duration[0]", log.histogramNdpSessionDurationMs[0], 10, 20, 1); 524 validateProtoHistBucket("Duration[1]", log.histogramNdpSessionDurationMs[1], 100, 200, 3); 525 } 526 527 /** 528 * Validate that the histogram configuration is initialized correctly: bucket starting points 529 * and sub-bucket widths. 530 */ 531 @Test 532 public void testHistParamInit() { 533 collector.checkThat("HIST1.mLog", HIST1.mLog, equalTo(Math.log(10))); 534 collector.checkThat("HIST1.bb[0]", HIST1.bb[0], equalTo(1.0)); 535 collector.checkThat("HIST1.bb[1]", HIST1.bb[1], equalTo(10.0)); 536 collector.checkThat("HIST1.bb[2]", HIST1.bb[2], equalTo(100.0)); 537 collector.checkThat("HIST1.bb[3]", HIST1.bb[3], equalTo(1000.0)); 538 collector.checkThat("HIST1.bb[4]", HIST1.bb[4], equalTo(10000.0)); 539 collector.checkThat("HIST1.bb[5]", HIST1.bb[5], equalTo(100000.0)); 540 collector.checkThat("HIST1.sbw[0]", HIST1.sbw[0], equalTo(1.0)); 541 collector.checkThat("HIST1.sbw[1]", HIST1.sbw[1], equalTo(10.0)); 542 collector.checkThat("HIST1.sbw[2]", HIST1.sbw[2], equalTo(100.0)); 543 collector.checkThat("HIST1.sbw[3]", HIST1.sbw[3], equalTo(1000.0)); 544 collector.checkThat("HIST1.sbw[4]", HIST1.sbw[4], equalTo(10000.0)); 545 collector.checkThat("HIST1.sbw[5]", HIST1.sbw[5], equalTo(100000.0)); 546 547 collector.checkThat("HIST2.mLog", HIST1.mLog, equalTo(Math.log(10))); 548 collector.checkThat("HIST2.bb[0]", HIST2.bb[0], equalTo(-18.0)); 549 collector.checkThat("HIST2.bb[1]", HIST2.bb[1], equalTo(-10.0)); 550 collector.checkThat("HIST2.bb[2]", HIST2.bb[2], equalTo(30.0)); 551 collector.checkThat("HIST2.sbw[0]", HIST2.sbw[0], equalTo(0.2)); 552 collector.checkThat("HIST2.sbw[1]", HIST2.sbw[1], equalTo(1.0)); 553 collector.checkThat("HIST2.sbw[2]", HIST2.sbw[2], equalTo(5.0)); 554 } 555 556 /** 557 * Validate the conversion to a NanStatusType proto raw histogram. 558 */ 559 @Test 560 public void testNanStatusTypeHistogram() { 561 SparseIntArray statusHistogram = new SparseIntArray(); 562 563 addNanHalStatusToHistogram(NanStatusType.SUCCESS, statusHistogram); 564 addNanHalStatusToHistogram(-1, statusHistogram); 565 addNanHalStatusToHistogram(NanStatusType.ALREADY_ENABLED, statusHistogram); 566 addNanHalStatusToHistogram(NanStatusType.SUCCESS, statusHistogram); 567 addNanHalStatusToHistogram(NanStatusType.INTERNAL_FAILURE, statusHistogram); 568 addNanHalStatusToHistogram(NanStatusType.SUCCESS, statusHistogram); 569 addNanHalStatusToHistogram(NanStatusType.INTERNAL_FAILURE, statusHistogram); 570 addNanHalStatusToHistogram(55, statusHistogram); 571 addNanHalStatusToHistogram(65, statusHistogram); 572 573 WifiMetricsProto.WifiAwareLog.NanStatusHistogramBucket[] sh = histogramToProtoArray( 574 statusHistogram); 575 collector.checkThat("Number of buckets", sh.length, equalTo(4)); 576 validateNanStatusProtoHistBucket("Bucket[SUCCESS]", sh[0], 577 WifiMetricsProto.WifiAwareLog.SUCCESS, 3); 578 validateNanStatusProtoHistBucket("Bucket[INTERNAL_FAILURE]", sh[1], 579 WifiMetricsProto.WifiAwareLog.INTERNAL_FAILURE, 2); 580 validateNanStatusProtoHistBucket("Bucket[ALREADY_ENABLED]", sh[2], 581 WifiMetricsProto.WifiAwareLog.ALREADY_ENABLED, 1); 582 validateNanStatusProtoHistBucket("Bucket[UNKNOWN_HAL_STATUS]", sh[3], 583 WifiMetricsProto.WifiAwareLog.UNKNOWN_HAL_STATUS, 3); 584 } 585 586 // utilities 587 588 /** 589 * Mock the elapsed time since boot to the input argument. 590 */ 591 private void setTime(long timeMs) { 592 when(mClock.getElapsedSinceBootMillis()).thenReturn(timeMs); 593 } 594 595 /** 596 * Sum all the 'count' entries in the histogram array. 597 */ 598 private int countAllHistogramSamples(WifiMetricsProto.WifiAwareLog.HistogramBucket[] hba) { 599 int sum = 0; 600 for (WifiMetricsProto.WifiAwareLog.HistogramBucket hb: hba) { 601 sum += hb.count; 602 } 603 return sum; 604 } 605 606 private int countAllHistogramSamples( 607 WifiMetricsProto.WifiAwareLog.NanStatusHistogramBucket[] nshba) { 608 int sum = 0; 609 for (WifiMetricsProto.WifiAwareLog.NanStatusHistogramBucket nshb: nshba) { 610 sum += nshb.count; 611 } 612 return sum; 613 } 614 615 private void validateProtoHistBucket(String logPrefix, 616 WifiMetricsProto.WifiAwareLog.HistogramBucket bucket, long start, long end, int count) { 617 collector.checkThat(logPrefix + ": start", bucket.start, equalTo(start)); 618 collector.checkThat(logPrefix + ": end", bucket.end, equalTo(end)); 619 collector.checkThat(logPrefix + ": count", bucket.count, equalTo(count)); 620 } 621 622 private void validateNanStatusProtoHistBucket(String logPrefix, 623 WifiMetricsProto.WifiAwareLog.NanStatusHistogramBucket bucket, int type, int count) { 624 collector.checkThat(logPrefix + ": type", bucket.nanStatusType, equalTo(type)); 625 collector.checkThat(logPrefix + ": count", bucket.count, equalTo(count)); 626 } 627 628 private WifiAwareNetworkSpecifier addNetworkInfoToCache( 629 Map<WifiAwareNetworkSpecifier, WifiAwareDataPathStateManager 630 .AwareNetworkRequestInformation> networkRequestCache, 631 int index, int uid, String interfaceName, String passphrase) { 632 WifiAwareNetworkSpecifier ns = new WifiAwareNetworkSpecifier(0, 0, 0, index, 0, null, null, 633 passphrase, 0); 634 WifiAwareDataPathStateManager.AwareNetworkRequestInformation anri = 635 new WifiAwareDataPathStateManager.AwareNetworkRequestInformation(); 636 anri.networkSpecifier = ns; 637 anri.state = WifiAwareDataPathStateManager.AwareNetworkRequestInformation.STATE_CONFIRMED; 638 anri.uid = uid; 639 anri.interfaceName = interfaceName; 640 641 networkRequestCache.put(ns, anri); 642 return ns; 643 } 644 645 private void dumpDut(String prefix) { 646 StringWriter sw = new StringWriter(); 647 mDut.dump(null, new PrintWriter(sw), null); 648 Log.e("WifiAwareMetrics", prefix + sw.toString()); 649 } 650 } 651