blob: 3c89cb6387d656ea16820c2111cd8e572dd1213d [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"
Gilad Arnold1b9d6ae2014-03-03 13:46:07 -080011#include "update_engine/mock_dbus_wrapper.h"
Jay Srinivasan43488792012-06-19 00:25:31 -070012#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_;
Gilad Arnold1b9d6ae2014-03-03 13:46:07 -080053 MockDBusWrapper dbus_iface_;
Jay Srinivasan43488792012-06-19 00:25:31 -070054 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.
Gilad Arnoldb752fb32014-03-03 12:23:39 -080094 EXPECT_CALL(dbus_iface_, ProxyCall_0_1(kMockFlimFlamManagerProxy_,
95 StrEq(kGetPropertiesMethod),
96 _, _))
97 .WillOnce(DoAll(SetArgumentPointee<3>(manager_hash_table), Return(TRUE)));
Jay Srinivasan43488792012-06-19 00:25:31 -070098
99 // Set other expectations.
100 EXPECT_CALL(dbus_iface_,
Gilad Arnoldb752fb32014-03-03 12:23:39 -0800101 ProxyNewForName(kMockSystemBus_,
102 StrEq(shill::kFlimflamServiceName),
103 StrEq(shill::kFlimflamServicePath),
104 StrEq(shill::kFlimflamManagerInterface)))
Jay Srinivasan43488792012-06-19 00:25:31 -0700105 .WillOnce(Return(kMockFlimFlamManagerProxy_));
106 EXPECT_CALL(dbus_iface_, ProxyUnref(kMockFlimFlamManagerProxy_));
107 EXPECT_CALL(dbus_iface_, BusGet(DBUS_BUS_SYSTEM, _))
108 .RetiresOnSaturation();
109}
110
Alex Deymo1c4e6382013-07-15 12:09:51 -0700111void ConnectionManagerTest::SetServiceReply(const char* service_type,
112 const char* physical_technology) {
Jay Srinivasan43488792012-06-19 00:25:31 -0700113 // Initialize return value for D-Bus call to Service object.
114 // TODO (jaysri): Free the objects allocated here.
115 GHashTable* service_hash_table = g_hash_table_new(g_str_hash, g_str_equal);
116
117 GValue* service_type_value = g_new0(GValue, 1);
118 EXPECT_EQ(service_type_value,
119 g_value_init(service_type_value, G_TYPE_STRING));
120 g_value_set_static_string(service_type_value, service_type);
121
122 g_hash_table_insert(service_hash_table,
123 const_cast<char*>("Type"),
124 service_type_value);
125
Alex Deymo1c4e6382013-07-15 12:09:51 -0700126 if (physical_technology != NULL) {
127 GValue* physical_technology_value = g_new0(GValue, 1);
128 EXPECT_EQ(physical_technology_value,
129 g_value_init(physical_technology_value, G_TYPE_STRING));
130 g_value_set_static_string(physical_technology_value, physical_technology);
131
132 g_hash_table_insert(service_hash_table,
133 const_cast<char*>("PhysicalTechnology"),
134 physical_technology_value);
135 }
136
Jay Srinivasan43488792012-06-19 00:25:31 -0700137 // Plumb return value into mock object.
Gilad Arnoldb752fb32014-03-03 12:23:39 -0800138 EXPECT_CALL(dbus_iface_, ProxyCall_0_1(kMockFlimFlamServiceProxy_,
139 StrEq(kGetPropertiesMethod),
140 _, _))
141 .WillOnce(DoAll(SetArgumentPointee<3>(service_hash_table), Return(TRUE)));
Jay Srinivasan43488792012-06-19 00:25:31 -0700142
143 // Set other expectations.
144 EXPECT_CALL(dbus_iface_,
Gilad Arnoldb752fb32014-03-03 12:23:39 -0800145 ProxyNewForName(kMockSystemBus_,
146 StrEq(shill::kFlimflamServiceName),
147 StrEq(kServicePath_),
148 StrEq(shill::kFlimflamServiceInterface)))
Jay Srinivasan43488792012-06-19 00:25:31 -0700149 .WillOnce(Return(kMockFlimFlamServiceProxy_));
150 EXPECT_CALL(dbus_iface_, ProxyUnref(kMockFlimFlamServiceProxy_));
151 EXPECT_CALL(dbus_iface_, BusGet(DBUS_BUS_SYSTEM, _))
152 .RetiresOnSaturation();
153}
154
155void ConnectionManagerTest::TestWithServiceType(
156 const char* service_type,
Alex Deymo1c4e6382013-07-15 12:09:51 -0700157 const char* physical_technology,
Jay Srinivasan43488792012-06-19 00:25:31 -0700158 NetworkConnectionType expected_type) {
159
160 SetupMocks("/service/guest-network");
161 SetManagerReply(kServicePath_, DBUS_TYPE_G_OBJECT_PATH_ARRAY);
Alex Deymo1c4e6382013-07-15 12:09:51 -0700162 SetServiceReply(service_type, physical_technology);
Jay Srinivasan43488792012-06-19 00:25:31 -0700163
164 NetworkConnectionType type;
165 EXPECT_TRUE(cmut_.GetConnectionType(&dbus_iface_, &type));
166 EXPECT_EQ(expected_type, type);
167}
168
169TEST_F(ConnectionManagerTest, SimpleTest) {
Ben Chanc6007e42013-09-19 23:49:22 -0700170 TestWithServiceType(shill::kTypeEthernet, NULL, kNetEthernet);
171 TestWithServiceType(shill::kTypeWifi, NULL, kNetWifi);
172 TestWithServiceType(shill::kTypeWimax, NULL, kNetWimax);
173 TestWithServiceType(shill::kTypeBluetooth, NULL, kNetBluetooth);
174 TestWithServiceType(shill::kTypeCellular, NULL, kNetCellular);
Alex Deymo1c4e6382013-07-15 12:09:51 -0700175}
176
177TEST_F(ConnectionManagerTest, PhysicalTechnologyTest) {
Ben Chanc6007e42013-09-19 23:49:22 -0700178 TestWithServiceType(shill::kTypeVPN, NULL, kNetUnknown);
179 TestWithServiceType(shill::kTypeVPN, shill::kTypeVPN, kNetUnknown);
180 TestWithServiceType(shill::kTypeVPN, shill::kTypeWifi, kNetWifi);
181 TestWithServiceType(shill::kTypeVPN, shill::kTypeWimax, kNetWimax);
Jay Srinivasan43488792012-06-19 00:25:31 -0700182}
183
184TEST_F(ConnectionManagerTest, UnknownTest) {
Alex Deymo1c4e6382013-07-15 12:09:51 -0700185 TestWithServiceType("foo", NULL, kNetUnknown);
Jay Srinivasan43488792012-06-19 00:25:31 -0700186}
187
188TEST_F(ConnectionManagerTest, AllowUpdatesOverEthernetTest) {
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800189 EXPECT_CALL(mock_system_state_, device_policy()).Times(0);
Jay Srinivasan43488792012-06-19 00:25:31 -0700190
191 // Updates over Ethernet are allowed even if there's no policy.
192 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetEthernet));
193}
194
195TEST_F(ConnectionManagerTest, AllowUpdatesOverWifiTest) {
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800196 EXPECT_CALL(mock_system_state_, device_policy()).Times(0);
Jay Srinivasan43488792012-06-19 00:25:31 -0700197 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetWifi));
198}
199
200TEST_F(ConnectionManagerTest, AllowUpdatesOverWimaxTest) {
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800201 EXPECT_CALL(mock_system_state_, device_policy()).Times(0);
Jay Srinivasan43488792012-06-19 00:25:31 -0700202 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetWimax));
203}
204
205TEST_F(ConnectionManagerTest, BlockUpdatesOverBluetoothTest) {
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800206 EXPECT_CALL(mock_system_state_, device_policy()).Times(0);
Jay Srinivasan43488792012-06-19 00:25:31 -0700207 EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetBluetooth));
208}
209
210TEST_F(ConnectionManagerTest, AllowUpdatesOnlyOver3GPerPolicyTest) {
211 policy::MockDevicePolicy allow_3g_policy;
212
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800213 EXPECT_CALL(mock_system_state_, device_policy())
Jay Srinivasan43488792012-06-19 00:25:31 -0700214 .Times(1)
215 .WillOnce(Return(&allow_3g_policy));
216
Alex Deymof4867c42013-06-28 14:41:39 -0700217 // This test tests cellular (3G) being the only connection type being allowed.
Jay Srinivasan43488792012-06-19 00:25:31 -0700218 set<string> allowed_set;
219 allowed_set.insert(cmut_.StringForConnectionType(kNetCellular));
220
221 EXPECT_CALL(allow_3g_policy, GetAllowedConnectionTypesForUpdate(_))
222 .Times(1)
223 .WillOnce(DoAll(SetArgumentPointee<0>(allowed_set), Return(true)));
224
225 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetCellular));
226}
227
228TEST_F(ConnectionManagerTest, AllowUpdatesOver3GAndOtherTypesPerPolicyTest) {
229 policy::MockDevicePolicy allow_3g_policy;
230
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800231 EXPECT_CALL(mock_system_state_, device_policy())
Jay Srinivasan43488792012-06-19 00:25:31 -0700232 .Times(1)
233 .WillOnce(Return(&allow_3g_policy));
234
235 // This test tests multiple connection types being allowed, with
Alex Deymof4867c42013-06-28 14:41:39 -0700236 // 3G one among them. Only Cellular is currently enforced by the policy
237 // setting, the others are ignored (see Bluetooth for example).
Jay Srinivasan43488792012-06-19 00:25:31 -0700238 set<string> allowed_set;
Jay Srinivasan43488792012-06-19 00:25:31 -0700239 allowed_set.insert(cmut_.StringForConnectionType(kNetCellular));
Alex Deymof4867c42013-06-28 14:41:39 -0700240 allowed_set.insert(cmut_.StringForConnectionType(kNetBluetooth));
Jay Srinivasan43488792012-06-19 00:25:31 -0700241
242 EXPECT_CALL(allow_3g_policy, GetAllowedConnectionTypesForUpdate(_))
243 .Times(1)
244 .WillOnce(DoAll(SetArgumentPointee<0>(allowed_set), Return(true)));
245
Alex Deymof4867c42013-06-28 14:41:39 -0700246 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetEthernet));
Jay Srinivasan43488792012-06-19 00:25:31 -0700247 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetCellular));
Alex Deymof4867c42013-06-28 14:41:39 -0700248 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetWifi));
249 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetWimax));
250 EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetBluetooth));
Jay Srinivasan43488792012-06-19 00:25:31 -0700251}
252
Alex Deymof4867c42013-06-28 14:41:39 -0700253TEST_F(ConnectionManagerTest, BlockUpdatesOverCellularByDefaultTest) {
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800254 EXPECT_CALL(mock_system_state_, device_policy()).Times(1);
Jay Srinivasan43488792012-06-19 00:25:31 -0700255 EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetCellular));
256}
257
258TEST_F(ConnectionManagerTest, BlockUpdatesOver3GPerPolicyTest) {
259 policy::MockDevicePolicy block_3g_policy;
260
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800261 EXPECT_CALL(mock_system_state_, device_policy())
Jay Srinivasan43488792012-06-19 00:25:31 -0700262 .Times(1)
263 .WillOnce(Return(&block_3g_policy));
264
265 // Test that updates for 3G are blocked while updates are allowed
266 // over several other types.
267 set<string> allowed_set;
268 allowed_set.insert(cmut_.StringForConnectionType(kNetEthernet));
269 allowed_set.insert(cmut_.StringForConnectionType(kNetWifi));
270 allowed_set.insert(cmut_.StringForConnectionType(kNetWimax));
271
272 EXPECT_CALL(block_3g_policy, GetAllowedConnectionTypesForUpdate(_))
273 .Times(1)
274 .WillOnce(DoAll(SetArgumentPointee<0>(allowed_set), Return(true)));
275
276 EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetCellular));
277}
278
279TEST_F(ConnectionManagerTest, BlockUpdatesOver3GIfErrorInPolicyFetchTest) {
280 policy::MockDevicePolicy allow_3g_policy;
281
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800282 EXPECT_CALL(mock_system_state_, device_policy())
Jay Srinivasan43488792012-06-19 00:25:31 -0700283 .Times(1)
284 .WillOnce(Return(&allow_3g_policy));
285
286 set<string> allowed_set;
287 allowed_set.insert(cmut_.StringForConnectionType(kNetCellular));
288
289 // Return false for GetAllowedConnectionTypesForUpdate and see
290 // that updates are still blocked for 3G despite the value being in
291 // the string set above.
292 EXPECT_CALL(allow_3g_policy, GetAllowedConnectionTypesForUpdate(_))
293 .Times(1)
294 .WillOnce(DoAll(SetArgumentPointee<0>(allowed_set), Return(false)));
295
296 EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetCellular));
297}
298
Alex Deymof4867c42013-06-28 14:41:39 -0700299TEST_F(ConnectionManagerTest, UseUserPrefForUpdatesOverCellularIfNoPolicyTest) {
300 policy::MockDevicePolicy no_policy;
301 testing::NiceMock<PrefsMock>* prefs = mock_system_state_.mock_prefs();
302
303 EXPECT_CALL(mock_system_state_, device_policy())
304 .Times(3)
305 .WillRepeatedly(Return(&no_policy));
306
307 // No setting enforced by the device policy, user prefs should be used.
308 EXPECT_CALL(no_policy, GetAllowedConnectionTypesForUpdate(_))
309 .Times(3)
310 .WillRepeatedly(Return(false));
311
312 // No user pref: block.
313 EXPECT_CALL(*prefs, Exists(kPrefsUpdateOverCellularPermission))
314 .Times(1)
315 .WillOnce(Return(false));
316 EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetCellular));
317
318 // Allow per user pref.
319 EXPECT_CALL(*prefs, Exists(kPrefsUpdateOverCellularPermission))
320 .Times(1)
321 .WillOnce(Return(true));
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700322 EXPECT_CALL(*prefs, GetBoolean(kPrefsUpdateOverCellularPermission, _))
Alex Deymof4867c42013-06-28 14:41:39 -0700323 .Times(1)
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700324 .WillOnce(DoAll(SetArgumentPointee<1>(true), Return(true)));
Alex Deymof4867c42013-06-28 14:41:39 -0700325 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetCellular));
326
327 // Block per user pref.
328 EXPECT_CALL(*prefs, Exists(kPrefsUpdateOverCellularPermission))
329 .Times(1)
330 .WillOnce(Return(true));
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700331 EXPECT_CALL(*prefs, GetBoolean(kPrefsUpdateOverCellularPermission, _))
Alex Deymof4867c42013-06-28 14:41:39 -0700332 .Times(1)
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700333 .WillOnce(DoAll(SetArgumentPointee<1>(false), Return(true)));
Alex Deymof4867c42013-06-28 14:41:39 -0700334 EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetCellular));
335}
336
Jay Srinivasan43488792012-06-19 00:25:31 -0700337TEST_F(ConnectionManagerTest, StringForConnectionTypeTest) {
Ben Chanc6007e42013-09-19 23:49:22 -0700338 EXPECT_STREQ(shill::kTypeEthernet,
Jay Srinivasan43488792012-06-19 00:25:31 -0700339 cmut_.StringForConnectionType(kNetEthernet));
Ben Chanc6007e42013-09-19 23:49:22 -0700340 EXPECT_STREQ(shill::kTypeWifi,
Jay Srinivasan43488792012-06-19 00:25:31 -0700341 cmut_.StringForConnectionType(kNetWifi));
Ben Chanc6007e42013-09-19 23:49:22 -0700342 EXPECT_STREQ(shill::kTypeWimax,
Jay Srinivasan43488792012-06-19 00:25:31 -0700343 cmut_.StringForConnectionType(kNetWimax));
Ben Chanc6007e42013-09-19 23:49:22 -0700344 EXPECT_STREQ(shill::kTypeBluetooth,
Jay Srinivasan43488792012-06-19 00:25:31 -0700345 cmut_.StringForConnectionType(kNetBluetooth));
Ben Chanc6007e42013-09-19 23:49:22 -0700346 EXPECT_STREQ(shill::kTypeCellular,
Jay Srinivasan43488792012-06-19 00:25:31 -0700347 cmut_.StringForConnectionType(kNetCellular));
348 EXPECT_STREQ("Unknown",
349 cmut_.StringForConnectionType(kNetUnknown));
350 EXPECT_STREQ("Unknown",
351 cmut_.StringForConnectionType(
352 static_cast<NetworkConnectionType>(999999)));
353}
354
355TEST_F(ConnectionManagerTest, MalformedServiceList) {
356 SetupMocks("/service/guest-network");
357 string service_name(kServicePath_);
358 SetManagerReply(&service_name, DBUS_TYPE_G_STRING_ARRAY);
359
360 NetworkConnectionType type;
361 EXPECT_FALSE(cmut_.GetConnectionType(&dbus_iface_, &type));
362}
363
364} // namespace chromeos_update_engine