1 /*
2  * Copyright (C) 2024 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 <gtest/gtest.h>
18 
19 #include "config/Config.h"
20 
21 #define LOG_TAG "ConfigTest"
22 #include <android-base/logging.h>
23 
24 // using namespace ::testing::Eq;
25 using namespace testing;
26 
27 #define SP_DEFAULT_astring "astringSP"
28 #define SP_DEFAULT_aint32 32
29 #define SP_DEFAULT_aint64 64
30 #define SP_DEFAULT_abool false
31 #define SP_DEFAULT_avector \
32     { 1, 2, 3 }
33 namespace aidl::android::hardware::biometrics {
34 namespace TestHalProperties {
35 OptString val_astring = SP_DEFAULT_astring;
36 OptInt32 val_aint32 = SP_DEFAULT_aint32;
37 OptInt64 val_aint64 = SP_DEFAULT_aint64;
38 OptBool val_abool = SP_DEFAULT_abool;
39 OptIntVec val_avector = SP_DEFAULT_avector;
40 
astring()41 OptString astring() {
42     return val_astring;
43 }
astring(const OptString & v)44 bool astring(const OptString& v) {
45     val_astring = v;
46     return true;
47 }
aint32()48 OptInt32 aint32() {
49     return val_aint32;
50 }
aint32(const OptInt32 & v)51 bool aint32(const OptInt32& v) {
52     val_aint32 = v;
53     return true;
54 }
aint64()55 OptInt64 aint64() {
56     return val_aint64;
57 }
aint64(const OptInt64 & v)58 bool aint64(const OptInt64& v) {
59     val_aint64 = v;
60     return true;
61 }
abool()62 OptBool abool() {
63     return val_abool;
64 }
abool(const OptBool & v)65 bool abool(const OptBool& v) {
66     val_abool = v;
67     return true;
68 }
avector()69 OptIntVec avector() {
70     return val_avector;
71 }
avector(const OptIntVec & v)72 bool avector(const OptIntVec& v) {
73     val_avector = v;
74     return true;
75 }
76 }  // namespace TestHalProperties
77 using namespace TestHalProperties;
78 #define AIDL_DEFAULT_astring "astringAIDL"
79 #define AIDL_DEFAULT_aint32 "320"
80 #define AIDL_DEFAULT_aint64 "640"
81 #define AIDL_DEFAULT_abool "true"
82 #define AIDL_DEFAULT_avector "10,20,30"
83 #define CREATE_GETTER_SETTER_WRAPPER(_NAME_, _T_)           \
84     ConfigValue _NAME_##Getter() {                          \
85         return TestHalProperties::_NAME_();                 \
86     }                                                       \
87     bool _NAME_##Setter(const ConfigValue& v) {             \
88         return TestHalProperties::_NAME_(std::get<_T_>(v)); \
89     }
90 CREATE_GETTER_SETTER_WRAPPER(astring, OptString)
91 CREATE_GETTER_SETTER_WRAPPER(aint32, OptInt32)
92 CREATE_GETTER_SETTER_WRAPPER(aint64, OptInt64)
93 CREATE_GETTER_SETTER_WRAPPER(abool, OptBool)
94 CREATE_GETTER_SETTER_WRAPPER(avector, std::vector<OptInt32>)
95 
96 // Name,Getter, Setter, Parser and default value
97 #define NGS(_NAME_) #_NAME_, _NAME_##Getter, _NAME_##Setter
98 static Config::Data configData[] = {
99         {NGS(astring), &Config::parseString, AIDL_DEFAULT_astring},
100         {NGS(aint32), &Config::parseInt32, AIDL_DEFAULT_aint32},
101         {NGS(aint64), &Config::parseInt64, AIDL_DEFAULT_aint64},
102         {NGS(abool), &Config::parseBool, AIDL_DEFAULT_abool},
103         {NGS(avector), &Config::parseIntVec, AIDL_DEFAULT_avector},
104 };
105 
106 class TestConfig : public Config {
getConfigData(int * size)107     Config::Data* getConfigData(int* size) {
108         *size = sizeof(configData) / sizeof(configData[0]);
109         return configData;
110     }
111 };
112 
113 class ConfigTest : public ::testing::Test {
114   protected:
SetUp()115     void SetUp() override { cfg.init(); }
TearDown()116     void TearDown() override {}
117 
switch2aidl()118     void switch2aidl() { cfg.sourcedFromAidl(); }
119 
120     TestConfig cfg;
121 };
122 
TEST_F(ConfigTest,parseInt32)123 TEST_F(ConfigTest, parseInt32) {
124     std::int32_t defval = 5678;
125     struct {
126         std::string strval;
127         std::int32_t expval;
128     } values[] = {
129             {"1234", 1234},
130             {"0", 0},
131             {"", defval},
132     };
133     for (int i = 0; i < sizeof(values) / sizeof(values[0]); i++) {
134         ASSERT_EQ((std::get<OptInt32>(cfg.parseInt32(values[i].strval))).value_or(defval),
135                   values[i].expval);
136     }
137 }
138 
TEST_F(ConfigTest,parseInt64)139 TEST_F(ConfigTest, parseInt64) {
140     std::int64_t defval = 5678;
141     struct {
142         std::string strval;
143         std::int64_t expval;
144     } values[] = {
145             {"1234", 1234},
146             {"12345678909876", 12345678909876},
147             {"0", 0},
148             {"", defval},
149     };
150     for (int i = 0; i < sizeof(values) / sizeof(values[0]); i++) {
151         ASSERT_EQ((std::get<OptInt64>(cfg.parseInt64(values[i].strval))).value_or(defval),
152                   values[i].expval);
153     }
154 }
155 
TEST_F(ConfigTest,parseBool)156 TEST_F(ConfigTest, parseBool) {
157     bool defval = true;
158     struct {
159         std::string strval;
160         bool expval;
161     } values[] = {
162             {"false", false},
163             {"true", true},
164     };
165     for (int i = 0; i < sizeof(values) / sizeof(values[0]); i++) {
166         ASSERT_EQ((std::get<OptBool>(cfg.parseBool(values[i].strval))).value_or(defval),
167                   values[i].expval);
168     }
169 }
170 
TEST_F(ConfigTest,parseIntVec)171 TEST_F(ConfigTest, parseIntVec) {
172     std::vector<std::optional<int>> defval = {};
173     struct {
174         std::string strval;
175         std::vector<std::optional<int>> expval;
176     } values[] = {{"1", {1}}, {"1,2,3", {1, 2, 3}}, {"1,2,b", defval}, {"", defval}};
177     for (int i = 0; i < sizeof(values) / sizeof(values[0]); i++) {
178         ASSERT_EQ(std::get<OptIntVec>(cfg.parseIntVec(values[i].strval)), values[i].expval);
179     }
180 }
181 
TEST_F(ConfigTest,getters_sp)182 TEST_F(ConfigTest, getters_sp) {
183     ASSERT_EQ(cfg.get<std::string>("astring"), val_astring);
184     ASSERT_EQ(cfg.get<std::int32_t>("aint32"), val_aint32);
185     ASSERT_EQ(cfg.get<std::int64_t>("aint64"), val_aint64);
186     ASSERT_EQ(cfg.get<bool>("abool"), val_abool);
187     OptIntVec exp{val_avector};
188     EXPECT_EQ(cfg.getopt<OptIntVec>("avector"), exp);
189 }
190 
TEST_F(ConfigTest,setters_sp)191 TEST_F(ConfigTest, setters_sp) {
192     std::string val_astring_new("astringNew");
193     ASSERT_TRUE(cfg.set<std::string>("astring", val_astring_new));
194     ASSERT_EQ(cfg.get<std::string>("astring"), val_astring_new);
195 
196     std::int32_t val_aint32_new = val_aint32.value() + 100;
197     ASSERT_TRUE(cfg.set<std::int32_t>("aint32", val_aint32_new));
198     ASSERT_EQ(cfg.get<std::int32_t>("aint32"), val_aint32_new);
199 
200     std::int64_t val_aint64_new = val_aint64.value() + 200;
201     ASSERT_TRUE(cfg.set<std::int64_t>("aint64", val_aint64_new));
202     ASSERT_EQ(cfg.get<std::int64_t>("aint64"), val_aint64_new);
203 
204     bool val_abool_new = !val_abool.value();
205     ASSERT_TRUE(cfg.set<bool>("abool", val_abool_new));
206     ASSERT_EQ(cfg.get<bool>("abool"), val_abool_new);
207 
208     OptIntVec val_avector_new{100, 200};
209     ASSERT_TRUE(cfg.setopt<OptIntVec>("avector", val_avector_new));
210     EXPECT_EQ(cfg.getopt<OptIntVec>("avector"), val_avector_new);
211 }
212 
TEST_F(ConfigTest,setters_sp_null)213 TEST_F(ConfigTest, setters_sp_null) {
214     val_astring = std::nullopt;
215     ASSERT_EQ(cfg.get<std::string>("astring"),
216               (std::get<OptString>(cfg.parseString(AIDL_DEFAULT_astring))).value());
217 }
218 
TEST_F(ConfigTest,getters_aidl)219 TEST_F(ConfigTest, getters_aidl) {
220     cfg.setParam("astring", "astringAIDL");
221     ASSERT_EQ(cfg.get<std::string>("astring"),
222               (std::get<OptString>(cfg.parseString(AIDL_DEFAULT_astring))).value());
223     ASSERT_EQ(cfg.get<std::int32_t>("aint32"),
224               (std::get<OptInt32>(cfg.parseInt32(AIDL_DEFAULT_aint32))).value());
225     ASSERT_EQ(cfg.get<std::int64_t>("aint64"),
226               (std::get<OptInt64>(cfg.parseInt64(AIDL_DEFAULT_aint64))).value());
227     ASSERT_EQ(cfg.get<bool>("abool"),
228               (std::get<OptBool>(cfg.parseBool(AIDL_DEFAULT_abool))).value());
229     OptIntVec exp{std::get<OptIntVec>(cfg.parseIntVec(AIDL_DEFAULT_avector))};
230     EXPECT_EQ(cfg.getopt<OptIntVec>("avector"), exp);
231 }
232 
TEST_F(ConfigTest,setters_aidl)233 TEST_F(ConfigTest, setters_aidl) {
234     std::string val_astring_new("astringNewAidl");
235     ASSERT_TRUE(cfg.set<std::string>("astring", val_astring_new));
236     ASSERT_EQ(cfg.get<std::string>("astring"), val_astring_new);
237 
238     std::int32_t val_aint32_new = val_aint32.value() + 1000;
239     ASSERT_TRUE(cfg.set<std::int32_t>("aint32", val_aint32_new));
240     ASSERT_EQ(cfg.get<std::int32_t>("aint32"), val_aint32_new);
241 
242     std::int64_t val_aint64_new = val_aint64.value() + 2000;
243     ASSERT_TRUE(cfg.set<std::int64_t>("aint64", val_aint64_new));
244     ASSERT_EQ(cfg.get<std::int64_t>("aint64"), val_aint64_new);
245 
246     bool val_abool_new = !val_abool.value();
247     ASSERT_TRUE(cfg.set<bool>("abool", val_abool_new));
248     ASSERT_EQ(cfg.get<bool>("abool"), val_abool_new);
249 
250     OptIntVec val_avector_new{1000, 2000};
251     ASSERT_TRUE(cfg.setopt<OptIntVec>("avector", val_avector_new));
252     EXPECT_EQ(cfg.getopt<OptIntVec>("avector"), val_avector_new);
253 }
254 
255 }  // namespace aidl::android::hardware::biometrics
256