1 //
2 // Copyright (C) 2015 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 "shill/dhcp_properties.h"
18 
19 #if defined(__ANDROID__)
20 #include <dbus/service_constants.h>
21 #else
22 #include <chromeos/dbus/service_constants.h>
23 #endif  // __ANDROID__
24 #include <gtest/gtest.h>
25 
26 #include "shill/mock_property_store.h"
27 #include "shill/mock_store.h"
28 
29 using std::string;
30 using std::unique_ptr;
31 using testing::_;
32 using testing::DoAll;
33 using testing::Mock;
34 using testing::Return;
35 using testing::SetArgumentPointee;
36 using testing::Test;
37 
38 namespace shill {
39 
40 namespace {
41 const char kVendorClass[] = "Chromebook";
42 const char kHostname[] = "TestHost";
43 const char kStorageID[] = "dhcp_service_id";
44 const char kOverrideValue[] = "override";
45 }
46 
47 class DhcpPropertiesTest : public Test {
48  public:
DhcpPropertiesTest()49   DhcpPropertiesTest() { }
50 
~DhcpPropertiesTest()51   virtual ~DhcpPropertiesTest() { }
52 
53  protected:
54   DhcpProperties dhcp_properties_;
55 };
56 
TEST_F(DhcpPropertiesTest,Ctor)57 TEST_F(DhcpPropertiesTest, Ctor) {
58   EXPECT_TRUE(dhcp_properties_.properties_.IsEmpty());
59 }
60 
TEST_F(DhcpPropertiesTest,InitPropertyStore)61 TEST_F(DhcpPropertiesTest, InitPropertyStore) {
62   PropertyStore store;
63   dhcp_properties_.InitPropertyStore(&store);
64 
65   Error error;
66   string value_in_prop_store;
67   // DHCPProperty.Hostname is a valid option.
68   EXPECT_FALSE(store.GetStringProperty("DHCPProperty.Hostname",
69                                        &value_in_prop_store,
70                                        &error));
71   EXPECT_EQ(Error::kNotFound, error.type());
72 
73   // DHCPProperty.VendorClass is a valid option.
74   EXPECT_FALSE(store.GetStringProperty("DHCPProperty.VendorClass",
75                                        &value_in_prop_store,
76                                        &error));
77   EXPECT_EQ(Error::kNotFound, error.type());
78 
79   // DhcpProperty.NotAProp is not a valid option.
80   EXPECT_FALSE(store.GetStringProperty("DHCPProperty.NotAProp",
81                                        &value_in_prop_store,
82                                        &error));
83   EXPECT_EQ(Error::kInvalidProperty, error.type());
84 }
85 
TEST_F(DhcpPropertiesTest,SetMappedStringPropertyOverrideExisting)86 TEST_F(DhcpPropertiesTest, SetMappedStringPropertyOverrideExisting) {
87   PropertyStore store;
88   dhcp_properties_.InitPropertyStore(&store);
89   dhcp_properties_.properties_.SetString("Hostname", kHostname);
90 
91   Error error;
92   EXPECT_TRUE(store.SetStringProperty("DHCPProperty.Hostname", kOverrideValue, &error));
93   EXPECT_EQ(kOverrideValue, dhcp_properties_.properties_.GetString("Hostname"));
94 }
95 
TEST_F(DhcpPropertiesTest,SetMappedStringPropertyNoExistingValue)96 TEST_F(DhcpPropertiesTest, SetMappedStringPropertyNoExistingValue) {
97   PropertyStore store;
98   dhcp_properties_.InitPropertyStore(&store);
99 
100   Error error;
101   EXPECT_TRUE(store.SetStringProperty("DHCPProperty.Hostname", kHostname, &error));
102   EXPECT_EQ(kHostname, dhcp_properties_.properties_.GetString("Hostname"));
103 }
104 
TEST_F(DhcpPropertiesTest,SetMappedStringPropertySameAsExistingValue)105 TEST_F(DhcpPropertiesTest, SetMappedStringPropertySameAsExistingValue) {
106   PropertyStore store;
107   dhcp_properties_.InitPropertyStore(&store);
108   dhcp_properties_.properties_.SetString("Hostname", kHostname);
109 
110   Error error;
111   EXPECT_FALSE(store.SetStringProperty("DHCPProperty.Hostname", kHostname, &error));
112   EXPECT_EQ(kHostname, dhcp_properties_.properties_.GetString("Hostname"));
113 }
114 
TEST_F(DhcpPropertiesTest,GetMappedStringPropertyWithSetValue)115 TEST_F(DhcpPropertiesTest, GetMappedStringPropertyWithSetValue) {
116   PropertyStore store;
117   dhcp_properties_.InitPropertyStore(&store);
118   dhcp_properties_.properties_.SetString("Hostname", kHostname);
119 
120   Error error;
121   string value_in_prop_store;
122   store.GetStringProperty("DHCPProperty.Hostname", &value_in_prop_store, &error);
123   EXPECT_EQ(kHostname, value_in_prop_store);
124 }
125 
TEST_F(DhcpPropertiesTest,GetMappedStringPropertyNoExistingValue)126 TEST_F(DhcpPropertiesTest, GetMappedStringPropertyNoExistingValue) {
127   PropertyStore store;
128   dhcp_properties_.InitPropertyStore(&store);
129 
130   Error error;
131   string value_in_prop_store;
132   store.GetStringProperty("DHCPProperty.Hostname", &value_in_prop_store, &error);
133   EXPECT_EQ(Error::kNotFound, error.type());
134 }
135 
TEST_F(DhcpPropertiesTest,ClearMappedStringPropertyWithSetValue)136 TEST_F(DhcpPropertiesTest, ClearMappedStringPropertyWithSetValue) {
137   PropertyStore store;
138   dhcp_properties_.InitPropertyStore(&store);
139   dhcp_properties_.properties_.SetString("Hostname", kHostname);
140 
141   Error error;
142   string value_in_prop_store;
143   store.ClearProperty("DHCPProperty.Hostname", &error);
144   EXPECT_FALSE(dhcp_properties_.properties_.ContainsString("Hostname"));
145 }
146 
TEST_F(DhcpPropertiesTest,ClearMappedStringPropertyNoExistingValue)147 TEST_F(DhcpPropertiesTest, ClearMappedStringPropertyNoExistingValue) {
148   PropertyStore store;
149   dhcp_properties_.InitPropertyStore(&store);
150 
151   Error error;
152   string value_in_prop_store;
153   store.ClearProperty("DHCPProperty.Hostname", &error);
154   EXPECT_EQ(Error::kNotFound, error.type());
155 }
156 
TEST_F(DhcpPropertiesTest,LoadEmpty)157 TEST_F(DhcpPropertiesTest, LoadEmpty) {
158   MockStore storage;
159   EXPECT_CALL(storage, GetString(kStorageID, "DHCPProperty.VendorClass", _))
160       .WillOnce(Return(false));
161   EXPECT_CALL(storage, GetString(kStorageID, "DHCPProperty.Hostname", _))
162       .WillOnce(Return(false));
163   dhcp_properties_.Load(&storage, kStorageID);
164   EXPECT_TRUE(dhcp_properties_.properties_.IsEmpty());
165 }
166 
TEST_F(DhcpPropertiesTest,Load)167 TEST_F(DhcpPropertiesTest, Load) {
168   MockStore storage;
169   EXPECT_CALL(storage, GetString(kStorageID, "DHCPProperty.VendorClass", _))
170       .WillOnce(DoAll(SetArgumentPointee<2>(string(kVendorClass)),
171                       Return(true)));
172   EXPECT_CALL(storage, GetString(kStorageID, "DHCPProperty.Hostname", _))
173       .WillOnce(DoAll(SetArgumentPointee<2>(string(kHostname)),
174                       Return(true)));
175   dhcp_properties_.Load(&storage, kStorageID);
176   EXPECT_EQ(kVendorClass,
177             dhcp_properties_.properties_.GetString("VendorClass"));
178   EXPECT_EQ(kHostname, dhcp_properties_.properties_.GetString("Hostname"));
179 }
180 
TEST_F(DhcpPropertiesTest,LoadWithValuesSetAndClearRequired)181 TEST_F(DhcpPropertiesTest, LoadWithValuesSetAndClearRequired) {
182   MockStore storage;
183   dhcp_properties_.properties_.SetString("Hostname", kHostname);
184 
185   EXPECT_CALL(storage, GetString(kStorageID, "DHCPProperty.VendorClass", _))
186       .WillOnce(DoAll(SetArgumentPointee<2>(string(kVendorClass)),
187                       Return(true)));
188   EXPECT_CALL(storage, GetString(kStorageID, "DHCPProperty.Hostname", _))
189       .WillOnce(Return(false));
190   dhcp_properties_.Load(&storage, kStorageID);
191   EXPECT_EQ(kVendorClass, dhcp_properties_.properties_.GetString("VendorClass"));
192   EXPECT_FALSE(dhcp_properties_.properties_.Contains("Hostname"));
193 }
194 
TEST_F(DhcpPropertiesTest,SaveWithValuesSet)195 TEST_F(DhcpPropertiesTest, SaveWithValuesSet) {
196   MockStore storage;
197   dhcp_properties_.properties_.SetString("VendorClass", kVendorClass);
198   dhcp_properties_.properties_.SetString("Hostname", "");
199 
200   EXPECT_CALL(storage,
201               SetString(kStorageID, "DHCPProperty.VendorClass", kVendorClass))
202       .WillOnce(Return(true));
203   EXPECT_CALL(storage,
204               SetString(kStorageID, "DHCPProperty.Hostname", ""))
205       .WillOnce(Return(true));
206   dhcp_properties_.Save(&storage, kStorageID);
207 }
208 
TEST_F(DhcpPropertiesTest,SavePropertyNotSetShouldBeDeleted)209 TEST_F(DhcpPropertiesTest, SavePropertyNotSetShouldBeDeleted) {
210   MockStore storage;
211   dhcp_properties_.properties_.SetString("VendorClass", kVendorClass);
212 
213   EXPECT_CALL(storage, SetString(_, _, _)).Times(0);
214   EXPECT_CALL(storage,
215               SetString(kStorageID, "DHCPProperty.VendorClass", kVendorClass))
216       .WillOnce(Return(true));
217   EXPECT_CALL(storage,
218               DeleteKey(kStorageID, "DHCPProperty.Hostname"))
219       .WillOnce(Return(true));
220   dhcp_properties_.Save(&storage, kStorageID);
221 }
222 
TEST_F(DhcpPropertiesTest,CombineIntoEmpty)223 TEST_F(DhcpPropertiesTest, CombineIntoEmpty) {
224   DhcpProperties to_merge;
225   to_merge.properties_.SetString("VendorClass", kVendorClass);
226   to_merge.properties_.SetString("Hostname", kHostname);
227 
228   unique_ptr<DhcpProperties> merged_props =
229       DhcpProperties::Combine(dhcp_properties_, to_merge);
230   EXPECT_EQ(merged_props->properties_, to_merge.properties_);
231 }
232 
TEST_F(DhcpPropertiesTest,CombineEmptyIntoExisting)233 TEST_F(DhcpPropertiesTest, CombineEmptyIntoExisting) {
234   DhcpProperties to_merge;
235   dhcp_properties_.properties_.SetString("VendorClass", kVendorClass);
236   dhcp_properties_.properties_.SetString("Hostname", kHostname);
237 
238   unique_ptr<DhcpProperties> merged_props =
239       DhcpProperties::Combine(dhcp_properties_, to_merge);
240   EXPECT_EQ(merged_props->properties_, dhcp_properties_.properties_);
241 }
242 
TEST_F(DhcpPropertiesTest,CombineConflicting)243 TEST_F(DhcpPropertiesTest, CombineConflicting) {
244   DhcpProperties to_merge;
245   to_merge.properties_.SetString("VendorClass", kOverrideValue);
246   to_merge.properties_.SetString("Hostname", kHostname);
247   dhcp_properties_.properties_.SetString("VendorClass", kVendorClass);
248 
249   unique_ptr<DhcpProperties> merged_props =
250       DhcpProperties::Combine(dhcp_properties_, to_merge);
251   EXPECT_EQ(kOverrideValue, merged_props->properties_.GetString("VendorClass"));
252   EXPECT_EQ(kHostname, merged_props->properties_.GetString("Hostname"));
253 }
254 
TEST_F(DhcpPropertiesTest,GetValueForProperty)255 TEST_F(DhcpPropertiesTest, GetValueForProperty) {
256   string value;
257   EXPECT_FALSE(dhcp_properties_.GetValueForProperty("VendorClass", &value));
258   EXPECT_FALSE(dhcp_properties_.GetValueForProperty("Hostname", &value));
259 
260   dhcp_properties_.properties_.SetString("VendorClass", kVendorClass);
261   EXPECT_TRUE(dhcp_properties_.GetValueForProperty("VendorClass", &value));
262   EXPECT_EQ(kVendorClass, value);
263   EXPECT_FALSE(dhcp_properties_.GetValueForProperty("Hostname", &value));
264 
265   dhcp_properties_.properties_.SetString("Hostname", kHostname);
266   EXPECT_TRUE(dhcp_properties_.GetValueForProperty("VendorClass", &value));
267   EXPECT_EQ(kVendorClass, value);
268   EXPECT_TRUE(dhcp_properties_.GetValueForProperty("Hostname", &value));
269   EXPECT_EQ(kHostname, value);
270 }
271 
272 } // namespace shill
273