• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/timer_stress_test.h>
18 
19 #include <cinttypes>
20 #include <cstddef>
21 
22 #include <shared/send_message.h>
23 
24 #include <chre.h>
25 
26 using nanoapp_testing::sendFatalFailureToHost;
27 using nanoapp_testing::sendInternalFailureToHost;
28 using nanoapp_testing::sendSuccessToHost;
29 
30 /*
31  * We stress the system by setting more and more timers until the system
32  * runs out.  We then cancel one (CT) and set a new timer post-cancel (NT).
33  * We make sure all the timers we set fire.
34  *
35  * Our stages are:
36  * Stage 0: Successfully cancel CT.
37  * Stage 1: All of our "exhaustion" timers fire.
38  * Stage 2: The new timer, NT, fires.
39  *
40  * After all of our stages have succeeded, we send success to the host.  Note
41  * there is no system requirement that Stage 2 happens after Stage 1, so
42  * we use markSuccess() to track this.
43  */
44 
45 // Allow 1000ms to create the large number of timers specified below. This
46 // equates to approximately 1ms per timer which should give ample time for
47 // timer creation to complete.
48 constexpr uint64_t kDuration = UINT64_C(1000000000);
49 
50 // If the system keeps claiming it can set more timers, we don't let it
51 // continue forever.  Instead, we'll cut it off at this limit.  And then
52 // we'll call its bluff, and make sure that all of these timers legitimately
53 // fire.  While it won't be an actual exhaustion test (we never took the
54 // system down to no more timers available), it will still give us confidence
55 // that this CHRE can properly handle any semi-reasonable timer load properly.
56 // 1030 is an arbitrary number, slightly over 2^10.  The hope is this
57 // balances between catching incorrect behavior and the test taking too long.
58 constexpr int32_t kMaxTimersToSet = INT32_C(1030);
59 
60 namespace general_test {
61 
62 namespace {
63 
64 const uint32_t kCookies[] = {0, 1, 2};
65 
66 }  // anonymous namespace
67 
startStages()68 void TimerStressTest::startStages() {
69   uint32_t cancelId = chreTimerSet(kDuration, &kCookies[0], true);
70   if (cancelId == CHRE_TIMER_INVALID) {
71     sendFatalFailureToHost("No timers available");
72   }
73 
74   mStage1CallbacksLeft = 0;
75   // We anticipate most CHREs will not reach kMaxTimersToSet.
76   while (mStage1CallbacksLeft < kMaxTimersToSet) {
77     if (chreTimerSet(kDuration, &kCookies[1], true) == CHRE_TIMER_INVALID) {
78       break;
79     }
80     mStage1CallbacksLeft++;
81   }
82   if (mStage1CallbacksLeft == 0) {
83     sendFatalFailureToHost("Insufficient timers available");
84   }
85   if (!chreTimerCancel(cancelId)) {
86     sendFatalFailureToHost("Unable to cancel timer");
87   }
88   markSuccess(0);
89   if (chreTimerSet(kDuration, &kCookies[2], true) == CHRE_TIMER_INVALID) {
90     sendFatalFailureToHost("Unable to set new timer after successful cancel.");
91   }
92 }
93 
TimerStressTest()94 TimerStressTest::TimerStressTest()
95     : Test(CHRE_API_VERSION_1_0),
96       mInMethod(false),
97       mFinishedBitmask(0),
98       mStage1CallbacksLeft(0) {}
99 
setUp(uint32_t messageSize,const void *)100 void TimerStressTest::setUp(uint32_t messageSize, const void * /* message */) {
101   mInMethod = true;
102 
103   if (messageSize != 0) {
104     sendFatalFailureToHost(
105         "TimerStress message expects 0 additional bytes, got ", &messageSize);
106   }
107 
108   startStages();
109 
110   mInMethod = false;
111 }
112 
handleStageEvent(uint32_t index)113 void TimerStressTest::handleStageEvent(uint32_t index) {
114   switch (index) {
115     case 0:
116       sendFatalFailureToHost("Canceled timer fired:", &index);
117       break;
118 
119     case 1:
120       --mStage1CallbacksLeft;
121       if (mStage1CallbacksLeft <= 0) {
122         markSuccess(index);
123       }
124       break;
125 
126     case 2:
127       markSuccess(index);
128       break;
129 
130     default:
131       sendFatalFailureToHost("Unexpected event stage:", &index);
132   }
133 }
134 
handleEvent(uint32_t senderInstanceId,uint16_t eventType,const void * eventData)135 void TimerStressTest::handleEvent(uint32_t senderInstanceId, uint16_t eventType,
136                                   const void *eventData) {
137   if (mInMethod) {
138     sendFatalFailureToHost(
139         "handleEvent invoked while another nanoapp method is running");
140   }
141   mInMethod = true;
142   if (senderInstanceId != CHRE_INSTANCE_ID) {
143     sendFatalFailureToHost("handleEvent got event from unexpected sender:",
144                            &senderInstanceId);
145   }
146   if (eventType != CHRE_EVENT_TIMER) {
147     unexpectedEvent(eventType);
148   }
149 
150   const uint32_t *data = static_cast<const uint32_t *>(eventData);
151   handleStageEvent(*data);
152 
153   mInMethod = false;
154 }
155 
markSuccess(uint32_t stage)156 void TimerStressTest::markSuccess(uint32_t stage) {
157   chreLog(CHRE_LOG_DEBUG, "Stage %" PRIu32 " succeeded", stage);
158   uint32_t finishedBit = (1 << stage);
159   if ((kAllFinished & finishedBit) == 0) {
160     sendFatalFailureToHost("markSuccess bad stage:", &stage);
161   }
162   if ((mFinishedBitmask & finishedBit) != 0) {
163     sendFatalFailureToHost("timer over-triggered:", &stage);
164   }
165   mFinishedBitmask |= finishedBit;
166   if (mFinishedBitmask == kAllFinished) {
167     sendSuccessToHost();
168   }
169 }
170 
171 }  // namespace general_test
172