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