• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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             "calibration/f0_stored",
40             "default/f0_offset",
41             "calibration/redc_stored",
42             "calibration/q_stored",
43             "default/f0_comp_enable",
44             "default/redc_comp_enable",
45             "default/owt_free_space",
46             "default/num_waves",
47             "default/delay_before_stop_playback_us",
48     };
49 
50   public:
SetUp()51     void SetUp() override {
52         std::string prefix;
53         for (auto n : FILE_NAMES) {
54             auto name = std::filesystem::path(n);
55             auto path = std::filesystem::path(mFilesDir.path) / name;
56             fs_mkdirs(path.c_str(), S_IRWXU);
57             std::ofstream touch{path};
58             mFileMap[name] = path;
59         }
60         prefix = std::filesystem::path(mFilesDir.path) / "";
61         setenv("HWAPI_PATH_PREFIX", prefix.c_str(), true);
62         mHwApi = std::make_unique<HwApi>();
63 
64         for (auto n : FILE_NAMES) {
65             auto name = std::filesystem::path(n);
66             auto path = std::filesystem::path(mEmptyDir.path) / name;
67         }
68         prefix = std::filesystem::path(mEmptyDir.path) / "";
69         setenv("HWAPI_PATH_PREFIX", prefix.c_str(), true);
70         mNoApi = std::make_unique<HwApi>();
71     }
72 
TearDown()73     void TearDown() override { verifyContents(); }
74 
ParamNameFixup(std::string str)75     static auto ParamNameFixup(std::string str) {
76         std::replace(str.begin(), str.end(), '/', '_');
77         return str;
78     }
79 
80   protected:
81     // Set expected file content for a test.
82     template <typename T>
expectContent(const std::string & name,const T & value)83     void expectContent(const std::string &name, const T &value) {
84         mExpectedContent[name] << value << std::endl;
85     }
86 
87     // Set actual file content for an input test.
88     template <typename T>
updateContent(const std::string & name,const T & value)89     void updateContent(const std::string &name, const T &value) {
90         std::ofstream(mFileMap[name]) << value << std::endl;
91     }
92 
93     template <typename T>
expectAndUpdateContent(const std::string & name,const T & value)94     void expectAndUpdateContent(const std::string &name, const T &value) {
95         expectContent(name, value);
96         updateContent(name, value);
97     }
98 
99     // Compare all file contents against expected contents.
verifyContents()100     void verifyContents() {
101         for (auto &a : mFileMap) {
102             std::ifstream file{a.second};
103             std::string expect = mExpectedContent[a.first].str();
104             std::string actual = std::string(std::istreambuf_iterator<char>(file),
105                                              std::istreambuf_iterator<char>());
106             EXPECT_EQ(expect, actual) << a.first;
107         }
108     }
109 
110   protected:
111     std::unique_ptr<Vibrator::HwApi> mHwApi;
112     std::unique_ptr<Vibrator::HwApi> mNoApi;
113     std::map<std::string, std::string> mFileMap;
114     TemporaryDir mFilesDir;
115     TemporaryDir mEmptyDir;
116     std::map<std::string, std::stringstream> mExpectedContent;
117 };
118 
119 template <typename T>
120 class HwApiTypedTest : public HwApiTest,
121                        public WithParamInterface<std::tuple<std::string, std::function<T>>> {
122   public:
PrintParam(const TestParamInfo<typename HwApiTypedTest::ParamType> & info)123     static auto PrintParam(const TestParamInfo<typename HwApiTypedTest::ParamType> &info) {
124         return ParamNameFixup(std::get<0>(info.param));
125     }
MakeParam(std::string name,std::function<T> func)126     static auto MakeParam(std::string name, std::function<T> func) {
127         return std::make_tuple(name, func);
128     }
129 };
130 
131 using HasTest = HwApiTypedTest<bool(Vibrator::HwApi &)>;
132 
TEST_P(HasTest,success_returnsTrue)133 TEST_P(HasTest, success_returnsTrue) {
134     auto param = GetParam();
135     auto func = std::get<1>(param);
136 
137     EXPECT_TRUE(func(*mHwApi));
138 }
139 
TEST_P(HasTest,success_returnsFalse)140 TEST_P(HasTest, success_returnsFalse) {
141     auto param = GetParam();
142     auto func = std::get<1>(param);
143 
144     EXPECT_FALSE(func(*mNoApi));
145 }
146 
147 INSTANTIATE_TEST_CASE_P(HwApiTests, HasTest,
148                         ValuesIn({
149                                 HasTest::MakeParam("default/owt_free_space",
150                                                    &Vibrator::HwApi::hasOwtFreeSpace),
151                         }),
152                         HasTest::PrintParam);
153 
154 using GetUint32Test = HwApiTypedTest<bool(Vibrator::HwApi &, uint32_t *)>;
155 
TEST_P(GetUint32Test,success)156 TEST_P(GetUint32Test, success) {
157     auto param = GetParam();
158     auto name = std::get<0>(param);
159     auto func = std::get<1>(param);
160     uint32_t expect = std::rand();
161     uint32_t actual = ~expect;
162 
163     expectAndUpdateContent(name, expect);
164 
165     EXPECT_TRUE(func(*mHwApi, &actual));
166     EXPECT_EQ(expect, actual);
167 }
168 
TEST_P(GetUint32Test,failure)169 TEST_P(GetUint32Test, failure) {
170     auto param = GetParam();
171     auto func = std::get<1>(param);
172     uint32_t value;
173 
174     EXPECT_FALSE(func(*mNoApi, &value));
175 }
176 
177 INSTANTIATE_TEST_CASE_P(HwApiTests, GetUint32Test,
178                         ValuesIn({
179                                 GetUint32Test::MakeParam("default/num_waves",
180                                                          &Vibrator::HwApi::getEffectCount),
181                                 GetUint32Test::MakeParam("default/owt_free_space",
182                                                          &Vibrator::HwApi::getOwtFreeSpace),
183                         }),
184                         GetUint32Test::PrintParam);
185 
186 using SetBoolTest = HwApiTypedTest<bool(Vibrator::HwApi &, bool)>;
187 
TEST_P(SetBoolTest,success_returnsTrue)188 TEST_P(SetBoolTest, success_returnsTrue) {
189     auto param = GetParam();
190     auto name = std::get<0>(param);
191     auto func = std::get<1>(param);
192 
193     expectContent(name, "1");
194 
195     EXPECT_TRUE(func(*mHwApi, true));
196 }
197 
TEST_P(SetBoolTest,success_returnsFalse)198 TEST_P(SetBoolTest, success_returnsFalse) {
199     auto param = GetParam();
200     auto name = std::get<0>(param);
201     auto func = std::get<1>(param);
202 
203     expectContent(name, "0");
204 
205     EXPECT_TRUE(func(*mHwApi, false));
206 }
207 
TEST_P(SetBoolTest,failure)208 TEST_P(SetBoolTest, failure) {
209     auto param = GetParam();
210     auto func = std::get<1>(param);
211 
212     EXPECT_FALSE(func(*mNoApi, true));
213     EXPECT_FALSE(func(*mNoApi, false));
214 }
215 
216 INSTANTIATE_TEST_CASE_P(HwApiTests, SetBoolTest,
217                         ValuesIn({
218                                 SetBoolTest::MakeParam("default/f0_comp_enable",
219                                                        &Vibrator::HwApi::setF0CompEnable),
220                                 SetBoolTest::MakeParam("default/redc_comp_enable",
221                                                        &Vibrator::HwApi::setRedcCompEnable),
222                         }),
223                         SetBoolTest::PrintParam);
224 
225 using SetUint32Test = HwApiTypedTest<bool(Vibrator::HwApi &, uint32_t)>;
226 
TEST_P(SetUint32Test,success)227 TEST_P(SetUint32Test, success) {
228     auto param = GetParam();
229     auto name = std::get<0>(param);
230     auto func = std::get<1>(param);
231     uint32_t value = std::rand();
232 
233     expectContent(name, value);
234 
235     EXPECT_TRUE(func(*mHwApi, value));
236 }
237 
TEST_P(SetUint32Test,failure)238 TEST_P(SetUint32Test, failure) {
239     auto param = GetParam();
240     auto func = std::get<1>(param);
241     uint32_t value = std::rand();
242 
243     EXPECT_FALSE(func(*mNoApi, value));
244 }
245 
246 INSTANTIATE_TEST_CASE_P(HwApiTests, SetUint32Test,
247                         ValuesIn({
248                                 SetUint32Test::MakeParam("default/f0_offset",
249                                                          &Vibrator::HwApi::setF0Offset),
250                                 SetUint32Test::MakeParam("default/delay_before_stop_playback_us",
251                                                          &Vibrator::HwApi::setMinOnOffInterval),
252                         }),
253                         SetUint32Test::PrintParam);
254 
255 using SetStringTest = HwApiTypedTest<bool(Vibrator::HwApi &, std::string)>;
256 
TEST_P(SetStringTest,success)257 TEST_P(SetStringTest, success) {
258     auto param = GetParam();
259     auto name = std::get<0>(param);
260     auto func = std::get<1>(param);
261     std::string value = TemporaryFile().path;
262 
263     expectContent(name, value);
264 
265     EXPECT_TRUE(func(*mHwApi, value));
266 }
267 
TEST_P(SetStringTest,failure)268 TEST_P(SetStringTest, failure) {
269     auto param = GetParam();
270     auto func = std::get<1>(param);
271     std::string value = TemporaryFile().path;
272 
273     EXPECT_FALSE(func(*mNoApi, value));
274 }
275 
276 INSTANTIATE_TEST_CASE_P(
277         HwApiTests, SetStringTest,
278         ValuesIn({
279                 SetStringTest::MakeParam("calibration/f0_stored", &Vibrator::HwApi::setF0),
280                 SetStringTest::MakeParam("calibration/redc_stored", &Vibrator::HwApi::setRedc),
281                 SetStringTest::MakeParam("calibration/q_stored", &Vibrator::HwApi::setQ),
282         }),
283         SetStringTest::PrintParam);
284 
285 }  // namespace vibrator
286 }  // namespace hardware
287 }  // namespace android
288 }  // namespace aidl
289