xref: /aosp_15_r20/system/chre/pal/util/tests/wifi_scan_cache_test.cc (revision 84e339476a462649f82315436d70fd732297a399)
1 /*
2  * Copyright (C) 2020 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 #include "chre/pal/util/wifi_scan_cache.h"
18 
19 #include <algorithm>
20 #include <cinttypes>
21 #include <cstring>
22 
23 #include "chre/platform/linux/system_time.h"
24 #include "chre/platform/log.h"
25 #include "chre/platform/shared/pal_system_api.h"
26 #include "chre/util/fixed_size_vector.h"
27 #include "chre/util/macros.h"
28 #include "chre/util/nanoapp/wifi.h"
29 #include "chre/util/optional.h"
30 #include "chre/util/time.h"
31 #include "chre_api/chre/common.h"
32 #include "gtest/gtest.h"
33 
34 using chre::Milliseconds;
35 using chre::Nanoseconds;
36 using chre::Seconds;
37 using chre::platform_linux::clearMonotonicTimeOverride;
38 using chre::platform_linux::overrideMonotonicTime;
39 
40 namespace {
41 
42 /************************************************
43  *  Prototypes
44  ***********************************************/
45 void chreWifiScanResponseCallback(bool pending, uint8_t errorCode);
46 void chreWifiScanEventCallback(struct chreWifiScanEvent *event);
47 
48 struct WifiScanResponse {
49   bool pending;
50   uint8_t errorCode;
51 };
52 
53 /************************************************
54  *  Global variables
55  ***********************************************/
56 const chrePalWifiCallbacks gChreWifiPalCallbacks = {
57     .scanResponseCallback = chreWifiScanResponseCallback,
58     .scanEventCallback = chreWifiScanEventCallback,
59 };
60 
61 using InputVec = std::vector<chreWifiScanResult>;
62 using ResultVec = chre::FixedSizeVector<chreWifiScanResult,
63                                         CHRE_PAL_WIFI_SCAN_CACHE_CAPACITY>;
64 
65 chre::Optional<WifiScanResponse> gWifiScanResponse;
66 ResultVec gWifiScanResultList;
67 chre::Optional<chreWifiScanEvent> gExpectedWifiScanEvent;
68 bool gWifiScanEventCompleted;
69 
70 /************************************************
71  *  Test class
72  ***********************************************/
73 class WifiScanCacheTests : public ::testing::Test {
74  protected:
SetUp()75   void SetUp() override {
76     clearTestState();
77     EXPECT_TRUE(chreWifiScanCacheInit(&chre::gChrePalSystemApi,
78                                       &gChreWifiPalCallbacks));
79   }
80 
TearDown()81   void TearDown() override {
82     chreWifiScanCacheDeinit();
83     clearMonotonicTimeOverride();
84   }
85 
clearTestState()86   void clearTestState() {
87     gExpectedWifiScanEvent.reset();
88     gWifiScanResponse.reset();
89     while (!gWifiScanResultList.empty()) {
90       gWifiScanResultList.pop_back();
91     }
92   }
93 };
94 
95 /************************************************
96  *  Private functions
97  ***********************************************/
chreWifiScanResponseCallback(bool pending,uint8_t errorCode)98 void chreWifiScanResponseCallback(bool pending, uint8_t errorCode) {
99   WifiScanResponse response = {
100       .pending = pending,
101       .errorCode = errorCode,
102   };
103   gWifiScanResponse = response;
104 }
105 
chreWifiScanEventCallback(struct chreWifiScanEvent * event)106 void chreWifiScanEventCallback(struct chreWifiScanEvent *event) {
107   ASSERT_TRUE(gExpectedWifiScanEvent.has_value());
108   EXPECT_EQ(event->version, gExpectedWifiScanEvent->version);
109   EXPECT_EQ(event->scanType, gExpectedWifiScanEvent->scanType);
110   EXPECT_EQ(event->ssidSetSize, gExpectedWifiScanEvent->ssidSetSize);
111   ASSERT_EQ(event->scannedFreqListLen,
112             gExpectedWifiScanEvent->scannedFreqListLen);
113   if (event->scannedFreqListLen > 0) {
114     ASSERT_NE(event->scannedFreqList, nullptr);
115     EXPECT_EQ(
116         memcmp(gExpectedWifiScanEvent->scannedFreqList, event->scannedFreqList,
117                event->scannedFreqListLen * sizeof(uint32_t)),
118         0);
119   }
120 
121   EXPECT_EQ(event->radioChainPref, gExpectedWifiScanEvent->radioChainPref);
122   EXPECT_EQ(event->eventIndex, gExpectedWifiScanEvent->eventIndex);
123   gExpectedWifiScanEvent->eventIndex++;
124 
125   for (uint8_t i = 0; i < event->resultCount; i++) {
126     const chreWifiScanResult &result = event->results[i];
127     gWifiScanResultList.push_back(result);
128   }
129 
130   if (gWifiScanResultList.size() == event->resultTotal) {
131     gWifiScanEventCompleted = true;
132   }
133 
134   chreWifiScanCacheReleaseScanEvent(event);
135 }
136 
beginDefaultWifiCache(const uint32_t * scannedFreqList,uint16_t scannedFreqListLen,bool scanRequestedByChre=true)137 void beginDefaultWifiCache(const uint32_t *scannedFreqList,
138                            uint16_t scannedFreqListLen,
139                            bool scanRequestedByChre = true) {
140   chreWifiScanEvent event;
141   memset(&event, 0, sizeof(chreWifiScanEvent));
142   event.version = CHRE_WIFI_SCAN_EVENT_VERSION;
143   event.scanType = CHRE_WIFI_SCAN_TYPE_ACTIVE;
144   event.scannedFreqList = scannedFreqList;
145   event.scannedFreqListLen = scannedFreqListLen;
146   event.radioChainPref = CHRE_WIFI_RADIO_CHAIN_PREF_DEFAULT;
147   gExpectedWifiScanEvent = event;
148 
149   chreWifiScanCacheScanEventBegin(
150       static_cast<enum chreWifiScanType>(gExpectedWifiScanEvent->scanType),
151       gExpectedWifiScanEvent->ssidSetSize,
152       gExpectedWifiScanEvent->scannedFreqList,
153       gExpectedWifiScanEvent->scannedFreqListLen,
154       gExpectedWifiScanEvent->radioChainPref, scanRequestedByChre);
155 }
156 
resultSpecifiedWifiCacheTest(size_t numEvents,InputVec & inputResults,ResultVec & expectedResults,const uint32_t * scannedFreqList,uint16_t scannedFreqListLen,bool scanRequestedByChre=true,bool scanMonitoringEnabled=false)157 void resultSpecifiedWifiCacheTest(size_t numEvents, InputVec &inputResults,
158                                   ResultVec &expectedResults,
159                                   const uint32_t *scannedFreqList,
160                                   uint16_t scannedFreqListLen,
161                                   bool scanRequestedByChre = true,
162                                   bool scanMonitoringEnabled = false) {
163   gWifiScanEventCompleted = false;
164   beginDefaultWifiCache(scannedFreqList, scannedFreqListLen,
165                         scanRequestedByChre);
166 
167   for (size_t i = 0; i < numEvents; i++) {
168     chreWifiScanCacheScanEventAdd(&inputResults[i]);
169   }
170 
171   chreWifiScanCacheScanEventEnd(CHRE_ERROR_NONE);
172 
173   if (scanRequestedByChre) {
174     EXPECT_TRUE(gWifiScanResponse.has_value());
175     EXPECT_EQ(gWifiScanResponse->pending, true);
176     ASSERT_EQ(gWifiScanResponse->errorCode, CHRE_ERROR_NONE);
177   } else {
178     EXPECT_FALSE(gWifiScanResponse.has_value());
179   }
180 
181   size_t numEventsExpected = 0;
182   if (scanRequestedByChre || scanMonitoringEnabled) {
183     numEventsExpected = std::min(
184         numEvents, static_cast<size_t>(CHRE_PAL_WIFI_SCAN_CACHE_CAPACITY));
185     ASSERT_TRUE(gWifiScanEventCompleted);
186   }
187 
188   ASSERT_EQ(gWifiScanResultList.size(), numEventsExpected);
189   for (size_t i = 0; i < gWifiScanResultList.size(); i++) {
190     // ageMs is not known apriori
191     expectedResults[i].ageMs = gWifiScanResultList[i].ageMs;
192     EXPECT_EQ(memcmp(&gWifiScanResultList[i], &expectedResults[i],
193                      sizeof(chreWifiScanResult)),
194               0);
195   }
196 }
197 
cacheDefaultWifiCacheTest(size_t numEvents,const uint32_t * scannedFreqList,uint16_t scannedFreqListLen,bool scanRequestedByChre=true,bool scanMonitoringEnabled=false)198 void cacheDefaultWifiCacheTest(size_t numEvents,
199                                const uint32_t *scannedFreqList,
200                                uint16_t scannedFreqListLen,
201                                bool scanRequestedByChre = true,
202                                bool scanMonitoringEnabled = false) {
203   InputVec inputResults;
204   ResultVec expectedResults;
205 
206   // Generate a default set of input and expected results if not specified
207   chreWifiScanResult result = {};
208   for (uint64_t i = 0; i < numEvents; i++) {
209     result.rssi = static_cast<int8_t>(i);
210     memcpy(result.bssid, &i, sizeof(result.bssid));
211     inputResults.push_back(result);
212 
213     if (!expectedResults.full()) {
214       expectedResults.push_back(result);
215     } else {
216       int8_t minRssi = result.rssi;
217       int minIdx = -1;
218       for (uint64_t idx = 0; idx < expectedResults.size(); idx++) {
219         if (expectedResults[idx].rssi < minRssi) {
220           minRssi = expectedResults[idx].rssi;
221           minIdx = idx;
222         }
223       }
224       if (minIdx != -1) {
225         expectedResults[minIdx] = result;
226       }
227     }
228   }
229 
230   resultSpecifiedWifiCacheTest(numEvents, inputResults, expectedResults,
231                                scannedFreqList, scannedFreqListLen,
232                                scanRequestedByChre, scanMonitoringEnabled);
233 }
234 
testCacheDispatch(size_t numEvents,uint32_t maxScanAgeMs,bool expectSuccess)235 void testCacheDispatch(size_t numEvents, uint32_t maxScanAgeMs,
236                        bool expectSuccess) {
237   cacheDefaultWifiCacheTest(numEvents, nullptr /* scannedFreqList */,
238                             0 /* scannedFreqListLen */);
239 
240   gExpectedWifiScanEvent->eventIndex = 0;
241   gWifiScanResponse.reset();
242   while (!gWifiScanResultList.empty()) {
243     gWifiScanResultList.pop_back();
244   }
245 
246   struct chreWifiScanParams params = {
247       .scanType = CHRE_WIFI_SCAN_TYPE_NO_PREFERENCE,
248       .maxScanAgeMs = maxScanAgeMs,
249       .frequencyListLen = 0,
250       .frequencyList = nullptr,
251       .ssidListLen = 0,
252       .ssidList = nullptr,
253       .radioChainPref = CHRE_WIFI_RADIO_CHAIN_PREF_DEFAULT,
254       .channelSet = CHRE_WIFI_CHANNEL_SET_NON_DFS,
255   };
256   EXPECT_EQ(chreWifiScanCacheDispatchFromCache(&params), expectSuccess);
257 
258   EXPECT_EQ(gWifiScanResponse.has_value(), expectSuccess);
259   if (expectSuccess) {
260     EXPECT_TRUE(gWifiScanResponse->pending);
261     EXPECT_EQ(gWifiScanResponse->errorCode, CHRE_ERROR_NONE);
262   }
263 
264   EXPECT_EQ(gWifiScanResultList.size(), expectSuccess ? numEvents : 0);
265 }
266 
267 }  // anonymous namespace
268 
269 /************************************************
270  *  Tests
271  ***********************************************/
TEST_F(WifiScanCacheTests,SingleWifiResultTest)272 TEST_F(WifiScanCacheTests, SingleWifiResultTest) {
273   cacheDefaultWifiCacheTest(1 /* numEvents */, nullptr /* scannedFreqList */,
274                             0 /* scannedFreqListLen */);
275 }
276 
TEST_F(WifiScanCacheTests,MultiWifiResultTest)277 TEST_F(WifiScanCacheTests, MultiWifiResultTest) {
278   cacheDefaultWifiCacheTest(
279       CHRE_PAL_WIFI_SCAN_CACHE_MAX_RESULT_COUNT + 1 /* numEvents */,
280       nullptr /* scannedFreqList */, 0 /* scannedFreqListLen */);
281 }
282 
TEST_F(WifiScanCacheTests,WifiResultOverflowTest)283 TEST_F(WifiScanCacheTests, WifiResultOverflowTest) {
284   cacheDefaultWifiCacheTest(
285       CHRE_PAL_WIFI_SCAN_CACHE_CAPACITY + 42 /* numEvents */,
286       nullptr /* scannedFreqList */, 0 /* scannedFreqListLen */);
287 }
288 
TEST_F(WifiScanCacheTests,WeakestRssiNotAddedToFullCacheTest)289 TEST_F(WifiScanCacheTests, WeakestRssiNotAddedToFullCacheTest) {
290   size_t numEvents = CHRE_PAL_WIFI_SCAN_CACHE_CAPACITY + 1;
291   InputVec inputResults;
292   ResultVec expectedResults;
293 
294   chreWifiScanResult result = {};
295   result.rssi = -20;
296   uint64_t i;
297   for (i = 0; i < CHRE_PAL_WIFI_SCAN_CACHE_CAPACITY; i++) {
298     memcpy(result.bssid, &i, sizeof(result.bssid));
299     inputResults.push_back(result);
300     expectedResults.push_back(result);
301   }
302 
303   result.rssi = -21;
304   memcpy(result.bssid, &i, sizeof(result.bssid));
305   inputResults.push_back(result);
306 
307   resultSpecifiedWifiCacheTest(numEvents, inputResults, expectedResults,
308                                nullptr /* scannedFreqList */,
309                                0 /* scannedFreqListLen */);
310 }
311 
TEST_F(WifiScanCacheTests,WeakestRssiReplacedAtEndOfFullCacheTest)312 TEST_F(WifiScanCacheTests, WeakestRssiReplacedAtEndOfFullCacheTest) {
313   size_t numEvents = CHRE_PAL_WIFI_SCAN_CACHE_CAPACITY + 1;
314   InputVec inputResults;
315   ResultVec expectedResults;
316 
317   chreWifiScanResult result = {};
318   result.rssi = -20;
319   uint64_t i;
320   for (i = 0; i < CHRE_PAL_WIFI_SCAN_CACHE_CAPACITY - 1; i++) {
321     memcpy(result.bssid, &i, sizeof(result.bssid));
322     inputResults.push_back(result);
323     expectedResults.push_back(result);
324   }
325 
326   result.rssi = -21;
327   memcpy(result.bssid, &i, sizeof(result.bssid));
328   i++;
329   inputResults.push_back(result);
330 
331   result.rssi = -19;
332   memcpy(result.bssid, &i, sizeof(result.bssid));
333   i++;
334   inputResults.push_back(result);
335   expectedResults.push_back(result);
336 
337   resultSpecifiedWifiCacheTest(numEvents, inputResults, expectedResults,
338                                nullptr /* scannedFreqList */,
339                                0 /* scannedFreqListLen */);
340 }
341 
TEST_F(WifiScanCacheTests,EmptyWifiResultTest)342 TEST_F(WifiScanCacheTests, EmptyWifiResultTest) {
343   cacheDefaultWifiCacheTest(0 /* numEvents */, nullptr /* scannedFreqList */,
344                             0 /* scannedFreqListLen */);
345 }
346 
TEST_F(WifiScanCacheTests,FailedWifiCacheTest)347 TEST_F(WifiScanCacheTests, FailedWifiCacheTest) {
348   beginDefaultWifiCache(nullptr /* scannedFreqList */,
349                         0 /* scannedFreqListLen */);
350 
351   chreWifiScanCacheScanEventEnd(CHRE_ERROR);
352 
353   EXPECT_TRUE(gWifiScanResponse.has_value());
354   EXPECT_FALSE(gWifiScanResponse->pending);
355   EXPECT_EQ(gWifiScanResponse->errorCode, CHRE_ERROR);
356 
357   EXPECT_EQ(gWifiScanResultList.size(), 0);
358 }
359 
TEST_F(WifiScanCacheTests,FrequencyListTest)360 TEST_F(WifiScanCacheTests, FrequencyListTest) {
361   const uint32_t freqList[2] = {5210, 5240};
362   cacheDefaultWifiCacheTest(1 /* numEvents */, freqList, ARRAY_SIZE(freqList));
363 }
364 
TEST_F(WifiScanCacheTests,InvalidFrequencyListTest)365 TEST_F(WifiScanCacheTests, InvalidFrequencyListTest) {
366   beginDefaultWifiCache(nullptr /* scannedFreqList */,
367                         1 /* scannedFreqListLen */);
368 
369   EXPECT_TRUE(gWifiScanResponse.has_value());
370   EXPECT_FALSE(gWifiScanResponse->pending);
371   EXPECT_EQ(gWifiScanResponse->errorCode, CHRE_ERROR_INVALID_ARGUMENT);
372 
373   EXPECT_EQ(gWifiScanResultList.size(), 0);
374 }
375 
TEST_F(WifiScanCacheTests,SequentialWifiResultTest)376 TEST_F(WifiScanCacheTests, SequentialWifiResultTest) {
377   cacheDefaultWifiCacheTest(1 /* numEvents */, nullptr /* scannedFreqList */,
378                             0 /* scannedFreqListLen */);
379 
380   clearTestState();
381   cacheDefaultWifiCacheTest(1 /* numEvents */, nullptr /* scannedFreqList */,
382                             0 /* scannedFreqListLen */);
383 }
384 
TEST_F(WifiScanCacheTests,ScanMonitorDisabledTest)385 TEST_F(WifiScanCacheTests, ScanMonitorDisabledTest) {
386   cacheDefaultWifiCacheTest(1 /* numEvents */, nullptr /* scannedFreqList */,
387                             0 /* scannedFreqListLen */,
388                             false /* scanRequestedByChre */,
389                             false /* scanMonitoringEnabled */);
390 }
391 
TEST_F(WifiScanCacheTests,ScanMonitorEnabledTest)392 TEST_F(WifiScanCacheTests, ScanMonitorEnabledTest) {
393   chreWifiScanCacheConfigureScanMonitor(true /* enable */);
394   cacheDefaultWifiCacheTest(1 /* numEvents */, nullptr /* scannedFreqList */,
395                             0 /* scannedFreqListLen */,
396                             false /* scanRequestedByChre */,
397                             true /* scanMonitoringEnabled */);
398 }
399 
TEST_F(WifiScanCacheTests,ScanMonitorEnableDisableTest)400 TEST_F(WifiScanCacheTests, ScanMonitorEnableDisableTest) {
401   chreWifiScanCacheConfigureScanMonitor(true /* enable */);
402   cacheDefaultWifiCacheTest(1 /* numEvents */, nullptr /* scannedFreqList */,
403                             0 /* scannedFreqListLen */,
404                             false /* scanRequestedByChre */,
405                             true /* scanMonitoringEnabled */);
406 
407   clearTestState();
408   chreWifiScanCacheConfigureScanMonitor(false /* enable */);
409   cacheDefaultWifiCacheTest(1 /* numEvents */, nullptr /* scannedFreqList */,
410                             0 /* scannedFreqListLen */,
411                             false /* scanRequestedByChre */,
412                             false /* scanMonitoringEnabled */);
413 }
414 
TEST_F(WifiScanCacheTests,CacheDispatchTest)415 TEST_F(WifiScanCacheTests, CacheDispatchTest) {
416   testCacheDispatch(1 /* numEvents */, 5000 /* maxScanAgeMs */,
417                     true /* expectSuccess */);
418 }
419 
TEST_F(WifiScanCacheTests,ZeroMaxScanAgeCacheDispatchTest)420 TEST_F(WifiScanCacheTests, ZeroMaxScanAgeCacheDispatchTest) {
421   testCacheDispatch(1 /* numEvents */, 0 /* maxScanAgeMs */,
422                     false /* expectSuccess */);
423 }
424 
TEST_F(WifiScanCacheTests,DuplicateScanResultTest)425 TEST_F(WifiScanCacheTests, DuplicateScanResultTest) {
426   beginDefaultWifiCache(nullptr /* scannedFreqList */,
427                         0 /* scannedFreqListLen */,
428                         true /* scanRequestedByChre */);
429 
430   chreWifiScanResult result = {};
431   result.rssi = -98;
432   result.primaryChannel = 5270;
433   std::string sampleSsid = "Test ssid";
434   memcpy(result.ssid, sampleSsid.c_str(), sampleSsid.length());
435   result.ssidLen = sampleSsid.length();
436   std::string sampleBssid = "12:34:56:78:9a:bc";
437   memcpy(result.bssid, sampleBssid.c_str(), sampleBssid.length());
438   chreWifiScanResult result2 = {};
439   result2.rssi = -98;
440   result2.primaryChannel = 5270;
441   std::string sampleSsid2 = "Test ssid 2";
442   memcpy(result2.ssid, sampleSsid2.c_str(), sampleSsid2.length());
443   result2.ssidLen = sampleSsid2.length();
444   std::string sampleBssid2 = "34:56:78:9a:bc:de";
445   memcpy(result2.bssid, sampleBssid2.c_str(), sampleBssid2.length());
446 
447   chreWifiScanCacheScanEventAdd(&result);
448   chreWifiScanCacheScanEventAdd(&result2);
449   chreWifiScanCacheScanEventAdd(&result);
450 
451   chreWifiScanCacheScanEventEnd(CHRE_ERROR_NONE);
452 
453   EXPECT_TRUE(gWifiScanResponse.has_value());
454   EXPECT_EQ(gWifiScanResponse->pending, true);
455   ASSERT_EQ(gWifiScanResponse->errorCode, CHRE_ERROR_NONE);
456 
457   ASSERT_EQ(gWifiScanResultList.size(), 2);
458   result.ageMs = gWifiScanResultList[0].ageMs;
459   EXPECT_EQ(
460       memcmp(&gWifiScanResultList[0], &result, sizeof(chreWifiScanResult)), 0);
461   result2.ageMs = gWifiScanResultList[1].ageMs;
462   EXPECT_EQ(
463       memcmp(&gWifiScanResultList[1], &result2, sizeof(chreWifiScanResult)), 0);
464 }
465 
TEST_F(WifiScanCacheTests,IncomingRequestDuringCachePopulationTest)466 TEST_F(WifiScanCacheTests, IncomingRequestDuringCachePopulationTest) {
467   beginDefaultWifiCache(nullptr /* scannedFreqList */,
468                         0 /* scannedFreqListLen */,
469                         false /* scanRequestedByChre */);
470 
471   chreWifiScanResult result = {};
472   chreWifiScanCacheScanEventAdd(&result);
473 
474   // An incoming request should upgrade the cache to a CHRE requested scan
475   // event.
476   chreWifiScanParams params = {
477       .scanType = CHRE_WIFI_SCAN_TYPE_ACTIVE,
478       .maxScanAgeMs = 5000,
479       .frequencyListLen = 0,
480       .frequencyList = nullptr,
481       .ssidListLen = 0,
482       .ssidList = nullptr,
483       .radioChainPref = CHRE_WIFI_RADIO_CHAIN_PREF_DEFAULT,
484       .channelSet = CHRE_WIFI_CHANNEL_SET_NON_DFS,
485   };
486   EXPECT_TRUE(chreWifiScanCacheDispatchFromCache(&params));
487 
488   // We shouldn't get the scan response until cache population is complete.
489   EXPECT_FALSE(gWifiScanResponse.has_value());
490 
491   result.bssid[0] = 1;
492   chreWifiScanCacheScanEventAdd(&result);
493   chreWifiScanCacheScanEventEnd(CHRE_ERROR_NONE);
494 
495   // CHRE should get the full cache result.
496   EXPECT_TRUE(gWifiScanResponse.has_value());
497   EXPECT_EQ(gWifiScanResponse->pending, true);
498   EXPECT_EQ(gWifiScanResponse->errorCode, CHRE_ERROR_NONE);
499   EXPECT_EQ(gWifiScanResultList.size(), 2);
500 }
501 
TEST_F(WifiScanCacheTests,AgeCalculatedCorrectly)502 TEST_F(WifiScanCacheTests, AgeCalculatedCorrectly) {
503   constexpr auto kStartTime = Seconds(4);
504   overrideMonotonicTime(kStartTime);
505   beginDefaultWifiCache(nullptr /* scannedFreqList */,
506                         0 /* scannedFreqListLen */);
507 
508   overrideMonotonicTime(kStartTime + Milliseconds(100));
509   chreWifiScanResult result = {};
510   chreWifiScanCacheScanEventAdd(&result);
511 
512   overrideMonotonicTime(kStartTime + Milliseconds(500));
513   chreWifiScanCacheScanEventEnd(CHRE_ERROR_NONE);
514 
515   ASSERT_EQ(gWifiScanResultList.size(), 1);
516   EXPECT_EQ(gWifiScanResultList[0].ageMs, 500 - 100);
517 }
518 
TEST_F(WifiScanCacheTests,AgeLongUptime)519 TEST_F(WifiScanCacheTests, AgeLongUptime) {
520   constexpr auto kStartTime = Seconds(60 * 60 * 24 * 50);  // 50 days
521   overrideMonotonicTime(kStartTime);
522   beginDefaultWifiCache(nullptr /* scannedFreqList */,
523                         0 /* scannedFreqListLen */);
524 
525   overrideMonotonicTime(kStartTime + Milliseconds(500));
526   chreWifiScanResult result = {};
527   chreWifiScanCacheScanEventAdd(&result);
528 
529   overrideMonotonicTime(kStartTime + Milliseconds(4000));
530   chreWifiScanCacheScanEventEnd(CHRE_ERROR_NONE);
531 
532   ASSERT_EQ(gWifiScanResultList.size(), 1);
533   EXPECT_EQ(gWifiScanResultList[0].ageMs, 4000 - 500);
534 }
535 
TEST_F(WifiScanCacheTests,AgeAvoidsUnderflow)536 TEST_F(WifiScanCacheTests, AgeAvoidsUnderflow) {
537   constexpr auto kStartTime = Seconds(30);
538   constexpr auto kEndTime = kStartTime + Seconds(5);
539   overrideMonotonicTime(kStartTime);
540   beginDefaultWifiCache(nullptr /* scannedFreqList */,
541                         0 /* scannedFreqListLen */);
542 
543   overrideMonotonicTime(Nanoseconds(0));
544   chreWifiScanResult result = {};
545   chreWifiScanCacheScanEventAdd(&result);
546 
547   overrideMonotonicTime(kEndTime);
548   chreWifiScanCacheScanEventEnd(CHRE_ERROR_NONE);
549 
550   ASSERT_EQ(gWifiScanResultList.size(), 1);
551   EXPECT_LT(gWifiScanResultList[0].ageMs,
552             Milliseconds(kEndTime - kStartTime).getMilliseconds());
553 }
554