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