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