• 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   protected:
38     static constexpr const char *FILE_NAMES[]{
39         "device/autocal",
40         "device/ol_lra_period",
41         "activate",
42         "duration",
43         "state",
44         "device/rtp_input",
45         "device/mode",
46         "device/set_sequencer",
47         "device/scale",
48         "device/ctrl_loop",
49         "device/lp_trigger_effect",
50         "device/lra_wave_shape",
51         "device/od_clamp",
52     };
53 
54     static constexpr const char *REQUIRED[]{
55         "activate",
56         "duration",
57         "state",
58     };
59 
60   public:
SetUp()61     void SetUp() override {
62         std::string prefix;
63         for (auto n : FILE_NAMES) {
64             auto name = std::filesystem::path(n);
65             auto path = std::filesystem::path(mFilesDir.path) / name;
66             fs_mkdirs(path.c_str(), S_IRWXU);
67             std::ofstream touch{path};
68             mFileMap[name] = path;
69         }
70         prefix = std::filesystem::path(mFilesDir.path) / "";
71         setenv("HWAPI_PATH_PREFIX", prefix.c_str(), true);
72         mHwApi = HwApi::Create();
73 
74         for (auto n : REQUIRED) {
75             auto name = std::filesystem::path(n);
76             auto path = std::filesystem::path(mEmptyDir.path) / name;
77             fs_mkdirs(path.c_str(), S_IRWXU);
78             std::ofstream touch{path};
79         }
80         prefix = std::filesystem::path(mEmptyDir.path) / "";
81         setenv("HWAPI_PATH_PREFIX", prefix.c_str(), true);
82         mNoApi = HwApi::Create();
83     }
84 
TearDown()85     void TearDown() override { verifyContents(); }
86 
87   protected:
88     // Set expected file content for a test.
89     template <typename T>
expectContent(const std::string & name,const T & value)90     void expectContent(const std::string &name, const T &value) {
91         mExpectedContent[name] << value << std::endl;
92     }
93 
94     // Set actual file content for an input test.
95     template <typename T>
updateContent(const std::string & name,const T & value)96     void updateContent(const std::string &name, const T &value) {
97         std::ofstream(mFileMap[name]) << value << std::endl;
98     }
99 
100     template <typename T>
expectAndUpdateContent(const std::string & name,const T & value)101     void expectAndUpdateContent(const std::string &name, const T &value) {
102         expectContent(name, value);
103         updateContent(name, value);
104     }
105 
106     // Compare all file contents against expected contents.
verifyContents()107     void verifyContents() {
108         for (auto &a : mFileMap) {
109             std::ifstream file{a.second};
110             std::string expect = mExpectedContent[a.first].str();
111             std::string actual = std::string(std::istreambuf_iterator<char>(file),
112                                              std::istreambuf_iterator<char>());
113             EXPECT_EQ(expect, actual) << a.first;
114         }
115     }
116 
117     // TODO(eliptus): Determine how to induce errors in required files
isRequired(const std::string & name)118     static bool isRequired(const std::string &name) {
119         for (auto n : REQUIRED) {
120             if (std::string(n) == name) {
121                 return true;
122             }
123         }
124         return false;
125     }
126 
ParamNameFixup(std::string str)127     static auto ParamNameFixup(std::string str) {
128         std::replace(str.begin(), str.end(), '/', '_');
129         return str;
130     }
131 
132   protected:
133     std::unique_ptr<Vibrator::HwApi> mHwApi;
134     std::unique_ptr<Vibrator::HwApi> mNoApi;
135     std::map<std::string, std::string> mFileMap;
136     TemporaryDir mFilesDir;
137     TemporaryDir mEmptyDir;
138     std::map<std::string, std::stringstream> mExpectedContent;
139 };
140 
141 class CreateTest : public HwApiTest, public WithParamInterface<const char *> {
142   public:
SetUp()143     void SetUp() override{};
TearDown()144     void TearDown() override{};
145 
PrintParam(const TestParamInfo<CreateTest::ParamType> & info)146     static auto PrintParam(const TestParamInfo<CreateTest::ParamType> &info) {
147         return ParamNameFixup(info.param);
148     }
AllParams()149     static auto &AllParams() { return FILE_NAMES; }
150 };
151 
TEST_P(CreateTest,file_missing)152 TEST_P(CreateTest, file_missing) {
153     auto skip = std::string(GetParam());
154     TemporaryDir dir;
155     std::unique_ptr<HwApi> hwapi;
156     std::string prefix;
157 
158     for (auto n : FILE_NAMES) {
159         auto name = std::string(n);
160         auto path = std::string(dir.path) + "/" + name;
161         if (name == skip) {
162             continue;
163         }
164         fs_mkdirs(path.c_str(), S_IRWXU);
165         std::ofstream touch{path};
166     }
167 
168     prefix = std::filesystem::path(dir.path) / "";
169     setenv("HWAPI_PATH_PREFIX", prefix.c_str(), true);
170     hwapi = HwApi::Create();
171     if (isRequired(skip)) {
172         EXPECT_EQ(nullptr, hwapi);
173     } else {
174         EXPECT_NE(nullptr, hwapi);
175     }
176 }
177 
178 INSTANTIATE_TEST_CASE_P(HwApiTests, CreateTest, ValuesIn(CreateTest::AllParams()),
179                         CreateTest::PrintParam);
180 
181 template <typename T>
182 class HwApiTypedTest : public HwApiTest,
183                        public WithParamInterface<std::tuple<std::string, std::function<T>>> {
184   public:
PrintParam(const TestParamInfo<typename HwApiTypedTest::ParamType> & info)185     static auto PrintParam(const TestParamInfo<typename HwApiTypedTest::ParamType> &info) {
186         return ParamNameFixup(std::get<0>(info.param));
187     }
MakeParam(std::string name,std::function<T> func)188     static auto MakeParam(std::string name, std::function<T> func) {
189         return std::make_tuple(name, func);
190     }
191 };
192 
193 using HasTest = HwApiTypedTest<bool(Vibrator::HwApi &)>;
194 
TEST_P(HasTest,success_returnsTrue)195 TEST_P(HasTest, success_returnsTrue) {
196     auto param = GetParam();
197     auto func = std::get<1>(param);
198 
199     EXPECT_TRUE(func(*mHwApi));
200 }
201 
TEST_P(HasTest,success_returnsFalse)202 TEST_P(HasTest, success_returnsFalse) {
203     auto param = GetParam();
204     auto func = std::get<1>(param);
205 
206     EXPECT_FALSE(func(*mNoApi));
207 }
208 
209 INSTANTIATE_TEST_CASE_P(HwApiTests, HasTest,
210                         ValuesIn({
211                             HasTest::MakeParam("device/rtp_input", &Vibrator::HwApi::hasRtpInput),
212                         }),
213                         HasTest::PrintParam);
214 
215 using SetBoolTest = HwApiTypedTest<bool(Vibrator::HwApi &, bool)>;
216 
TEST_P(SetBoolTest,success_returnsTrue)217 TEST_P(SetBoolTest, success_returnsTrue) {
218     auto param = GetParam();
219     auto name = std::get<0>(param);
220     auto func = std::get<1>(param);
221 
222     expectContent(name, "1");
223 
224     EXPECT_TRUE(func(*mHwApi, true));
225 }
226 
TEST_P(SetBoolTest,success_returnsFalse)227 TEST_P(SetBoolTest, success_returnsFalse) {
228     auto param = GetParam();
229     auto name = std::get<0>(param);
230     auto func = std::get<1>(param);
231 
232     expectContent(name, "0");
233 
234     EXPECT_TRUE(func(*mHwApi, false));
235 }
236 
TEST_P(SetBoolTest,failure)237 TEST_P(SetBoolTest, failure) {
238     auto param = GetParam();
239     auto name = std::get<0>(param);
240     auto func = std::get<1>(param);
241 
242     if (isRequired(name)) {
243         GTEST_SKIP();
244     }
245 
246     EXPECT_FALSE(func(*mNoApi, true));
247     EXPECT_FALSE(func(*mNoApi, false));
248 }
249 
250 INSTANTIATE_TEST_CASE_P(HwApiTests, SetBoolTest,
251                         ValuesIn({
252                             SetBoolTest::MakeParam("activate", &Vibrator::HwApi::setActivate),
253                             SetBoolTest::MakeParam("state", &Vibrator::HwApi::setState),
254                             SetBoolTest::MakeParam("device/ctrl_loop",
255                                                    &Vibrator::HwApi::setCtrlLoop),
256                         }),
257                         SetBoolTest::PrintParam);
258 
259 using SetInt8Test = HwApiTypedTest<bool(Vibrator::HwApi &, int8_t)>;
260 
TEST_P(SetInt8Test,success)261 TEST_P(SetInt8Test, success) {
262     auto param = GetParam();
263     auto name = std::get<0>(param);
264     auto func = std::get<1>(param);
265     int8_t value = std::rand();
266 
267     expectContent(name, +value);
268 
269     EXPECT_TRUE(func(*mHwApi, value));
270 }
271 
TEST_P(SetInt8Test,failure)272 TEST_P(SetInt8Test, failure) {
273     auto param = GetParam();
274     auto name = std::get<0>(param);
275     auto func = std::get<1>(param);
276     int8_t value = std::rand();
277 
278     if (isRequired(name)) {
279         GTEST_SKIP();
280     }
281 
282     EXPECT_FALSE(func(*mNoApi, value));
283 }
284 
285 INSTANTIATE_TEST_CASE_P(HwApiTests, SetInt8Test,
286                         ValuesIn({
287                             SetInt8Test::MakeParam("device/rtp_input",
288                                                    &Vibrator::HwApi::setRtpInput),
289                         }),
290                         SetInt8Test::PrintParam);
291 
292 using SetUint8Test = HwApiTypedTest<bool(Vibrator::HwApi &, uint8_t)>;
293 
TEST_P(SetUint8Test,success)294 TEST_P(SetUint8Test, success) {
295     auto param = GetParam();
296     auto name = std::get<0>(param);
297     auto func = std::get<1>(param);
298     uint8_t value = std::rand();
299 
300     expectContent(name, +value);
301 
302     EXPECT_TRUE(func(*mHwApi, value));
303 }
304 
TEST_P(SetUint8Test,failure)305 TEST_P(SetUint8Test, failure) {
306     auto param = GetParam();
307     auto name = std::get<0>(param);
308     auto func = std::get<1>(param);
309     uint8_t value = std::rand();
310 
311     if (isRequired(name)) {
312         GTEST_SKIP();
313     }
314 
315     EXPECT_FALSE(func(*mNoApi, value));
316 }
317 
318 INSTANTIATE_TEST_CASE_P(HwApiTests, SetUint8Test,
319                         ValuesIn({
320                             SetUint8Test::MakeParam("device/scale", &Vibrator::HwApi::setScale),
321                         }),
322                         SetUint8Test::PrintParam);
323 
324 using SetUint32Test = HwApiTypedTest<bool(Vibrator::HwApi &, uint32_t)>;
325 
TEST_P(SetUint32Test,success)326 TEST_P(SetUint32Test, success) {
327     auto param = GetParam();
328     auto name = std::get<0>(param);
329     auto func = std::get<1>(param);
330     uint32_t value = std::rand();
331 
332     expectContent(name, value);
333 
334     EXPECT_TRUE(func(*mHwApi, value));
335 }
336 
TEST_P(SetUint32Test,failure)337 TEST_P(SetUint32Test, failure) {
338     auto param = GetParam();
339     auto name = std::get<0>(param);
340     auto func = std::get<1>(param);
341     uint32_t value = std::rand();
342 
343     if (isRequired(name)) {
344         GTEST_SKIP();
345     }
346 
347     EXPECT_FALSE(func(*mNoApi, value));
348 }
349 
350 INSTANTIATE_TEST_CASE_P(
351     HwApiTests, SetUint32Test,
352     ValuesIn({
353         SetUint32Test::MakeParam("device/ol_lra_period", &Vibrator::HwApi::setOlLraPeriod),
354         SetUint32Test::MakeParam("duration", &Vibrator::HwApi::setDuration),
355         SetUint32Test::MakeParam("device/lp_trigger_effect", &Vibrator::HwApi::setLpTriggerEffect),
356         SetUint32Test::MakeParam("device/lra_wave_shape", &Vibrator::HwApi::setLraWaveShape),
357         SetUint32Test::MakeParam("device/od_clamp", &Vibrator::HwApi::setOdClamp),
358     }),
359     SetUint32Test::PrintParam);
360 
361 using SetStringTest = HwApiTypedTest<bool(Vibrator::HwApi &, std::string)>;
362 
TEST_P(SetStringTest,success)363 TEST_P(SetStringTest, success) {
364     auto param = GetParam();
365     auto name = std::get<0>(param);
366     auto func = std::get<1>(param);
367     std::string value = TemporaryFile().path;
368 
369     expectContent(name, value);
370 
371     EXPECT_TRUE(func(*mHwApi, value));
372 }
373 
TEST_P(SetStringTest,failure)374 TEST_P(SetStringTest, failure) {
375     auto param = GetParam();
376     auto name = std::get<0>(param);
377     auto func = std::get<1>(param);
378     std::string value = TemporaryFile().path;
379 
380     if (isRequired(name)) {
381         GTEST_SKIP();
382     }
383 
384     EXPECT_FALSE(func(*mNoApi, value));
385 }
386 
387 INSTANTIATE_TEST_CASE_P(
388     HwApiTests, SetStringTest,
389     ValuesIn({
390         SetStringTest::MakeParam("device/autocal", &Vibrator::HwApi::setAutocal),
391         SetStringTest::MakeParam("device/mode", &Vibrator::HwApi::setMode),
392         SetStringTest::MakeParam("device/set_sequencer", &Vibrator::HwApi::setSequencer),
393     }),
394     SetStringTest::PrintParam);
395 
396 }  // namespace vibrator
397 }  // namespace hardware
398 }  // namespace android
399 }  // namespace aidl
400