blob: b1a384d23cb1a03cf07e1bb33d4cf7c856ce237a [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>
21#include <android-base/test_utils.h>
22
23#include <gtest/gtest.h>
24
25#include "perfmgr/Node.h"
26
27namespace android {
28namespace perfmgr {
29
30using namespace std::chrono_literals;
31
32constexpr double kTIMING_TOLERANCE_MS = std::chrono::milliseconds(25).count();
33constexpr auto kSLEEP_TOLERANCE_MS = 2ms;
34
35static inline void _VerifyPathValue(std::string path, std::string value) {
36 std::string s;
37 EXPECT_TRUE(android::base::ReadFileToString(path, &s)) << strerror(errno);
38 EXPECT_EQ(value, s);
39}
40
41// Test init with no default value
42TEST(NodeTest, NoInitDefaultTest) {
43 TemporaryFile tf;
44 Node t("t", tf.path, {{"value0"}, {"value1"}, {"value2"}}, 1, false);
45 _VerifyPathValue(tf.path, "");
46}
47
48// Test init with default value
49TEST(NodeTest, InitDefaultTest) {
50 TemporaryFile tf;
51 Node t("t", tf.path, {{"value0"}, {"value1"}, {"value2"}}, 1, true);
52 _VerifyPathValue(tf.path, "value1");
Wei Wanga8768fc2017-12-31 23:26:50 -080053 TemporaryFile tf2;
54 Node t2("t2", tf2.path, {{"value0"}, {"value1"}, {"value2"}}, 0, true);
55 _VerifyPathValue(tf2.path, "value0");
Wei Wangf72cfad2017-10-26 22:41:03 -070056}
57
58// Test GetValueIndex
59TEST(NodeTest, GetValueIndexTest) {
60 TemporaryFile tf;
61 Node t("t", tf.path, {{"value0"}, {"value1"}, {"value2"}}, 1, false);
62 std::size_t index = 0;
63 EXPECT_TRUE(t.GetValueIndex("value2", &index));
64 EXPECT_EQ(2u, index);
65 index = 1234;
66 EXPECT_FALSE(t.GetValueIndex("NON_EXIST", &index));
67 EXPECT_EQ(1234u, index);
68}
69
70// Test GetValues
71TEST(NodeTest, GetValuesTest) {
72 TemporaryFile tf;
73 Node t("t", tf.path, {{"value0"}, {"value1"}, {"value2"}}, 1, false);
74 std::vector values = t.GetValues();
75 EXPECT_EQ(3u, values.size());
76 EXPECT_EQ("value0", values[0]);
77 EXPECT_EQ("value1", values[1]);
78 EXPECT_EQ("value2", values[2]);
79}
80
81// Test get more properties
82TEST(NodeTest, GetPropertiesTest) {
83 std::string test_name = "TESTREQ_1";
84 std::string test_path = "TEST_PATH";
85 Node t(test_name, test_path, {}, 0, false, true);
86 EXPECT_EQ(test_name, t.GetName());
87 EXPECT_EQ(test_path, t.GetPath());
88 EXPECT_EQ(0u, t.GetValues().size());
89 EXPECT_EQ(0u, t.GetDefaultIndex());
90 EXPECT_FALSE(t.GetResetOnInit());
91 EXPECT_TRUE(t.GetHoldFd());
92}
93
Wei Wanga8768fc2017-12-31 23:26:50 -080094// Test add request fail and retry
95TEST(NodeTest, AddRequestTestFail) {
96 Node t("t", "/sys/android/nonexist_node_test",
97 {{"value0"}, {"value1"}, {"value2"}}, 2, true);
98 auto start = std::chrono::steady_clock::now();
99 EXPECT_TRUE(t.AddRequest(1, "INTERACTION", start + 200ms));
100 std::chrono::milliseconds expire_time = t.Update();
101 // Add request @ value1
102 EXPECT_NEAR(std::chrono::milliseconds(200).count(), expire_time.count(),
103 kTIMING_TOLERANCE_MS);
104 // Add request @ value0 higher prio than value1
105 EXPECT_TRUE(t.AddRequest(0, "LAUNCH", start + 2000ms));
106 expire_time = t.Update();
107 // Retry in 500 ms
108 EXPECT_NEAR(std::chrono::milliseconds(500).count(), expire_time.count(),
109 kTIMING_TOLERANCE_MS);
110}
111
Wei Wangf72cfad2017-10-26 22:41:03 -0700112// Test add request
113TEST(NodeTest, AddRequestTest) {
114 TemporaryFile tf;
115 Node t("t", tf.path, {{"value0"}, {"value1"}, {"value2"}}, 2, true);
116 auto start = std::chrono::steady_clock::now();
117 EXPECT_TRUE(t.AddRequest(1, "INTERACTION", start + 500ms));
118 std::chrono::milliseconds expire_time = t.Update();
119 // Add request @ value1
120 _VerifyPathValue(tf.path, "value1");
121 EXPECT_NEAR(std::chrono::milliseconds(500).count(), expire_time.count(),
122 kTIMING_TOLERANCE_MS);
123 // Add request @ value0 higher prio than value1
124 EXPECT_TRUE(t.AddRequest(0, "LAUNCH", start + 200ms));
125 expire_time = t.Update();
126 _VerifyPathValue(tf.path, "value0");
127 EXPECT_NEAR(std::chrono::milliseconds(200).count(), expire_time.count(),
128 kTIMING_TOLERANCE_MS);
129 // Let high prio request timeout, now only request @ value1 active
130 std::this_thread::sleep_for(expire_time + kSLEEP_TOLERANCE_MS);
131 expire_time = t.Update();
132 _VerifyPathValue(tf.path, "value1");
133 EXPECT_NEAR(std::chrono::milliseconds(300).count(), expire_time.count(),
134 kTIMING_TOLERANCE_MS);
135 // Let all requests timeout, now default value2
136 std::this_thread::sleep_for(expire_time + kSLEEP_TOLERANCE_MS);
137 expire_time = t.Update();
138 _VerifyPathValue(tf.path, "value2");
139 EXPECT_EQ(std::chrono::milliseconds::max(), expire_time);
140}
141
142// Test remove request
143TEST(NodeTest, RemoveRequestTest) {
144 TemporaryFile tf;
145 Node t("t", tf.path, {{"value0"}, {"value1"}, {"value2"}}, 2, true);
146 auto start = std::chrono::steady_clock::now();
147 EXPECT_TRUE(t.AddRequest(1, "INTERACTION", start + 500ms));
148 std::chrono::milliseconds expire_time = t.Update();
149 // Add request @ value1
150 _VerifyPathValue(tf.path, "value1");
151 EXPECT_NEAR(std::chrono::milliseconds(500).count(), expire_time.count(),
152 kTIMING_TOLERANCE_MS);
153 // Add request @ value0 higher prio than value1
154 EXPECT_TRUE(t.AddRequest(0, "LAUNCH", start + 200ms));
155 expire_time = t.Update();
156 _VerifyPathValue(tf.path, "value0");
157 EXPECT_NEAR(std::chrono::milliseconds(200).count(), expire_time.count(),
158 kTIMING_TOLERANCE_MS);
159 // Remove high prio request, now only request @ value1 active
160 t.RemoveRequest("LAUNCH");
161 expire_time = t.Update();
162 _VerifyPathValue(tf.path, "value1");
163 EXPECT_NEAR(std::chrono::milliseconds(500).count(), expire_time.count(),
164 kTIMING_TOLERANCE_MS);
165 // Remove request, now default value2
166 t.RemoveRequest("INTERACTION");
167 expire_time = t.Update();
168 _VerifyPathValue(tf.path, "value2");
169 EXPECT_EQ(std::chrono::milliseconds::max(), expire_time);
170}
171
172// Test add request with holding fd
173TEST(NodeTest, AddRequestTestHoldFdOverride) {
174 TemporaryFile tf;
175 Node t("t", tf.path, {{"value0"}, {"value1"}, {"value2"}}, 2, true, true);
176 EXPECT_TRUE(t.GetHoldFd());
177 auto start = std::chrono::steady_clock::now();
178 EXPECT_TRUE(t.AddRequest(1, "INTERACTION", start + 500ms));
179 std::chrono::milliseconds expire_time = t.Update();
180 // Add request @ value1
181 _VerifyPathValue(tf.path, "value1");
182 EXPECT_NEAR(std::chrono::milliseconds(500).count(), expire_time.count(),
183 kTIMING_TOLERANCE_MS);
184 // Add request @ value0 higher prio than value1
185 EXPECT_TRUE(t.AddRequest(0, "LAUNCH", start + 200ms));
186 expire_time = t.Update();
187 _VerifyPathValue(tf.path, "value0");
188 EXPECT_NEAR(std::chrono::milliseconds(200).count(), expire_time.count(),
189 kTIMING_TOLERANCE_MS);
190 // Add request @ value0 shorter
191 EXPECT_TRUE(t.AddRequest(0, "LAUNCH", start + 100ms));
192 expire_time = t.Update();
193 _VerifyPathValue(tf.path, "value0");
194 EXPECT_NEAR(std::chrono::milliseconds(200).count(), expire_time.count(),
195 kTIMING_TOLERANCE_MS);
196 // Add request @ value0 longer
197 EXPECT_TRUE(t.AddRequest(0, "LAUNCH", start + 300ms));
198 expire_time = t.Update();
199 _VerifyPathValue(tf.path, "value0");
200 EXPECT_NEAR(std::chrono::milliseconds(300).count(), expire_time.count(),
201 kTIMING_TOLERANCE_MS);
202 // Remove high prio request, now only request @ value1 active
203 t.RemoveRequest("LAUNCH");
204 expire_time = t.Update();
205 _VerifyPathValue(tf.path, "value1");
206 EXPECT_NEAR(std::chrono::milliseconds(500).count(), expire_time.count(),
207 kTIMING_TOLERANCE_MS);
208 // Remove request, now default value2
209 t.RemoveRequest("INTERACTION");
210 expire_time = t.Update();
211 _VerifyPathValue(tf.path, "value2");
212 EXPECT_EQ(std::chrono::milliseconds::max(), expire_time);
213}
214
215} // namespace perfmgr
216} // namespace android