Home | History | Annotate | Download | only in dbus
      1 // Copyright 2014 The Chromium OS 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 <brillo/dbus/exported_object_manager.h>
      6 
      7 #include <base/bind.h>
      8 #include <brillo/dbus/dbus_object_test_helpers.h>
      9 #include <brillo/dbus/utils.h>
     10 #include <dbus/mock_bus.h>
     11 #include <dbus/mock_exported_object.h>
     12 #include <dbus/object_manager.h>
     13 #include <dbus/object_path.h>
     14 #include <gtest/gtest.h>
     15 
     16 using ::testing::AnyNumber;
     17 using ::testing::InSequence;
     18 using ::testing::Invoke;
     19 using ::testing::Return;
     20 using ::testing::_;
     21 
     22 namespace brillo {
     23 
     24 namespace dbus_utils {
     25 
     26 namespace {
     27 
     28 const dbus::ObjectPath kTestPath(std::string("/test/om_path"));
     29 const dbus::ObjectPath kClaimedTestPath(std::string("/test/claimed_path"));
     30 const std::string kClaimedInterface("claimed.interface");
     31 const std::string kTestPropertyName("PropertyName");
     32 const std::string kTestPropertyValue("PropertyValue");
     33 
     34 void WriteTestPropertyDict(VariantDictionary* dict) {
     35   dict->insert(std::make_pair(kTestPropertyName, Any(kTestPropertyValue)));
     36 }
     37 
     38 void ReadTestPropertyDict(dbus::MessageReader* reader) {
     39   dbus::MessageReader all_properties(nullptr);
     40   dbus::MessageReader each_property(nullptr);
     41   ASSERT_TRUE(reader->PopArray(&all_properties));
     42   ASSERT_TRUE(all_properties.PopDictEntry(&each_property));
     43   std::string property_name;
     44   std::string property_value;
     45   ASSERT_TRUE(each_property.PopString(&property_name));
     46   ASSERT_TRUE(each_property.PopVariantOfString(&property_value));
     47   EXPECT_FALSE(each_property.HasMoreData());
     48   EXPECT_FALSE(all_properties.HasMoreData());
     49   EXPECT_EQ(property_name, kTestPropertyName);
     50   EXPECT_EQ(property_value, kTestPropertyValue);
     51 }
     52 
     53 void VerifyInterfaceClaimSignal(dbus::Signal* signal) {
     54   EXPECT_EQ(signal->GetInterface(), std::string(dbus::kObjectManagerInterface));
     55   EXPECT_EQ(signal->GetMember(),
     56             std::string(dbus::kObjectManagerInterfacesAdded));
     57   //   org.freedesktop.DBus.ObjectManager.InterfacesAdded (
     58   //       OBJPATH object_path,
     59   //       DICT<STRING,DICT<STRING,VARIANT>> interfaces_and_properties);
     60   dbus::MessageReader reader(signal);
     61   dbus::MessageReader all_interfaces(nullptr);
     62   dbus::MessageReader each_interface(nullptr);
     63   dbus::ObjectPath path;
     64   ASSERT_TRUE(reader.PopObjectPath(&path));
     65   ASSERT_TRUE(reader.PopArray(&all_interfaces));
     66   ASSERT_TRUE(all_interfaces.PopDictEntry(&each_interface));
     67   std::string interface_name;
     68   ASSERT_TRUE(each_interface.PopString(&interface_name));
     69   ReadTestPropertyDict(&each_interface);
     70   EXPECT_FALSE(each_interface.HasMoreData());
     71   EXPECT_FALSE(all_interfaces.HasMoreData());
     72   EXPECT_FALSE(reader.HasMoreData());
     73   EXPECT_EQ(interface_name, kClaimedInterface);
     74   EXPECT_EQ(path, kClaimedTestPath);
     75 }
     76 
     77 void VerifyInterfaceDropSignal(dbus::Signal* signal) {
     78   EXPECT_EQ(signal->GetInterface(), std::string(dbus::kObjectManagerInterface));
     79   EXPECT_EQ(signal->GetMember(),
     80             std::string(dbus::kObjectManagerInterfacesRemoved));
     81   //   org.freedesktop.DBus.ObjectManager.InterfacesRemoved (
     82   //       OBJPATH object_path, ARRAY<STRING> interfaces);
     83   dbus::MessageReader reader(signal);
     84   dbus::MessageReader each_interface(nullptr);
     85   dbus::ObjectPath path;
     86   ASSERT_TRUE(reader.PopObjectPath(&path));
     87   ASSERT_TRUE(reader.PopArray(&each_interface));
     88   std::string interface_name;
     89   ASSERT_TRUE(each_interface.PopString(&interface_name));
     90   EXPECT_FALSE(each_interface.HasMoreData());
     91   EXPECT_FALSE(reader.HasMoreData());
     92   EXPECT_EQ(interface_name, kClaimedInterface);
     93   EXPECT_EQ(path, kClaimedTestPath);
     94 }
     95 
     96 }  // namespace
     97 
     98 class ExportedObjectManagerTest : public ::testing::Test {
     99  public:
    100   void SetUp() override {
    101     dbus::Bus::Options options;
    102     options.bus_type = dbus::Bus::SYSTEM;
    103     bus_ = new dbus::MockBus(options);
    104     // By default, don't worry about threading assertions.
    105     EXPECT_CALL(*bus_, AssertOnOriginThread()).Times(AnyNumber());
    106     EXPECT_CALL(*bus_, AssertOnDBusThread()).Times(AnyNumber());
    107     // Use a mock exported object.
    108     mock_exported_object_ = new dbus::MockExportedObject(bus_.get(), kTestPath);
    109     EXPECT_CALL(*bus_, GetExportedObject(kTestPath)).Times(1).WillOnce(
    110         Return(mock_exported_object_.get()));
    111     EXPECT_CALL(*mock_exported_object_, ExportMethod(_, _, _, _))
    112         .Times(AnyNumber());
    113     om_.reset(new ExportedObjectManager(bus_.get(), kTestPath));
    114     property_writer_ = base::Bind(&WriteTestPropertyDict);
    115     om_->RegisterAsync(AsyncEventSequencer::GetDefaultCompletionAction());
    116   }
    117 
    118   void TearDown() override {
    119     EXPECT_CALL(*mock_exported_object_, Unregister()).Times(1);
    120     om_.reset();
    121     bus_ = nullptr;
    122   }
    123 
    124   std::unique_ptr<dbus::Response> CallHandleGetManagedObjects() {
    125     dbus::MethodCall method_call(dbus::kObjectManagerInterface,
    126                                  dbus::kObjectManagerGetManagedObjects);
    127     method_call.SetSerial(1234);
    128     return brillo::dbus_utils::testing::CallMethod(om_->dbus_object_,
    129                                                    &method_call);
    130   }
    131 
    132   scoped_refptr<dbus::MockBus> bus_;
    133   scoped_refptr<dbus::MockExportedObject> mock_exported_object_;
    134   std::unique_ptr<ExportedObjectManager> om_;
    135   ExportedPropertySet::PropertyWriter property_writer_;
    136 };
    137 
    138 TEST_F(ExportedObjectManagerTest, ClaimInterfaceSendsSignals) {
    139   EXPECT_CALL(*mock_exported_object_, SendSignal(_))
    140       .Times(1).WillOnce(Invoke(&VerifyInterfaceClaimSignal));
    141   om_->ClaimInterface(kClaimedTestPath, kClaimedInterface, property_writer_);
    142 }
    143 
    144 TEST_F(ExportedObjectManagerTest, ReleaseInterfaceSendsSignals) {
    145   InSequence dummy;
    146   EXPECT_CALL(*mock_exported_object_, SendSignal(_)).Times(1);
    147   EXPECT_CALL(*mock_exported_object_, SendSignal(_))
    148       .Times(1).WillOnce(Invoke(&VerifyInterfaceDropSignal));
    149   om_->ClaimInterface(kClaimedTestPath, kClaimedInterface, property_writer_);
    150   om_->ReleaseInterface(kClaimedTestPath, kClaimedInterface);
    151 }
    152 
    153 TEST_F(ExportedObjectManagerTest, GetManagedObjectsResponseEmptyCorrectness) {
    154   auto response = CallHandleGetManagedObjects();
    155   dbus::MessageReader reader(response.get());
    156   dbus::MessageReader all_paths(nullptr);
    157   ASSERT_TRUE(reader.PopArray(&all_paths));
    158   EXPECT_FALSE(reader.HasMoreData());
    159 }
    160 
    161 TEST_F(ExportedObjectManagerTest, GetManagedObjectsResponseCorrectness) {
    162   // org.freedesktop.DBus.ObjectManager.GetManagedObjects (
    163   //     out DICT<OBJPATH,
    164   //              DICT<STRING,
    165   //                   DICT<STRING,VARIANT>>> )
    166   EXPECT_CALL(*mock_exported_object_, SendSignal(_)).Times(1);
    167   om_->ClaimInterface(kClaimedTestPath, kClaimedInterface, property_writer_);
    168   auto response = CallHandleGetManagedObjects();
    169   dbus::MessageReader reader(response.get());
    170   dbus::MessageReader all_paths(nullptr);
    171   dbus::MessageReader each_path(nullptr);
    172   dbus::MessageReader all_interfaces(nullptr);
    173   dbus::MessageReader each_interface(nullptr);
    174   ASSERT_TRUE(reader.PopArray(&all_paths));
    175   ASSERT_TRUE(all_paths.PopDictEntry(&each_path));
    176   dbus::ObjectPath path;
    177   ASSERT_TRUE(each_path.PopObjectPath(&path));
    178   ASSERT_TRUE(each_path.PopArray(&all_interfaces));
    179   ASSERT_TRUE(all_interfaces.PopDictEntry(&each_interface));
    180   std::string interface_name;
    181   ASSERT_TRUE(each_interface.PopString(&interface_name));
    182   ReadTestPropertyDict(&each_interface);
    183   EXPECT_FALSE(each_interface.HasMoreData());
    184   EXPECT_FALSE(all_interfaces.HasMoreData());
    185   EXPECT_FALSE(each_path.HasMoreData());
    186   EXPECT_FALSE(all_paths.HasMoreData());
    187   EXPECT_FALSE(reader.HasMoreData());
    188   EXPECT_EQ(path, kClaimedTestPath);
    189   EXPECT_EQ(interface_name, kClaimedInterface);
    190 }
    191 
    192 }  // namespace dbus_utils
    193 
    194 }  // namespace brillo
    195