Home | History | Annotate | Download | only in dbus
      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 "chromeos/dbus/shill_client_unittest_base.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/json/json_writer.h"
      9 #include "base/values.h"
     10 #include "chromeos/network/shill_property_util.h"
     11 #include "dbus/message.h"
     12 #include "dbus/object_path.h"
     13 #include "dbus/values_util.h"
     14 #include "testing/gmock/include/gmock/gmock.h"
     15 #include "testing/gtest/include/gtest/gtest.h"
     16 #include "third_party/cros_system_api/dbus/service_constants.h"
     17 
     18 using ::testing::_;
     19 using ::testing::Invoke;
     20 using ::testing::Return;
     21 
     22 namespace chromeos {
     23 
     24 namespace {
     25 
     26 // Pops a string-to-string dictionary from the reader.
     27 base::DictionaryValue* PopStringToStringDictionary(
     28     dbus::MessageReader* reader) {
     29   dbus::MessageReader array_reader(NULL);
     30   if (!reader->PopArray(&array_reader))
     31     return NULL;
     32   scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue);
     33   while (array_reader.HasMoreData()) {
     34     dbus::MessageReader entry_reader(NULL);
     35     std::string key;
     36     std::string value;
     37     if (!array_reader.PopDictEntry(&entry_reader) ||
     38         !entry_reader.PopString(&key) ||
     39         !entry_reader.PopString(&value))
     40       return NULL;
     41     result->SetWithoutPathExpansion(key, new base::StringValue(value));
     42   }
     43   return result.release();
     44 }
     45 
     46 }  // namespace
     47 
     48 ValueMatcher::ValueMatcher(const base::Value& value)
     49   : expected_value_(value.DeepCopy()) {}
     50 
     51 bool ValueMatcher::MatchAndExplain(const base::Value& value,
     52                              MatchResultListener* listener) const {
     53   return expected_value_->Equals(&value);
     54 }
     55 
     56 void ValueMatcher::DescribeTo(::std::ostream* os) const {
     57   std::string expected_value_str;
     58   base::JSONWriter::WriteWithOptions(expected_value_.get(),
     59                                      base::JSONWriter::OPTIONS_PRETTY_PRINT,
     60                                      &expected_value_str);
     61   *os << "value equals " << expected_value_str;
     62 }
     63 
     64 void ValueMatcher::DescribeNegationTo(::std::ostream* os) const {
     65   std::string expected_value_str;
     66   base::JSONWriter::WriteWithOptions(expected_value_.get(),
     67                                      base::JSONWriter::OPTIONS_PRETTY_PRINT,
     68                                      &expected_value_str);
     69   *os << "value does not equal " << expected_value_str;
     70 }
     71 
     72 
     73 ShillClientUnittestBase::MockClosure::MockClosure() {}
     74 
     75 ShillClientUnittestBase::MockClosure::~MockClosure() {}
     76 
     77 base::Closure ShillClientUnittestBase::MockClosure::GetCallback() {
     78   return base::Bind(&MockClosure::Run, base::Unretained(this));
     79 }
     80 
     81 
     82 ShillClientUnittestBase::MockListValueCallback::MockListValueCallback() {}
     83 
     84 ShillClientUnittestBase::MockListValueCallback::~MockListValueCallback() {}
     85 
     86 ShillClientHelper::ListValueCallback
     87 ShillClientUnittestBase::MockListValueCallback::GetCallback() {
     88   return base::Bind(&MockListValueCallback::Run, base::Unretained(this));
     89 }
     90 
     91 
     92 ShillClientUnittestBase::MockErrorCallback::MockErrorCallback() {}
     93 
     94 ShillClientUnittestBase::MockErrorCallback::~MockErrorCallback() {}
     95 
     96 ShillClientUnittestBase::MockPropertyChangeObserver::
     97   MockPropertyChangeObserver() {}
     98 
     99 ShillClientUnittestBase::MockPropertyChangeObserver::
    100   ~MockPropertyChangeObserver() {}
    101 
    102 ShillClientHelper::ErrorCallback
    103 ShillClientUnittestBase::MockErrorCallback::GetCallback() {
    104   return base::Bind(&MockErrorCallback::Run, base::Unretained(this));
    105 }
    106 
    107 
    108 ShillClientUnittestBase::ShillClientUnittestBase(
    109     const std::string& interface_name,
    110     const dbus::ObjectPath& object_path)
    111     : interface_name_(interface_name),
    112       object_path_(object_path),
    113       response_(NULL) {
    114 }
    115 
    116 ShillClientUnittestBase::~ShillClientUnittestBase() {
    117 }
    118 
    119 void ShillClientUnittestBase::SetUp() {
    120   // Create a mock bus.
    121   dbus::Bus::Options options;
    122   options.bus_type = dbus::Bus::SYSTEM;
    123   mock_bus_ = new dbus::MockBus(options);
    124 
    125   // Create a mock proxy.
    126   mock_proxy_ = new dbus::MockObjectProxy(
    127       mock_bus_.get(),
    128       shill::kFlimflamServiceName,
    129       object_path_);
    130 
    131   // Set an expectation so mock_proxy's CallMethod() will use OnCallMethod()
    132   // to return responses.
    133   EXPECT_CALL(*mock_proxy_.get(), CallMethod(_, _, _))
    134       .WillRepeatedly(Invoke(this, &ShillClientUnittestBase::OnCallMethod));
    135 
    136   // Set an expectation so mock_proxy's CallMethodWithErrorCallback() will use
    137   // OnCallMethodWithErrorCallback() to return responses.
    138   EXPECT_CALL(*mock_proxy_.get(), CallMethodWithErrorCallback(_, _, _, _))
    139       .WillRepeatedly(Invoke(
    140            this, &ShillClientUnittestBase::OnCallMethodWithErrorCallback));
    141 
    142   // Set an expectation so mock_proxy's ConnectToSignal() will use
    143   // OnConnectToSignal() to run the callback.
    144   EXPECT_CALL(
    145       *mock_proxy_.get(),
    146       ConnectToSignal(interface_name_, shill::kMonitorPropertyChanged, _, _))
    147       .WillRepeatedly(
    148            Invoke(this, &ShillClientUnittestBase::OnConnectToSignal));
    149 
    150   // Set an expectation so mock_bus's GetObjectProxy() for the given
    151   // service name and the object path will return mock_proxy_.
    152   EXPECT_CALL(*mock_bus_.get(),
    153               GetObjectProxy(shill::kFlimflamServiceName, object_path_))
    154       .WillOnce(Return(mock_proxy_.get()));
    155 
    156   // Set an expectation so mock_bus's GetDBusTaskRunner will return the current
    157   // task runner.
    158   EXPECT_CALL(*mock_bus_.get(), GetDBusTaskRunner())
    159       .WillRepeatedly(Return(message_loop_.message_loop_proxy().get()));
    160 
    161   // ShutdownAndBlock() will be called in TearDown().
    162   EXPECT_CALL(*mock_bus_.get(), ShutdownAndBlock()).WillOnce(Return());
    163 }
    164 
    165 void ShillClientUnittestBase::TearDown() {
    166   mock_bus_->ShutdownAndBlock();
    167 }
    168 
    169 void ShillClientUnittestBase::PrepareForMethodCall(
    170     const std::string& method_name,
    171     const ArgumentCheckCallback& argument_checker,
    172     dbus::Response* response) {
    173   expected_method_name_ = method_name;
    174   argument_checker_ = argument_checker;
    175   response_ = response;
    176 }
    177 
    178 void ShillClientUnittestBase::SendPropertyChangedSignal(
    179     dbus::Signal* signal) {
    180   ASSERT_FALSE(property_changed_handler_.is_null());
    181   property_changed_handler_.Run(signal);
    182 }
    183 
    184 // static
    185 void ShillClientUnittestBase::ExpectPropertyChanged(
    186     const std::string& expected_name,
    187     const base::Value* expected_value,
    188     const std::string& name,
    189     const base::Value& value) {
    190   EXPECT_EQ(expected_name, name);
    191   EXPECT_TRUE(expected_value->Equals(&value));
    192 }
    193 
    194 // static
    195 void ShillClientUnittestBase::ExpectNoArgument(dbus::MessageReader* reader) {
    196   EXPECT_FALSE(reader->HasMoreData());
    197 }
    198 
    199 // static
    200 void ShillClientUnittestBase::ExpectStringArgument(
    201     const std::string& expected_string,
    202     dbus::MessageReader* reader) {
    203   std::string str;
    204   ASSERT_TRUE(reader->PopString(&str));
    205   EXPECT_EQ(expected_string, str);
    206   EXPECT_FALSE(reader->HasMoreData());
    207 }
    208 
    209 // static
    210 void ShillClientUnittestBase::ExpectArrayOfStringsArgument(
    211     const std::vector<std::string>& expected_strings,
    212     dbus::MessageReader* reader) {
    213   std::vector<std::string> strs;
    214   ASSERT_TRUE(reader->PopArrayOfStrings(&strs));
    215   EXPECT_EQ(expected_strings, strs);
    216   EXPECT_FALSE(reader->HasMoreData());
    217 }
    218 
    219 // static
    220 void ShillClientUnittestBase::ExpectValueArgument(
    221     const base::Value* expected_value,
    222     dbus::MessageReader* reader) {
    223   scoped_ptr<base::Value> value(dbus::PopDataAsValue(reader));
    224   ASSERT_TRUE(value.get());
    225   EXPECT_TRUE(value->Equals(expected_value));
    226   EXPECT_FALSE(reader->HasMoreData());
    227 }
    228 
    229 // static
    230 void ShillClientUnittestBase::ExpectStringAndValueArguments(
    231     const std::string& expected_string,
    232     const base::Value* expected_value,
    233     dbus::MessageReader* reader) {
    234   std::string str;
    235   ASSERT_TRUE(reader->PopString(&str));
    236   EXPECT_EQ(expected_string, str);
    237   scoped_ptr<base::Value> value(dbus::PopDataAsValue(reader));
    238   ASSERT_TRUE(value.get());
    239   EXPECT_TRUE(value->Equals(expected_value));
    240   EXPECT_FALSE(reader->HasMoreData());
    241 }
    242 
    243 // static
    244 void ShillClientUnittestBase::ExpectDictionaryValueArgument(
    245     const base::DictionaryValue* expected_dictionary,
    246     dbus::MessageReader* reader) {
    247   dbus::MessageReader array_reader(NULL);
    248   ASSERT_TRUE(reader->PopArray(&array_reader));
    249   while (array_reader.HasMoreData()) {
    250     dbus::MessageReader entry_reader(NULL);
    251     ASSERT_TRUE(array_reader.PopDictEntry(&entry_reader));
    252     std::string key;
    253     ASSERT_TRUE(entry_reader.PopString(&key));
    254     dbus::MessageReader variant_reader(NULL);
    255     ASSERT_TRUE(entry_reader.PopVariant(&variant_reader));
    256     scoped_ptr<base::Value> value;
    257     // Variants in the dictionary can be basic types or string-to-string
    258     // dictinoary.
    259     switch (variant_reader.GetDataType()) {
    260       case dbus::Message::ARRAY:
    261         value.reset(PopStringToStringDictionary(&variant_reader));
    262         break;
    263       case dbus::Message::BOOL:
    264       case dbus::Message::INT32:
    265       case dbus::Message::STRING:
    266         value.reset(dbus::PopDataAsValue(&variant_reader));
    267         break;
    268       default:
    269         NOTREACHED();
    270     }
    271     ASSERT_TRUE(value.get());
    272     const base::Value* expected_value = NULL;
    273     EXPECT_TRUE(expected_dictionary->GetWithoutPathExpansion(key,
    274                                                              &expected_value));
    275     EXPECT_TRUE(value->Equals(expected_value));
    276   }
    277 }
    278 
    279 // static
    280 base::DictionaryValue*
    281 ShillClientUnittestBase::CreateExampleServiceProperties() {
    282   base::DictionaryValue* properties = new base::DictionaryValue;
    283   properties->SetWithoutPathExpansion(
    284       shill::kGuidProperty,
    285       new base::StringValue("00000000-0000-0000-0000-000000000000"));
    286   properties->SetWithoutPathExpansion(
    287       shill::kModeProperty, new base::StringValue(shill::kModeManaged));
    288   properties->SetWithoutPathExpansion(shill::kTypeProperty,
    289                                       new base::StringValue(shill::kTypeWifi));
    290   shill_property_util::SetSSID("testssid", properties);
    291   properties->SetWithoutPathExpansion(
    292       shill::kSecurityProperty, new base::StringValue(shill::kSecurityPsk));
    293   return properties;
    294 }
    295 
    296 
    297 // static
    298 void ShillClientUnittestBase::ExpectNoResultValue(
    299     DBusMethodCallStatus call_status) {
    300   EXPECT_EQ(DBUS_METHOD_CALL_SUCCESS, call_status);
    301 }
    302 
    303 // static
    304 void ShillClientUnittestBase::ExpectObjectPathResult(
    305     const dbus::ObjectPath& expected_result,
    306     DBusMethodCallStatus call_status,
    307     const dbus::ObjectPath& result) {
    308   EXPECT_EQ(DBUS_METHOD_CALL_SUCCESS, call_status);
    309   EXPECT_EQ(expected_result, result);
    310 }
    311 
    312 // static
    313 void ShillClientUnittestBase::ExpectObjectPathResultWithoutStatus(
    314     const dbus::ObjectPath& expected_result,
    315     const dbus::ObjectPath& result) {
    316   EXPECT_EQ(expected_result, result);
    317 }
    318 
    319 // static
    320 void ShillClientUnittestBase::ExpectBoolResultWithoutStatus(
    321     bool expected_result,
    322     bool result) {
    323   EXPECT_EQ(expected_result, result);
    324 }
    325 
    326 // static
    327 void ShillClientUnittestBase::ExpectStringResultWithoutStatus(
    328     const std::string& expected_result,
    329     const std::string& result) {
    330   EXPECT_EQ(expected_result, result);
    331 }
    332 
    333 // static
    334 void ShillClientUnittestBase::ExpectDictionaryValueResultWithoutStatus(
    335     const base::DictionaryValue* expected_result,
    336     const base::DictionaryValue& result) {
    337   std::string expected_result_string;
    338   base::JSONWriter::Write(expected_result, &expected_result_string);
    339   std::string result_string;
    340   base::JSONWriter::Write(&result, &result_string);
    341   EXPECT_EQ(expected_result_string, result_string);
    342 }
    343 
    344 // static
    345 void ShillClientUnittestBase::ExpectDictionaryValueResult(
    346     const base::DictionaryValue* expected_result,
    347     DBusMethodCallStatus call_status,
    348     const base::DictionaryValue& result) {
    349   EXPECT_EQ(DBUS_METHOD_CALL_SUCCESS, call_status);
    350   ExpectDictionaryValueResultWithoutStatus(expected_result, result);
    351 }
    352 
    353 void ShillClientUnittestBase::OnConnectToSignal(
    354     const std::string& interface_name,
    355     const std::string& signal_name,
    356     const dbus::ObjectProxy::SignalCallback& signal_callback,
    357     const dbus::ObjectProxy::OnConnectedCallback& on_connected_callback) {
    358   property_changed_handler_ = signal_callback;
    359   const bool success = true;
    360   message_loop_.PostTask(FROM_HERE,
    361                          base::Bind(on_connected_callback,
    362                                     interface_name,
    363                                     signal_name,
    364                                     success));
    365 }
    366 
    367 void ShillClientUnittestBase::OnCallMethod(
    368     dbus::MethodCall* method_call,
    369     int timeout_ms,
    370     const dbus::ObjectProxy::ResponseCallback& response_callback) {
    371   EXPECT_EQ(interface_name_, method_call->GetInterface());
    372   EXPECT_EQ(expected_method_name_, method_call->GetMember());
    373   dbus::MessageReader reader(method_call);
    374   argument_checker_.Run(&reader);
    375   message_loop_.PostTask(FROM_HERE,
    376                          base::Bind(response_callback, response_));
    377 }
    378 
    379 void ShillClientUnittestBase::OnCallMethodWithErrorCallback(
    380     dbus::MethodCall* method_call,
    381     int timeout_ms,
    382     const dbus::ObjectProxy::ResponseCallback& response_callback,
    383     const dbus::ObjectProxy::ErrorCallback& error_callback) {
    384   OnCallMethod(method_call, timeout_ms, response_callback);
    385 }
    386 
    387 }  // namespace chromeos
    388