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