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/mutation.h"
18 
19 #include <gmock/gmock.h>
20 #include <gtest/gtest.h>
21 
22 #include "storage/config_cache.h"
23 #include "storage/device.h"
24 
25 namespace testing {
26 
27 using bluetooth::storage::ConfigCache;
28 using bluetooth::storage::Device;
29 using bluetooth::storage::Mutation;
30 using bluetooth::storage::MutationEntry;
31 
TEST(MutationTest,simple_sequence_test)32 TEST(MutationTest, simple_sequence_test) {
33   ConfigCache config(100, Device::kLinkKeyProperties);
34   ConfigCache memory_only_config(100, {});
35   config.SetProperty("A", "B", "C");
36   config.SetProperty("AA:BB:CC:DD:EE:FF", "B", "C");
37   config.SetProperty("AA:BB:CC:DD:EE:FF", "C", "D");
38   config.SetProperty("CC:DD:EE:FF:00:11", "LinkKey", "AABBAABBCCDDEE");
39   Mutation mutation(&config, &memory_only_config);
40   mutation.Add(MutationEntry::Set(MutationEntry::PropertyType::NORMAL, "AA:BB:CC:DD:EE:FF", "LinkKey", "CCDDEEFFGG"));
41   mutation.Add(MutationEntry::Remove(MutationEntry::PropertyType::NORMAL, "AA:BB:CC:DD:EE:FF", "LinkKey"));
42   mutation.Commit();
43   ASSERT_THAT(config.GetPersistentSections(), ElementsAre("CC:DD:EE:FF:00:11"));
44   Mutation mutation2(&config, &memory_only_config);
45   mutation2.Add(MutationEntry::Set(MutationEntry::PropertyType::NORMAL, "AA:BB:CC:DD:EE:FF", "LinkKey", "CCDDEEFFGG"));
46   mutation2.Commit();
47   ASSERT_THAT(config.GetPersistentSections(), ElementsAre("CC:DD:EE:FF:00:11", "AA:BB:CC:DD:EE:FF"));
48 }
49 
TEST(MutationTest,remove_property_and_section)50 TEST(MutationTest, remove_property_and_section) {
51   ConfigCache config(100, Device::kLinkKeyProperties);
52   ConfigCache memory_only_config(100, {});
53   config.SetProperty("A", "B", "C");
54   config.SetProperty("A", "C", "D");
55   config.SetProperty("B", "B", "C");
56   config.SetProperty("B", "C", "D");
57   ASSERT_TRUE(config.HasSection("A"));
58   ASSERT_TRUE(config.HasProperty("A", "B"));
59   ASSERT_TRUE(config.HasProperty("A", "C"));
60   ASSERT_TRUE(config.HasSection("B"));
61   ASSERT_TRUE(config.HasProperty("B", "B"));
62   ASSERT_TRUE(config.HasProperty("B", "C"));
63   {
64     Mutation mutation(&config, &memory_only_config);
65     mutation.Add(MutationEntry::Remove(MutationEntry::PropertyType::NORMAL, "A", "B"));
66     mutation.Commit();
67   }
68   ASSERT_TRUE(config.HasSection("A"));
69   ASSERT_FALSE(config.HasProperty("A", "B"));
70   ASSERT_TRUE(config.HasProperty("A", "C"));
71   ASSERT_TRUE(config.HasSection("B"));
72   ASSERT_TRUE(config.HasProperty("B", "B"));
73   ASSERT_TRUE(config.HasProperty("B", "C"));
74   {
75     Mutation mutation(&config, &memory_only_config);
76     mutation.Add(MutationEntry::Remove(MutationEntry::PropertyType::NORMAL, "B"));
77     mutation.Commit();
78   }
79   ASSERT_TRUE(config.HasSection("A"));
80   ASSERT_FALSE(config.HasProperty("A", "B"));
81   ASSERT_TRUE(config.HasProperty("A", "C"));
82   ASSERT_FALSE(config.HasSection("B"));
83   ASSERT_FALSE(config.HasProperty("B", "B"));
84   ASSERT_FALSE(config.HasProperty("B", "C"));
85   {
86     Mutation mutation(&config, &memory_only_config);
87     mutation.Add(MutationEntry::Remove(MutationEntry::PropertyType::NORMAL, "A", "C"));
88     mutation.Commit();
89   }
90   ASSERT_FALSE(config.HasSection("A"));
91   ASSERT_FALSE(config.HasProperty("A", "B"));
92   ASSERT_FALSE(config.HasProperty("A", "C"));
93   ASSERT_FALSE(config.HasSection("B"));
94   ASSERT_FALSE(config.HasProperty("B", "B"));
95   ASSERT_FALSE(config.HasProperty("B", "C"));
96 }
97 
TEST(MutationTest,add_and_remove_cancel_each_other)98 TEST(MutationTest, add_and_remove_cancel_each_other) {
99   ConfigCache config(100, Device::kLinkKeyProperties);
100   ConfigCache memory_only_config(100, {});
101   ASSERT_FALSE(config.HasSection("A"));
102   Mutation mutation(&config, &memory_only_config);
103   mutation.Add(MutationEntry::Set(MutationEntry::PropertyType::NORMAL, "A", "B", "C"));
104   mutation.Add(MutationEntry::Remove(MutationEntry::PropertyType::NORMAL, "A", "B"));
105   mutation.Commit();
106   ASSERT_FALSE(config.HasSection("A"));
107 }
108 
TEST(MutationTest,add_to_different_configs)109 TEST(MutationTest, add_to_different_configs) {
110   ConfigCache config(100, Device::kLinkKeyProperties);
111   ConfigCache memory_only_config(100, {});
112   ASSERT_FALSE(config.HasSection("A"));
113   Mutation mutation(&config, &memory_only_config);
114   mutation.Add(MutationEntry::Set(MutationEntry::PropertyType::NORMAL, "A", "B", "C"));
115   mutation.Add(MutationEntry::Set(MutationEntry::PropertyType::MEMORY_ONLY, "A", "D", "Hello"));
116   mutation.Commit();
117   ASSERT_TRUE(config.HasProperty("A", "B"));
118   ASSERT_FALSE(config.HasProperty("A", "D"));
119   ASSERT_THAT(config.GetProperty("A", "B"), Optional(StrEq("C")));
120   ASSERT_FALSE(memory_only_config.HasProperty("A", "B"));
121   ASSERT_TRUE(memory_only_config.HasProperty("A", "D"));
122   ASSERT_THAT(memory_only_config.GetProperty("A", "D"), Optional(StrEq("Hello")));
123 }
124 
125 }  // namespace testing