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