Home | History | Annotate | Download | only in aware
      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