blob: 0c86f0378c44c625cc8950d29c1e6d658b92360c [file] [log] [blame]
Jay Srinivasan43488792012-06-19 00:25:31 -07001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <base/logging.h>
6#include <chromeos/dbus/service_constants.h>
7#include <gtest/gtest.h>
8#include <string>
9
10#include "update_engine/connection_manager.h"
11#include "update_engine/mock_dbus_interface.h"
12#include "update_engine/mock_system_state.h"
13
14using std::set;
15using std::string;
16using testing::_;
17using testing::AnyNumber;
18using testing::Return;
19using testing::SetArgumentPointee;
20using testing::StrEq;
21
22namespace chromeos_update_engine {
23
24class ConnectionManagerTest : public ::testing::Test {
25 public:
26 ConnectionManagerTest()
27 : kMockFlimFlamManagerProxy_(NULL),
28 kMockFlimFlamServiceProxy_(NULL),
29 kServicePath_(NULL),
30 cmut_(&mock_system_state_) {
Jay Srinivasan6f6ea002012-12-14 11:26:28 -080031 mock_system_state_.set_connection_manager(&cmut_);
Jay Srinivasan43488792012-06-19 00:25:31 -070032 }
33
34 protected:
35 void SetupMocks(const char* service_path);
36 void SetManagerReply(gconstpointer value, const GType& type);
Alex Deymo1c4e6382013-07-15 12:09:51 -070037
38 // Sets the |service_type| Type and the |physical_technology|
39 // PhysicalTechnology properties in the mocked service. If a NULL
40 // |physical_technology| is passed, the property is not set (not present).
41 void SetServiceReply(const char* service_type,
42 const char* physical_technology);
Jay Srinivasan43488792012-06-19 00:25:31 -070043 void TestWithServiceType(
Alex Deymo1c4e6382013-07-15 12:09:51 -070044 const char* service_type,
45 const char* physical_technology,
46 NetworkConnectionType expected_type);
Jay Srinivasan43488792012-06-19 00:25:31 -070047
48 static const char* kGetPropertiesMethod;
49 DBusGProxy* kMockFlimFlamManagerProxy_;
50 DBusGProxy* kMockFlimFlamServiceProxy_;
51 DBusGConnection* kMockSystemBus_;
52 const char* kServicePath_;
53 MockDbusGlib dbus_iface_;
54 ConnectionManager cmut_; // ConnectionManager under test.
55 MockSystemState mock_system_state_;
56};
57
58// static
59const char* ConnectionManagerTest::kGetPropertiesMethod = "GetProperties";
60
61void ConnectionManagerTest::SetupMocks(const char* service_path) {
62 int number = 1;
63 kMockSystemBus_ = reinterpret_cast<DBusGConnection*>(number++);
64 kMockFlimFlamManagerProxy_ = reinterpret_cast<DBusGProxy*>(number++);
65 kMockFlimFlamServiceProxy_ = reinterpret_cast<DBusGProxy*>(number++);
66 ASSERT_NE(kMockSystemBus_, reinterpret_cast<DBusGConnection*>(NULL));
67
68 kServicePath_ = service_path;
69
70 ON_CALL(dbus_iface_, BusGet(DBUS_BUS_SYSTEM, _))
71 .WillByDefault(Return(kMockSystemBus_));
72 EXPECT_CALL(dbus_iface_, BusGet(DBUS_BUS_SYSTEM, _))
73 .Times(AnyNumber());
74}
75
76void ConnectionManagerTest::SetManagerReply(gconstpointer reply_value,
77 const GType& reply_type) {
78 // Initialize return value for D-Bus call to Manager object.
79 // TODO (jaysri): Free the objects allocated here.
80 GHashTable* manager_hash_table = g_hash_table_new(g_str_hash, g_str_equal);
81
82 GArray* array = g_array_new(FALSE, FALSE, sizeof(const char*));
83 ASSERT_TRUE(array != NULL);
84
85 EXPECT_EQ(array, g_array_append_val(array, reply_value));
86 GValue* array_as_value = g_new0(GValue, 1);
87 EXPECT_EQ(array_as_value, g_value_init(array_as_value, reply_type));
88 g_value_take_boxed(array_as_value, array);
89 g_hash_table_insert(manager_hash_table,
90 const_cast<char*>("Services"),
91 array_as_value);
92
93 // Plumb return value into mock object.
94 EXPECT_CALL(dbus_iface_, ProxyCall(kMockFlimFlamManagerProxy_,
95 StrEq(kGetPropertiesMethod),
96 _,
97 G_TYPE_INVALID,
98 dbus_g_type_get_map("GHashTable",
99 G_TYPE_STRING,
100 G_TYPE_VALUE),
101 _,
102 G_TYPE_INVALID))
103 .WillOnce(DoAll(SetArgumentPointee<5>(manager_hash_table), Return(TRUE)));
104
105 // Set other expectations.
106 EXPECT_CALL(dbus_iface_,
107 ProxyNewForNameOwner(kMockSystemBus_,
108 StrEq(flimflam::kFlimflamServiceName),
109 StrEq(flimflam::kFlimflamServicePath),
110 StrEq(flimflam::kFlimflamManagerInterface),
111 _))
112 .WillOnce(Return(kMockFlimFlamManagerProxy_));
113 EXPECT_CALL(dbus_iface_, ProxyUnref(kMockFlimFlamManagerProxy_));
114 EXPECT_CALL(dbus_iface_, BusGet(DBUS_BUS_SYSTEM, _))
115 .RetiresOnSaturation();
116}
117
Alex Deymo1c4e6382013-07-15 12:09:51 -0700118void ConnectionManagerTest::SetServiceReply(const char* service_type,
119 const char* physical_technology) {
Jay Srinivasan43488792012-06-19 00:25:31 -0700120 // Initialize return value for D-Bus call to Service object.
121 // TODO (jaysri): Free the objects allocated here.
122 GHashTable* service_hash_table = g_hash_table_new(g_str_hash, g_str_equal);
123
124 GValue* service_type_value = g_new0(GValue, 1);
125 EXPECT_EQ(service_type_value,
126 g_value_init(service_type_value, G_TYPE_STRING));
127 g_value_set_static_string(service_type_value, service_type);
128
129 g_hash_table_insert(service_hash_table,
130 const_cast<char*>("Type"),
131 service_type_value);
132
Alex Deymo1c4e6382013-07-15 12:09:51 -0700133 if (physical_technology != NULL) {
134 GValue* physical_technology_value = g_new0(GValue, 1);
135 EXPECT_EQ(physical_technology_value,
136 g_value_init(physical_technology_value, G_TYPE_STRING));
137 g_value_set_static_string(physical_technology_value, physical_technology);
138
139 g_hash_table_insert(service_hash_table,
140 const_cast<char*>("PhysicalTechnology"),
141 physical_technology_value);
142 }
143
Jay Srinivasan43488792012-06-19 00:25:31 -0700144 // Plumb return value into mock object.
145 EXPECT_CALL(dbus_iface_, ProxyCall(kMockFlimFlamServiceProxy_,
146 StrEq(kGetPropertiesMethod),
147 _,
148 G_TYPE_INVALID,
149 dbus_g_type_get_map("GHashTable",
150 G_TYPE_STRING,
151 G_TYPE_VALUE),
152 _,
153 G_TYPE_INVALID))
154 .WillOnce(DoAll(SetArgumentPointee<5>(service_hash_table), Return(TRUE)));
155
156 // Set other expectations.
157 EXPECT_CALL(dbus_iface_,
158 ProxyNewForNameOwner(kMockSystemBus_,
159 StrEq(flimflam::kFlimflamServiceName),
160 StrEq(kServicePath_),
161 StrEq(flimflam::kFlimflamServiceInterface),
162 _))
163 .WillOnce(Return(kMockFlimFlamServiceProxy_));
164 EXPECT_CALL(dbus_iface_, ProxyUnref(kMockFlimFlamServiceProxy_));
165 EXPECT_CALL(dbus_iface_, BusGet(DBUS_BUS_SYSTEM, _))
166 .RetiresOnSaturation();
167}
168
169void ConnectionManagerTest::TestWithServiceType(
170 const char* service_type,
Alex Deymo1c4e6382013-07-15 12:09:51 -0700171 const char* physical_technology,
Jay Srinivasan43488792012-06-19 00:25:31 -0700172 NetworkConnectionType expected_type) {
173
174 SetupMocks("/service/guest-network");
175 SetManagerReply(kServicePath_, DBUS_TYPE_G_OBJECT_PATH_ARRAY);
Alex Deymo1c4e6382013-07-15 12:09:51 -0700176 SetServiceReply(service_type, physical_technology);
Jay Srinivasan43488792012-06-19 00:25:31 -0700177
178 NetworkConnectionType type;
179 EXPECT_TRUE(cmut_.GetConnectionType(&dbus_iface_, &type));
180 EXPECT_EQ(expected_type, type);
181}
182
183TEST_F(ConnectionManagerTest, SimpleTest) {
Alex Deymo1c4e6382013-07-15 12:09:51 -0700184 TestWithServiceType(flimflam::kTypeEthernet, NULL, kNetEthernet);
185 TestWithServiceType(flimflam::kTypeWifi, NULL, kNetWifi);
186 TestWithServiceType(flimflam::kTypeWimax, NULL, kNetWimax);
187 TestWithServiceType(flimflam::kTypeBluetooth, NULL, kNetBluetooth);
188 TestWithServiceType(flimflam::kTypeCellular, NULL, kNetCellular);
189}
190
191TEST_F(ConnectionManagerTest, PhysicalTechnologyTest) {
192 TestWithServiceType(flimflam::kTypeVPN, NULL, kNetUnknown);
193 TestWithServiceType(flimflam::kTypeVPN, flimflam::kTypeVPN, kNetUnknown);
194 TestWithServiceType(flimflam::kTypeVPN, flimflam::kTypeWifi, kNetWifi);
195 TestWithServiceType(flimflam::kTypeVPN, flimflam::kTypeWimax, kNetWimax);
Jay Srinivasan43488792012-06-19 00:25:31 -0700196}
197
198TEST_F(ConnectionManagerTest, UnknownTest) {
Alex Deymo1c4e6382013-07-15 12:09:51 -0700199 TestWithServiceType("foo", NULL, kNetUnknown);
Jay Srinivasan43488792012-06-19 00:25:31 -0700200}
201
202TEST_F(ConnectionManagerTest, AllowUpdatesOverEthernetTest) {
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800203 EXPECT_CALL(mock_system_state_, device_policy()).Times(0);
Jay Srinivasan43488792012-06-19 00:25:31 -0700204
205 // Updates over Ethernet are allowed even if there's no policy.
206 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetEthernet));
207}
208
209TEST_F(ConnectionManagerTest, AllowUpdatesOverWifiTest) {
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800210 EXPECT_CALL(mock_system_state_, device_policy()).Times(0);
Jay Srinivasan43488792012-06-19 00:25:31 -0700211 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetWifi));
212}
213
214TEST_F(ConnectionManagerTest, AllowUpdatesOverWimaxTest) {
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800215 EXPECT_CALL(mock_system_state_, device_policy()).Times(0);
Jay Srinivasan43488792012-06-19 00:25:31 -0700216 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetWimax));
217}
218
219TEST_F(ConnectionManagerTest, BlockUpdatesOverBluetoothTest) {
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800220 EXPECT_CALL(mock_system_state_, device_policy()).Times(0);
Jay Srinivasan43488792012-06-19 00:25:31 -0700221 EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetBluetooth));
222}
223
224TEST_F(ConnectionManagerTest, AllowUpdatesOnlyOver3GPerPolicyTest) {
225 policy::MockDevicePolicy allow_3g_policy;
226
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800227 EXPECT_CALL(mock_system_state_, device_policy())
Jay Srinivasan43488792012-06-19 00:25:31 -0700228 .Times(1)
229 .WillOnce(Return(&allow_3g_policy));
230
Alex Deymof4867c42013-06-28 14:41:39 -0700231 // This test tests cellular (3G) being the only connection type being allowed.
Jay Srinivasan43488792012-06-19 00:25:31 -0700232 set<string> allowed_set;
233 allowed_set.insert(cmut_.StringForConnectionType(kNetCellular));
234
235 EXPECT_CALL(allow_3g_policy, GetAllowedConnectionTypesForUpdate(_))
236 .Times(1)
237 .WillOnce(DoAll(SetArgumentPointee<0>(allowed_set), Return(true)));
238
239 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetCellular));
240}
241
242TEST_F(ConnectionManagerTest, AllowUpdatesOver3GAndOtherTypesPerPolicyTest) {
243 policy::MockDevicePolicy allow_3g_policy;
244
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800245 EXPECT_CALL(mock_system_state_, device_policy())
Jay Srinivasan43488792012-06-19 00:25:31 -0700246 .Times(1)
247 .WillOnce(Return(&allow_3g_policy));
248
249 // This test tests multiple connection types being allowed, with
Alex Deymof4867c42013-06-28 14:41:39 -0700250 // 3G one among them. Only Cellular is currently enforced by the policy
251 // setting, the others are ignored (see Bluetooth for example).
Jay Srinivasan43488792012-06-19 00:25:31 -0700252 set<string> allowed_set;
Jay Srinivasan43488792012-06-19 00:25:31 -0700253 allowed_set.insert(cmut_.StringForConnectionType(kNetCellular));
Alex Deymof4867c42013-06-28 14:41:39 -0700254 allowed_set.insert(cmut_.StringForConnectionType(kNetBluetooth));
Jay Srinivasan43488792012-06-19 00:25:31 -0700255
256 EXPECT_CALL(allow_3g_policy, GetAllowedConnectionTypesForUpdate(_))
257 .Times(1)
258 .WillOnce(DoAll(SetArgumentPointee<0>(allowed_set), Return(true)));
259
Alex Deymof4867c42013-06-28 14:41:39 -0700260 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetEthernet));
Jay Srinivasan43488792012-06-19 00:25:31 -0700261 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetCellular));
Alex Deymof4867c42013-06-28 14:41:39 -0700262 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetWifi));
263 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetWimax));
264 EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetBluetooth));
Jay Srinivasan43488792012-06-19 00:25:31 -0700265}
266
Alex Deymof4867c42013-06-28 14:41:39 -0700267TEST_F(ConnectionManagerTest, BlockUpdatesOverCellularByDefaultTest) {
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800268 EXPECT_CALL(mock_system_state_, device_policy()).Times(1);
Jay Srinivasan43488792012-06-19 00:25:31 -0700269 EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetCellular));
270}
271
272TEST_F(ConnectionManagerTest, BlockUpdatesOver3GPerPolicyTest) {
273 policy::MockDevicePolicy block_3g_policy;
274
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800275 EXPECT_CALL(mock_system_state_, device_policy())
Jay Srinivasan43488792012-06-19 00:25:31 -0700276 .Times(1)
277 .WillOnce(Return(&block_3g_policy));
278
279 // Test that updates for 3G are blocked while updates are allowed
280 // over several other types.
281 set<string> allowed_set;
282 allowed_set.insert(cmut_.StringForConnectionType(kNetEthernet));
283 allowed_set.insert(cmut_.StringForConnectionType(kNetWifi));
284 allowed_set.insert(cmut_.StringForConnectionType(kNetWimax));
285
286 EXPECT_CALL(block_3g_policy, GetAllowedConnectionTypesForUpdate(_))
287 .Times(1)
288 .WillOnce(DoAll(SetArgumentPointee<0>(allowed_set), Return(true)));
289
290 EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetCellular));
291}
292
293TEST_F(ConnectionManagerTest, BlockUpdatesOver3GIfErrorInPolicyFetchTest) {
294 policy::MockDevicePolicy allow_3g_policy;
295
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800296 EXPECT_CALL(mock_system_state_, device_policy())
Jay Srinivasan43488792012-06-19 00:25:31 -0700297 .Times(1)
298 .WillOnce(Return(&allow_3g_policy));
299
300 set<string> allowed_set;
301 allowed_set.insert(cmut_.StringForConnectionType(kNetCellular));
302
303 // Return false for GetAllowedConnectionTypesForUpdate and see
304 // that updates are still blocked for 3G despite the value being in
305 // the string set above.
306 EXPECT_CALL(allow_3g_policy, GetAllowedConnectionTypesForUpdate(_))
307 .Times(1)
308 .WillOnce(DoAll(SetArgumentPointee<0>(allowed_set), Return(false)));
309
310 EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetCellular));
311}
312
Alex Deymof4867c42013-06-28 14:41:39 -0700313TEST_F(ConnectionManagerTest, UseUserPrefForUpdatesOverCellularIfNoPolicyTest) {
314 policy::MockDevicePolicy no_policy;
315 testing::NiceMock<PrefsMock>* prefs = mock_system_state_.mock_prefs();
316
317 EXPECT_CALL(mock_system_state_, device_policy())
318 .Times(3)
319 .WillRepeatedly(Return(&no_policy));
320
321 // No setting enforced by the device policy, user prefs should be used.
322 EXPECT_CALL(no_policy, GetAllowedConnectionTypesForUpdate(_))
323 .Times(3)
324 .WillRepeatedly(Return(false));
325
326 // No user pref: block.
327 EXPECT_CALL(*prefs, Exists(kPrefsUpdateOverCellularPermission))
328 .Times(1)
329 .WillOnce(Return(false));
330 EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetCellular));
331
332 // Allow per user pref.
333 EXPECT_CALL(*prefs, Exists(kPrefsUpdateOverCellularPermission))
334 .Times(1)
335 .WillOnce(Return(true));
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700336 EXPECT_CALL(*prefs, GetBoolean(kPrefsUpdateOverCellularPermission, _))
Alex Deymof4867c42013-06-28 14:41:39 -0700337 .Times(1)
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700338 .WillOnce(DoAll(SetArgumentPointee<1>(true), Return(true)));
Alex Deymof4867c42013-06-28 14:41:39 -0700339 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetCellular));
340
341 // Block per user pref.
342 EXPECT_CALL(*prefs, Exists(kPrefsUpdateOverCellularPermission))
343 .Times(1)
344 .WillOnce(Return(true));
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700345 EXPECT_CALL(*prefs, GetBoolean(kPrefsUpdateOverCellularPermission, _))
Alex Deymof4867c42013-06-28 14:41:39 -0700346 .Times(1)
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700347 .WillOnce(DoAll(SetArgumentPointee<1>(false), Return(true)));
Alex Deymof4867c42013-06-28 14:41:39 -0700348 EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetCellular));
349}
350
Jay Srinivasan43488792012-06-19 00:25:31 -0700351TEST_F(ConnectionManagerTest, StringForConnectionTypeTest) {
352 EXPECT_STREQ(flimflam::kTypeEthernet,
353 cmut_.StringForConnectionType(kNetEthernet));
354 EXPECT_STREQ(flimflam::kTypeWifi,
355 cmut_.StringForConnectionType(kNetWifi));
356 EXPECT_STREQ(flimflam::kTypeWimax,
357 cmut_.StringForConnectionType(kNetWimax));
358 EXPECT_STREQ(flimflam::kTypeBluetooth,
359 cmut_.StringForConnectionType(kNetBluetooth));
360 EXPECT_STREQ(flimflam::kTypeCellular,
361 cmut_.StringForConnectionType(kNetCellular));
362 EXPECT_STREQ("Unknown",
363 cmut_.StringForConnectionType(kNetUnknown));
364 EXPECT_STREQ("Unknown",
365 cmut_.StringForConnectionType(
366 static_cast<NetworkConnectionType>(999999)));
367}
368
369TEST_F(ConnectionManagerTest, MalformedServiceList) {
370 SetupMocks("/service/guest-network");
371 string service_name(kServicePath_);
372 SetManagerReply(&service_name, DBUS_TYPE_G_STRING_ARRAY);
373
374 NetworkConnectionType type;
375 EXPECT_FALSE(cmut_.GetConnectionType(&dbus_iface_, &type));
376}
377
378} // namespace chromeos_update_engine