blob: 3df1fb54d8091345ac59cd77f5da27e765056517 [file] [log] [blame]
Wei Wangf72cfad2017-10-26 22:41:03 -07001/*
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>
Wei Wangea78eca2017-12-27 18:18:45 -080021#include <android-base/logging.h>
Wei Wanga4823192018-10-19 21:57:04 -070022#include <android-base/properties.h>
Wei Wangf72cfad2017-10-26 22:41:03 -070023
24#include <gtest/gtest.h>
25
Wei Wanga4823192018-10-19 21:57:04 -070026#include "perfmgr/FileNode.h"
Wei Wangf72cfad2017-10-26 22:41:03 -070027#include "perfmgr/HintManager.h"
Wei Wanga4823192018-10-19 21:57:04 -070028#include "perfmgr/PropertyNode.h"
Wei Wangf72cfad2017-10-26 22:41:03 -070029
30namespace android {
31namespace perfmgr {
32
33using namespace std::chrono_literals;
34
35constexpr auto kSLEEP_TOLERANCE_MS = 50ms;
36
37// JSON_CONFIG
38// {
39// "Nodes": [
40// {
41// "Name": "CPUCluster0MinFreq",
42// "Path": "/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq",
43// "Values": [
44// "1512000",
45// "1134000",
46// "384000"
47// ],
48// "DefaultIndex": 2,
49// "ResetOnInit": true
50// },
51// {
52// "Name": "CPUCluster1MinFreq",
53// "Path": "/sys/devices/system/cpu/cpu4/cpufreq/scaling_min_freq",
54// "Values": [
55// "1512000",
56// "1134000",
57// "384000"
58// ],
59// "HoldFd": true
Wei Wanga4823192018-10-19 21:57:04 -070060// },
61// {
62// "Name": "ModeProperty",
63// "Path": "vendor.pwhal.mode",
64// "Values": [
65// "HIGH",
66// "LOW",
67// "NONE"
68// ],
69// "Type": "Property"
Wei Wangf72cfad2017-10-26 22:41:03 -070070// }
71// ],
72// "Actions": [
73// {
74// "PowerHint": "INTERACTION",
75// "Node": "CPUCluster1MinFreq",
Wei Wang55b9d6d2018-04-16 20:30:36 -070076// "Value": "1134000",
Wei Wangf72cfad2017-10-26 22:41:03 -070077// "Duration": 800
78// },
79// {
Wei Wanga4823192018-10-19 21:57:04 -070080// "PowerHint": "INTERACTION",
81// "Node": "ModeProperty",
82// "Value": "LOW",
83// "Duration": 800
84// },
85// {
Wei Wangf72cfad2017-10-26 22:41:03 -070086// "PowerHint": "LAUNCH",
87// "Node": "CPUCluster0MinFreq",
Wei Wang55b9d6d2018-04-16 20:30:36 -070088// "Value": "1134000",
Wei Wangf72cfad2017-10-26 22:41:03 -070089// "Duration": 500
90// },
91// {
92// "PowerHint": "LAUNCH",
Wei Wanga4823192018-10-19 21:57:04 -070093// "Node": "ModeProperty",
94// "Value": "HIGH",
95// "Duration": 500
96// },
97// {
98// "PowerHint": "LAUNCH",
Wei Wangf72cfad2017-10-26 22:41:03 -070099// "Node": "CPUCluster1MinFreq",
Wei Wang55b9d6d2018-04-16 20:30:36 -0700100// "Value": "1512000",
Wei Wangf72cfad2017-10-26 22:41:03 -0700101// "Duration": 2000
102// }
103// ]
104// }
105constexpr char kJSON_RAW[] =
106 "{\"Nodes\":[{\"Name\":\"CPUCluster0MinFreq\",\"Path\":\"/sys/devices/"
107 "system/cpu/cpu0/cpufreq/"
108 "scaling_min_freq\",\"Values\":[\"1512000\",\"1134000\",\"384000\"],"
109 "\"DefaultIndex\":2,\"ResetOnInit\":true},{\"Name\":\"CPUCluster1MinFreq\","
110 "\"Path\":\"/sys/devices/system/cpu/cpu4/cpufreq/"
111 "scaling_min_freq\",\"Values\":[\"1512000\",\"1134000\",\"384000\"],"
Wei Wanga4823192018-10-19 21:57:04 -0700112 "\"HoldFd\":true},{\"Name\":\"ModeProperty\",\"Path\":\"vendor.pwhal."
113 "mode\",\"Values\":[\"HIGH\",\"LOW\",\"NONE\"],\"Type\":\"Property\"}],"
114 "\"Actions\":[{\"PowerHint\":\"INTERACTION\",\"Node\":"
Wei Wang55b9d6d2018-04-16 20:30:36 -0700115 "\"CPUCluster1MinFreq\",\"Value\":\"1134000\",\"Duration\":800},{"
Wei Wanga4823192018-10-19 21:57:04 -0700116 "\"PowerHint\":\"INTERACTION\",\"Node\":\"ModeProperty\",\"Value\":\"LOW\","
117 "\"Duration\":800},{\"PowerHint\":\"LAUNCH\",\"Node\":"
118 "\"CPUCluster0MinFreq\",\"Value\":\"1134000\",\"Duration\":500},{"
119 "\"PowerHint\":\"LAUNCH\",\"Node\":\"ModeProperty\",\"Value\":\"HIGH\","
120 "\"Duration\":500},{\"PowerHint\":\"LAUNCH\",\"Node\":"
121 "\"CPUCluster1MinFreq\",\"Value\":\"1512000\",\"Duration\":2000}]}";
Wei Wangf72cfad2017-10-26 22:41:03 -0700122
123class HintManagerTest : public ::testing::Test, public HintManager {
124 protected:
125 HintManagerTest()
126 : HintManager(nullptr,
Wei Wangea78eca2017-12-27 18:18:45 -0800127 std::map<std::string, std::vector<NodeAction>>{}) {
128 android::base::SetMinimumLogSeverity(android::base::VERBOSE);
Wei Wanga4823192018-10-19 21:57:04 -0700129 prop_ = "vendor.pwhal.mode";
Wei Wangea78eca2017-12-27 18:18:45 -0800130 }
Wei Wangf72cfad2017-10-26 22:41:03 -0700131
132 virtual void SetUp() {
Wei Wanga4823192018-10-19 21:57:04 -0700133 // Set up 3 dummy nodes
Wei Wangf72cfad2017-10-26 22:41:03 -0700134 std::unique_ptr<TemporaryFile> tf = std::make_unique<TemporaryFile>();
Wei Wanga4823192018-10-19 21:57:04 -0700135 nodes_.emplace_back(new FileNode(
136 "n0", tf->path, {{"n0_value0"}, {"n0_value1"}, {"n0_value2"}}, 2,
137 false));
Wei Wangf72cfad2017-10-26 22:41:03 -0700138 files_.emplace_back(std::move(tf));
139 tf = std::make_unique<TemporaryFile>();
Wei Wanga4823192018-10-19 21:57:04 -0700140 nodes_.emplace_back(new FileNode(
141 "n1", tf->path, {{"n1_value0"}, {"n1_value1"}, {"n1_value2"}}, 2,
142 true));
Wei Wangf72cfad2017-10-26 22:41:03 -0700143 files_.emplace_back(std::move(tf));
Wei Wanga4823192018-10-19 21:57:04 -0700144 nodes_.emplace_back(new PropertyNode(
145 "n2", prop_, {{"n2_value0"}, {"n2_value1"}, {"n2_value2"}}, 2,
146 true));
Wei Wangf72cfad2017-10-26 22:41:03 -0700147 nm_ = new NodeLooperThread(std::move(nodes_));
148 // Set up dummy actions
149 // "INTERACTION"
150 // Node0, value1, 800ms
151 // Node1, value1, forever
Wei Wanga4823192018-10-19 21:57:04 -0700152 // Node2, value1, 800ms
Wei Wangf72cfad2017-10-26 22:41:03 -0700153 // "LAUNCH"
154 // Node0, value0, forever
155 // Node1, value0, 400ms
Wei Wanga4823192018-10-19 21:57:04 -0700156 // Node2, value0, 400ms
Wei Wangf72cfad2017-10-26 22:41:03 -0700157 actions_ = std::map<std::string, std::vector<NodeAction>>{
Wei Wanga4823192018-10-19 21:57:04 -0700158 {"INTERACTION", {{0, 1, 800ms}, {1, 1, 0ms}, {2, 1, 800ms}}},
159 {"LAUNCH", {{0, 0, 0ms}, {1, 0, 400ms}, {2, 0, 400ms}}}};
Wei Wangf72cfad2017-10-26 22:41:03 -0700160
161 // Prepare dummy files to replace the nodes' path in example json_doc
162 files_.emplace_back(std::make_unique<TemporaryFile>());
163 files_.emplace_back(std::make_unique<TemporaryFile>());
Wei Wanga4823192018-10-19 21:57:04 -0700164 // replace file path
Wei Wangf72cfad2017-10-26 22:41:03 -0700165 json_doc_ = kJSON_RAW;
166 std::string from =
167 "/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq";
168 size_t start_pos = json_doc_.find(from);
169 json_doc_.replace(start_pos, from.length(), files_[0 + 2]->path);
170 from = "/sys/devices/system/cpu/cpu4/cpufreq/scaling_min_freq";
171 start_pos = json_doc_.find(from);
172 json_doc_.replace(start_pos, from.length(), files_[1 + 2]->path);
Wei Wanga4823192018-10-19 21:57:04 -0700173 EXPECT_TRUE(android::base::SetProperty(prop_, ""))
174 << "failed to clear property";
Wei Wangf72cfad2017-10-26 22:41:03 -0700175 }
176
177 virtual void TearDown() {
178 actions_.clear();
179 nodes_.clear();
180 files_.clear();
181 nm_ = nullptr;
182 }
183 sp<NodeLooperThread> nm_;
184 std::map<std::string, std::vector<NodeAction>> actions_;
185 std::vector<std::unique_ptr<Node>> nodes_;
186 std::vector<std::unique_ptr<TemporaryFile>> files_;
187 std::string json_doc_;
Wei Wanga4823192018-10-19 21:57:04 -0700188 std::string prop_;
Wei Wangf72cfad2017-10-26 22:41:03 -0700189};
190
Wei Wanga4823192018-10-19 21:57:04 -0700191static inline void _VerifyPropertyValue(const std::string& path,
192 const std::string& value) {
193 std::string s = android::base::GetProperty(path, "");
194 EXPECT_EQ(value, s);
195}
196
Wei Wang55b9d6d2018-04-16 20:30:36 -0700197static inline void _VerifyPathValue(const std::string& path,
198 const std::string& value) {
Wei Wangf72cfad2017-10-26 22:41:03 -0700199 std::string s;
200 EXPECT_TRUE(android::base::ReadFileToString(path, &s)) << strerror(errno);
201 EXPECT_EQ(value, s);
202}
203
Wei Wang90fc4d42018-01-25 14:45:33 -0800204// Test GetHints
205TEST_F(HintManagerTest, GetHintsTest) {
206 HintManager hm(nm_, actions_);
207 std::vector<std::string> hints = hm.GetHints();
208 EXPECT_TRUE(hm.IsRunning());
209 EXPECT_EQ(2u, hints.size());
210 EXPECT_NE(std::find(hints.begin(), hints.end(), "INTERACTION"), hints.end());
211 EXPECT_NE(std::find(hints.begin(), hints.end(), "LAUNCH"), hints.end());
212}
213
Wei Wangf72cfad2017-10-26 22:41:03 -0700214// Test initialization of default values
215TEST_F(HintManagerTest, HintInitDefaultTest) {
216 HintManager hm(nm_, actions_);
217 std::this_thread::sleep_for(kSLEEP_TOLERANCE_MS);
218 EXPECT_TRUE(hm.IsRunning());
219 _VerifyPathValue(files_[0]->path, "");
220 _VerifyPathValue(files_[1]->path, "n1_value2");
Wei Wanga4823192018-10-19 21:57:04 -0700221 _VerifyPropertyValue(prop_, "");
Wei Wangf72cfad2017-10-26 22:41:03 -0700222}
223
Wei Wanga4823192018-10-19 21:57:04 -0700224// Test hint/cancel/expire with dummy actions
Wei Wangf72cfad2017-10-26 22:41:03 -0700225TEST_F(HintManagerTest, HintTest) {
226 HintManager hm(nm_, actions_);
227 EXPECT_TRUE(hm.IsRunning());
228 EXPECT_TRUE(hm.DoHint("INTERACTION"));
229 std::this_thread::sleep_for(kSLEEP_TOLERANCE_MS);
230 _VerifyPathValue(files_[0]->path, "n0_value1");
231 _VerifyPathValue(files_[1]->path, "n1_value1");
Wei Wanga4823192018-10-19 21:57:04 -0700232 _VerifyPropertyValue(prop_, "n2_value1");
Wei Wangf72cfad2017-10-26 22:41:03 -0700233 // this won't change the expire time of INTERACTION hint
234 EXPECT_TRUE(hm.DoHint("INTERACTION", 200ms));
235 // now place new hint
236 EXPECT_TRUE(hm.DoHint("LAUNCH"));
237 std::this_thread::sleep_for(kSLEEP_TOLERANCE_MS);
238 _VerifyPathValue(files_[0]->path, "n0_value0");
239 _VerifyPathValue(files_[1]->path, "n1_value0");
Wei Wanga4823192018-10-19 21:57:04 -0700240 _VerifyPropertyValue(prop_, "n2_value0");
Wei Wangf72cfad2017-10-26 22:41:03 -0700241 EXPECT_TRUE(hm.DoHint("LAUNCH", 500ms));
Wei Wanga4823192018-10-19 21:57:04 -0700242 // "LAUNCH" node1 not expired
Wei Wangf72cfad2017-10-26 22:41:03 -0700243 std::this_thread::sleep_for(400ms);
244 _VerifyPathValue(files_[0]->path, "n0_value0");
245 _VerifyPathValue(files_[1]->path, "n1_value0");
Wei Wanga4823192018-10-19 21:57:04 -0700246 _VerifyPropertyValue(prop_, "n2_value0");
Wei Wangf72cfad2017-10-26 22:41:03 -0700247 // "LAUNCH" node1 expired
248 std::this_thread::sleep_for(100ms + kSLEEP_TOLERANCE_MS);
249 _VerifyPathValue(files_[0]->path, "n0_value0");
250 _VerifyPathValue(files_[1]->path, "n1_value1");
Wei Wanga4823192018-10-19 21:57:04 -0700251 _VerifyPropertyValue(prop_, "n2_value1");
Wei Wangf72cfad2017-10-26 22:41:03 -0700252 EXPECT_TRUE(hm.EndHint("LAUNCH"));
253 std::this_thread::sleep_for(kSLEEP_TOLERANCE_MS);
254 // "LAUNCH" canceled
255 _VerifyPathValue(files_[0]->path, "n0_value1");
256 _VerifyPathValue(files_[1]->path, "n1_value1");
Wei Wanga4823192018-10-19 21:57:04 -0700257 _VerifyPropertyValue(prop_, "n2_value1");
Wei Wangf72cfad2017-10-26 22:41:03 -0700258 std::this_thread::sleep_for(200ms);
259 // "INTERACTION" node0 expired
260 _VerifyPathValue(files_[0]->path, "n0_value2");
261 _VerifyPathValue(files_[1]->path, "n1_value1");
Wei Wanga4823192018-10-19 21:57:04 -0700262 _VerifyPropertyValue(prop_, "n2_value2");
Wei Wangf72cfad2017-10-26 22:41:03 -0700263 EXPECT_TRUE(hm.EndHint("INTERACTION"));
264 std::this_thread::sleep_for(kSLEEP_TOLERANCE_MS);
265 // "INTERACTION" canceled
266 _VerifyPathValue(files_[0]->path, "n0_value2");
267 _VerifyPathValue(files_[1]->path, "n1_value2");
Wei Wanga4823192018-10-19 21:57:04 -0700268 _VerifyPropertyValue(prop_, "n2_value2");
Wei Wangf72cfad2017-10-26 22:41:03 -0700269}
270
Wei Wanga4823192018-10-19 21:57:04 -0700271// Test parsing nodes
Wei Wangf72cfad2017-10-26 22:41:03 -0700272TEST_F(HintManagerTest, ParseNodesTest) {
273 std::vector<std::unique_ptr<Node>> nodes =
274 HintManager::ParseNodes(json_doc_);
Wei Wanga4823192018-10-19 21:57:04 -0700275 EXPECT_EQ(3u, nodes.size());
Wei Wangf72cfad2017-10-26 22:41:03 -0700276 EXPECT_EQ("CPUCluster0MinFreq", nodes[0]->GetName());
277 EXPECT_EQ("CPUCluster1MinFreq", nodes[1]->GetName());
278 EXPECT_EQ(files_[0 + 2]->path, nodes[0]->GetPath());
279 EXPECT_EQ(files_[1 + 2]->path, nodes[1]->GetPath());
280 EXPECT_EQ("1512000", nodes[0]->GetValues()[0]);
281 EXPECT_EQ("1134000", nodes[0]->GetValues()[1]);
282 EXPECT_EQ("384000", nodes[0]->GetValues()[2]);
283 EXPECT_EQ("1512000", nodes[1]->GetValues()[0]);
284 EXPECT_EQ("1134000", nodes[1]->GetValues()[1]);
285 EXPECT_EQ("384000", nodes[1]->GetValues()[2]);
286 EXPECT_EQ(2u, nodes[0]->GetDefaultIndex());
287 EXPECT_EQ(2u, nodes[1]->GetDefaultIndex());
288 EXPECT_TRUE(nodes[0]->GetResetOnInit());
289 EXPECT_FALSE(nodes[1]->GetResetOnInit());
Wei Wanga4823192018-10-19 21:57:04 -0700290 // no dynamic_cast intentionally in Android
291 EXPECT_FALSE(reinterpret_cast<FileNode*>(nodes[0].get())->GetHoldFd());
292 EXPECT_TRUE(reinterpret_cast<FileNode*>(nodes[1].get())->GetHoldFd());
293 EXPECT_EQ("ModeProperty", nodes[2]->GetName());
294 EXPECT_EQ(prop_, nodes[2]->GetPath());
295 EXPECT_EQ("HIGH", nodes[2]->GetValues()[0]);
296 EXPECT_EQ("LOW", nodes[2]->GetValues()[1]);
297 EXPECT_EQ("NONE", nodes[2]->GetValues()[2]);
298 EXPECT_EQ(2u, nodes[2]->GetDefaultIndex());
299 EXPECT_FALSE(nodes[2]->GetResetOnInit());
Wei Wangf72cfad2017-10-26 22:41:03 -0700300}
301
Wei Wanga4823192018-10-19 21:57:04 -0700302// Test parsing nodes with duplicate name
Wei Wangf72cfad2017-10-26 22:41:03 -0700303TEST_F(HintManagerTest, ParseNodesDuplicateNameTest) {
304 std::string from = "CPUCluster0MinFreq";
305 size_t start_pos = json_doc_.find(from);
306 json_doc_.replace(start_pos, from.length(), "CPUCluster1MinFreq");
307 std::vector<std::unique_ptr<Node>> nodes =
308 HintManager::ParseNodes(json_doc_);
309 EXPECT_EQ(0u, nodes.size());
310}
311
Wei Wanga4823192018-10-19 21:57:04 -0700312TEST_F(HintManagerTest, ParsePropertyNodesDuplicatNameTest) {
313 std::string from = "ModeProperty";
314 size_t start_pos = json_doc_.find(from);
315 json_doc_.replace(start_pos, from.length(), "CPUCluster1MinFreq");
316 std::vector<std::unique_ptr<Node>> nodes =
317 HintManager::ParseNodes(json_doc_);
318 EXPECT_EQ(0u, nodes.size());
319}
320
Wei Wangf72cfad2017-10-26 22:41:03 -0700321// Test parsing nodes with duplicate path
322TEST_F(HintManagerTest, ParseNodesDuplicatePathTest) {
323 std::string from = files_[0 + 2]->path;
324 size_t start_pos = json_doc_.find(from);
325 json_doc_.replace(start_pos, from.length(), files_[1 + 2]->path);
326 std::vector<std::unique_ptr<Node>> nodes =
327 HintManager::ParseNodes(json_doc_);
328 EXPECT_EQ(0u, nodes.size());
329}
330
Wei Wang0437ece2018-11-19 21:15:00 -0800331// Test parsing file node with duplicate value
332TEST_F(HintManagerTest, ParseFileNodesDuplicateValueTest) {
333 std::string from = "1512000";
334 size_t start_pos = json_doc_.find(from);
335 json_doc_.replace(start_pos, from.length(), "1134000");
336 std::vector<std::unique_ptr<Node>> nodes =
337 HintManager::ParseNodes(json_doc_);
338 EXPECT_EQ(0u, nodes.size());
339}
340
341// Test parsing property node with duplicate value
342TEST_F(HintManagerTest, ParsePropertyNodesDuplicateValueTest) {
343 std::string from = "HIGH";
344 size_t start_pos = json_doc_.find(from);
345 json_doc_.replace(start_pos, from.length(), "LOW");
346 std::vector<std::unique_ptr<Node>> nodes =
347 HintManager::ParseNodes(json_doc_);
348 EXPECT_EQ(0u, nodes.size());
349}
350
351// Test parsing file node with empty value
352TEST_F(HintManagerTest, ParseFileNodesEmptyValueTest) {
353 std::string from = "384000";
354 size_t start_pos = json_doc_.find(from);
355 json_doc_.replace(start_pos, from.length(), "");
356 std::vector<std::unique_ptr<Node>> nodes =
357 HintManager::ParseNodes(json_doc_);
358 EXPECT_EQ(0u, nodes.size());
359}
360
361// Test parsing property node with empty value
362TEST_F(HintManagerTest, ParsePropertyNodesEmptyValueTest) {
363 std::string from = "LOW";
364 size_t start_pos = json_doc_.find(from);
365 json_doc_.replace(start_pos, from.length(), "");
366 std::vector<std::unique_ptr<Node>> nodes =
367 HintManager::ParseNodes(json_doc_);
368 EXPECT_EQ(3u, nodes.size());
369 EXPECT_EQ("CPUCluster0MinFreq", nodes[0]->GetName());
370 EXPECT_EQ("CPUCluster1MinFreq", nodes[1]->GetName());
371 EXPECT_EQ(files_[0 + 2]->path, nodes[0]->GetPath());
372 EXPECT_EQ(files_[1 + 2]->path, nodes[1]->GetPath());
373 EXPECT_EQ("1512000", nodes[0]->GetValues()[0]);
374 EXPECT_EQ("1134000", nodes[0]->GetValues()[1]);
375 EXPECT_EQ("384000", nodes[0]->GetValues()[2]);
376 EXPECT_EQ("1512000", nodes[1]->GetValues()[0]);
377 EXPECT_EQ("1134000", nodes[1]->GetValues()[1]);
378 EXPECT_EQ("384000", nodes[1]->GetValues()[2]);
379 EXPECT_EQ(2u, nodes[0]->GetDefaultIndex());
380 EXPECT_EQ(2u, nodes[1]->GetDefaultIndex());
381 EXPECT_TRUE(nodes[0]->GetResetOnInit());
382 EXPECT_FALSE(nodes[1]->GetResetOnInit());
383 // no dynamic_cast intentionally in Android
384 EXPECT_FALSE(reinterpret_cast<FileNode*>(nodes[0].get())->GetHoldFd());
385 EXPECT_TRUE(reinterpret_cast<FileNode*>(nodes[1].get())->GetHoldFd());
386 EXPECT_EQ("ModeProperty", nodes[2]->GetName());
387 EXPECT_EQ(prop_, nodes[2]->GetPath());
388 EXPECT_EQ("HIGH", nodes[2]->GetValues()[0]);
389 EXPECT_EQ("", nodes[2]->GetValues()[1]);
390 EXPECT_EQ("NONE", nodes[2]->GetValues()[2]);
391 EXPECT_EQ(2u, nodes[2]->GetDefaultIndex());
392 EXPECT_FALSE(nodes[2]->GetResetOnInit());
393}
394
Wei Wangf72cfad2017-10-26 22:41:03 -0700395// Test parsing invalid json for nodes
Wei Wanga4823192018-10-19 21:57:04 -0700396TEST_F(HintManagerTest, ParseBadFileNodesTest) {
Wei Wangf72cfad2017-10-26 22:41:03 -0700397 std::vector<std::unique_ptr<Node>> nodes =
398 HintManager::ParseNodes("invalid json");
399 EXPECT_EQ(0u, nodes.size());
400 nodes = HintManager::ParseNodes(
401 "{\"devices\":{\"15\":[\"armeabi-v7a\"],\"16\":[\"armeabi-v7a\"],"
402 "\"26\":[\"armeabi-v7a\",\"arm64-v8a\",\"x86\",\"x86_64\"]}}");
403 EXPECT_EQ(0u, nodes.size());
404}
405
406// Test parsing actions
407TEST_F(HintManagerTest, ParseActionsTest) {
408 std::vector<std::unique_ptr<Node>> nodes =
409 HintManager::ParseNodes(json_doc_);
410 std::map<std::string, std::vector<NodeAction>> actions =
411 HintManager::ParseActions(json_doc_, nodes);
412 EXPECT_EQ(2u, actions.size());
Wei Wangf72cfad2017-10-26 22:41:03 -0700413
Wei Wanga4823192018-10-19 21:57:04 -0700414 EXPECT_EQ(2u, actions["INTERACTION"].size());
Wei Wangf72cfad2017-10-26 22:41:03 -0700415 EXPECT_EQ(1u, actions["INTERACTION"][0].node_index);
416 EXPECT_EQ(1u, actions["INTERACTION"][0].value_index);
417 EXPECT_EQ(std::chrono::milliseconds(800).count(),
418 actions["INTERACTION"][0].timeout_ms.count());
419
Wei Wanga4823192018-10-19 21:57:04 -0700420 EXPECT_EQ(2u, actions["INTERACTION"][1].node_index);
421 EXPECT_EQ(1u, actions["INTERACTION"][1].value_index);
422 EXPECT_EQ(std::chrono::milliseconds(800).count(),
423 actions["INTERACTION"][1].timeout_ms.count());
424
425 EXPECT_EQ(3u, actions["LAUNCH"].size());
Wei Wangf72cfad2017-10-26 22:41:03 -0700426
427 EXPECT_EQ(0u, actions["LAUNCH"][0].node_index);
428 EXPECT_EQ(1u, actions["LAUNCH"][0].value_index);
429 EXPECT_EQ(std::chrono::milliseconds(500).count(),
430 actions["LAUNCH"][0].timeout_ms.count());
431
Wei Wanga4823192018-10-19 21:57:04 -0700432 EXPECT_EQ(2u, actions["LAUNCH"][1].node_index);
Wei Wangf72cfad2017-10-26 22:41:03 -0700433 EXPECT_EQ(0u, actions["LAUNCH"][1].value_index);
Wei Wanga4823192018-10-19 21:57:04 -0700434 EXPECT_EQ(std::chrono::milliseconds(500).count(),
Wei Wangf72cfad2017-10-26 22:41:03 -0700435 actions["LAUNCH"][1].timeout_ms.count());
Wei Wanga4823192018-10-19 21:57:04 -0700436
437 EXPECT_EQ(1u, actions["LAUNCH"][2].node_index);
438 EXPECT_EQ(0u, actions["LAUNCH"][2].value_index);
439 EXPECT_EQ(std::chrono::milliseconds(2000).count(),
440 actions["LAUNCH"][2].timeout_ms.count());
Wei Wangf72cfad2017-10-26 22:41:03 -0700441}
442
Wei Wanga9786b62018-10-22 15:19:46 -0700443// Test parsing actions with duplicate File node
444TEST_F(HintManagerTest, ParseActionDuplicateFileNodeTest) {
Wei Wangabb9e8f2018-01-11 23:10:01 -0800445 std::string from = "\"Node\":\"CPUCluster0MinFreq\"";
446 size_t start_pos = json_doc_.find(from);
447 json_doc_.replace(start_pos, from.length(),
Wei Wanga4823192018-10-19 21:57:04 -0700448 "\"Node\":\"CPUCluster1MinFreq\"");
Wei Wangabb9e8f2018-01-11 23:10:01 -0800449 std::vector<std::unique_ptr<Node>> nodes =
450 HintManager::ParseNodes(json_doc_);
Wei Wanga4823192018-10-19 21:57:04 -0700451 EXPECT_EQ(3u, nodes.size());
Wei Wangabb9e8f2018-01-11 23:10:01 -0800452 std::map<std::string, std::vector<NodeAction>> actions =
453 HintManager::ParseActions(json_doc_, nodes);
454 EXPECT_EQ(0u, actions.size());
455}
456
Wei Wanga9786b62018-10-22 15:19:46 -0700457// Test parsing actions with duplicate Property node
458TEST_F(HintManagerTest, ParseActionDuplicatePropertyNodeTest) {
459 std::string from = "\"Node\":\"CPUCluster0MinFreq\"";
460 size_t start_pos = json_doc_.find(from);
461 json_doc_.replace(start_pos, from.length(), "\"Node\":\"ModeProperty\"");
462 std::vector<std::unique_ptr<Node>> nodes =
463 HintManager::ParseNodes(json_doc_);
464 EXPECT_EQ(3u, nodes.size());
465 std::map<std::string, std::vector<NodeAction>> actions =
466 HintManager::ParseActions(json_doc_, nodes);
467 EXPECT_EQ(0u, actions.size());
468}
469
Wei Wangf72cfad2017-10-26 22:41:03 -0700470// Test parsing invalid json for actions
471TEST_F(HintManagerTest, ParseBadActionsTest) {
472 std::vector<std::unique_ptr<Node>> nodes =
473 HintManager::ParseNodes(json_doc_);
474 std::map<std::string, std::vector<NodeAction>> actions =
475 HintManager::ParseActions("invalid json", nodes);
476 EXPECT_EQ(0u, actions.size());
477 actions = HintManager::ParseActions(
478 "{\"devices\":{\"15\":[\"armeabi-v7a\"],\"16\":[\"armeabi-v7a\"],"
479 "\"26\":[\"armeabi-v7a\",\"arm64-v8a\",\"x86\",\"x86_64\"]}}",
480 nodes);
481 EXPECT_EQ(0u, actions.size());
482}
483
484// Test hint/cancel/expire with json config
485TEST_F(HintManagerTest, GetFromJSONTest) {
486 TemporaryFile json_file;
487 ASSERT_TRUE(android::base::WriteStringToFile(json_doc_, json_file.path))
488 << strerror(errno);
489 std::unique_ptr<HintManager> hm = HintManager::GetFromJSON(json_file.path);
490 EXPECT_NE(nullptr, hm.get());
491 std::this_thread::sleep_for(kSLEEP_TOLERANCE_MS);
492 EXPECT_TRUE(hm->IsRunning());
493 // Initial default value on Node0
494 _VerifyPathValue(files_[0 + 2]->path, "384000");
495 _VerifyPathValue(files_[1 + 2]->path, "");
Wei Wanga4823192018-10-19 21:57:04 -0700496 _VerifyPropertyValue(prop_, "");
Wei Wangf72cfad2017-10-26 22:41:03 -0700497 // Do INTERACTION
498 EXPECT_TRUE(hm->DoHint("INTERACTION"));
499 std::this_thread::sleep_for(kSLEEP_TOLERANCE_MS);
500 _VerifyPathValue(files_[0 + 2]->path, "384000");
501 _VerifyPathValue(files_[1 + 2]->path, "1134000");
Wei Wanga4823192018-10-19 21:57:04 -0700502 _VerifyPropertyValue(prop_, "LOW");
Wei Wangf72cfad2017-10-26 22:41:03 -0700503 // Do LAUNCH
504 EXPECT_TRUE(hm->DoHint("LAUNCH"));
505 std::this_thread::sleep_for(kSLEEP_TOLERANCE_MS);
506 _VerifyPathValue(files_[0 + 2]->path, "1134000");
507 _VerifyPathValue(files_[1 + 2]->path, "1512000");
Wei Wanga4823192018-10-19 21:57:04 -0700508 _VerifyPropertyValue(prop_, "HIGH");
Wei Wangf72cfad2017-10-26 22:41:03 -0700509 std::this_thread::sleep_for(500ms);
510 // "LAUNCH" node0 expired
511 _VerifyPathValue(files_[0 + 2]->path, "384000");
512 _VerifyPathValue(files_[1 + 2]->path, "1512000");
Wei Wanga4823192018-10-19 21:57:04 -0700513 _VerifyPropertyValue(prop_, "LOW");
Wei Wangf72cfad2017-10-26 22:41:03 -0700514 EXPECT_TRUE(hm->EndHint("LAUNCH"));
515 std::this_thread::sleep_for(kSLEEP_TOLERANCE_MS);
516 // "LAUNCH" canceled
517 _VerifyPathValue(files_[0 + 2]->path, "384000");
518 _VerifyPathValue(files_[1 + 2]->path, "1134000");
Wei Wanga4823192018-10-19 21:57:04 -0700519 _VerifyPropertyValue(prop_, "LOW");
Wei Wangf72cfad2017-10-26 22:41:03 -0700520 std::this_thread::sleep_for(300ms);
521 // "INTERACTION" node1 expired
522 _VerifyPathValue(files_[0 + 2]->path, "384000");
523 _VerifyPathValue(files_[1 + 2]->path, "384000");
Wei Wanga4823192018-10-19 21:57:04 -0700524 _VerifyPropertyValue(prop_, "NONE");
Wei Wangf72cfad2017-10-26 22:41:03 -0700525}
526
527} // namespace perfmgr
528} // namespace android