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.
5 #include "chromeos/dbus/shill_client_unittest_base.h"
8 #include "base/json/json_writer.h"
9 #include "base/location.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/values.h"
12 #include "chromeos/network/shill_property_util.h"
13 #include "dbus/message.h"
14 #include "dbus/object_path.h"
15 #include "dbus/values_util.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "third_party/cros_system_api/dbus/service_constants.h"
20 using ::testing::Invoke
;
21 using ::testing::Return
;
27 // Pops a string-to-string dictionary from the reader.
28 base::DictionaryValue
* PopStringToStringDictionary(
29 dbus::MessageReader
* reader
) {
30 dbus::MessageReader
array_reader(NULL
);
31 if (!reader
->PopArray(&array_reader
))
33 scoped_ptr
<base::DictionaryValue
> result(new base::DictionaryValue
);
34 while (array_reader
.HasMoreData()) {
35 dbus::MessageReader
entry_reader(NULL
);
38 if (!array_reader
.PopDictEntry(&entry_reader
) ||
39 !entry_reader
.PopString(&key
) ||
40 !entry_reader
.PopString(&value
))
42 result
->SetWithoutPathExpansion(key
, new base::StringValue(value
));
44 return result
.release();
49 ValueMatcher::ValueMatcher(const base::Value
& value
)
50 : expected_value_(value
.DeepCopy()) {}
52 bool ValueMatcher::MatchAndExplain(const base::Value
& value
,
53 MatchResultListener
* listener
) const {
54 return expected_value_
->Equals(&value
);
57 void ValueMatcher::DescribeTo(::std::ostream
* os
) const {
58 std::string expected_value_str
;
59 base::JSONWriter::WriteWithOptions(*expected_value_
,
60 base::JSONWriter::OPTIONS_PRETTY_PRINT
,
62 *os
<< "value equals " << expected_value_str
;
65 void ValueMatcher::DescribeNegationTo(::std::ostream
* os
) const {
66 std::string expected_value_str
;
67 base::JSONWriter::WriteWithOptions(*expected_value_
,
68 base::JSONWriter::OPTIONS_PRETTY_PRINT
,
70 *os
<< "value does not equal " << expected_value_str
;
74 ShillClientUnittestBase::MockClosure::MockClosure() {}
76 ShillClientUnittestBase::MockClosure::~MockClosure() {}
78 base::Closure
ShillClientUnittestBase::MockClosure::GetCallback() {
79 return base::Bind(&MockClosure::Run
, base::Unretained(this));
83 ShillClientUnittestBase::MockListValueCallback::MockListValueCallback() {}
85 ShillClientUnittestBase::MockListValueCallback::~MockListValueCallback() {}
87 ShillClientHelper::ListValueCallback
88 ShillClientUnittestBase::MockListValueCallback::GetCallback() {
89 return base::Bind(&MockListValueCallback::Run
, base::Unretained(this));
93 ShillClientUnittestBase::MockErrorCallback::MockErrorCallback() {}
95 ShillClientUnittestBase::MockErrorCallback::~MockErrorCallback() {}
97 ShillClientUnittestBase::MockPropertyChangeObserver::
98 MockPropertyChangeObserver() {}
100 ShillClientUnittestBase::MockPropertyChangeObserver::
101 ~MockPropertyChangeObserver() {}
103 ShillClientHelper::ErrorCallback
104 ShillClientUnittestBase::MockErrorCallback::GetCallback() {
105 return base::Bind(&MockErrorCallback::Run
, base::Unretained(this));
109 ShillClientUnittestBase::ShillClientUnittestBase(
110 const std::string
& interface_name
,
111 const dbus::ObjectPath
& object_path
)
112 : interface_name_(interface_name
),
113 object_path_(object_path
),
117 ShillClientUnittestBase::~ShillClientUnittestBase() {
120 void ShillClientUnittestBase::SetUp() {
121 // Create a mock bus.
122 dbus::Bus::Options options
;
123 options
.bus_type
= dbus::Bus::SYSTEM
;
124 mock_bus_
= new dbus::MockBus(options
);
126 // Create a mock proxy.
127 mock_proxy_
= new dbus::MockObjectProxy(
129 shill::kFlimflamServiceName
,
132 // Set an expectation so mock_proxy's CallMethod() will use OnCallMethod()
133 // to return responses.
134 EXPECT_CALL(*mock_proxy_
.get(), CallMethod(_
, _
, _
))
135 .WillRepeatedly(Invoke(this, &ShillClientUnittestBase::OnCallMethod
));
137 // Set an expectation so mock_proxy's CallMethodWithErrorCallback() will use
138 // OnCallMethodWithErrorCallback() to return responses.
139 EXPECT_CALL(*mock_proxy_
.get(), CallMethodWithErrorCallback(_
, _
, _
, _
))
140 .WillRepeatedly(Invoke(
141 this, &ShillClientUnittestBase::OnCallMethodWithErrorCallback
));
143 // Set an expectation so mock_proxy's ConnectToSignal() will use
144 // OnConnectToPropertyChanged() to run the callback.
147 ConnectToSignal(interface_name_
, shill::kMonitorPropertyChanged
, _
, _
))
149 Invoke(this, &ShillClientUnittestBase::OnConnectToPropertyChanged
));
153 ConnectToSignal(interface_name_
, shill::kOnPlatformMessageFunction
, _
, _
))
155 Invoke(this, &ShillClientUnittestBase::OnConnectToPlatformMessage
));
159 ConnectToSignal(interface_name_
, shill::kOnPacketReceivedFunction
, _
, _
))
161 Invoke(this, &ShillClientUnittestBase::OnConnectToPacketReceived
));
163 // Set an expectation so mock_bus's GetObjectProxy() for the given
164 // service name and the object path will return mock_proxy_.
165 EXPECT_CALL(*mock_bus_
.get(),
166 GetObjectProxy(shill::kFlimflamServiceName
, object_path_
))
167 .WillOnce(Return(mock_proxy_
.get()));
169 // Set an expectation so mock_bus's GetDBusTaskRunner will return the current
171 EXPECT_CALL(*mock_bus_
.get(), GetDBusTaskRunner())
172 .WillRepeatedly(Return(message_loop_
.task_runner().get()));
174 // ShutdownAndBlock() will be called in TearDown().
175 EXPECT_CALL(*mock_bus_
.get(), ShutdownAndBlock()).WillOnce(Return());
178 void ShillClientUnittestBase::TearDown() {
179 mock_bus_
->ShutdownAndBlock();
182 void ShillClientUnittestBase::PrepareForMethodCall(
183 const std::string
& method_name
,
184 const ArgumentCheckCallback
& argument_checker
,
185 dbus::Response
* response
) {
186 expected_method_name_
= method_name
;
187 argument_checker_
= argument_checker
;
188 response_
= response
;
191 void ShillClientUnittestBase::SendPlatformMessageSignal(
192 dbus::Signal
* signal
) {
193 ASSERT_FALSE(platform_message_handler_
.is_null());
194 platform_message_handler_
.Run(signal
);
197 void ShillClientUnittestBase::SendPacketReceievedSignal(
198 dbus::Signal
* signal
) {
199 ASSERT_FALSE(packet_receieved__handler_
.is_null());
200 packet_receieved__handler_
.Run(signal
);
203 void ShillClientUnittestBase::SendPropertyChangedSignal(
204 dbus::Signal
* signal
) {
205 ASSERT_FALSE(property_changed_handler_
.is_null());
206 property_changed_handler_
.Run(signal
);
210 void ShillClientUnittestBase::ExpectPropertyChanged(
211 const std::string
& expected_name
,
212 const base::Value
* expected_value
,
213 const std::string
& name
,
214 const base::Value
& value
) {
215 EXPECT_EQ(expected_name
, name
);
216 EXPECT_TRUE(expected_value
->Equals(&value
));
220 void ShillClientUnittestBase::ExpectNoArgument(dbus::MessageReader
* reader
) {
221 EXPECT_FALSE(reader
->HasMoreData());
225 void ShillClientUnittestBase::ExpectUint32Argument(
226 uint32_t expected_value
,
227 dbus::MessageReader
* reader
) {
229 ASSERT_TRUE(reader
->PopUint32(&value
));
230 EXPECT_EQ(expected_value
, value
);
231 EXPECT_FALSE(reader
->HasMoreData());
235 void ShillClientUnittestBase::ExpectArrayOfBytesArgument(
236 const std::string
& expected_bytes
,
237 dbus::MessageReader
* reader
) {
238 const uint8_t* bytes
= nullptr;
240 ASSERT_TRUE(reader
->PopArrayOfBytes(&bytes
, &size
));
241 EXPECT_EQ(expected_bytes
.size(), size
);
242 for (size_t i
= 0; i
< size
; ++i
) {
243 EXPECT_EQ(expected_bytes
[i
], bytes
[i
]);
245 EXPECT_FALSE(reader
->HasMoreData());
249 void ShillClientUnittestBase::ExpectStringArgument(
250 const std::string
& expected_string
,
251 dbus::MessageReader
* reader
) {
253 ASSERT_TRUE(reader
->PopString(&str
));
254 EXPECT_EQ(expected_string
, str
);
255 EXPECT_FALSE(reader
->HasMoreData());
259 void ShillClientUnittestBase::ExpectArrayOfStringsArgument(
260 const std::vector
<std::string
>& expected_strings
,
261 dbus::MessageReader
* reader
) {
262 std::vector
<std::string
> strs
;
263 ASSERT_TRUE(reader
->PopArrayOfStrings(&strs
));
264 EXPECT_EQ(expected_strings
, strs
);
265 EXPECT_FALSE(reader
->HasMoreData());
269 void ShillClientUnittestBase::ExpectValueArgument(
270 const base::Value
* expected_value
,
271 dbus::MessageReader
* reader
) {
272 scoped_ptr
<base::Value
> value(dbus::PopDataAsValue(reader
));
273 ASSERT_TRUE(value
.get());
274 EXPECT_TRUE(value
->Equals(expected_value
));
275 EXPECT_FALSE(reader
->HasMoreData());
279 void ShillClientUnittestBase::ExpectStringAndValueArguments(
280 const std::string
& expected_string
,
281 const base::Value
* expected_value
,
282 dbus::MessageReader
* reader
) {
284 ASSERT_TRUE(reader
->PopString(&str
));
285 EXPECT_EQ(expected_string
, str
);
286 scoped_ptr
<base::Value
> value(dbus::PopDataAsValue(reader
));
287 ASSERT_TRUE(value
.get());
288 EXPECT_TRUE(value
->Equals(expected_value
));
289 EXPECT_FALSE(reader
->HasMoreData());
293 void ShillClientUnittestBase::ExpectDictionaryValueArgument(
294 const base::DictionaryValue
* expected_dictionary
,
296 dbus::MessageReader
* reader
) {
297 dbus::MessageReader
array_reader(NULL
);
298 ASSERT_TRUE(reader
->PopArray(&array_reader
));
299 while (array_reader
.HasMoreData()) {
300 dbus::MessageReader
entry_reader(NULL
);
301 ASSERT_TRUE(array_reader
.PopDictEntry(&entry_reader
));
303 ASSERT_TRUE(entry_reader
.PopString(&key
));
306 std::string expected_value
;
307 ASSERT_TRUE(entry_reader
.PopString(&value
));
308 EXPECT_TRUE(expected_dictionary
->GetStringWithoutPathExpansion(
309 key
, &expected_value
));
310 EXPECT_EQ(expected_value
, value
);
313 dbus::MessageReader
variant_reader(NULL
);
314 ASSERT_TRUE(entry_reader
.PopVariant(&variant_reader
));
315 scoped_ptr
<base::Value
> value
;
316 // Variants in the dictionary can be basic types or string-to-string
318 switch (variant_reader
.GetDataType()) {
319 case dbus::Message::ARRAY
:
320 value
.reset(PopStringToStringDictionary(&variant_reader
));
322 case dbus::Message::BOOL
:
323 case dbus::Message::INT32
:
324 case dbus::Message::STRING
:
325 value
.reset(dbus::PopDataAsValue(&variant_reader
));
330 ASSERT_TRUE(value
.get());
331 const base::Value
* expected_value
= NULL
;
332 EXPECT_TRUE(expected_dictionary
->GetWithoutPathExpansion(key
,
334 EXPECT_TRUE(value
->Equals(expected_value
));
339 base::DictionaryValue
*
340 ShillClientUnittestBase::CreateExampleServiceProperties() {
341 base::DictionaryValue
* properties
= new base::DictionaryValue
;
342 properties
->SetWithoutPathExpansion(
343 shill::kGuidProperty
,
344 new base::StringValue("00000000-0000-0000-0000-000000000000"));
345 properties
->SetWithoutPathExpansion(
346 shill::kModeProperty
, new base::StringValue(shill::kModeManaged
));
347 properties
->SetWithoutPathExpansion(shill::kTypeProperty
,
348 new base::StringValue(shill::kTypeWifi
));
349 shill_property_util::SetSSID("testssid", properties
);
350 properties
->SetWithoutPathExpansion(
351 shill::kSecurityClassProperty
,
352 new base::StringValue(shill::kSecurityPsk
));
358 void ShillClientUnittestBase::ExpectNoResultValue(
359 DBusMethodCallStatus call_status
) {
360 EXPECT_EQ(DBUS_METHOD_CALL_SUCCESS
, call_status
);
364 void ShillClientUnittestBase::ExpectObjectPathResult(
365 const dbus::ObjectPath
& expected_result
,
366 DBusMethodCallStatus call_status
,
367 const dbus::ObjectPath
& result
) {
368 EXPECT_EQ(DBUS_METHOD_CALL_SUCCESS
, call_status
);
369 EXPECT_EQ(expected_result
, result
);
373 void ShillClientUnittestBase::ExpectObjectPathResultWithoutStatus(
374 const dbus::ObjectPath
& expected_result
,
375 const dbus::ObjectPath
& result
) {
376 EXPECT_EQ(expected_result
, result
);
380 void ShillClientUnittestBase::ExpectBoolResultWithoutStatus(
381 bool expected_result
,
383 EXPECT_EQ(expected_result
, result
);
387 void ShillClientUnittestBase::ExpectStringResultWithoutStatus(
388 const std::string
& expected_result
,
389 const std::string
& result
) {
390 EXPECT_EQ(expected_result
, result
);
394 void ShillClientUnittestBase::ExpectDictionaryValueResultWithoutStatus(
395 const base::DictionaryValue
* expected_result
,
396 const base::DictionaryValue
& result
) {
397 std::string expected_result_string
;
398 base::JSONWriter::Write(*expected_result
, &expected_result_string
);
399 std::string result_string
;
400 base::JSONWriter::Write(result
, &result_string
);
401 EXPECT_EQ(expected_result_string
, result_string
);
405 void ShillClientUnittestBase::ExpectDictionaryValueResult(
406 const base::DictionaryValue
* expected_result
,
407 DBusMethodCallStatus call_status
,
408 const base::DictionaryValue
& result
) {
409 EXPECT_EQ(DBUS_METHOD_CALL_SUCCESS
, call_status
);
410 ExpectDictionaryValueResultWithoutStatus(expected_result
, result
);
413 void ShillClientUnittestBase::OnConnectToPlatformMessage(
414 const std::string
& interface_name
,
415 const std::string
& signal_name
,
416 const dbus::ObjectProxy::SignalCallback
& signal_callback
,
417 const dbus::ObjectProxy::OnConnectedCallback
& on_connected_callback
) {
418 platform_message_handler_
= signal_callback
;
419 const bool success
= true;
420 message_loop_
.task_runner()->PostTask(
422 base::Bind(on_connected_callback
, interface_name
, signal_name
, success
));
425 void ShillClientUnittestBase::OnConnectToPacketReceived(
426 const std::string
& interface_name
,
427 const std::string
& signal_name
,
428 const dbus::ObjectProxy::SignalCallback
& signal_callback
,
429 const dbus::ObjectProxy::OnConnectedCallback
& on_connected_callback
) {
430 packet_receieved__handler_
= signal_callback
;
431 const bool success
= true;
432 message_loop_
.task_runner()->PostTask(
434 base::Bind(on_connected_callback
, interface_name
, signal_name
, success
));
437 void ShillClientUnittestBase::OnConnectToPropertyChanged(
438 const std::string
& interface_name
,
439 const std::string
& signal_name
,
440 const dbus::ObjectProxy::SignalCallback
& signal_callback
,
441 const dbus::ObjectProxy::OnConnectedCallback
& on_connected_callback
) {
442 property_changed_handler_
= signal_callback
;
443 const bool success
= true;
444 message_loop_
.task_runner()->PostTask(
446 base::Bind(on_connected_callback
, interface_name
, signal_name
, success
));
449 void ShillClientUnittestBase::OnCallMethod(
450 dbus::MethodCall
* method_call
,
452 const dbus::ObjectProxy::ResponseCallback
& response_callback
) {
453 EXPECT_EQ(interface_name_
, method_call
->GetInterface());
454 EXPECT_EQ(expected_method_name_
, method_call
->GetMember());
455 dbus::MessageReader
reader(method_call
);
456 argument_checker_
.Run(&reader
);
457 message_loop_
.task_runner()->PostTask(
458 FROM_HERE
, base::Bind(response_callback
, response_
));
461 void ShillClientUnittestBase::OnCallMethodWithErrorCallback(
462 dbus::MethodCall
* method_call
,
464 const dbus::ObjectProxy::ResponseCallback
& response_callback
,
465 const dbus::ObjectProxy::ErrorCallback
& error_callback
) {
466 OnCallMethod(method_call
, timeout_ms
, response_callback
);
469 } // namespace chromeos