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