network_configuration_handler_unittest.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
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/json/json_writer.h" 7#include "base/message_loop.h" 8#include "base/strings/string_piece.h" 9#include "base/values.h" 10#include "chromeos/dbus/dbus_thread_manager.h" 11#include "chromeos/dbus/mock_dbus_thread_manager.h" 12#include "chromeos/dbus/mock_shill_manager_client.h" 13#include "chromeos/dbus/mock_shill_profile_client.h" 14#include "chromeos/dbus/mock_shill_service_client.h" 15#include "chromeos/network/network_configuration_handler.h" 16#include "chromeos/network/network_state_handler.h" 17#include "testing/gmock/include/gmock/gmock.h" 18#include "testing/gtest/include/gtest/gtest.h" 19 20using ::testing::_; 21using ::testing::Invoke; 22using ::testing::Pointee; 23using ::testing::Return; 24using ::testing::SaveArg; 25using ::testing::StrEq; 26 27// Matcher to match base::Value. 28MATCHER_P(IsEqualTo, value, "") { return arg.Equals(value); } 29 30namespace chromeos { 31 32namespace { 33 34static std::string PrettyJson(const base::DictionaryValue& value) { 35 std::string pretty; 36 base::JSONWriter::WriteWithOptions(&value, 37 base::JSONWriter::OPTIONS_PRETTY_PRINT, 38 &pretty); 39 return pretty; 40} 41 42void DictionaryValueCallback( 43 const std::string& expected_id, 44 const std::string& expected_json, 45 const std::string& service_path, 46 const base::DictionaryValue& dictionary) { 47 std::string dict_str = PrettyJson(dictionary); 48 EXPECT_EQ(expected_json, dict_str); 49 EXPECT_EQ(expected_id, service_path); 50} 51 52void ErrorCallback(bool error_expected, 53 const std::string& expected_id, 54 const std::string& error_name, 55 scoped_ptr<base::DictionaryValue> error_data) { 56 EXPECT_TRUE(error_expected) << "Unexpected error: " << error_name 57 << " with associated data: \n" 58 << PrettyJson(*error_data); 59} 60 61void StringResultCallback(const std::string& expected_result, 62 const std::string& result) { 63 EXPECT_EQ(expected_result, result); 64} 65 66void DBusErrorCallback(const std::string& error_name, 67 const std::string& error_message) { 68 EXPECT_TRUE(false) << "DBus Error: " << error_name << "(" 69 << error_message << ")"; 70} 71 72class TestCallback { 73 public: 74 TestCallback() : run_count_(0) {} 75 void Run() { 76 ++run_count_; 77 } 78 int run_count() const { return run_count_; } 79 80 private: 81 int run_count_; 82}; 83 84} // namespace 85 86class NetworkConfigurationHandlerTest : public testing::Test { 87 public: 88 NetworkConfigurationHandlerTest() 89 : mock_manager_client_(NULL), 90 mock_profile_client_(NULL), 91 mock_service_client_(NULL), 92 dictionary_value_result_(NULL) {} 93 virtual ~NetworkConfigurationHandlerTest() {} 94 95 virtual void SetUp() OVERRIDE { 96 MockDBusThreadManager* mock_dbus_thread_manager = new MockDBusThreadManager; 97 EXPECT_CALL(*mock_dbus_thread_manager, GetSystemBus()) 98 .WillRepeatedly(Return(reinterpret_cast<dbus::Bus*>(NULL))); 99 DBusThreadManager::InitializeForTesting(mock_dbus_thread_manager); 100 mock_manager_client_ = 101 mock_dbus_thread_manager->mock_shill_manager_client(); 102 mock_profile_client_ = 103 mock_dbus_thread_manager->mock_shill_profile_client(); 104 mock_service_client_ = 105 mock_dbus_thread_manager->mock_shill_service_client(); 106 107 network_state_handler_.reset(NetworkStateHandler::InitializeForTest()); 108 network_configuration_handler_.reset(new NetworkConfigurationHandler()); 109 network_configuration_handler_->Init(network_state_handler_.get()); 110 message_loop_.RunUntilIdle(); 111 } 112 113 virtual void TearDown() OVERRIDE { 114 network_configuration_handler_.reset(); 115 network_state_handler_.reset(); 116 DBusThreadManager::Shutdown(); 117 } 118 119 // Handles responses for GetProperties method calls. 120 void OnGetProperties( 121 const dbus::ObjectPath& path, 122 const ShillClientHelper::DictionaryValueCallback& callback) { 123 callback.Run(DBUS_METHOD_CALL_SUCCESS, *dictionary_value_result_); 124 } 125 126 // Handles responses for SetProperties method calls. 127 void OnSetProperties(const dbus::ObjectPath& service_path, 128 const base::DictionaryValue& properties, 129 const base::Closure& callback, 130 const ShillClientHelper::ErrorCallback& error_callback) { 131 callback.Run(); 132 } 133 134 // Handles responses for ClearProperties method calls. 135 void OnClearProperties( 136 const dbus::ObjectPath& service_path, 137 const std::vector<std::string>& names, 138 const ShillClientHelper::ListValueCallback& callback, 139 const ShillClientHelper::ErrorCallback& error_callback) { 140 base::ListValue result; 141 result.AppendBoolean(true); 142 callback.Run(result); 143 } 144 145 // Handles responses for ClearProperties method calls, and simulates an error 146 // result. 147 void OnClearPropertiesError( 148 const dbus::ObjectPath& service_path, 149 const std::vector<std::string>& names, 150 const ShillClientHelper::ListValueCallback& callback, 151 const ShillClientHelper::ErrorCallback& error_callback) { 152 base::ListValue result; 153 result.AppendBoolean(false); 154 callback.Run(result); 155 } 156 157 void OnConfigureService(const base::DictionaryValue& properties, 158 const ObjectPathCallback& callback, 159 const ShillClientHelper::ErrorCallback& error_callback) { 160 callback.Run(dbus::ObjectPath("/service/2")); 161 } 162 163 void OnGetLoadableProfileEntries( 164 const dbus::ObjectPath& service_path, 165 const ShillClientHelper::DictionaryValueCallback& callback) { 166 base::DictionaryValue entries; 167 entries.SetString("profile1", "entry1"); 168 entries.SetString("profile2", "entry2"); 169 callback.Run(DBUS_METHOD_CALL_SUCCESS, entries); 170 } 171 172 void OnDeleteEntry(const dbus::ObjectPath& profile_path, 173 const std::string& entry_path, 174 const base::Closure& callback, 175 const ShillClientHelper::ErrorCallback& error_callback) { 176 // Don't run the callback immediately to emulate actual behavior. 177 message_loop_.PostTask(FROM_HERE, callback); 178 } 179 180 bool PendingProfileEntryDeleterForTest(const std::string& service_path) { 181 return network_configuration_handler_-> 182 PendingProfileEntryDeleterForTest(service_path); 183 } 184 185 protected: 186 MockShillManagerClient* mock_manager_client_; 187 MockShillProfileClient* mock_profile_client_; 188 MockShillServiceClient* mock_service_client_; 189 scoped_ptr<NetworkStateHandler> network_state_handler_; 190 scoped_ptr<NetworkConfigurationHandler> network_configuration_handler_; 191 base::MessageLoop message_loop_; 192 base::DictionaryValue* dictionary_value_result_; 193}; 194 195TEST_F(NetworkConfigurationHandlerTest, GetProperties) { 196 std::string service_path = "/service/1"; 197 std::string expected_json = "{\n \"SSID\": \"MyNetwork\"\n}\n"; 198 std::string networkName = "MyNetwork"; 199 std::string key = "SSID"; 200 scoped_ptr<base::StringValue> networkNameValue( 201 base::Value::CreateStringValue(networkName)); 202 203 base::DictionaryValue value; 204 value.Set(key, base::Value::CreateStringValue(networkName)); 205 dictionary_value_result_ = &value; 206 EXPECT_CALL(*mock_service_client_, 207 SetProperty(dbus::ObjectPath(service_path), key, 208 IsEqualTo(networkNameValue.get()), _, _)).Times(1); 209 DBusThreadManager::Get()->GetShillServiceClient()->SetProperty( 210 dbus::ObjectPath(service_path), key, *networkNameValue, 211 base::Bind(&base::DoNothing), 212 base::Bind(&DBusErrorCallback)); 213 message_loop_.RunUntilIdle(); 214 215 ShillServiceClient::DictionaryValueCallback get_properties_callback; 216 EXPECT_CALL(*mock_service_client_, 217 GetProperties(_, _)).WillOnce( 218 Invoke(this, 219 &NetworkConfigurationHandlerTest::OnGetProperties)); 220 network_configuration_handler_->GetProperties( 221 service_path, 222 base::Bind(&DictionaryValueCallback, 223 service_path, 224 expected_json), 225 base::Bind(&ErrorCallback, false, service_path)); 226 message_loop_.RunUntilIdle(); 227} 228 229TEST_F(NetworkConfigurationHandlerTest, SetProperties) { 230 std::string service_path = "/service/1"; 231 std::string networkName = "MyNetwork"; 232 std::string key = "SSID"; 233 scoped_ptr<base::StringValue> networkNameValue( 234 base::Value::CreateStringValue(networkName)); 235 236 base::DictionaryValue value; 237 value.Set(key, base::Value::CreateStringValue(networkName)); 238 dictionary_value_result_ = &value; 239 EXPECT_CALL(*mock_service_client_, 240 SetProperties(_, _, _, _)).WillOnce( 241 Invoke(this, 242 &NetworkConfigurationHandlerTest::OnSetProperties)); 243 network_configuration_handler_->SetProperties( 244 service_path, 245 value, 246 base::Bind(&base::DoNothing), 247 base::Bind(&ErrorCallback, false, service_path)); 248 message_loop_.RunUntilIdle(); 249} 250 251TEST_F(NetworkConfigurationHandlerTest, ClearProperties) { 252 std::string service_path = "/service/1"; 253 std::string networkName = "MyNetwork"; 254 std::string key = "SSID"; 255 scoped_ptr<base::StringValue> networkNameValue( 256 base::Value::CreateStringValue(networkName)); 257 258 // First set up a value to clear. 259 base::DictionaryValue value; 260 value.Set(key, base::Value::CreateStringValue(networkName)); 261 dictionary_value_result_ = &value; 262 EXPECT_CALL(*mock_service_client_, 263 SetProperties(_, _, _, _)).WillOnce( 264 Invoke(this, 265 &NetworkConfigurationHandlerTest::OnSetProperties)); 266 network_configuration_handler_->SetProperties( 267 service_path, 268 value, 269 base::Bind(&base::DoNothing), 270 base::Bind(&ErrorCallback, false, service_path)); 271 message_loop_.RunUntilIdle(); 272 273 // Now clear it. 274 std::vector<std::string> values_to_clear; 275 values_to_clear.push_back(key); 276 EXPECT_CALL(*mock_service_client_, 277 ClearProperties(_, _, _, _)).WillOnce( 278 Invoke(this, 279 &NetworkConfigurationHandlerTest::OnClearProperties)); 280 network_configuration_handler_->ClearProperties( 281 service_path, 282 values_to_clear, 283 base::Bind(&base::DoNothing), 284 base::Bind(&ErrorCallback, false, service_path)); 285 message_loop_.RunUntilIdle(); 286} 287 288TEST_F(NetworkConfigurationHandlerTest, ClearPropertiesError) { 289 std::string service_path = "/service/1"; 290 std::string networkName = "MyNetwork"; 291 std::string key = "SSID"; 292 scoped_ptr<base::StringValue> networkNameValue( 293 base::Value::CreateStringValue(networkName)); 294 295 // First set up a value to clear. 296 base::DictionaryValue value; 297 value.Set(key, base::Value::CreateStringValue(networkName)); 298 dictionary_value_result_ = &value; 299 EXPECT_CALL(*mock_service_client_, 300 SetProperties(_, _, _, _)).WillOnce( 301 Invoke(this, 302 &NetworkConfigurationHandlerTest::OnSetProperties)); 303 network_configuration_handler_->SetProperties( 304 service_path, 305 value, 306 base::Bind(&base::DoNothing), 307 base::Bind(&ErrorCallback, false, service_path)); 308 message_loop_.RunUntilIdle(); 309 310 // Now clear it. 311 std::vector<std::string> values_to_clear; 312 values_to_clear.push_back(key); 313 EXPECT_CALL( 314 *mock_service_client_, 315 ClearProperties(_, _, _, _)).WillOnce( 316 Invoke(this, 317 &NetworkConfigurationHandlerTest::OnClearPropertiesError)); 318 network_configuration_handler_->ClearProperties( 319 service_path, 320 values_to_clear, 321 base::Bind(&base::DoNothing), 322 base::Bind(&ErrorCallback, true, service_path)); 323 message_loop_.RunUntilIdle(); 324} 325 326TEST_F(NetworkConfigurationHandlerTest, CreateConfiguration) { 327 std::string expected_json = "{\n \"SSID\": \"MyNetwork\"\n}\n"; 328 std::string networkName = "MyNetwork"; 329 std::string key = "SSID"; 330 scoped_ptr<base::StringValue> networkNameValue( 331 base::Value::CreateStringValue(networkName)); 332 base::DictionaryValue value; 333 value.Set(key, base::Value::CreateStringValue(networkName)); 334 335 EXPECT_CALL( 336 *mock_manager_client_, 337 ConfigureService(_, _, _)).WillOnce( 338 Invoke(this, 339 &NetworkConfigurationHandlerTest::OnConfigureService)); 340 network_configuration_handler_->CreateConfiguration( 341 value, 342 base::Bind(&StringResultCallback, std::string("/service/2")), 343 base::Bind(&ErrorCallback, false, std::string(""))); 344 message_loop_.RunUntilIdle(); 345} 346 347TEST_F(NetworkConfigurationHandlerTest, RemoveConfiguration) { 348 std::string service_path = "/service/1"; 349 350 TestCallback test_callback; 351 EXPECT_CALL( 352 *mock_service_client_, 353 GetLoadableProfileEntries(_, _)).WillOnce(Invoke( 354 this, 355 &NetworkConfigurationHandlerTest::OnGetLoadableProfileEntries)); 356 EXPECT_CALL( 357 *mock_profile_client_, 358 DeleteEntry(_, _, _, _)).WillRepeatedly(Invoke( 359 this, 360 &NetworkConfigurationHandlerTest::OnDeleteEntry)); 361 362 network_configuration_handler_->RemoveConfiguration( 363 service_path, 364 base::Bind(&TestCallback::Run, base::Unretained(&test_callback)), 365 base::Bind(&ErrorCallback, false, service_path)); 366 message_loop_.RunUntilIdle(); 367 EXPECT_EQ(1, test_callback.run_count()); 368 EXPECT_FALSE(PendingProfileEntryDeleterForTest(service_path)); 369} 370 371} // namespace chromeos 372