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
29using std::string;
30using std::unique_ptr;
31using testing::_;
32using testing::DoAll;
33using testing::Mock;
34using testing::Return;
35using testing::SetArgumentPointee;
36using testing::Test;
37
38namespace shill {
39
40namespace {
41const char kVendorClass[] = "Chromebook";
42const char kHostname[] = "TestHost";
43const char kStorageID[] = "dhcp_service_id";
44const char kOverrideValue[] = "override";
45}
46
47class DhcpPropertiesTest : public Test {
48 public:
49  DhcpPropertiesTest() { }
50
51  virtual ~DhcpPropertiesTest() { }
52
53 protected:
54  DhcpProperties dhcp_properties_;
55};
56
57TEST_F(DhcpPropertiesTest, Ctor) {
58  EXPECT_TRUE(dhcp_properties_.properties_.IsEmpty());
59}
60
61TEST_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
86TEST_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
96TEST_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
105TEST_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
115TEST_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
126TEST_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
136TEST_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
147TEST_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
157TEST_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
167TEST_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
181TEST_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
195TEST_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
209TEST_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
223TEST_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
233TEST_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
243TEST_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
255TEST_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