1 // Copyright (c) 2012 The Chromium 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/bind.h" 6 #include "base/values.h" 7 #include "chromeos/dbus/shill_client_unittest_base.h" 8 #include "chromeos/dbus/shill_device_client.h" 9 #include "dbus/message.h" 10 #include "dbus/object_path.h" 11 #include "dbus/values_util.h" 12 #include "testing/gtest/include/gtest/gtest.h" 13 #include "third_party/cros_system_api/dbus/service_constants.h" 14 15 using testing::_; 16 using testing::ByRef; 17 18 namespace chromeos { 19 20 namespace { 21 22 const char kExampleDevicePath[] = "/foo/bar"; 23 24 // Expects the reader to have a string and a bool. 25 void ExpectStringAndBoolArguments(const std::string& expected_string, 26 bool expected_bool, 27 dbus::MessageReader* reader) { 28 std::string arg1; 29 ASSERT_TRUE(reader->PopString(&arg1)); 30 EXPECT_EQ(expected_string, arg1); 31 bool arg2 = false; 32 ASSERT_TRUE(reader->PopBool(&arg2)); 33 EXPECT_EQ(expected_bool, arg2); 34 EXPECT_FALSE(reader->HasMoreData()); 35 } 36 37 // Expects the reader to have two strings. 38 void ExpectTwoStringArguments(const std::string& expected_string1, 39 const std::string& expected_string2, 40 dbus::MessageReader* reader) { 41 std::string arg1; 42 ASSERT_TRUE(reader->PopString(&arg1)); 43 EXPECT_EQ(expected_string1, arg1); 44 std::string arg2; 45 ASSERT_TRUE(reader->PopString(&arg2)); 46 EXPECT_EQ(expected_string2, arg2); 47 EXPECT_FALSE(reader->HasMoreData()); 48 } 49 50 } // namespace 51 52 class ShillDeviceClientTest : public ShillClientUnittestBase { 53 public: 54 ShillDeviceClientTest() 55 : ShillClientUnittestBase(shill::kFlimflamDeviceInterface, 56 dbus::ObjectPath(kExampleDevicePath)) { 57 } 58 59 virtual void SetUp() { 60 ShillClientUnittestBase::SetUp(); 61 // Create a client with the mock bus. 62 client_.reset(ShillDeviceClient::Create()); 63 client_->Init(mock_bus_.get()); 64 // Run the message loop to run the signal connection result callback. 65 message_loop_.RunUntilIdle(); 66 } 67 68 virtual void TearDown() { 69 ShillClientUnittestBase::TearDown(); 70 } 71 72 protected: 73 scoped_ptr<ShillDeviceClient> client_; 74 }; 75 76 TEST_F(ShillDeviceClientTest, PropertyChanged) { 77 const bool kValue = true; 78 // Create a signal. 79 dbus::Signal signal(shill::kFlimflamDeviceInterface, 80 shill::kMonitorPropertyChanged); 81 dbus::MessageWriter writer(&signal); 82 writer.AppendString(shill::kCellularAllowRoamingProperty); 83 writer.AppendVariantOfBool(kValue); 84 85 // Set expectations. 86 const base::FundamentalValue value(kValue); 87 MockPropertyChangeObserver observer; 88 EXPECT_CALL(observer, 89 OnPropertyChanged(shill::kCellularAllowRoamingProperty, 90 ValueEq(ByRef(value)))).Times(1); 91 92 // Add the observer 93 client_->AddPropertyChangedObserver( 94 dbus::ObjectPath(kExampleDevicePath), 95 &observer); 96 97 // Run the signal callback. 98 SendPropertyChangedSignal(&signal); 99 100 // Remove the observer. 101 client_->RemovePropertyChangedObserver( 102 dbus::ObjectPath(kExampleDevicePath), 103 &observer); 104 105 EXPECT_CALL(observer, 106 OnPropertyChanged(shill::kCellularAllowRoamingProperty, 107 ValueEq(ByRef(value)))).Times(0); 108 109 // Run the signal callback again and make sure the observer isn't called. 110 SendPropertyChangedSignal(&signal); 111 } 112 113 TEST_F(ShillDeviceClientTest, GetProperties) { 114 const bool kValue = true; 115 // Create response. 116 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); 117 dbus::MessageWriter writer(response.get()); 118 dbus::MessageWriter array_writer(NULL); 119 writer.OpenArray("{sv}", &array_writer); 120 dbus::MessageWriter entry_writer(NULL); 121 array_writer.OpenDictEntry(&entry_writer); 122 entry_writer.AppendString(shill::kCellularAllowRoamingProperty); 123 entry_writer.AppendVariantOfBool(kValue); 124 array_writer.CloseContainer(&entry_writer); 125 writer.CloseContainer(&array_writer); 126 127 // Set expectations. 128 base::DictionaryValue value; 129 value.SetWithoutPathExpansion(shill::kCellularAllowRoamingProperty, 130 base::Value::CreateBooleanValue(kValue)); 131 PrepareForMethodCall(shill::kGetPropertiesFunction, 132 base::Bind(&ExpectNoArgument), 133 response.get()); 134 // Call method. 135 client_->GetProperties(dbus::ObjectPath(kExampleDevicePath), 136 base::Bind(&ExpectDictionaryValueResult, &value)); 137 // Run the message loop. 138 message_loop_.RunUntilIdle(); 139 } 140 141 TEST_F(ShillDeviceClientTest, ProposeScan) { 142 // Create response. 143 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); 144 145 // Set expectations. 146 PrepareForMethodCall(shill::kProposeScanFunction, 147 base::Bind(&ExpectNoArgument), 148 response.get()); 149 // Call method. 150 client_->ProposeScan(dbus::ObjectPath(kExampleDevicePath), 151 base::Bind(&ExpectNoResultValue)); 152 // Run the message loop. 153 message_loop_.RunUntilIdle(); 154 } 155 156 TEST_F(ShillDeviceClientTest, SetProperty) { 157 const bool kValue = true; 158 // Create response. 159 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); 160 161 // Set expectations. 162 const base::FundamentalValue value(kValue); 163 PrepareForMethodCall(shill::kSetPropertyFunction, 164 base::Bind(&ExpectStringAndValueArguments, 165 shill::kCellularAllowRoamingProperty, 166 &value), 167 response.get()); 168 // Call method. 169 MockClosure mock_closure; 170 MockErrorCallback mock_error_callback; 171 client_->SetProperty(dbus::ObjectPath(kExampleDevicePath), 172 shill::kCellularAllowRoamingProperty, 173 value, 174 mock_closure.GetCallback(), 175 mock_error_callback.GetCallback()); 176 EXPECT_CALL(mock_closure, Run()).Times(1); 177 EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0); 178 179 // Run the message loop. 180 message_loop_.RunUntilIdle(); 181 } 182 183 TEST_F(ShillDeviceClientTest, ClearProperty) { 184 // Create response. 185 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); 186 187 // Set expectations. 188 PrepareForMethodCall(shill::kClearPropertyFunction, 189 base::Bind(&ExpectStringArgument, 190 shill::kCellularAllowRoamingProperty), 191 response.get()); 192 // Call method. 193 client_->ClearProperty(dbus::ObjectPath(kExampleDevicePath), 194 shill::kCellularAllowRoamingProperty, 195 base::Bind(&ExpectNoResultValue)); 196 // Run the message loop. 197 message_loop_.RunUntilIdle(); 198 } 199 200 TEST_F(ShillDeviceClientTest, AddIPConfig) { 201 const dbus::ObjectPath expected_result("/result/path"); 202 // Create response. 203 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); 204 dbus::MessageWriter writer(response.get()); 205 writer.AppendObjectPath(expected_result); 206 207 // Set expectations. 208 PrepareForMethodCall(shill::kAddIPConfigFunction, 209 base::Bind(&ExpectStringArgument, shill::kTypeDHCP), 210 response.get()); 211 // Call method. 212 client_->AddIPConfig(dbus::ObjectPath(kExampleDevicePath), 213 shill::kTypeDHCP, 214 base::Bind(&ExpectObjectPathResult, expected_result)); 215 // Run the message loop. 216 message_loop_.RunUntilIdle(); 217 } 218 219 TEST_F(ShillDeviceClientTest, RequirePin) { 220 const char kPin[] = "123456"; 221 const bool kRequired = true; 222 // Create response. 223 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); 224 225 // Set expectations. 226 MockClosure mock_closure; 227 MockErrorCallback mock_error_callback; 228 PrepareForMethodCall(shill::kRequirePinFunction, 229 base::Bind(&ExpectStringAndBoolArguments, 230 kPin, 231 kRequired), 232 response.get()); 233 EXPECT_CALL(mock_closure, Run()).Times(1); 234 EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0); 235 // Call method. 236 client_->RequirePin(dbus::ObjectPath(kExampleDevicePath), 237 kPin, 238 kRequired, 239 mock_closure.GetCallback(), 240 mock_error_callback.GetCallback()); 241 // Run the message loop. 242 message_loop_.RunUntilIdle(); 243 } 244 245 TEST_F(ShillDeviceClientTest, EnterPin) { 246 const char kPin[] = "123456"; 247 // Create response. 248 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); 249 250 // Set expectations. 251 MockClosure mock_closure; 252 MockErrorCallback mock_error_callback; 253 PrepareForMethodCall(shill::kEnterPinFunction, 254 base::Bind(&ExpectStringArgument, 255 kPin), 256 response.get()); 257 EXPECT_CALL(mock_closure, Run()).Times(1); 258 EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0); 259 260 // Call method. 261 client_->EnterPin(dbus::ObjectPath(kExampleDevicePath), 262 kPin, 263 mock_closure.GetCallback(), 264 mock_error_callback.GetCallback()); 265 // Run the message loop. 266 message_loop_.RunUntilIdle(); 267 } 268 269 TEST_F(ShillDeviceClientTest, UnblockPin) { 270 const char kPuk[] = "987654"; 271 const char kPin[] = "123456"; 272 // Create response. 273 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); 274 275 // Set expectations. 276 MockClosure mock_closure; 277 MockErrorCallback mock_error_callback; 278 PrepareForMethodCall(shill::kUnblockPinFunction, 279 base::Bind(&ExpectTwoStringArguments, kPuk, kPin), 280 response.get()); 281 EXPECT_CALL(mock_closure, Run()).Times(1); 282 EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0); 283 284 // Call method. 285 client_->UnblockPin(dbus::ObjectPath(kExampleDevicePath), 286 kPuk, 287 kPin, 288 mock_closure.GetCallback(), 289 mock_error_callback.GetCallback()); 290 // Run the message loop. 291 message_loop_.RunUntilIdle(); 292 } 293 294 TEST_F(ShillDeviceClientTest, ChangePin) { 295 const char kOldPin[] = "123456"; 296 const char kNewPin[] = "234567"; 297 // Create response. 298 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); 299 300 // Set expectations. 301 MockClosure mock_closure; 302 MockErrorCallback mock_error_callback; 303 PrepareForMethodCall(shill::kChangePinFunction, 304 base::Bind(&ExpectTwoStringArguments, 305 kOldPin, 306 kNewPin), 307 response.get()); 308 EXPECT_CALL(mock_closure, Run()).Times(1); 309 EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0); 310 311 // Call method. 312 client_->ChangePin(dbus::ObjectPath(kExampleDevicePath), 313 kOldPin, 314 kNewPin, 315 mock_closure.GetCallback(), 316 mock_error_callback.GetCallback()); 317 // Run the message loop. 318 message_loop_.RunUntilIdle(); 319 } 320 321 TEST_F(ShillDeviceClientTest, Register) { 322 const char kNetworkId[] = "networkid"; 323 // Create response. 324 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); 325 326 // Set expectations. 327 MockClosure mock_closure; 328 MockErrorCallback mock_error_callback; 329 PrepareForMethodCall(shill::kRegisterFunction, 330 base::Bind(&ExpectStringArgument, kNetworkId), 331 response.get()); 332 EXPECT_CALL(mock_closure, Run()).Times(1); 333 EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0); 334 335 // Call method. 336 client_->Register(dbus::ObjectPath(kExampleDevicePath), 337 kNetworkId, 338 mock_closure.GetCallback(), 339 mock_error_callback.GetCallback()); 340 // Run the message loop. 341 message_loop_.RunUntilIdle(); 342 } 343 344 TEST_F(ShillDeviceClientTest, SetCarrier) { 345 const char kCarrier[] = "carrier"; 346 // Create response. 347 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); 348 349 // Set expectations. 350 MockClosure mock_closure; 351 MockErrorCallback mock_error_callback; 352 PrepareForMethodCall(shill::kSetCarrierFunction, 353 base::Bind(&ExpectStringArgument, kCarrier), 354 response.get()); 355 EXPECT_CALL(mock_closure, Run()).Times(1); 356 // Call method. 357 client_->SetCarrier(dbus::ObjectPath(kExampleDevicePath), 358 kCarrier, 359 mock_closure.GetCallback(), 360 mock_error_callback.GetCallback()); 361 // Run the message loop. 362 message_loop_.RunUntilIdle(); 363 } 364 365 TEST_F(ShillDeviceClientTest, Reset) { 366 // Create response. 367 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); 368 369 // Set expectations. 370 MockClosure mock_closure; 371 MockErrorCallback mock_error_callback; 372 PrepareForMethodCall(shill::kResetFunction, 373 base::Bind(&ExpectNoArgument), 374 response.get()); 375 EXPECT_CALL(mock_closure, Run()).Times(1); 376 // Call method. 377 client_->Reset(dbus::ObjectPath(kExampleDevicePath), 378 mock_closure.GetCallback(), 379 mock_error_callback.GetCallback()); 380 // Run the message loop. 381 message_loop_.RunUntilIdle(); 382 } 383 384 } // namespace chromeos 385