1 /*
2 * Copyright (C) 2020 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 #include <aidl/Gtest.h>
17 #include <aidl/Vintf.h>
18
19 #include <aidl/android/hardware/weaver/IWeaver.h>
20 #include <android/binder_manager.h>
21 #include <android/binder_process.h>
22
23 #include <limits>
24
25 using ::aidl::android::hardware::weaver::IWeaver;
26 using ::aidl::android::hardware::weaver::WeaverConfig;
27 using ::aidl::android::hardware::weaver::WeaverReadResponse;
28
29 using ::ndk::SpAIBinder;
30
31 const std::vector<uint8_t> KEY{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
32 const std::vector<uint8_t> WRONG_KEY{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
33 const std::vector<uint8_t> VALUE{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
34 const std::vector<uint8_t> OTHER_VALUE{0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 255, 255};
35
36 struct WeaverAidlTest : public ::testing::TestWithParam<std::string> {
SetUpWeaverAidlTest37 virtual void SetUp() override {
38 weaver = IWeaver::fromBinder(
39 SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
40 ASSERT_NE(weaver, nullptr);
41 }
42
TearDownWeaverAidlTest43 virtual void TearDown() override {}
44
45 std::shared_ptr<IWeaver> weaver;
46 };
47
48 /*
49 * Checks config values are suitably large
50 */
TEST_P(WeaverAidlTest,GetConfig)51 TEST_P(WeaverAidlTest, GetConfig) {
52 WeaverConfig config;
53
54 auto ret = weaver->getConfig(&config);
55
56 ASSERT_TRUE(ret.isOk());
57
58 EXPECT_GE(config.slots, 16u);
59 EXPECT_GE(config.keySize, 16u);
60 EXPECT_GE(config.valueSize, 16u);
61 }
62
63 /*
64 * Gets the config twice and checks they are the same
65 */
TEST_P(WeaverAidlTest,GettingConfigMultipleTimesGivesSameResult)66 TEST_P(WeaverAidlTest, GettingConfigMultipleTimesGivesSameResult) {
67 WeaverConfig config1;
68 WeaverConfig config2;
69
70 auto ret = weaver->getConfig(&config1);
71 ASSERT_TRUE(ret.isOk());
72
73 ret = weaver->getConfig(&config2);
74 ASSERT_TRUE(ret.isOk());
75
76 EXPECT_EQ(config1, config2);
77 }
78
79 /*
80 * Gets the number of slots from the config and writes a key and value to the last one
81 */
TEST_P(WeaverAidlTest,WriteToLastSlot)82 TEST_P(WeaverAidlTest, WriteToLastSlot) {
83 WeaverConfig config;
84 const auto configRet = weaver->getConfig(&config);
85
86 ASSERT_TRUE(configRet.isOk());
87
88 const uint32_t lastSlot = config.slots - 1;
89 const auto writeRet = weaver->write(lastSlot, KEY, VALUE);
90 ASSERT_TRUE(writeRet.isOk());
91 }
92
93 /*
94 * Writes a key and value to a slot
95 * Reads the slot with the same key and receives the value that was previously written
96 */
TEST_P(WeaverAidlTest,WriteFollowedByReadGivesTheSameValue)97 TEST_P(WeaverAidlTest, WriteFollowedByReadGivesTheSameValue) {
98 constexpr uint32_t slotId = 0;
99 const auto ret = weaver->write(slotId, KEY, VALUE);
100 ASSERT_TRUE(ret.isOk());
101
102 WeaverReadResponse response;
103 std::vector<uint8_t> readValue;
104 uint32_t timeout;
105 const auto readRet = weaver->read(slotId, KEY, &response);
106
107 readValue = response.value;
108 timeout = response.timeout;
109
110 ASSERT_TRUE(readRet.isOk());
111 EXPECT_EQ(readValue, VALUE);
112 EXPECT_EQ(timeout, 0u);
113 }
114
115 /*
116 * Writes a key and value to a slot
117 * Overwrites the slot with a new key and value
118 * Reads the slot with the new key and receives the new value
119 */
TEST_P(WeaverAidlTest,OverwritingSlotUpdatesTheValue)120 TEST_P(WeaverAidlTest, OverwritingSlotUpdatesTheValue) {
121 constexpr uint32_t slotId = 0;
122 const auto initialWriteRet = weaver->write(slotId, WRONG_KEY, VALUE);
123 ASSERT_TRUE(initialWriteRet.isOk());
124
125 const auto overwriteRet = weaver->write(slotId, KEY, OTHER_VALUE);
126 ASSERT_TRUE(overwriteRet.isOk());
127
128 WeaverReadResponse response;
129 std::vector<uint8_t> readValue;
130 uint32_t timeout;
131 const auto readRet = weaver->read(slotId, KEY, &response);
132
133 readValue = response.value;
134 timeout = response.timeout;
135
136 ASSERT_TRUE(readRet.isOk());
137 EXPECT_EQ(readValue, OTHER_VALUE);
138 EXPECT_EQ(timeout, 0u);
139 }
140
141 /*
142 * Writes a key and value to a slot
143 * Reads the slot with a different key so does not receive the value
144 */
TEST_P(WeaverAidlTest,WriteFollowedByReadWithWrongKeyDoesNotGiveTheValue)145 TEST_P(WeaverAidlTest, WriteFollowedByReadWithWrongKeyDoesNotGiveTheValue) {
146 constexpr uint32_t slotId = 0;
147 const auto ret = weaver->write(slotId, KEY, VALUE);
148 ASSERT_TRUE(ret.isOk());
149
150 WeaverReadResponse response;
151 std::vector<uint8_t> readValue;
152 const auto readRet =
153 weaver->read(slotId, WRONG_KEY, &response);
154
155 readValue = response.value;
156
157 ASSERT_FALSE(readRet.isOk());
158 ASSERT_EQ(EX_SERVICE_SPECIFIC, readRet.getExceptionCode());
159 ASSERT_EQ(IWeaver::STATUS_INCORRECT_KEY, readRet.getServiceSpecificError());
160 EXPECT_TRUE(readValue.empty());
161 }
162
163 /*
164 * Writing to an invalid slot fails
165 */
TEST_P(WeaverAidlTest,WritingToInvalidSlotFails)166 TEST_P(WeaverAidlTest, WritingToInvalidSlotFails) {
167 WeaverConfig config;
168 const auto configRet = weaver->getConfig(&config);
169 ASSERT_TRUE(configRet.isOk());
170
171 if (config.slots == std::numeric_limits<uint32_t>::max()) {
172 // If there are no invalid slots then pass
173 return;
174 }
175
176 const auto writeRet = weaver->write(config.slots, KEY, VALUE);
177 ASSERT_FALSE(writeRet.isOk());
178 }
179
180 /*
181 * Reading from an invalid slot fails rather than incorrect key
182 */
TEST_P(WeaverAidlTest,ReadingFromInvalidSlotFails)183 TEST_P(WeaverAidlTest, ReadingFromInvalidSlotFails) {
184 WeaverConfig config;
185 const auto configRet = weaver->getConfig(&config);
186 ASSERT_TRUE(configRet.isOk());
187
188 if (config.slots == std::numeric_limits<uint32_t>::max()) {
189 // If there are no invalid slots then pass
190 return;
191 }
192
193 WeaverReadResponse response;
194 std::vector<uint8_t> readValue;
195 uint32_t timeout;
196 const auto readRet =
197 weaver->read(config.slots, KEY, &response);
198
199 readValue = response.value;
200 timeout = response.timeout;
201
202 ASSERT_FALSE(readRet.isOk());
203 ASSERT_EQ(EX_SERVICE_SPECIFIC, readRet.getExceptionCode());
204 ASSERT_EQ(IWeaver::STATUS_FAILED, readRet.getServiceSpecificError());
205 EXPECT_TRUE(readValue.empty());
206 EXPECT_EQ(timeout, 0u);
207 }
208
209 /*
210 * Writing a key that is too large fails
211 */
TEST_P(WeaverAidlTest,WriteWithTooLargeKeyFails)212 TEST_P(WeaverAidlTest, WriteWithTooLargeKeyFails) {
213 WeaverConfig config;
214 const auto configRet = weaver->getConfig(&config);
215 ASSERT_TRUE(configRet.isOk());
216
217 std::vector<uint8_t> bigKey(config.keySize + 1);
218
219 constexpr uint32_t slotId = 0;
220 const auto writeRet = weaver->write(slotId, bigKey, VALUE);
221 ASSERT_FALSE(writeRet.isOk());
222 }
223
224 /*
225 * Writing a value that is too large fails
226 */
TEST_P(WeaverAidlTest,WriteWithTooLargeValueFails)227 TEST_P(WeaverAidlTest, WriteWithTooLargeValueFails) {
228 WeaverConfig config;
229 const auto configRet = weaver->getConfig(&config);
230 ASSERT_TRUE(configRet.isOk());
231
232 std::vector<uint8_t> bigValue(config.valueSize + 1);
233
234 constexpr uint32_t slotId = 0;
235 const auto writeRet = weaver->write(slotId, KEY, bigValue);
236 ASSERT_FALSE(writeRet.isOk());
237 }
238
239 /*
240 * Reading with a key that is loo large fails
241 */
TEST_P(WeaverAidlTest,ReadWithTooLargeKeyFails)242 TEST_P(WeaverAidlTest, ReadWithTooLargeKeyFails) {
243 WeaverConfig config;
244 const auto configRet = weaver->getConfig(&config);
245 ASSERT_TRUE(configRet.isOk());
246
247 std::vector<uint8_t> bigKey(config.keySize + 1);
248
249 constexpr uint32_t slotId = 0;
250 WeaverReadResponse response;
251 std::vector<uint8_t> readValue;
252 uint32_t timeout;
253 const auto readRet =
254 weaver->read(slotId, bigKey, &response);
255
256 readValue = response.value;
257 timeout = response.timeout;
258
259 ASSERT_FALSE(readRet.isOk());
260 ASSERT_EQ(EX_SERVICE_SPECIFIC, readRet.getExceptionCode());
261 ASSERT_EQ(IWeaver::STATUS_FAILED, readRet.getServiceSpecificError());
262 EXPECT_TRUE(readValue.empty());
263 EXPECT_EQ(timeout, 0u);
264 }
265
266 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WeaverAidlTest);
267 INSTANTIATE_TEST_SUITE_P(
268 PerInstance, WeaverAidlTest,
269 testing::ValuesIn(android::getAidlHalInstanceNames(IWeaver::descriptor)),
270 android::PrintInstanceNameToString);
271
main(int argc,char ** argv)272 int main(int argc, char** argv) {
273 ::testing::InitGoogleTest(&argc, argv);
274 ABinderProcess_setThreadPoolMaxThreadCount(1);
275 ABinderProcess_startThreadPool();
276 return RUN_ALL_TESTS();
277 }
278