• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 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 
17 #include "storage/config_cache.h"
18 
19 #include <gmock/gmock.h>
20 #include <gtest/gtest.h>
21 
22 #include <cstdio>
23 
24 #include "hci/enum_helper.h"
25 #include "storage/config_keys.h"
26 #include "storage/device.h"
27 
28 namespace testing {
29 
30 namespace {
GetTestAddress(int i)31 std::string GetTestAddress(int i) {
32   std::string res = "00:00:00:00:00:00";
33   res.reserve(res.size() + 1);
34   std::snprintf(res.data(), res.capacity(), "AA:BB:CC:DD:EE:%02d", i);
35   return res;
36 }
37 }  // namespace
38 
39 using bluetooth::storage::ConfigCache;
40 using bluetooth::storage::Device;
41 using SectionAndPropertyValue = bluetooth::storage::ConfigCache::SectionAndPropertyValue;
42 
TEST(ConfigCacheTest,simple_set_get_test)43 TEST(ConfigCacheTest, simple_set_get_test) {
44   ConfigCache config(100, Device::kLinkKeyProperties);
45   config.SetProperty("A", "B", "C");
46   auto value = config.GetProperty("A", "B");
47   ASSERT_TRUE(value);
48   ASSERT_EQ(*value, "C");
49 }
50 
TEST(ConfigCacheTest,empty_values_test)51 TEST(ConfigCacheTest, empty_values_test) {
52   ConfigCache config(100, Device::kLinkKeyProperties);
53   ASSERT_DEATH({ config.SetProperty("", "B", "C"); }, "Empty section name not allowed");
54   ASSERT_DEATH({ config.SetProperty("A", "", "C"); }, "Empty property name not allowed");
55   // empty value is allowed
56   config.SetProperty("A", "B", "");
57   auto value = config.GetProperty("A", "B");
58   ASSERT_TRUE(value);
59   ASSERT_EQ(*value, "");
60 }
61 
TEST(ConfigCacheTest,insert_boundary_device_with_linkkey_test)62 TEST(ConfigCacheTest, insert_boundary_device_with_linkkey_test) {
63   ConfigCache config(2, Device::kLinkKeyProperties);
64   config.SetProperty("A", "B", "C");
65   config.SetProperty("CC:DD:EE:FF:00:10", BTIF_STORAGE_KEY_NAME, "Hello");
66   config.SetProperty("CC:DD:EE:FF:00:09", BTIF_STORAGE_KEY_NAME, "Hello 2");
67   config.SetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LINK_KEY, "AABBAABBCCDDEE");
68   ASSERT_TRUE(config.GetProperty("CC:DD:EE:FF:00:10", BTIF_STORAGE_KEY_NAME));
69 }
70 
TEST(ConfigCacheTest,comparison_test)71 TEST(ConfigCacheTest, comparison_test) {
72   ConfigCache config_1(2, Device::kLinkKeyProperties);
73   config_1.SetProperty("A", "B", "C");
74   config_1.SetProperty("CC:DD:EE:FF:00:10", BTIF_STORAGE_KEY_NAME, "Hello");
75   config_1.SetProperty("CC:DD:EE:FF:00:09", BTIF_STORAGE_KEY_NAME, "Hello 2");
76   config_1.SetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LINK_KEY, "AABBAABBCCDDEE");
77   ConfigCache config_2(2, Device::kLinkKeyProperties);
78   config_2.SetProperty("A", "B", "C");
79   config_2.SetProperty("CC:DD:EE:FF:00:10", BTIF_STORAGE_KEY_NAME, "Hello");
80   config_2.SetProperty("CC:DD:EE:FF:00:09", BTIF_STORAGE_KEY_NAME, "Hello 2");
81   config_2.SetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LINK_KEY, "AABBAABBCCDDEE");
82   ASSERT_EQ(config_1, config_2);
83   // Config with different temp device order should not be equal
84   ASSERT_TRUE(config_2.GetProperty("CC:DD:EE:FF:00:10", BTIF_STORAGE_KEY_NAME));
85   ASSERT_NE(config_1, config_2);
86   ASSERT_TRUE(config_1.GetProperty("CC:DD:EE:FF:00:10", BTIF_STORAGE_KEY_NAME));
87   ASSERT_EQ(config_1, config_2);
88   // Config with different persistent device order should not be equal
89   config_1.SetProperty("CC:DD:EE:FF:00:12", BTIF_STORAGE_KEY_LINK_KEY, "AABBAABBCCDDEE");
90   config_2.RemoveSection("CC:DD:EE:FF:00:11");
91   config_2.SetProperty("CC:DD:EE:FF:00:12", BTIF_STORAGE_KEY_LINK_KEY, "AABBAABBCCDDEE");
92   config_2.SetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LINK_KEY, "AABBAABBCCDDEE");
93   ASSERT_NE(config_1, config_2);
94   // Config with different capacity should not be equal
95   ConfigCache config_3(3, Device::kLinkKeyProperties);
96   config_3.SetProperty("A", "B", "C");
97   config_3.SetProperty("CC:DD:EE:FF:00:10", BTIF_STORAGE_KEY_NAME, "Hello");
98   config_3.SetProperty("CC:DD:EE:FF:00:09", BTIF_STORAGE_KEY_NAME, "Hello 2");
99   config_3.SetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LINK_KEY, "AABBAABBCCDDEE");
100   config_3.SetProperty("CC:DD:EE:FF:00:12", BTIF_STORAGE_KEY_LINK_KEY, "AABBAABBCCDDEE");
101   ASSERT_NE(config_1, config_3);
102   // Empty config should not be equal to non-empty ones
103   ConfigCache config_4(2, Device::kLinkKeyProperties);
104   ASSERT_NE(config_1, config_4);
105   // Empty configs should be equal
106   ConfigCache config_5(2, Device::kLinkKeyProperties);
107   ASSERT_EQ(config_4, config_5);
108   // Empty configs with different capacity should not be equal
109   ConfigCache config_6(3, Device::kLinkKeyProperties);
110   ASSERT_NE(config_4, config_6);
111 }
112 
TEST(ConfigCacheTest,empty_string_test)113 TEST(ConfigCacheTest, empty_string_test) {
114   ConfigCache config(100, Device::kLinkKeyProperties);
115   config.SetProperty("A", "B", "");
116   auto value = config.GetProperty("A", "B");
117   ASSERT_TRUE(value);
118   ASSERT_EQ(*value, "");
119 }
120 
TEST(ConfigCacheTest,mac_address_set_get_test)121 TEST(ConfigCacheTest, mac_address_set_get_test) {
122   ConfigCache config(100, Device::kLinkKeyProperties);
123   config.SetProperty("A", "B", "C");
124   config.SetProperty("AA:BB:CC:DD:EE:FF", "B", "C");
125   auto value = config.GetProperty("A", "B");
126   ASSERT_TRUE(value);
127   ASSERT_EQ(*value, "C");
128   value = config.GetProperty("AA:BB:CC:DD:EE:FF", "B");
129   ASSERT_TRUE(value);
130   ASSERT_EQ(*value, "C");
131   ASSERT_FALSE(config.GetProperty("A", "BC"));
132   ASSERT_FALSE(config.GetProperty("ABC", "B"));
133 }
134 
TEST(ConfigCacheTest,has_section_and_property_test)135 TEST(ConfigCacheTest, has_section_and_property_test) {
136   ConfigCache config(100, Device::kLinkKeyProperties);
137   config.SetProperty("A", "B", "C");
138   config.SetProperty("AA:BB:CC:DD:EE:FF", "B", "C");
139   config.SetProperty("AA:BB:CC:DD:EE:FF", "C", "D");
140   ASSERT_TRUE(config.HasSection("A"));
141   ASSERT_TRUE(config.HasSection("AA:BB:CC:DD:EE:FF"));
142   ASSERT_TRUE(config.HasProperty("A", "B"));
143   ASSERT_TRUE(config.HasProperty("AA:BB:CC:DD:EE:FF", "B"));
144   config.SetProperty("AA:BB:CC:DD:EE:FF", "C", "D");
145   auto value = config.GetProperty("AA:BB:CC:DD:EE:FF", "C");
146   ASSERT_TRUE(value);
147   ASSERT_EQ(*value, "D");
148   value = config.GetProperty("AA:BB:CC:DD:EE:FF", "B");
149   ASSERT_TRUE(value);
150   ASSERT_EQ(*value, "C");
151   config.SetProperty("AA:BB:CC:DD:EE:FF", "B", "E");
152   value = config.GetProperty("AA:BB:CC:DD:EE:FF", "B");
153   ASSERT_TRUE(value);
154   ASSERT_THAT(value, Optional(StrEq("E")));
155   ASSERT_FALSE(config.HasSection("Ab"));
156   ASSERT_FALSE(config.HasSection("AA:11:CC:DD:EE:FF"));
157   ASSERT_FALSE(config.HasProperty("A", "bB"));
158   ASSERT_FALSE(config.HasProperty("AA:BB:11:DD:EE:FF", "B"));
159 }
160 
TEST(ConfigCacheTest,remove_section_test)161 TEST(ConfigCacheTest, remove_section_test) {
162   ConfigCache config(100, Device::kLinkKeyProperties);
163   config.SetProperty("A", "B", "C");
164   config.SetProperty("AA:BB:CC:DD:EE:FF", "B", "C");
165   config.SetProperty("AA:BB:CC:DD:EE:FF", "C", "D");
166   ASSERT_TRUE(config.HasSection("A"));
167   ASSERT_TRUE(config.HasSection("AA:BB:CC:DD:EE:FF"));
168   ASSERT_TRUE(config.HasProperty("A", "B"));
169   ASSERT_TRUE(config.HasProperty("AA:BB:CC:DD:EE:FF", "B"));
170   ASSERT_TRUE(config.RemoveSection("AA:BB:CC:DD:EE:FF"));
171   ASSERT_TRUE(config.RemoveSection("A"));
172   ASSERT_FALSE(config.HasProperty("A", "B"));
173   ASSERT_FALSE(config.HasProperty("AA:BB:CC:DD:EE:FF", "B"));
174 }
175 
TEST(ConfigCacheTest,remove_property_test)176 TEST(ConfigCacheTest, remove_property_test) {
177   ConfigCache config(100, Device::kLinkKeyProperties);
178   config.SetProperty("A", "B", "C");
179   config.SetProperty("AA:BB:CC:DD:EE:FF", "B", "C");
180   config.SetProperty("AA:BB:CC:DD:EE:FF", "C", "D");
181   ASSERT_TRUE(config.HasSection("A"));
182   ASSERT_TRUE(config.HasSection("AA:BB:CC:DD:EE:FF"));
183   ASSERT_TRUE(config.HasProperty("A", "B"));
184   ASSERT_TRUE(config.HasProperty("AA:BB:CC:DD:EE:FF", "B"));
185   ASSERT_TRUE(config.HasProperty("AA:BB:CC:DD:EE:FF", "C"));
186   ASSERT_TRUE(config.RemoveProperty("AA:BB:CC:DD:EE:FF", "B"));
187   ASSERT_FALSE(config.HasProperty("AA:BB:CC:DD:EE:FF", "B"));
188   ASSERT_FALSE(config.GetProperty("AA:BB:CC:DD:EE:FF", "B"));
189 }
190 
TEST(ConfigCacheTest,remove_all_properties_from_section_test)191 TEST(ConfigCacheTest, remove_all_properties_from_section_test) {
192   ConfigCache config(100, Device::kLinkKeyProperties);
193   config.SetProperty("A", "B", "C");
194   config.SetProperty("AA:BB:CC:DD:EE:FF", "B", "C");
195   config.SetProperty("AA:BB:CC:DD:EE:FF", "C", "D");
196   ASSERT_TRUE(config.HasSection("A"));
197   ASSERT_TRUE(config.HasSection("AA:BB:CC:DD:EE:FF"));
198   ASSERT_TRUE(config.HasProperty("A", "B"));
199   ASSERT_TRUE(config.HasProperty("AA:BB:CC:DD:EE:FF", "B"));
200   ASSERT_TRUE(config.HasProperty("AA:BB:CC:DD:EE:FF", "C"));
201   ASSERT_TRUE(config.RemoveSection("AA:BB:CC:DD:EE:FF"));
202   ASSERT_FALSE(config.HasSection("AA:BB:CC:DD:EE:FF"));
203   ASSERT_FALSE(config.HasProperty("AA:BB:CC:DD:EE:FF", "B"));
204   ASSERT_FALSE(config.GetProperty("AA:BB:CC:DD:EE:FF", "C"));
205 }
206 
TEST(ConfigCacheTest,get_persistent_devices_test)207 TEST(ConfigCacheTest, get_persistent_devices_test) {
208   ConfigCache config(100, Device::kLinkKeyProperties);
209   config.SetProperty("A", "B", "C");
210   config.SetProperty("AA:BB:CC:DD:EE:FF", "B", "C");
211   config.SetProperty("AA:BB:CC:DD:EE:FF", "C", "D");
212   config.SetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LINK_KEY, "AABBAABBCCDDEE");
213   ASSERT_TRUE(config.HasProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LINK_KEY));
214   ASSERT_THAT(config.GetPersistentSections(), ElementsAre("CC:DD:EE:FF:00:11"));
215   config.SetProperty("AA:BB:CC:DD:EE:FF", BTIF_STORAGE_KEY_LINK_KEY, "DEERDEERDEER");
216   ASSERT_THAT(config.GetPersistentSections(), ElementsAre("CC:DD:EE:FF:00:11", "AA:BB:CC:DD:EE:FF"));
217   ASSERT_TRUE(config.RemoveProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LINK_KEY));
218   ASSERT_THAT(config.GetPersistentSections(), ElementsAre("AA:BB:CC:DD:EE:FF"));
219 }
220 
TEST(ConfigCacheTest,appoaching_temporary_config_limit_test)221 TEST(ConfigCacheTest, appoaching_temporary_config_limit_test) {
222   ConfigCache config(2, Device::kLinkKeyProperties);
223   for (int i = 0; i < 10; ++i) {
224     config.SetProperty(GetTestAddress(i), BTIF_STORAGE_KEY_NAME, "Hello" + std::to_string(i));
225     if (i % 2 == 0) {
226       config.SetProperty(GetTestAddress(i), BTIF_STORAGE_KEY_LINK_KEY, "Key" + std::to_string(i));
227     }
228   }
229   for (int i = 0; i < 10; ++i) {
230     if (i % 2 == 0) {
231       ASSERT_TRUE(config.HasSection(GetTestAddress(i)));
232       ASSERT_TRUE(config.HasProperty(GetTestAddress(i), BTIF_STORAGE_KEY_LINK_KEY));
233       ASSERT_THAT(
234           config.GetProperty(GetTestAddress(i), BTIF_STORAGE_KEY_NAME),
235           Optional(StrEq("Hello" + std::to_string(i))));
236     } else if (i >= 7) {
237       ASSERT_TRUE(config.HasSection(GetTestAddress(i)));
238       ASSERT_THAT(
239           config.GetProperty(GetTestAddress(i), BTIF_STORAGE_KEY_NAME),
240           Optional(StrEq("Hello" + std::to_string(i))));
241     } else {
242       ASSERT_FALSE(config.HasSection(GetTestAddress(i)));
243     }
244   }
245   ASSERT_THAT(
246       config.GetPersistentSections(),
247       ElementsAre(GetTestAddress(0), GetTestAddress(2), GetTestAddress(4), GetTestAddress(6), GetTestAddress(8)));
248 }
249 
TEST(ConfigCacheTest,remove_section_with_property_test)250 TEST(ConfigCacheTest, remove_section_with_property_test) {
251   ConfigCache config(100, Device::kLinkKeyProperties);
252   config.SetProperty("A", "B", "C");
253   config.SetProperty("AA:BB:CC:DD:EE:FF", "B", "C");
254   config.SetProperty("AA:BB:CC:DD:EE:FF", "C", "D");
255   config.SetProperty("CC:DD:EE:FF:00:11", "B", "AABBAABBCCDDEE");
256   config.SetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LINK_KEY, "AABBAABBCCDDEE");
257   config.RemoveSectionWithProperty("B");
258   ASSERT_FALSE(config.HasSection("A"));
259   ASSERT_FALSE(config.HasSection("AA:BB:CC:DD:EE:FF"));
260   ASSERT_FALSE(config.HasSection("CC:DD:EE:FF:00:11"));
261 }
262 
TEST(ConfigCacheTest,persistent_config_changed_callback_test)263 TEST(ConfigCacheTest, persistent_config_changed_callback_test) {
264   ConfigCache config(100, Device::kLinkKeyProperties);
265   int num_change = 0;
266   config.SetPersistentConfigChangedCallback([&num_change] { num_change++; });
267   config.SetProperty("A", "B", "C");
268   ASSERT_EQ(num_change, 1);
269   config.SetProperty("AA:BB:CC:DD:EE:FF", "B", "C");
270   ASSERT_EQ(num_change, 1);
271   config.SetProperty("AA:BB:CC:DD:EE:FF", "C", "D");
272   ASSERT_EQ(num_change, 1);
273   config.SetProperty("CC:DD:EE:FF:00:11", "B", "AABBAABBCCDDEE");
274   ASSERT_EQ(num_change, 1);
275   config.SetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LINK_KEY, "AABBAABBCCDDEE");
276   ASSERT_EQ(num_change, 2);
277   config.RemoveProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LINK_KEY);
278   ASSERT_EQ(num_change, 3);
279   config.RemoveSectionWithProperty("B");
280   ASSERT_EQ(num_change, 4);
281 }
282 
TEST(ConfigCacheTest,fix_device_type_inconsistency_missing_devtype_no_keys_test)283 TEST(ConfigCacheTest, fix_device_type_inconsistency_missing_devtype_no_keys_test) {
284   ConfigCache config(100, Device::kLinkKeyProperties);
285   config.SetProperty("A", "B", "C");
286   config.SetProperty("AA:BB:CC:DD:EE:FF", "B", "C");
287   config.SetProperty("AA:BB:CC:DD:EE:FF", "C", "D");
288 
289   auto hadInconsistencies = config.FixDeviceTypeInconsistencies();
290 
291   ASSERT_TRUE(hadInconsistencies);
292   ASSERT_THAT(
293       config.GetProperty("AA:BB:CC:DD:EE:FF", BTIF_STORAGE_KEY_DEV_TYPE),
294       Optional(StrEq(std::to_string(bluetooth::hci::DeviceType::BR_EDR))));
295 }
296 
TEST(ConfigCacheTest,fix_device_type_inconsistency_consistent_devtype_test)297 TEST(ConfigCacheTest, fix_device_type_inconsistency_consistent_devtype_test) {
298   // arrange
299   ConfigCache config(100, Device::kLinkKeyProperties);
300   config.SetProperty("A", "B", "C");
301   config.SetProperty("AA:BB:CC:DD:EE:FF", "B", "C");
302   config.SetProperty("AA:BB:CC:DD:EE:FF", "C", "D");
303   config.SetProperty(
304       "AA:BB:CC:DD:EE:FF",
305       BTIF_STORAGE_KEY_DEV_TYPE,
306       std::to_string(bluetooth::hci::DeviceType::BR_EDR));
307 
308   config.SetProperty("CC:DD:EE:FF:00:11", "B", "AABBAABBCCDDEE");
309   config.SetProperty(
310       "CC:DD:EE:FF:00:11",
311       BTIF_STORAGE_KEY_DEV_TYPE,
312       std::to_string(bluetooth::hci::DeviceType::BR_EDR));
313   config.SetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LINK_KEY, "AABBAABBCCDDEE");
314 
315   // act
316   auto hadInconsistencies = config.FixDeviceTypeInconsistencies();
317 
318   // assert
319   ASSERT_FALSE(hadInconsistencies);
320   ASSERT_THAT(
321       config.GetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_DEV_TYPE),
322       Optional(StrEq(std::to_string(bluetooth::hci::DeviceType::BR_EDR))));
323 }
324 
TEST(ConfigCacheTest,fix_device_type_inconsistency_devtype_should_be_dual_test)325 TEST(ConfigCacheTest, fix_device_type_inconsistency_devtype_should_be_dual_test) {
326   // arrange
327   ConfigCache config(100, Device::kLinkKeyProperties);
328   config.SetProperty("A", "B", "C");
329   config.SetProperty("AA:BB:CC:DD:EE:FF", "B", "C");
330   config.SetProperty("AA:BB:CC:DD:EE:FF", "C", "D");
331   config.SetProperty(
332       "AA:BB:CC:DD:EE:FF",
333       BTIF_STORAGE_KEY_DEV_TYPE,
334       std::to_string(bluetooth::hci::DeviceType::BR_EDR));
335 
336   config.SetProperty("CC:DD:EE:FF:00:11", "B", "AABBAABBCCDDEE");
337   config.SetProperty(
338       "CC:DD:EE:FF:00:11",
339       BTIF_STORAGE_KEY_DEV_TYPE,
340       std::to_string(bluetooth::hci::DeviceType::BR_EDR));
341   config.SetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LINK_KEY, "AABBAABBCCDDEE");
342   config.SetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LE_KEY_PENC, "AABBAABBCCDDEE");
343 
344   // act
345   auto hadInconsistencies = config.FixDeviceTypeInconsistencies();
346 
347   // assert
348   ASSERT_TRUE(hadInconsistencies);
349   ASSERT_THAT(
350       config.GetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_DEV_TYPE),
351       Optional(StrEq(std::to_string(bluetooth::hci::DeviceType::DUAL))));
352 }
353 
TEST(ConfigCacheTest,fix_device_type_inconsistency_devtype_should_be_le_not_classic_test)354 TEST(ConfigCacheTest, fix_device_type_inconsistency_devtype_should_be_le_not_classic_test) {
355   // arrange
356   ConfigCache config(100, Device::kLinkKeyProperties);
357   config.SetProperty("A", "B", "C");
358   config.SetProperty("AA:BB:CC:DD:EE:FF", "B", "C");
359   config.SetProperty("AA:BB:CC:DD:EE:FF", "C", "D");
360   config.SetProperty(
361       "AA:BB:CC:DD:EE:FF",
362       BTIF_STORAGE_KEY_DEV_TYPE,
363       std::to_string(bluetooth::hci::DeviceType::BR_EDR));
364 
365   config.SetProperty("CC:DD:EE:FF:00:11", "B", "AABBAABBCCDDEE");
366   config.SetProperty(
367       "CC:DD:EE:FF:00:11",
368       BTIF_STORAGE_KEY_DEV_TYPE,
369       std::to_string(bluetooth::hci::DeviceType::BR_EDR));
370   config.SetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LE_KEY_PENC, "AABBAABBCCDDEE");
371 
372   // act
373   auto hadInconsistencies = config.FixDeviceTypeInconsistencies();
374 
375   // assert
376   ASSERT_TRUE(hadInconsistencies);
377   ASSERT_THAT(
378       config.GetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_DEV_TYPE),
379       Optional(StrEq(std::to_string(bluetooth::hci::DeviceType::LE))));
380 }
381 
TEST(ConfigCacheTest,fix_device_type_inconsistency_devtype_dont_override_dual_test)382 TEST(ConfigCacheTest, fix_device_type_inconsistency_devtype_dont_override_dual_test) {
383   // arrange
384   ConfigCache config(100, Device::kLinkKeyProperties);
385   config.SetProperty("A", "B", "C");
386   config.SetProperty("AA:BB:CC:DD:EE:FF", "B", "C");
387   config.SetProperty("AA:BB:CC:DD:EE:FF", "C", "D");
388   config.SetProperty(
389       "AA:BB:CC:DD:EE:FF",
390       BTIF_STORAGE_KEY_DEV_TYPE,
391       std::to_string(bluetooth::hci::DeviceType::BR_EDR));
392 
393   config.SetProperty("CC:DD:EE:FF:00:11", "B", "AABBAABBCCDDEE");
394   config.SetProperty(
395       "CC:DD:EE:FF:00:11",
396       BTIF_STORAGE_KEY_DEV_TYPE,
397       std::to_string(bluetooth::hci::DeviceType::DUAL));
398   config.SetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LINK_KEY, "AABBAABBCCDDEE");
399   config.SetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LE_KEY_PENC, "AABBAABBCCDDEE");
400 
401   // act
402   auto hadInconsistencies = config.FixDeviceTypeInconsistencies();
403 
404   // assert
405   ASSERT_FALSE(hadInconsistencies);
406   ASSERT_THAT(
407       config.GetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_DEV_TYPE),
408       Optional(StrEq(std::to_string(bluetooth::hci::DeviceType::DUAL))));
409 }
410 
TEST(ConfigCacheTest,test_get_section_with_property)411 TEST(ConfigCacheTest, test_get_section_with_property) {
412   ConfigCache config(100, Device::kLinkKeyProperties);
413   config.SetProperty("A", "B", "C");
414   config.SetProperty("AA:BB:CC:DD:EE:FF", "B", "C");
415   config.SetProperty("AA:BB:CC:DD:EE:EF", "C", "D");
416   ASSERT_THAT(
417       config.GetSectionNamesWithProperty("B"),
418       ElementsAre(
419           SectionAndPropertyValue{.section = "A", .property = "C"},
420           SectionAndPropertyValue{.section = "AA:BB:CC:DD:EE:FF", .property = "C"}));
421 }
422 
TEST(ConfigCacheTest,test_get_sections_matching_at_least_one_property)423 TEST(ConfigCacheTest, test_get_sections_matching_at_least_one_property) {
424   ConfigCache config(100, Device::kLinkKeyProperties);
425   config.SetProperty("A", "B", "C");
426   config.SetProperty("AA:BB:CC:DD:EE:FF", "B", "C");
427   config.SetProperty("AA:BB:CC:DD:EE:EF", "C", "D");
428   ASSERT_TRUE(config.HasAtLeastOneMatchingPropertiesInSection("AA:BB:CC:DD:EE:FF", {"B", "C", "D"}));
429   ASSERT_TRUE(config.HasAtLeastOneMatchingPropertiesInSection("A", {"B", "C", "D"}));
430   ASSERT_FALSE(config.HasAtLeastOneMatchingPropertiesInSection("AA:BB:CC:DD:EE:FF", {"BC", "D"}));
431 }
432 
TEST(ConfigCacheTest,test_empty_persistent_properties)433 TEST(ConfigCacheTest, test_empty_persistent_properties) {
434   ConfigCache config(100, {});
435   config.SetProperty("A", "B", "C");
436   config.SetProperty("AA:BB:CC:DD:EE:FF", "B", "C");
437   config.SetProperty("AA:BB:CC:DD:EE:EF", "C", "D");
438   config.SetProperty("AA:BB:CC:DD:EE:EF", BTIF_STORAGE_KEY_LINK_KEY, "D");
439   ASSERT_TRUE(config.HasAtLeastOneMatchingPropertiesInSection("AA:BB:CC:DD:EE:FF", {"B", "C", "D"}));
440   ASSERT_TRUE(config.HasAtLeastOneMatchingPropertiesInSection("A", {"B", "C", "D"}));
441   ASSERT_FALSE(config.HasAtLeastOneMatchingPropertiesInSection("AA:BB:CC:DD:EE:FF", {"BC", "D"}));
442   ASSERT_THAT(config.GetPersistentSections(), ElementsAre());
443 }
444 
TEST(ConfigCacheTest,test_get_section_property_names)445 TEST(ConfigCacheTest, test_get_section_property_names) {
446   ConfigCache config(100, Device::kLinkKeyProperties);
447   config.SetProperty("A", "A", "A");
448   config.SetProperty("AA:BB:CC:DD:EE:FF", "B", "B");
449   config.SetProperty("AA:BB:CC:DD:EE:EF", BTIF_STORAGE_KEY_LINK_KEY, "C");
450 
451   ASSERT_THAT(config.GetPropertyNames("A"), ElementsAre("A"));
452   ASSERT_THAT(config.GetPropertyNames("AA:BB:CC:DD:EE:FF"), ElementsAre("B"));
453   ASSERT_THAT(config.GetPropertyNames("AA:BB:CC:DD:EE:EF"), ElementsAre(BTIF_STORAGE_KEY_LINK_KEY));
454   ASSERT_THAT(config.GetPropertyNames("D"), ElementsAre());
455 }
456 
457 }  // namespace testing
458