14d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro/*
24d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * Copyright (C) 2016 The Android Open Source Project
34d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro *
44d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * Licensed under the Apache License, Version 2.0 (the "License");
54d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * you may not use this file except in compliance with the License.
64d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * You may obtain a copy of the License at
74d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro *
84d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro *      http://www.apache.org/licenses/LICENSE-2.0
94d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro *
104d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * Unless required by applicable law or agreed to in writing, software
114d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * distributed under the License is distributed on an "AS IS" BASIS,
124d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * See the License for the specific language governing permissions and
144d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * limitations under the License.
154d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro */
164d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
174d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#include <general_test/heap_exhaustion_stability_test.h>
184d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
194d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#include <cinttypes>
204d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#include <cstddef>
214d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
224d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#include <shared/send_message.h>
234d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
244d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#include <chre.h>
254d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
264d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurousing nanoapp_testing::sendFailureToHost;
274d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurousing nanoapp_testing::sendFatalFailureToHost;
284d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurousing nanoapp_testing::sendSuccessToHost;
294d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
304d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro/*
314d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * We set an "exhaustion timer" to go off when we're ready for the test to
324d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * be over.  Then we exhaust the heap.
334d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro *
344d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * We try a series of chre*() calls with the heap exhausted.  For many of
354d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * these calls, we're less interested in them succeeding than in the system
364d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * just not crashing.  However, for things which claim success, we require
374d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * they succeed.
384d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro *
394d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * To track the things which claim success, we have two "stages", kTimerStage
404d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * and kEventStage.
414d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro *
424d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * When the "exhaustion timer" fires, we free our memory, and make sure our
434d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * stages have all succeeded.
444d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro */
454d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
464d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguronamespace general_test {
474d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
484d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro// Note: We use pointers to the 'duration' to serve as our timer event data.
494d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro// Thus we make this "static const" instead of "constexpr", as we expect
504d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro// them to have backing memory.
514d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
524d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro// 5 seconds
534d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurostatic const uint64_t kExhaustionDuration = UINT64_C(5000000000);
544d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro// 10 milliseconds
554d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurostatic const uint64_t kShortDuration = UINT64_C(10000000);
564d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
574d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguroconstexpr uint16_t kEventType = CHRE_EVENT_FIRST_USER_VALUE;
584d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
594d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguroconstexpr uint32_t kTimerStage = 0;
604d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguroconstexpr uint32_t kEventStage = 1;
614d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
624d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurovoid HeapExhaustionStabilityTest::exhaustHeap() {
634d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  constexpr size_t kNumPtrs = 256;
644d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  mExhaustionPtrs = reinterpret_cast<void**>(
654d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro      chreHeapAlloc(kNumPtrs * sizeof(*mExhaustionPtrs)));
664d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (mExhaustionPtrs == nullptr) {
674d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    // Oh, the irony.
684d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost(
694d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro        "Insufficient free heap to exhaust the heap.");
704d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
714d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
724d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // We start by trying to allocate massive sizes (256MB to start).
734d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // When we're not able to allocate massive sizes, we cut the size in
744d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // half.  We repeat until we've either done kNumPtrs allocations,
754d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // or reduced our allocation size below 16 bytes.
764d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  uint32_t allocSize = 1024 * 1024 * 256;
774d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  for (mExhaustionPtrCount = 0;
784d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro       mExhaustionPtrCount < kNumPtrs;
794d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro       mExhaustionPtrCount++) {
804d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    void *ptr = chreHeapAlloc(allocSize);
814d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    while (ptr == nullptr) {
824d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro      allocSize /= 2;
834d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro      if (allocSize < 4) {
844d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro        break;
854d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro      }
864d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro      ptr = chreHeapAlloc(allocSize);
874d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    }
884d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    if (ptr == nullptr) {
894d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro      break;
904d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    }
914d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    mExhaustionPtrs[mExhaustionPtrCount] = ptr;
924d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
934d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (mExhaustionPtrCount == 0) {
944d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost(
954d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro        "Failed to allocate anything for heap exhaustion");
964d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
974d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro}
984d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
994d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurovoid HeapExhaustionStabilityTest::freeMemory() {
1004d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  for (size_t i = 0; i < mExhaustionPtrCount; i++) {
1014d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    chreHeapFree(mExhaustionPtrs[i]);
1024d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
1034d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  chreHeapFree(mExhaustionPtrs);
1044d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro}
1054d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
1064d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur IshiguroHeapExhaustionStabilityTest::HeapExhaustionStabilityTest()
1074d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  : Test(CHRE_API_VERSION_1_0) {
1084d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro}
1094d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
1104d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurovoid HeapExhaustionStabilityTest::setUp(uint32_t messageSize,
1114d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                                        const void * /* message */) {
1124d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  mInMethod = true;
1134d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (messageSize != 0) {
1144d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost(
1154d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro        "HeapExhaustionStability message expects 0 additional bytes, "
1164d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro        "got ", &messageSize);
1174d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
1184d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
1194d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (chreTimerSet(kExhaustionDuration, &kExhaustionDuration, true) ==
1204d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro      CHRE_TIMER_INVALID) {
1214d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("Unable to set initial timer");
1224d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
1234d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
1244d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  exhaustHeap();
1254d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
1264d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  testLog(messageSize);
1274d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  testSetTimer();
1284d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  testSendEvent();
1294d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  testSensor();
1304d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // TODO(b/32114261): This method currently doesn't test anything.
1314d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  testMessageToHost();
1324d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
1334d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // Some of the above 'test' methods might trigger events.  Even if they
1344d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // don't, the kExhaustionDuration timer we set earlier should trigger
1354d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // eventually, and that's when we'll conclude the test.
1364d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  mInMethod = false;
1374d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro}
1384d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
1394d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurovoid HeapExhaustionStabilityTest::testLog(uint32_t zero) {
1404d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // This doesn't need to land in the log (and indeed we have no automated
1414d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // means of checking that right now anyway), but it shouldn't crash.
1424d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  chreLog(CHRE_LOG_INFO, "Test log %s, zero: %" PRId32, "message", zero);
1434d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro}
1444d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
1454d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurovoid HeapExhaustionStabilityTest::testSetTimer() {
1464d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (chreTimerSet(kShortDuration, &kShortDuration, true) !=
1474d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro      CHRE_TIMER_INVALID) {
1484d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    // CHRE claims we were able to set this timer.  We'll
1494d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    // mark this stage a success when the timer fires.
1504d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  } else {
1514d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    // CHRE was not able to set this timer.  That's okay, since we're
1524d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    // out of heap.  We'll mark this stage as a success.
1534d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    markSuccess(kTimerStage);
1544d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
1554d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro}
1564d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
1574d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurovoid HeapExhaustionStabilityTest::testSendEvent() {
1584d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (chreSendEvent(kEventType, nullptr, nullptr, chreGetInstanceId())) {
1594d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    // CHRE claims we were able to send this event.  We'll make
1604d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    // this stage a success when the event is received.
1614d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  } else {
1624d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    // CHRE was not able to send this event.  That's okay, since we're
1634d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    // out of heap.  We'll mark this stage as a success.
1644d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    markSuccess(kEventStage);
1654d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
1664d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro}
1674d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
1684d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurovoid HeapExhaustionStabilityTest::testSensor() {
1694d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  static constexpr uint8_t kSensorType = CHRE_SENSOR_TYPE_ACCELEROMETER;
1704d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  uint32_t handle;
1714d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (!chreSensorFindDefault(kSensorType, &handle)) {
1724d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    // We still expect this to succeed without any heap left.
1734d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("chreSensorFindDefault failed");
1744d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
1754d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  chreSensorInfo info;
1764d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (!chreGetSensorInfo(handle, &info)) {
1774d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    // We still expect this to succeed, since we're supplying the memory.
1784d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("chreGetSensorInfo failed");
1794d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
1804d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (info.sensorType != kSensorType) {
1814d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("Invalid sensor info provided");
1824d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
1834d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
1844d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  chreSensorSamplingStatus samplingStatus;
1854d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (!chreGetSensorSamplingStatus(handle, &samplingStatus)) {
1864d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    // We still expect this to succeed, since we're supplying the memory.
1874d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("chreGetSensorSamplingStatus failed");
1884d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
1894d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
1904d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // TODO: We might want to consider calling chreSensorConfigure() for a
1914d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  //     more robust test of this.  However, we don't expect sensor events to
1924d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  //     necessarily get delivered under heap exhaustion, so it's unclear
1934d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  //     how we'd make sure we eventually tell the system we're DONE with
1944d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  //     the sensor (setting a timer isn't assured to work at this point).
1954d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro}
1964d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
1974d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurovoid HeapExhaustionStabilityTest::testMessageToHost() {
1984d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // TODO(b/32114261): We should invoke sendMessageToHost() here.
1994d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  //     Unfortunately, this is a real pain due to this bug, as we need to
2004d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  //     duplicate much of the contents of shared/send_message.cc to
2014d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  //     add the hack-around bytes (the method itself will internally
2024d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  //     fail if the send attempt fails, but we're in a state where
2034d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  //     we'll allow a failed send attempt).  Or we need to take this
2044d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  //     off of the General test infrastructure to allow raw byte sending.
2054d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  //     That seems not worth the effort for NYC, and just easier to wait
2064d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  //     until OMC when this is much easier to implement.
2074d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // OMC Note: When we've fixed this bug, and added a send here, we'll
2084d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  //     need to make this no longer Simple protocol, since this nanoapp
2094d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  //     might send a message.
2104d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro}
2114d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
2124d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurovoid HeapExhaustionStabilityTest::handleEvent(uint32_t senderInstanceId,
2134d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                                              uint16_t eventType,
2144d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                                              const void* eventData) {
2154d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (mInMethod) {
2164d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("handleEvent invoked while another nanoapp "
2174d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                           "method is running");
2184d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
2194d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  mInMethod = true;
2204d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
2214d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (eventType == CHRE_EVENT_TIMER) {
2224d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    handleTimer(senderInstanceId, eventData);
2234d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  } else if (eventType == kEventType) {
2244d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    handleSelfEvent(senderInstanceId, eventData);
2254d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  } else {
2264d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    unexpectedEvent(eventType);
2274d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
2284d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  mInMethod = false;
2294d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro}
2304d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
2314d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurovoid HeapExhaustionStabilityTest::handleTimer(uint32_t senderInstanceId,
2324d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                                              const void *eventData) {
2334d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (senderInstanceId != CHRE_INSTANCE_ID) {
2344d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("handleTimer with unexpected sender:",
2354d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                           &senderInstanceId);
2364d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
2374d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (eventData == &kShortDuration) {
2384d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    // This was the timer we triggered while the heap was exhausted.
2394d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    markSuccess(kTimerStage);
2404d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
2414d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  } else if (eventData == &kExhaustionDuration) {
2424d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    // Our test is done.
2434d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    freeMemory();
2444d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    if (mFinishedBitmask != kAllFinished) {
2454d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro      sendFatalFailureToHost("Done with test, but not all stages "
2464d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                             "done.", &mFinishedBitmask);
2474d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    }
2484d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendSuccessToHost();
2494d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
2504d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  } else {
2514d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("Unexpected timer eventData");
2524d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
2534d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro}
2544d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
2554d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurovoid HeapExhaustionStabilityTest::handleSelfEvent(uint32_t senderInstanceId,
2564d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                                                  const void *eventData) {
2574d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (senderInstanceId != chreGetInstanceId()) {
2584d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("handleSelfEvent with unexpected sender:",
2594d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro                           &senderInstanceId);
2604d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
2614d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if (eventData != nullptr) {
2624d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("Unexpected data for event to self");
2634d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
2644d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  markSuccess(kEventStage);
2654d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro}
2664d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
2674d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurovoid HeapExhaustionStabilityTest::markSuccess(uint32_t stage) {
2684d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  chreLog(CHRE_LOG_DEBUG, "Stage %" PRIu32 " succeeded", stage);
2694d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  uint32_t finishedBit = (1 << stage);
2704d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if ((kAllFinished & finishedBit) == 0) {
2714d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("markSuccess bad stage", &stage);
2724d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
2734d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  if ((mFinishedBitmask & finishedBit) != 0) {
2744d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    // This could be when a timer/event method returned 'false', but
2754d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    // actually did end up triggering an event.
2764d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro    sendFatalFailureToHost("markSuccess stage triggered twice", &stage);
2774d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  }
2784d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  mFinishedBitmask |= finishedBit;
2794d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // Note that unlike many markSuccess() implementations, we do not
2804d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // check against kAllFinished here.  That happens when the
2814d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro  // timer for kExhaustionDuration fires.
2824d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro}
2834d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
2844d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro
2854d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro}  // namespace general_test
286