1 /* 2 * Copyright (C) 2017 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 specic language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <algorithm> 18 #include <thread> 19 20 #include <android-base/file.h> 21 #include <android-base/test_utils.h> 22 23 #include <gtest/gtest.h> 24 25 #include "perfmgr/NodeLooperThread.h" 26 27 namespace android { 28 namespace perfmgr { 29 30 using namespace std::chrono_literals; 31 32 constexpr auto kSLEEP_TOLERANCE_MS = 50ms; 33 34 class NodeLooperThreadTest : public ::testing::Test { 35 protected: 36 virtual void SetUp() { 37 std::unique_ptr<TemporaryFile> tf = std::make_unique<TemporaryFile>(); 38 nodes_.emplace_back( 39 new Node("n0", tf->path, 40 {{"n0_value0"}, {"n0_value1"}, {"n0_value2"}}, 2, false)); 41 files_.emplace_back(std::move(tf)); 42 tf = std::make_unique<TemporaryFile>(); 43 nodes_.emplace_back( 44 new Node("n1", tf->path, 45 {{"n1_value0"}, {"n1_value1"}, {"n1_value2"}}, 2, true)); 46 files_.emplace_back(std::move(tf)); 47 } 48 49 virtual void TearDown() { 50 nodes_.clear(); 51 files_.clear(); 52 } 53 std::vector<std::unique_ptr<Node>> nodes_; 54 std::vector<std::unique_ptr<TemporaryFile>> files_; 55 }; 56 57 static inline void _VerifyPathValue(const std::string& path, 58 const std::string& value) { 59 std::string s; 60 EXPECT_TRUE(android::base::ReadFileToString(path, &s)) << strerror(errno); 61 EXPECT_EQ(value, s); 62 } 63 64 // Test default value init 65 TEST_F(NodeLooperThreadTest, InitRunTest) { 66 sp<NodeLooperThread> th = new NodeLooperThread(std::move(nodes_)); 67 std::this_thread::sleep_for(kSLEEP_TOLERANCE_MS); 68 EXPECT_TRUE(th->isRunning()); 69 _VerifyPathValue(files_[0]->path, ""); 70 _VerifyPathValue(files_[1]->path, "n1_value2"); 71 th->Stop(); 72 EXPECT_FALSE(th->isRunning()); 73 } 74 75 // Test add request 76 TEST_F(NodeLooperThreadTest, AddRequest) { 77 sp<NodeLooperThread> th = new NodeLooperThread(std::move(nodes_)); 78 EXPECT_TRUE(th->isRunning()); 79 // Dummy LAUNCH boost actions: 80 // Node0, value0, 200ms 81 // Node1, value1, 400ms 82 std::vector<NodeAction> actions{{0, 0, 200ms}, {1, 1, 400ms}}; 83 EXPECT_TRUE(th->Request(actions, "LAUNCH")); 84 std::this_thread::sleep_for(kSLEEP_TOLERANCE_MS); 85 _VerifyPathValue(files_[0]->path, "n0_value0"); 86 _VerifyPathValue(files_[1]->path, "n1_value1"); 87 std::this_thread::sleep_for(200ms); 88 _VerifyPathValue(files_[0]->path, "n0_value2"); 89 _VerifyPathValue(files_[1]->path, "n1_value1"); 90 std::this_thread::sleep_for(200ms); 91 _VerifyPathValue(files_[0]->path, "n0_value2"); 92 _VerifyPathValue(files_[1]->path, "n1_value2"); 93 th->Stop(); 94 EXPECT_FALSE(th->isRunning()); 95 } 96 97 // Test request to override expire time 98 TEST_F(NodeLooperThreadTest, AddRequestOverride) { 99 sp<NodeLooperThread> th = new NodeLooperThread(std::move(nodes_)); 100 EXPECT_TRUE(th->isRunning()); 101 // Dummy LAUNCH boost actions: 102 // Node0, value0, 200ms 103 // Node1, value1, 500ms 104 std::vector<NodeAction> actions{{0, 0, 200ms}, {1, 1, 500ms}}; 105 EXPECT_TRUE(th->Request(actions, "LAUNCH")); 106 std::this_thread::sleep_for(kSLEEP_TOLERANCE_MS); 107 _VerifyPathValue(files_[0]->path, "n0_value0"); 108 _VerifyPathValue(files_[1]->path, "n1_value1"); 109 // Dummy LAUNCH boost actions: 110 // Node0, value0, 300ms will extend 111 // Node1, value1, 100ms will not extend 112 actions = std::vector<NodeAction>{{0, 0, 300ms}, {1, 1, 100ms}}; 113 EXPECT_TRUE(th->Request(actions, "LAUNCH")); 114 std::this_thread::sleep_for(200ms); 115 _VerifyPathValue(files_[0]->path, "n0_value0"); 116 _VerifyPathValue(files_[1]->path, "n1_value1"); 117 std::this_thread::sleep_for(150ms); 118 // Node0 value0 expired 119 _VerifyPathValue(files_[0]->path, "n0_value2"); 120 _VerifyPathValue(files_[1]->path, "n1_value1"); 121 std::this_thread::sleep_for(150ms); 122 _VerifyPathValue(files_[0]->path, "n0_value2"); 123 _VerifyPathValue(files_[1]->path, "n1_value2"); 124 th->Stop(); 125 EXPECT_FALSE(th->isRunning()); 126 } 127 128 // Test cancel request 129 TEST_F(NodeLooperThreadTest, CancelRequest) { 130 sp<NodeLooperThread> th = new NodeLooperThread(std::move(nodes_)); 131 EXPECT_TRUE(th->isRunning()); 132 // Dummy LAUNCH boost actions: 133 // Node0, value0, forever 134 // Node1, value1, forever 135 std::vector<NodeAction> actions{{0, 0, 0ms}, {1, 1, 0ms}}; 136 EXPECT_TRUE(th->Request(actions, "LAUNCH")); 137 std::this_thread::sleep_for(kSLEEP_TOLERANCE_MS); 138 _VerifyPathValue(files_[0]->path, "n0_value0"); 139 _VerifyPathValue(files_[1]->path, "n1_value1"); 140 EXPECT_TRUE(th->Cancel(actions, "LAUNCH")); 141 std::this_thread::sleep_for(kSLEEP_TOLERANCE_MS); 142 _VerifyPathValue(files_[0]->path, "n0_value2"); 143 _VerifyPathValue(files_[1]->path, "n1_value2"); 144 th->Stop(); 145 EXPECT_FALSE(th->isRunning()); 146 } 147 148 // Test multiple request 149 TEST_F(NodeLooperThreadTest, MultipleRequest) { 150 sp<NodeLooperThread> th = new NodeLooperThread(std::move(nodes_)); 151 EXPECT_TRUE(th->isRunning()); 152 // Dummy LAUNCH boost actions: 153 // Node0, value1, 800ms 154 // Node1, value1, forever 155 std::vector<NodeAction> actions_interaction{{0, 1, 800ms}, {1, 1, 0ms}}; 156 EXPECT_TRUE(th->Request(actions_interaction, "INTERACTION")); 157 std::this_thread::sleep_for(kSLEEP_TOLERANCE_MS); 158 _VerifyPathValue(files_[0]->path, "n0_value1"); 159 _VerifyPathValue(files_[1]->path, "n1_value1"); 160 // Dummy LAUNCH boost actions: 161 // Node0, value0, forever 162 // Node1, value0, 400ms 163 std::vector<NodeAction> actions_launch{{0, 0, 0ms}, {1, 0, 400ms}}; 164 EXPECT_TRUE(th->Request(actions_launch, "LAUNCH")); 165 std::this_thread::sleep_for(kSLEEP_TOLERANCE_MS); 166 _VerifyPathValue(files_[0]->path, "n0_value0"); 167 _VerifyPathValue(files_[1]->path, "n1_value0"); 168 std::this_thread::sleep_for(400ms); 169 // "LAUNCH" node1 expired 170 _VerifyPathValue(files_[0]->path, "n0_value0"); 171 _VerifyPathValue(files_[1]->path, "n1_value1"); 172 EXPECT_TRUE(th->Cancel(actions_launch, "LAUNCH")); 173 std::this_thread::sleep_for(kSLEEP_TOLERANCE_MS); 174 // "LAUNCH" canceled 175 _VerifyPathValue(files_[0]->path, "n0_value1"); 176 _VerifyPathValue(files_[1]->path, "n1_value1"); 177 std::this_thread::sleep_for(400ms); 178 // "INTERACTION" node0 expired 179 _VerifyPathValue(files_[0]->path, "n0_value2"); 180 _VerifyPathValue(files_[1]->path, "n1_value1"); 181 EXPECT_TRUE(th->Cancel(actions_interaction, "INTERACTION")); 182 std::this_thread::sleep_for(kSLEEP_TOLERANCE_MS); 183 // "INTERACTION" canceled 184 _VerifyPathValue(files_[0]->path, "n0_value2"); 185 _VerifyPathValue(files_[1]->path, "n1_value2"); 186 th->Stop(); 187 EXPECT_FALSE(th->isRunning()); 188 } 189 190 } // namespace perfmgr 191 } // namespace android 192