Home | History | Annotate | Download | only in general_test
      1 /*
      2  * Copyright (C) 2016 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 <general_test/send_event_stress_test.h>
     18 
     19 #include <cstddef>
     20 
     21 #include <shared/send_message.h>
     22 
     23 #include <chre.h>
     24 
     25 using nanoapp_testing::sendFatalFailureToHost;
     26 using nanoapp_testing::sendSuccessToHost;
     27 
     28 /*
     29  * We stress the system by sending more and more events until it runs out.
     30  * Then we wait for all the events to be delivered, and all the completion
     31  * callbacks to be invoked.
     32  */
     33 
     34 constexpr uint16_t kEventType = CHRE_EVENT_FIRST_USER_VALUE;
     35 void *const kEventData = reinterpret_cast<void *>(-1);
     36 
     37 // If the system keeps claiming it can send more events, we don't let it
     38 // continue forever.  Instead, we'll cut it off at this limit.  And then
     39 // we'll call its bluff, and make sure that all of these events get
     40 // delivered.  While it won't be an actual exhaustion test (we never took the
     41 // system down to no more events available), it will still give us confidence
     42 // that this CHRE can properly handle any semi-reasonable event load properly.
     43 // 1030 is an arbitrary number, slightly over 2^10.  The hope is this
     44 // balances between catching incorrect behavior and the test taking too long.
     45 constexpr int32_t kMaxEventsToSend = INT32_C(1030);
     46 
     47 namespace general_test {
     48 
     49 bool SendEventStressTest::sInMethod = false;
     50 bool SendEventStressTest::sInitTime = false;
     51 
     52 int32_t SendEventStressTest::sEventsLeft = 0;
     53 int32_t SendEventStressTest::sCompleteCallbacksLeft = 0;
     54 
     55 SendEventStressTest::SendEventStressTest()
     56     : Test(CHRE_API_VERSION_1_0) {
     57 }
     58 
     59 void SendEventStressTest::setUp(uint32_t messageSize,
     60                                 const void * /* message */) {
     61   sInMethod = true;
     62 
     63   if (messageSize != 0) {
     64     sendFatalFailureToHost(
     65         "SendEventStress message expects 0 additional bytes, got ",
     66         &messageSize);
     67   }
     68 
     69   mInstanceId = chreGetInstanceId();
     70 
     71   // When our chreSendEvent() call fails, the CHRE is allowed to
     72   // directly invoke our completeCallback.  We special case this
     73   // with sInitTime, so we can ignore sInMethod for that case only.
     74   sCompleteCallbacksLeft = 1;
     75   sInitTime = true;
     76 
     77   // We anticipate most CHREs will not reach kMaxEventsToSend.
     78   while ((sEventsLeft < kMaxEventsToSend) &&
     79          chreSendEvent(kEventType, kEventData, completeCallback,
     80                        mInstanceId)) {
     81     sEventsLeft++;
     82   }
     83   sInitTime = false;
     84 
     85   // We want at least 2 events for this to pretend to be an exhaustion test.
     86   if (sEventsLeft < 2) {
     87     sendFatalFailureToHost("Insufficient events available");
     88   }
     89 
     90   // sCompleteCallbacksLeft may be 0 or 1 at this point.  We don't care.
     91   // We just know we also expect all the sEventsLeft to have callbacks.
     92   sCompleteCallbacksLeft += sEventsLeft;
     93 
     94   sInMethod = false;
     95 }
     96 
     97 void SendEventStressTest::handleEvent(uint32_t senderInstanceId,
     98                                       uint16_t eventType,
     99                                       const void* eventData) {
    100   if (sInMethod) {
    101     sendFatalFailureToHost("handleEvent invoked while another nanoapp "
    102                            "method is running");
    103   }
    104   sInMethod = true;
    105   if (senderInstanceId != mInstanceId) {
    106     sendFatalFailureToHost("handleEvent got event from unexpected sender:",
    107                            &senderInstanceId);
    108   }
    109   sanityCheck(eventType, eventData, 0);
    110 
    111   --sEventsLeft;
    112   if (sEventsLeft < 0) {
    113     sendFatalFailureToHost("Too many events delivered");
    114   }
    115 
    116   sInMethod = false;
    117 }
    118 
    119 void SendEventStressTest::sanityCheck(uint16_t eventType, const void *data,
    120                                       uint32_t num) {
    121   if (eventType != kEventType) {
    122     unexpectedEvent(eventType);
    123   }
    124   if (data != kEventData) {
    125     // 0: handleEvent, 1: completeCallback
    126     sendFatalFailureToHost("bad event data:", &num);
    127   }
    128 }
    129 
    130 
    131 void SendEventStressTest::completeCallback(uint16_t eventType, void *data) {
    132   if (sInitTime) {
    133     // The CHRE must be directly calling this from within
    134     // chreSendEvent(), after it failed.  We only allow a
    135     // single one of these calls.
    136     sInitTime = false;
    137     sanityCheck(eventType, data, 1);
    138     sCompleteCallbacksLeft--;
    139     return;
    140   }
    141 
    142   if (sInMethod) {
    143     sendFatalFailureToHost("completeCallback invoked while another nanoapp "
    144                            "method is running");
    145   }
    146   sanityCheck(eventType, data, 1);
    147 
    148   --sCompleteCallbacksLeft;
    149   if (sCompleteCallbacksLeft == 0) {
    150     if (sEventsLeft != 0) {
    151       sendFatalFailureToHost("completeCallbacks delivered before events");
    152     }
    153     sendSuccessToHost();
    154   } else if (sCompleteCallbacksLeft < 0) {
    155     // It's too late for the Host to catch this failure, but perhaps
    156     // the abort will screw up our unload, and trigger a failure that way.
    157     sendFatalFailureToHost("completeCallback called too many times");
    158   }
    159 }
    160 
    161 
    162 }  // namespace general_test
    163