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/util/time.h"
25 #include "chre_api/chre/version.h"
26 #include "inc/test_util.h"
27 #include "test_util.h"
28
29 namespace chre {
30
31 /**
32 * This base class initializes and runs the event loop.
33 *
34 * This test framework makes use of the TestEventQueue as a primary method
35 * of a test execution barrier (see its documentation for details). To simplify
36 * the test execution flow, it is encouraged that any communication between
37 * threads (e.g. a nanoapp and the main test thread) through this
38 * TestEventQueue. In this way, we can design simulation tests in a way that
39 * validates an expected sequence of events in a well-defined manner.
40 *
41 * To avoid the test from potentially stalling, we also push a timeout event
42 * to the TestEventQueue once a fixed timeout has elapsed since the start of
43 * this test.
44 */
SetUp()45 void TestBase::SetUp() {
46 TestEventQueueSingleton::init();
47 chre::PlatformLogSingleton::init();
48 chre::init();
49 EventLoopManagerSingleton::get()->lateInit();
50
51 mChreThread = std::thread(
52 []() { EventLoopManagerSingleton::get()->getEventLoop().run(); });
53
54 auto callback = [](void *) {
55 LOGE("Test timed out ...");
56 TestEventQueueSingleton::get()->pushEvent(
57 CHRE_EVENT_SIMULATION_TEST_TIMEOUT);
58 };
59
60 ASSERT_TRUE(mSystemTimer.init());
61 ASSERT_TRUE(mSystemTimer.set(callback, nullptr /*data*/,
62 Nanoseconds(getTimeoutNs())));
63 }
64
TearDown()65 void TestBase::TearDown() {
66 mSystemTimer.cancel();
67 // Free memory allocated for event on the test queue.
68 TestEventQueueSingleton::get()->flush();
69 EventLoopManagerSingleton::get()->getEventLoop().stop();
70 mChreThread.join();
71
72 chre::deinit();
73 chre::PlatformLogSingleton::deinit();
74 TestEventQueueSingleton::deinit();
75 deleteNanoappInfos();
76 }
77
TEST_F(TestBase,CanLoadAndStartSingleNanoapp)78 TEST_F(TestBase, CanLoadAndStartSingleNanoapp) {
79 constexpr uint64_t kAppId = 0x0123456789abcdef;
80 constexpr uint32_t kAppVersion = 0;
81 constexpr uint32_t kAppPerms = 0;
82
83 UniquePtr<Nanoapp> nanoapp = createStaticNanoapp(
84 "Test nanoapp", kAppId, kAppVersion, kAppPerms, defaultNanoappStart,
85 defaultNanoappHandleEvent, defaultNanoappEnd);
86
87 EventLoopManagerSingleton::get()->deferCallback(
88 SystemCallbackType::FinishLoadingNanoapp, std::move(nanoapp),
89 testFinishLoadingNanoappCallback);
90 waitForEvent(CHRE_EVENT_SIMULATION_TEST_NANOAPP_LOADED);
91 }
92
TEST_F(TestBase,CanLoadAndStartMultipleNanoapps)93 TEST_F(TestBase, CanLoadAndStartMultipleNanoapps) {
94 constexpr uint64_t kAppId1 = 0x123;
95 constexpr uint64_t kAppId2 = 0x456;
96 constexpr uint32_t kAppVersion = 0;
97 constexpr uint32_t kAppPerms = 0;
98 loadNanoapp("Test nanoapp", kAppId1, kAppVersion, kAppPerms,
99 defaultNanoappStart, defaultNanoappHandleEvent,
100 defaultNanoappEnd);
101
102 loadNanoapp("Test nanoapp", kAppId2, kAppVersion, kAppPerms,
103 defaultNanoappStart, defaultNanoappHandleEvent,
104 defaultNanoappEnd);
105
106 uint16_t id1;
107 EXPECT_TRUE(EventLoopManagerSingleton::get()
108 ->getEventLoop()
109 .findNanoappInstanceIdByAppId(kAppId1, &id1));
110 uint16_t id2;
111 EXPECT_TRUE(EventLoopManagerSingleton::get()
112 ->getEventLoop()
113 .findNanoappInstanceIdByAppId(kAppId2, &id2));
114
115 EXPECT_NE(id1, id2);
116 }
117
118 // Explicitly instantiate the TestEventQueueSingleton to reduce codesize.
119 template class Singleton<TestEventQueue>;
120
121 } // namespace chre
122