• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 "test_base.h"
18 
19 #include <gtest/gtest.h>
20 #include <pw_containers/vector.h>
21 
22 #include "chre/core/event_loop_manager.h"
23 #include "chre/core/init.h"
24 #include "chre/platform/linux/platform_log.h"
25 #include "chre/platform/linux/task_util/task_manager.h"
26 #include "chre/util/system/message_router.h"
27 #include "chre/util/time.h"
28 #include "chre_api/chre/version.h"
29 #include "inc/test_util.h"
30 #include "test_util.h"
31 
32 using ::chre::message::MessageRouter;
33 using ::chre::message::MessageRouterSingleton;
34 using ::chre::message::Session;
35 
36 namespace chre {
37 
38 namespace {
39 
40 constexpr size_t kMaxMessageHubs = 5;
41 constexpr size_t kMaxSessions = 25;
42 pw::Vector<MessageRouter::MessageHubRecord, kMaxMessageHubs> gMessageHubs;
43 pw::Vector<Session, kMaxSessions> gSessions;
44 
45 }  // anonymous namespace
46 
47 /**
48  * This base class initializes and runs the event loop.
49  *
50  * This test framework makes use of the TestEventQueue as a primary method
51  * of a test execution barrier (see its documentation for details). To simplify
52  * the test execution flow, it is encouraged that any communication between
53  * threads (e.g. a nanoapp and the main test thread) through this
54  * TestEventQueue. In this way, we can design simulation tests in a way that
55  * validates an expected sequence of events in a well-defined manner.
56  *
57  * To avoid the test from potentially stalling, we also push a timeout event
58  * to the TestEventQueue once a fixed timeout has elapsed since the start of
59  * this test.
60  */
SetUp()61 void TestBase::SetUp() {
62   setWaitTimeout(getTimeoutNs() / 2);
63 
64   MessageRouterSingleton::init(gMessageHubs, gSessions);
65   chre::PlatformLogSingleton::init();
66   TaskManagerSingleton::init();
67   TestEventQueueSingleton::init();
68   chre::init();
69   EventLoopManagerSingleton::get()->lateInit();
70 
71   mChreThread = std::thread(
72       []() { EventLoopManagerSingleton::get()->getEventLoop().run(); });
73 
74   auto callback = [](void *) {
75     LOGE("Test timed out ...");
76     TestEventQueueSingleton::get()->pushEvent(
77         CHRE_EVENT_SIMULATION_TEST_TIMEOUT);
78   };
79 
80   ASSERT_TRUE(mSystemTimer.init());
81   ASSERT_TRUE(mSystemTimer.set(callback, nullptr /*data*/,
82                                Nanoseconds(getTimeoutNs())));
83 }
84 
TearDown()85 void TestBase::TearDown() {
86   mSystemTimer.cancel();
87   // Free memory allocated for event on the test queue.
88   TestEventQueueSingleton::get()->flush();
89   EventLoopManagerSingleton::get()->getEventLoop().stop();
90   mChreThread.join();
91 
92   chre::deinit();
93   TestEventQueueSingleton::deinit();
94   TaskManagerSingleton::deinit();
95   deleteNanoappInfos();
96   unregisterAllTestNanoapps();
97   chre::PlatformLogSingleton::deinit();
98   MessageRouterSingleton::deinit();
99 }
100 
TEST_F(TestBase,CanLoadAndStartSingleNanoapp)101 TEST_F(TestBase, CanLoadAndStartSingleNanoapp) {
102   constexpr uint64_t kAppId = 0x0123456789abcdef;
103   constexpr uint32_t kAppVersion = 0;
104   constexpr uint32_t kAppPerms = 0;
105 
106   UniquePtr<Nanoapp> nanoapp = createStaticNanoapp(
107       "Test nanoapp", kAppId, kAppVersion, kAppPerms, defaultNanoappStart,
108       defaultNanoappHandleEvent, defaultNanoappEnd);
109 
110   EventLoopManagerSingleton::get()->deferCallback(
111       SystemCallbackType::FinishLoadingNanoapp, std::move(nanoapp),
112       testFinishLoadingNanoappCallback);
113   waitForEvent(CHRE_EVENT_SIMULATION_TEST_NANOAPP_LOADED);
114 }
115 
TEST_F(TestBase,CanLoadAndStartMultipleNanoapps)116 TEST_F(TestBase, CanLoadAndStartMultipleNanoapps) {
117   constexpr uint64_t kAppId1 = 0x123;
118   constexpr uint64_t kAppId2 = 0x456;
119   constexpr uint32_t kAppVersion = 0;
120   constexpr uint32_t kAppPerms = 0;
121   loadNanoapp("Test nanoapp", kAppId1, kAppVersion, kAppPerms,
122               defaultNanoappStart, defaultNanoappHandleEvent,
123               defaultNanoappEnd);
124 
125   loadNanoapp("Test nanoapp", kAppId2, kAppVersion, kAppPerms,
126               defaultNanoappStart, defaultNanoappHandleEvent,
127               defaultNanoappEnd);
128 
129   uint16_t id1;
130   EXPECT_TRUE(EventLoopManagerSingleton::get()
131                   ->getEventLoop()
132                   .findNanoappInstanceIdByAppId(kAppId1, &id1));
133   uint16_t id2;
134   EXPECT_TRUE(EventLoopManagerSingleton::get()
135                   ->getEventLoop()
136                   .findNanoappInstanceIdByAppId(kAppId2, &id2));
137 
138   EXPECT_NE(id1, id2);
139 }
140 
TEST_F(TestBase,methods)141 TEST_F(TestBase, methods) {
142   CREATE_CHRE_TEST_EVENT(SOME_EVENT, 0);
143 
144   class App : public TestNanoapp {
145    public:
146     explicit App(TestNanoappInfo info) : TestNanoapp(info) {}
147     bool start() override {
148       LOGE("start");
149       mTest = 0xc0ffee;
150       return true;
151     }
152 
153     void handleEvent(uint32_t /*senderInstanceId*/, uint16_t /*eventType*/,
154                      const void * /**eventData*/) override {
155       LOGE("handleEvent %" PRIx16, mTest);
156     }
157 
158     void end() override {
159       LOGE("end");
160     }
161 
162    protected:
163     uint32_t mTest = 0;
164   };
165 
166   uint64_t appId = loadNanoapp(MakeUnique<App>(TestNanoappInfo{.id = 0x456}));
167 
168   sendEventToNanoapp(appId, SOME_EVENT);
169 }
170 
171 // Explicitly instantiate the TestEventQueueSingleton to reduce codesize.
172 template class Singleton<TestEventQueue>;
173 
174 }  // namespace chre
175