1 /*
2 * Copyright (C) 2019 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 specific language governing permissions and
14 * limitations under the License.
15 */
16 #define LOG_TAG "PtsVibratorHalFloralTestSuite"
17
18 #include <android-base/file.h>
19 #include <gtest/gtest.h>
20
21 #include <cstdlib>
22 #include <fstream>
23
24 #include "Hardware.h"
25
26 using namespace ::testing;
27
28 namespace android {
29 namespace hardware {
30 namespace vibrator {
31 namespace V1_3 {
32 namespace implementation {
33
34 class HwApiTest : public Test {
35 private:
36 static constexpr const char *FILE_NAMES[]{
37 "F0_FILEPATH", "REDC_FILEPATH", "Q_FILEPATH", "ACTIVATE_PATH",
38 "DURATION_PATH", "STATE_PATH", "EFFECT_DURATION_PATH", "EFFECT_INDEX_PATH",
39 "EFFECT_QUEUE_PATH", "EFFECT_SCALE_PATH", "GLOBAL_SCALE_PATH", "ASP_ENABLE_PATH",
40 "GPIO_FALL_INDEX", "GPIO_FALL_SCALE", "GPIO_RISE_INDEX", "GPIO_RISE_SCALE",
41 };
42
43 public:
SetUp()44 void SetUp() override {
45 for (auto n : FILE_NAMES) {
46 auto name = std::filesystem::path(n);
47 auto path = std::filesystem::path(mFilesDir.path) / name;
48 std::ofstream touch{path};
49 setenv(name.c_str(), path.c_str(), true);
50 mFileMap[name] = path;
51 }
52 mHwApi = std::make_unique<HwApi>();
53
54 for (auto n : FILE_NAMES) {
55 auto name = std::filesystem::path(n);
56 auto path = std::filesystem::path(mEmptyDir.path) / name;
57 setenv(name.c_str(), path.c_str(), true);
58 }
59 mNoApi = std::make_unique<HwApi>();
60 }
61
TearDown()62 void TearDown() override { verifyContents(); }
63
64 protected:
65 // Set expected file content for a test.
66 template <typename T>
expectContent(const std::string & name,const T & value)67 void expectContent(const std::string &name, const T &value) {
68 mExpectedContent[name] << value << std::endl;
69 }
70
71 // Set actual file content for an input test.
72 template <typename T>
updateContent(const std::string & name,const T & value)73 void updateContent(const std::string &name, const T &value) {
74 std::ofstream(mFileMap[name]) << value << std::endl;
75 }
76
77 template <typename T>
expectAndUpdateContent(const std::string & name,const T & value)78 void expectAndUpdateContent(const std::string &name, const T &value) {
79 expectContent(name, value);
80 updateContent(name, value);
81 }
82
83 // Compare all file contents against expected contents.
verifyContents()84 void verifyContents() {
85 for (auto &a : mFileMap) {
86 std::ifstream file{a.second};
87 std::string expect = mExpectedContent[a.first].str();
88 std::string actual = std::string(std::istreambuf_iterator<char>(file),
89 std::istreambuf_iterator<char>());
90 EXPECT_EQ(expect, actual) << a.first;
91 }
92 }
93
94 protected:
95 std::unique_ptr<Vibrator::HwApi> mHwApi;
96 std::unique_ptr<Vibrator::HwApi> mNoApi;
97 std::map<std::string, std::string> mFileMap;
98 TemporaryDir mFilesDir;
99 TemporaryDir mEmptyDir;
100 std::map<std::string, std::stringstream> mExpectedContent;
101 };
102
103 template <typename T>
104 class HwApiTypedTest
105 : public HwApiTest,
106 public testing::WithParamInterface<std::tuple<std::string, std::function<T>>> {
107 public:
PrintParam(const testing::TestParamInfo<typename HwApiTypedTest::ParamType> & info)108 static auto PrintParam(const testing::TestParamInfo<typename HwApiTypedTest::ParamType> &info) {
109 return std::get<0>(info.param);
110 };
MakeParam(std::string name,std::function<T> func)111 static auto MakeParam(std::string name, std::function<T> func) {
112 return std::make_tuple(name, func);
113 }
114 };
115
116 using HasTest = HwApiTypedTest<bool(Vibrator::HwApi &)>;
117
TEST_P(HasTest,success_returnsTrue)118 TEST_P(HasTest, success_returnsTrue) {
119 auto param = GetParam();
120 auto func = std::get<1>(param);
121
122 EXPECT_TRUE(func(*mHwApi));
123 }
124
TEST_P(HasTest,success_returnsFalse)125 TEST_P(HasTest, success_returnsFalse) {
126 auto param = GetParam();
127 auto func = std::get<1>(param);
128
129 EXPECT_FALSE(func(*mNoApi));
130 }
131
132 INSTANTIATE_TEST_CASE_P(HwApiTests, HasTest,
133 ValuesIn({
134 HasTest::MakeParam("EFFECT_SCALE_PATH",
135 &Vibrator::HwApi::hasEffectScale),
136 HasTest::MakeParam("ASP_ENABLE_PATH", &Vibrator::HwApi::hasAspEnable),
137 }),
138 HasTest::PrintParam);
139
140 using GetBoolTest = HwApiTypedTest<bool(Vibrator::HwApi &, bool *)>;
141
TEST_P(GetBoolTest,success_returnsTrue)142 TEST_P(GetBoolTest, success_returnsTrue) {
143 auto param = GetParam();
144 auto name = std::get<0>(param);
145 auto func = std::get<1>(param);
146 bool expect = true;
147 bool actual = !expect;
148
149 expectAndUpdateContent(name, "1");
150
151 EXPECT_TRUE(func(*mHwApi, &actual));
152 EXPECT_EQ(expect, actual);
153 }
154
TEST_P(GetBoolTest,success_returnsFalse)155 TEST_P(GetBoolTest, success_returnsFalse) {
156 auto param = GetParam();
157 auto name = std::get<0>(param);
158 auto func = std::get<1>(param);
159 bool expect = false;
160 bool actual = !expect;
161
162 expectAndUpdateContent(name, "0");
163
164 EXPECT_TRUE(func(*mHwApi, &actual));
165 EXPECT_EQ(expect, actual);
166 }
167
TEST_P(GetBoolTest,failure)168 TEST_P(GetBoolTest, failure) {
169 auto param = GetParam();
170 auto func = std::get<1>(param);
171 bool value;
172
173 EXPECT_FALSE(func(*mNoApi, &value));
174 }
175
176 INSTANTIATE_TEST_CASE_P(HwApiTests, GetBoolTest,
177 ValuesIn({
178 GetBoolTest::MakeParam("ASP_ENABLE_PATH",
179 &Vibrator::HwApi::getAspEnable),
180 }),
181 GetBoolTest::PrintParam);
182
183 using GetUint32Test = HwApiTypedTest<bool(Vibrator::HwApi &, uint32_t *)>;
184
TEST_P(GetUint32Test,success)185 TEST_P(GetUint32Test, success) {
186 auto param = GetParam();
187 auto name = std::get<0>(param);
188 auto func = std::get<1>(param);
189 uint32_t expect = std::rand();
190 uint32_t actual = ~expect;
191
192 expectAndUpdateContent(name, expect);
193
194 EXPECT_TRUE(func(*mHwApi, &actual));
195 EXPECT_EQ(expect, actual);
196 }
197
TEST_P(GetUint32Test,failure)198 TEST_P(GetUint32Test, failure) {
199 auto param = GetParam();
200 auto func = std::get<1>(param);
201 uint32_t value;
202
203 EXPECT_FALSE(func(*mNoApi, &value));
204 }
205
206 INSTANTIATE_TEST_CASE_P(HwApiTests, GetUint32Test,
207 ValuesIn({
208 GetUint32Test::MakeParam("EFFECT_DURATION_PATH",
209 &Vibrator::HwApi::getEffectDuration),
210 }),
211 GetUint32Test::PrintParam);
212
213 using SetBoolTest = HwApiTypedTest<bool(Vibrator::HwApi &, bool)>;
214
TEST_P(SetBoolTest,success_returnsTrue)215 TEST_P(SetBoolTest, success_returnsTrue) {
216 auto param = GetParam();
217 auto name = std::get<0>(param);
218 auto func = std::get<1>(param);
219
220 expectContent(name, "1");
221
222 EXPECT_TRUE(func(*mHwApi, true));
223 }
224
TEST_P(SetBoolTest,success_returnsFalse)225 TEST_P(SetBoolTest, success_returnsFalse) {
226 auto param = GetParam();
227 auto name = std::get<0>(param);
228 auto func = std::get<1>(param);
229
230 expectContent(name, "0");
231
232 EXPECT_TRUE(func(*mHwApi, false));
233 }
234
TEST_P(SetBoolTest,failure)235 TEST_P(SetBoolTest, failure) {
236 auto param = GetParam();
237 auto func = std::get<1>(param);
238
239 EXPECT_FALSE(func(*mNoApi, true));
240 EXPECT_FALSE(func(*mNoApi, false));
241 }
242
243 INSTANTIATE_TEST_CASE_P(HwApiTests, SetBoolTest,
244 ValuesIn({
245 SetBoolTest::MakeParam("ACTIVATE_PATH", &Vibrator::HwApi::setActivate),
246 SetBoolTest::MakeParam("STATE_PATH", &Vibrator::HwApi::setState),
247 SetBoolTest::MakeParam("ASP_ENABLE_PATH",
248 &Vibrator::HwApi::setAspEnable),
249 }),
250 SetBoolTest::PrintParam);
251
252 using SetUint32Test = HwApiTypedTest<bool(Vibrator::HwApi &, uint32_t)>;
253
TEST_P(SetUint32Test,success)254 TEST_P(SetUint32Test, success) {
255 auto param = GetParam();
256 auto name = std::get<0>(param);
257 auto func = std::get<1>(param);
258 uint32_t value = std::rand();
259
260 expectContent(name, value);
261
262 EXPECT_TRUE(func(*mHwApi, value));
263 }
264
TEST_P(SetUint32Test,failure)265 TEST_P(SetUint32Test, failure) {
266 auto param = GetParam();
267 auto func = std::get<1>(param);
268 uint32_t value = std::rand();
269
270 EXPECT_FALSE(func(*mNoApi, value));
271 }
272
273 INSTANTIATE_TEST_CASE_P(
274 HwApiTests, SetUint32Test,
275 ValuesIn({
276 SetUint32Test::MakeParam("F0_FILEPATH", &Vibrator::HwApi::setF0),
277 SetUint32Test::MakeParam("REDC_FILEPATH", &Vibrator::HwApi::setRedc),
278 SetUint32Test::MakeParam("Q_FILEPATH", &Vibrator::HwApi::setQ),
279 SetUint32Test::MakeParam("DURATION_PATH", &Vibrator::HwApi::setDuration),
280 SetUint32Test::MakeParam("EFFECT_INDEX_PATH", &Vibrator::HwApi::setEffectIndex),
281 SetUint32Test::MakeParam("EFFECT_SCALE_PATH", &Vibrator::HwApi::setEffectScale),
282 SetUint32Test::MakeParam("GLOBAL_SCALE_PATH", &Vibrator::HwApi::setGlobalScale),
283 SetUint32Test::MakeParam("GPIO_FALL_INDEX", &Vibrator::HwApi::setGpioFallIndex),
284 SetUint32Test::MakeParam("GPIO_FALL_SCALE", &Vibrator::HwApi::setGpioFallScale),
285 SetUint32Test::MakeParam("GPIO_RISE_INDEX", &Vibrator::HwApi::setGpioRiseIndex),
286 SetUint32Test::MakeParam("GPIO_RISE_SCALE", &Vibrator::HwApi::setGpioRiseScale),
287 }),
288 SetUint32Test::PrintParam);
289
290 using SetStringTest = HwApiTypedTest<bool(Vibrator::HwApi &, std::string)>;
291
TEST_P(SetStringTest,success)292 TEST_P(SetStringTest, success) {
293 auto param = GetParam();
294 auto name = std::get<0>(param);
295 auto func = std::get<1>(param);
296 std::string value = TemporaryFile().path;
297
298 expectContent(name, value);
299
300 EXPECT_TRUE(func(*mHwApi, value));
301 }
302
TEST_P(SetStringTest,failure)303 TEST_P(SetStringTest, failure) {
304 auto param = GetParam();
305 auto func = std::get<1>(param);
306 std::string value = TemporaryFile().path;
307
308 EXPECT_FALSE(func(*mNoApi, value));
309 }
310
311 INSTANTIATE_TEST_CASE_P(HwApiTests, SetStringTest,
312 ValuesIn({
313 SetStringTest::MakeParam("EFFECT_QUEUE_PATH",
314 &Vibrator::HwApi::setEffectQueue),
315 }),
316 SetStringTest::PrintParam);
317
318 } // namespace implementation
319 } // namespace V1_3
320 } // namespace vibrator
321 } // namespace hardware
322 } // namespace android
323