blob: 724061bf7efb8b72f18740eadf6858e9df79fe65 [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);
37 void SetServiceReply(const char* service_type);
38 void TestWithServiceType(
39 const char* service_type, NetworkConnectionType expected_type);
40
41 static const char* kGetPropertiesMethod;
42 DBusGProxy* kMockFlimFlamManagerProxy_;
43 DBusGProxy* kMockFlimFlamServiceProxy_;
44 DBusGConnection* kMockSystemBus_;
45 const char* kServicePath_;
46 MockDbusGlib dbus_iface_;
47 ConnectionManager cmut_; // ConnectionManager under test.
48 MockSystemState mock_system_state_;
49};
50
51// static
52const char* ConnectionManagerTest::kGetPropertiesMethod = "GetProperties";
53
54void ConnectionManagerTest::SetupMocks(const char* service_path) {
55 int number = 1;
56 kMockSystemBus_ = reinterpret_cast<DBusGConnection*>(number++);
57 kMockFlimFlamManagerProxy_ = reinterpret_cast<DBusGProxy*>(number++);
58 kMockFlimFlamServiceProxy_ = reinterpret_cast<DBusGProxy*>(number++);
59 ASSERT_NE(kMockSystemBus_, reinterpret_cast<DBusGConnection*>(NULL));
60
61 kServicePath_ = service_path;
62
63 ON_CALL(dbus_iface_, BusGet(DBUS_BUS_SYSTEM, _))
64 .WillByDefault(Return(kMockSystemBus_));
65 EXPECT_CALL(dbus_iface_, BusGet(DBUS_BUS_SYSTEM, _))
66 .Times(AnyNumber());
67}
68
69void ConnectionManagerTest::SetManagerReply(gconstpointer reply_value,
70 const GType& reply_type) {
71 // Initialize return value for D-Bus call to Manager object.
72 // TODO (jaysri): Free the objects allocated here.
73 GHashTable* manager_hash_table = g_hash_table_new(g_str_hash, g_str_equal);
74
75 GArray* array = g_array_new(FALSE, FALSE, sizeof(const char*));
76 ASSERT_TRUE(array != NULL);
77
78 EXPECT_EQ(array, g_array_append_val(array, reply_value));
79 GValue* array_as_value = g_new0(GValue, 1);
80 EXPECT_EQ(array_as_value, g_value_init(array_as_value, reply_type));
81 g_value_take_boxed(array_as_value, array);
82 g_hash_table_insert(manager_hash_table,
83 const_cast<char*>("Services"),
84 array_as_value);
85
86 // Plumb return value into mock object.
87 EXPECT_CALL(dbus_iface_, ProxyCall(kMockFlimFlamManagerProxy_,
88 StrEq(kGetPropertiesMethod),
89 _,
90 G_TYPE_INVALID,
91 dbus_g_type_get_map("GHashTable",
92 G_TYPE_STRING,
93 G_TYPE_VALUE),
94 _,
95 G_TYPE_INVALID))
96 .WillOnce(DoAll(SetArgumentPointee<5>(manager_hash_table), Return(TRUE)));
97
98 // Set other expectations.
99 EXPECT_CALL(dbus_iface_,
100 ProxyNewForNameOwner(kMockSystemBus_,
101 StrEq(flimflam::kFlimflamServiceName),
102 StrEq(flimflam::kFlimflamServicePath),
103 StrEq(flimflam::kFlimflamManagerInterface),
104 _))
105 .WillOnce(Return(kMockFlimFlamManagerProxy_));
106 EXPECT_CALL(dbus_iface_, ProxyUnref(kMockFlimFlamManagerProxy_));
107 EXPECT_CALL(dbus_iface_, BusGet(DBUS_BUS_SYSTEM, _))
108 .RetiresOnSaturation();
109}
110
111void ConnectionManagerTest::SetServiceReply(const char* service_type) {
112 // Initialize return value for D-Bus call to Service object.
113 // TODO (jaysri): Free the objects allocated here.
114 GHashTable* service_hash_table = g_hash_table_new(g_str_hash, g_str_equal);
115
116 GValue* service_type_value = g_new0(GValue, 1);
117 EXPECT_EQ(service_type_value,
118 g_value_init(service_type_value, G_TYPE_STRING));
119 g_value_set_static_string(service_type_value, service_type);
120
121 g_hash_table_insert(service_hash_table,
122 const_cast<char*>("Type"),
123 service_type_value);
124
125 // Plumb return value into mock object.
126 EXPECT_CALL(dbus_iface_, ProxyCall(kMockFlimFlamServiceProxy_,
127 StrEq(kGetPropertiesMethod),
128 _,
129 G_TYPE_INVALID,
130 dbus_g_type_get_map("GHashTable",
131 G_TYPE_STRING,
132 G_TYPE_VALUE),
133 _,
134 G_TYPE_INVALID))
135 .WillOnce(DoAll(SetArgumentPointee<5>(service_hash_table), Return(TRUE)));
136
137 // Set other expectations.
138 EXPECT_CALL(dbus_iface_,
139 ProxyNewForNameOwner(kMockSystemBus_,
140 StrEq(flimflam::kFlimflamServiceName),
141 StrEq(kServicePath_),
142 StrEq(flimflam::kFlimflamServiceInterface),
143 _))
144 .WillOnce(Return(kMockFlimFlamServiceProxy_));
145 EXPECT_CALL(dbus_iface_, ProxyUnref(kMockFlimFlamServiceProxy_));
146 EXPECT_CALL(dbus_iface_, BusGet(DBUS_BUS_SYSTEM, _))
147 .RetiresOnSaturation();
148}
149
150void ConnectionManagerTest::TestWithServiceType(
151 const char* service_type,
152 NetworkConnectionType expected_type) {
153
154 SetupMocks("/service/guest-network");
155 SetManagerReply(kServicePath_, DBUS_TYPE_G_OBJECT_PATH_ARRAY);
156 SetServiceReply(service_type);
157
158 NetworkConnectionType type;
159 EXPECT_TRUE(cmut_.GetConnectionType(&dbus_iface_, &type));
160 EXPECT_EQ(expected_type, type);
161}
162
163TEST_F(ConnectionManagerTest, SimpleTest) {
164 TestWithServiceType(flimflam::kTypeEthernet, kNetEthernet);
165 TestWithServiceType(flimflam::kTypeWifi, kNetWifi);
166 TestWithServiceType(flimflam::kTypeWimax, kNetWimax);
167 TestWithServiceType(flimflam::kTypeBluetooth, kNetBluetooth);
168 TestWithServiceType(flimflam::kTypeCellular, kNetCellular);
169}
170
171TEST_F(ConnectionManagerTest, UnknownTest) {
172 TestWithServiceType("foo", kNetUnknown);
173}
174
175TEST_F(ConnectionManagerTest, AllowUpdatesOverEthernetTest) {
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800176 EXPECT_CALL(mock_system_state_, device_policy()).Times(0);
Jay Srinivasan43488792012-06-19 00:25:31 -0700177
178 // Updates over Ethernet are allowed even if there's no policy.
179 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetEthernet));
180}
181
182TEST_F(ConnectionManagerTest, AllowUpdatesOverWifiTest) {
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800183 EXPECT_CALL(mock_system_state_, device_policy()).Times(0);
Jay Srinivasan43488792012-06-19 00:25:31 -0700184 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetWifi));
185}
186
187TEST_F(ConnectionManagerTest, AllowUpdatesOverWimaxTest) {
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800188 EXPECT_CALL(mock_system_state_, device_policy()).Times(0);
Jay Srinivasan43488792012-06-19 00:25:31 -0700189 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetWimax));
190}
191
192TEST_F(ConnectionManagerTest, BlockUpdatesOverBluetoothTest) {
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800193 EXPECT_CALL(mock_system_state_, device_policy()).Times(0);
Jay Srinivasan43488792012-06-19 00:25:31 -0700194 EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetBluetooth));
195}
196
197TEST_F(ConnectionManagerTest, AllowUpdatesOnlyOver3GPerPolicyTest) {
198 policy::MockDevicePolicy allow_3g_policy;
199
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800200 EXPECT_CALL(mock_system_state_, device_policy())
Jay Srinivasan43488792012-06-19 00:25:31 -0700201 .Times(1)
202 .WillOnce(Return(&allow_3g_policy));
203
Alex Deymof4867c42013-06-28 14:41:39 -0700204 // This test tests cellular (3G) being the only connection type being allowed.
Jay Srinivasan43488792012-06-19 00:25:31 -0700205 set<string> allowed_set;
206 allowed_set.insert(cmut_.StringForConnectionType(kNetCellular));
207
208 EXPECT_CALL(allow_3g_policy, GetAllowedConnectionTypesForUpdate(_))
209 .Times(1)
210 .WillOnce(DoAll(SetArgumentPointee<0>(allowed_set), Return(true)));
211
212 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetCellular));
213}
214
215TEST_F(ConnectionManagerTest, AllowUpdatesOver3GAndOtherTypesPerPolicyTest) {
216 policy::MockDevicePolicy allow_3g_policy;
217
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800218 EXPECT_CALL(mock_system_state_, device_policy())
Jay Srinivasan43488792012-06-19 00:25:31 -0700219 .Times(1)
220 .WillOnce(Return(&allow_3g_policy));
221
222 // This test tests multiple connection types being allowed, with
Alex Deymof4867c42013-06-28 14:41:39 -0700223 // 3G one among them. Only Cellular is currently enforced by the policy
224 // setting, the others are ignored (see Bluetooth for example).
Jay Srinivasan43488792012-06-19 00:25:31 -0700225 set<string> allowed_set;
Jay Srinivasan43488792012-06-19 00:25:31 -0700226 allowed_set.insert(cmut_.StringForConnectionType(kNetCellular));
Alex Deymof4867c42013-06-28 14:41:39 -0700227 allowed_set.insert(cmut_.StringForConnectionType(kNetBluetooth));
Jay Srinivasan43488792012-06-19 00:25:31 -0700228
229 EXPECT_CALL(allow_3g_policy, GetAllowedConnectionTypesForUpdate(_))
230 .Times(1)
231 .WillOnce(DoAll(SetArgumentPointee<0>(allowed_set), Return(true)));
232
Alex Deymof4867c42013-06-28 14:41:39 -0700233 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetEthernet));
Jay Srinivasan43488792012-06-19 00:25:31 -0700234 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetCellular));
Alex Deymof4867c42013-06-28 14:41:39 -0700235 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetWifi));
236 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetWimax));
237 EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetBluetooth));
Jay Srinivasan43488792012-06-19 00:25:31 -0700238}
239
Alex Deymof4867c42013-06-28 14:41:39 -0700240TEST_F(ConnectionManagerTest, BlockUpdatesOverCellularByDefaultTest) {
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800241 EXPECT_CALL(mock_system_state_, device_policy()).Times(1);
Jay Srinivasan43488792012-06-19 00:25:31 -0700242 EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetCellular));
243}
244
245TEST_F(ConnectionManagerTest, BlockUpdatesOver3GPerPolicyTest) {
246 policy::MockDevicePolicy block_3g_policy;
247
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800248 EXPECT_CALL(mock_system_state_, device_policy())
Jay Srinivasan43488792012-06-19 00:25:31 -0700249 .Times(1)
250 .WillOnce(Return(&block_3g_policy));
251
252 // Test that updates for 3G are blocked while updates are allowed
253 // over several other types.
254 set<string> allowed_set;
255 allowed_set.insert(cmut_.StringForConnectionType(kNetEthernet));
256 allowed_set.insert(cmut_.StringForConnectionType(kNetWifi));
257 allowed_set.insert(cmut_.StringForConnectionType(kNetWimax));
258
259 EXPECT_CALL(block_3g_policy, GetAllowedConnectionTypesForUpdate(_))
260 .Times(1)
261 .WillOnce(DoAll(SetArgumentPointee<0>(allowed_set), Return(true)));
262
263 EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetCellular));
264}
265
266TEST_F(ConnectionManagerTest, BlockUpdatesOver3GIfErrorInPolicyFetchTest) {
267 policy::MockDevicePolicy allow_3g_policy;
268
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800269 EXPECT_CALL(mock_system_state_, device_policy())
Jay Srinivasan43488792012-06-19 00:25:31 -0700270 .Times(1)
271 .WillOnce(Return(&allow_3g_policy));
272
273 set<string> allowed_set;
274 allowed_set.insert(cmut_.StringForConnectionType(kNetCellular));
275
276 // Return false for GetAllowedConnectionTypesForUpdate and see
277 // that updates are still blocked for 3G despite the value being in
278 // the string set above.
279 EXPECT_CALL(allow_3g_policy, GetAllowedConnectionTypesForUpdate(_))
280 .Times(1)
281 .WillOnce(DoAll(SetArgumentPointee<0>(allowed_set), Return(false)));
282
283 EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetCellular));
284}
285
Alex Deymof4867c42013-06-28 14:41:39 -0700286TEST_F(ConnectionManagerTest, UseUserPrefForUpdatesOverCellularIfNoPolicyTest) {
287 policy::MockDevicePolicy no_policy;
288 testing::NiceMock<PrefsMock>* prefs = mock_system_state_.mock_prefs();
289
290 EXPECT_CALL(mock_system_state_, device_policy())
291 .Times(3)
292 .WillRepeatedly(Return(&no_policy));
293
294 // No setting enforced by the device policy, user prefs should be used.
295 EXPECT_CALL(no_policy, GetAllowedConnectionTypesForUpdate(_))
296 .Times(3)
297 .WillRepeatedly(Return(false));
298
299 // No user pref: block.
300 EXPECT_CALL(*prefs, Exists(kPrefsUpdateOverCellularPermission))
301 .Times(1)
302 .WillOnce(Return(false));
303 EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetCellular));
304
305 // Allow per user pref.
306 EXPECT_CALL(*prefs, Exists(kPrefsUpdateOverCellularPermission))
307 .Times(1)
308 .WillOnce(Return(true));
309 EXPECT_CALL(*prefs, GetInt64(kPrefsUpdateOverCellularPermission, _))
310 .Times(1)
311 .WillOnce(DoAll(SetArgumentPointee<1>(1), Return(true)));
312 EXPECT_TRUE(cmut_.IsUpdateAllowedOver(kNetCellular));
313
314 // Block per user pref.
315 EXPECT_CALL(*prefs, Exists(kPrefsUpdateOverCellularPermission))
316 .Times(1)
317 .WillOnce(Return(true));
318 EXPECT_CALL(*prefs, GetInt64(kPrefsUpdateOverCellularPermission, _))
319 .Times(1)
320 .WillOnce(DoAll(SetArgumentPointee<1>(0), Return(true)));
321 EXPECT_FALSE(cmut_.IsUpdateAllowedOver(kNetCellular));
322}
323
Jay Srinivasan43488792012-06-19 00:25:31 -0700324TEST_F(ConnectionManagerTest, StringForConnectionTypeTest) {
325 EXPECT_STREQ(flimflam::kTypeEthernet,
326 cmut_.StringForConnectionType(kNetEthernet));
327 EXPECT_STREQ(flimflam::kTypeWifi,
328 cmut_.StringForConnectionType(kNetWifi));
329 EXPECT_STREQ(flimflam::kTypeWimax,
330 cmut_.StringForConnectionType(kNetWimax));
331 EXPECT_STREQ(flimflam::kTypeBluetooth,
332 cmut_.StringForConnectionType(kNetBluetooth));
333 EXPECT_STREQ(flimflam::kTypeCellular,
334 cmut_.StringForConnectionType(kNetCellular));
335 EXPECT_STREQ("Unknown",
336 cmut_.StringForConnectionType(kNetUnknown));
337 EXPECT_STREQ("Unknown",
338 cmut_.StringForConnectionType(
339 static_cast<NetworkConnectionType>(999999)));
340}
341
342TEST_F(ConnectionManagerTest, MalformedServiceList) {
343 SetupMocks("/service/guest-network");
344 string service_name(kServicePath_);
345 SetManagerReply(&service_name, DBUS_TYPE_G_STRING_ARRAY);
346
347 NetworkConnectionType type;
348 EXPECT_FALSE(cmut_.GetConnectionType(&dbus_iface_, &type));
349}
350
351} // namespace chromeos_update_engine