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 <gtest/gtest.h>
18
19 #include <algorithm>
20 #include <thread>
21
22 #include "perfmgr/RequestGroup.h"
23
24 namespace android {
25 namespace perfmgr {
26
27 using namespace std::chrono_literals;
28
29 constexpr double kTIMING_TOLERANCE_MS = std::chrono::milliseconds(25).count();
30
31 // Test GetRequestValue()
TEST(RequestGroupTest,GetRequestValueTest)32 TEST(RequestGroupTest, GetRequestValueTest) {
33 std::string test_str = "TESTREQ_1";
34 RequestGroup req(test_str);
35 EXPECT_EQ(test_str, req.GetRequestValue());
36 }
37
38 // Test AddRequest()
TEST(RequestGroupTest,AddRequestTest)39 TEST(RequestGroupTest, AddRequestTest) {
40 RequestGroup req("");
41 auto start = std::chrono::steady_clock::now();
42 auto duration = 500ms;
43 bool ret = req.AddRequest("INTERACTION", start + duration);
44 EXPECT_EQ(true, ret);
45 auto sleep_time = 200ms;
46 std::this_thread::sleep_for(sleep_time);
47 std::chrono::milliseconds expire_time;
48 bool active = req.GetExpireTime(&expire_time);
49 EXPECT_NEAR((duration - sleep_time).count(), expire_time.count(),
50 kTIMING_TOLERANCE_MS);
51 EXPECT_EQ(true, active);
52 }
53
54 // Test AddRequest() with a huge expire time which could be done in some long
55 // persist power hint such as VR_MODE
TEST(RequestGroupTest,AddRequestNoExpireTest)56 TEST(RequestGroupTest, AddRequestNoExpireTest) {
57 RequestGroup req("");
58 bool ret = req.AddRequest("INTERACTION", ReqTime::max());
59 EXPECT_EQ(true, ret);
60 std::chrono::milliseconds expire_time;
61 bool active = req.GetExpireTime(&expire_time);
62 auto expect = std::chrono::duration_cast<std::chrono::milliseconds>(
63 ReqTime::max() - std::chrono::steady_clock::now());
64 EXPECT_NEAR(expect.count(), expire_time.count(), kTIMING_TOLERANCE_MS);
65 // expire time is greater than 1 year
66 EXPECT_LE(365 * 24 * 60 * 60 * 1000, expire_time.count());
67 EXPECT_EQ(true, active);
68 }
69
70 // Test AddRequest() and expires
TEST(RequestGroupTest,AddRequestTestExpire)71 TEST(RequestGroupTest, AddRequestTestExpire) {
72 RequestGroup req("");
73 auto start = std::chrono::steady_clock::now();
74 auto duration = 5ms;
75 bool ret = req.AddRequest("INTERACTION", start + duration);
76 EXPECT_EQ(true, ret);
77 ret = req.AddRequest("INTERACTION", start + duration + 1ms);
78 EXPECT_EQ(false, ret);
79 std::this_thread::sleep_for(duration + 10ms);
80 std::chrono::milliseconds expire_time;
81 bool active = req.GetExpireTime(&expire_time);
82 EXPECT_EQ(std::chrono::milliseconds::max(), expire_time);
83 EXPECT_EQ(false, active);
84 }
85
86 // Test AddRequest() with new value
TEST(RequestGroupTest,AddRequestNewValue)87 TEST(RequestGroupTest, AddRequestNewValue) {
88 RequestGroup req("");
89 auto start = std::chrono::steady_clock::now();
90 auto duration = 5000ms;
91 bool ret = req.AddRequest("INTERACTION", start + duration);
92 EXPECT_EQ(true, ret);
93 std::chrono::milliseconds expire_time;
94 bool active = req.GetExpireTime(&expire_time);
95 EXPECT_NEAR(duration.count(), expire_time.count(), kTIMING_TOLERANCE_MS);
96 EXPECT_EQ(true, active);
97 // Add a request shorter than the current outstanding one, expiration time
98 // not changed
99 auto shorter_duration = 100ms;
100 ret = req.AddRequest("INTERACTION", start + shorter_duration);
101 EXPECT_EQ(false, ret);
102 active = req.GetExpireTime(&expire_time);
103 EXPECT_NEAR(duration.count(), expire_time.count(), kTIMING_TOLERANCE_MS);
104 EXPECT_EQ(true, active);
105 // Add a request longer than the current outstanding one, expiration time
106 // changed
107 duration = 10000ms;
108 ret = req.AddRequest("INTERACTION", start + duration);
109 EXPECT_EQ(false, ret);
110 active = req.GetExpireTime(&expire_time);
111 EXPECT_NEAR(duration.count(), expire_time.count(), kTIMING_TOLERANCE_MS);
112 EXPECT_EQ(true, active);
113 }
114
115 // Test multiple AddRequest() with different hint_type
TEST(RequestGroupTest,AddRequestTestMultiple)116 TEST(RequestGroupTest, AddRequestTestMultiple) {
117 RequestGroup req("");
118 auto start = std::chrono::steady_clock::now();
119 auto duration_interact = 500ms;
120 req.AddRequest("INTERACTION", start + duration_interact);
121 auto duration_launch = 5000ms;
122 req.AddRequest("LAUNCH", start + duration_launch);
123 std::chrono::milliseconds expire_time;
124 bool active = req.GetExpireTime(&expire_time);
125 EXPECT_NEAR(std::min(duration_interact, duration_launch).count(),
126 expire_time.count(), kTIMING_TOLERANCE_MS);
127 EXPECT_EQ(true, active);
128 }
129
130 // Test RemoveRequest()
TEST(RequestGroupTest,RemoveRequestTest)131 TEST(RequestGroupTest, RemoveRequestTest) {
132 RequestGroup req("");
133 auto start = std::chrono::steady_clock::now();
134 auto duration_interact = 500ms;
135 req.AddRequest("INTERACTION", start + duration_interact);
136 bool ret = req.RemoveRequest("INTERACTION");
137 EXPECT_EQ(true, ret);
138 std::chrono::milliseconds expire_time;
139 bool active = req.GetExpireTime(&expire_time);
140 EXPECT_EQ(std::chrono::milliseconds::max(), expire_time);
141 EXPECT_EQ(false, active);
142 // Test removing an already-removed request
143 ret = req.RemoveRequest("INTERACTION");
144 EXPECT_EQ(false, ret);
145 }
146
147 // Test multiple RemoveRequest() with different hint_type
TEST(RequestGroupTest,RemoveRequestTestMultiple)148 TEST(RequestGroupTest, RemoveRequestTestMultiple) {
149 RequestGroup req("");
150 auto start = std::chrono::steady_clock::now();
151 auto duration_interact = 500ms;
152 req.AddRequest("INTERACTION", start + duration_interact);
153 auto duration_launch = 50000ms;
154 req.AddRequest("LAUNCH", start + duration_launch);
155 req.RemoveRequest("INTERACTION");
156 std::chrono::milliseconds expire_time;
157 bool active = req.GetExpireTime(&expire_time);
158 EXPECT_NEAR(duration_launch.count(), expire_time.count(),
159 kTIMING_TOLERANCE_MS);
160 EXPECT_EQ(true, active);
161 }
162
163 } // namespace perfmgr
164 } // namespace android
165