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