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/dbus_signal_handler.h>
      6 
      7 #include <string>
      8 
      9 #include <brillo/bind_lambda.h>
     10 #include <brillo/dbus/dbus_param_writer.h>
     11 #include <dbus/mock_bus.h>
     12 #include <dbus/mock_object_proxy.h>
     13 #include <gmock/gmock.h>
     14 #include <gtest/gtest.h>
     15 
     16 using testing::AnyNumber;
     17 using testing::Return;
     18 using testing::SaveArg;
     19 using testing::_;
     20 
     21 namespace brillo {
     22 namespace dbus_utils {
     23 
     24 const char kTestPath[] = "/test/path";
     25 const char kTestServiceName[] = "org.test.Object";
     26 const char kInterface[] = "org.test.Object.TestInterface";
     27 const char kSignal[] = "TestSignal";
     28 
     29 class DBusSignalHandlerTest : public testing::Test {
     30  public:
     31   void SetUp() override {
     32     dbus::Bus::Options options;
     33     options.bus_type = dbus::Bus::SYSTEM;
     34     bus_ = new dbus::MockBus(options);
     35     // By default, don't worry about threading assertions.
     36     EXPECT_CALL(*bus_, AssertOnOriginThread()).Times(AnyNumber());
     37     EXPECT_CALL(*bus_, AssertOnDBusThread()).Times(AnyNumber());
     38     // Use a mock object proxy.
     39     mock_object_proxy_ = new dbus::MockObjectProxy(
     40         bus_.get(), kTestServiceName, dbus::ObjectPath(kTestPath));
     41     EXPECT_CALL(*bus_,
     42                 GetObjectProxy(kTestServiceName, dbus::ObjectPath(kTestPath)))
     43         .WillRepeatedly(Return(mock_object_proxy_.get()));
     44   }
     45 
     46   void TearDown() override { bus_ = nullptr; }
     47 
     48  protected:
     49   template<typename SignalHandlerSink, typename... Args>
     50   void CallSignal(SignalHandlerSink* sink, Args... args) {
     51     dbus::ObjectProxy::SignalCallback signal_callback;
     52     EXPECT_CALL(*mock_object_proxy_, ConnectToSignal(kInterface, kSignal, _, _))
     53         .WillOnce(SaveArg<2>(&signal_callback));
     54 
     55     brillo::dbus_utils::ConnectToSignal(
     56         mock_object_proxy_.get(),
     57         kInterface,
     58         kSignal,
     59         base::Bind(&SignalHandlerSink::Handler, base::Unretained(sink)),
     60         {});
     61 
     62     dbus::Signal signal(kInterface, kSignal);
     63     dbus::MessageWriter writer(&signal);
     64     DBusParamWriter::Append(&writer, args...);
     65     signal_callback.Run(&signal);
     66   }
     67 
     68   scoped_refptr<dbus::MockBus> bus_;
     69   scoped_refptr<dbus::MockObjectProxy> mock_object_proxy_;
     70 };
     71 
     72 TEST_F(DBusSignalHandlerTest, ConnectToSignal) {
     73   EXPECT_CALL(*mock_object_proxy_, ConnectToSignal(kInterface, kSignal, _, _))
     74       .Times(1);
     75 
     76   brillo::dbus_utils::ConnectToSignal(
     77       mock_object_proxy_.get(), kInterface, kSignal, base::Closure{}, {});
     78 }
     79 
     80 TEST_F(DBusSignalHandlerTest, CallSignal_3Args) {
     81   class SignalHandlerSink {
     82    public:
     83     MOCK_METHOD3(Handler, void(int, int, double));
     84   } sink;
     85 
     86   EXPECT_CALL(sink, Handler(10, 20, 30.5)).Times(1);
     87   CallSignal(&sink, 10, 20, 30.5);
     88 }
     89 
     90 TEST_F(DBusSignalHandlerTest, CallSignal_2Args) {
     91   class SignalHandlerSink {
     92    public:
     93     // Take string both by reference and by value to make sure this works too.
     94     MOCK_METHOD2(Handler, void(const std::string&, std::string));
     95   } sink;
     96 
     97   EXPECT_CALL(sink, Handler(std::string{"foo"}, std::string{"bar"})).Times(1);
     98   CallSignal(&sink, std::string{"foo"}, std::string{"bar"});
     99 }
    100 
    101 TEST_F(DBusSignalHandlerTest, CallSignal_NoArgs) {
    102   class SignalHandlerSink {
    103    public:
    104     MOCK_METHOD0(Handler, void());
    105   } sink;
    106 
    107   EXPECT_CALL(sink, Handler()).Times(1);
    108   CallSignal(&sink);
    109 }
    110 
    111 TEST_F(DBusSignalHandlerTest, CallSignal_Error_TooManyArgs) {
    112   class SignalHandlerSink {
    113    public:
    114     MOCK_METHOD0(Handler, void());
    115   } sink;
    116 
    117   // Handler() expects no args, but we send an int.
    118   EXPECT_CALL(sink, Handler()).Times(0);
    119   CallSignal(&sink, 5);
    120 }
    121 
    122 TEST_F(DBusSignalHandlerTest, CallSignal_Error_TooFewArgs) {
    123   class SignalHandlerSink {
    124    public:
    125     MOCK_METHOD2(Handler, void(std::string, bool));
    126   } sink;
    127 
    128   // Handler() expects 2 args while we send it just one.
    129   EXPECT_CALL(sink, Handler(_, _)).Times(0);
    130   CallSignal(&sink, std::string{"bar"});
    131 }
    132 
    133 TEST_F(DBusSignalHandlerTest, CallSignal_Error_TypeMismatchArgs) {
    134   class SignalHandlerSink {
    135    public:
    136     MOCK_METHOD2(Handler, void(std::string, bool));
    137   } sink;
    138 
    139   // Handler() expects "sb" while we send it "ii".
    140   EXPECT_CALL(sink, Handler(_, _)).Times(0);
    141   CallSignal(&sink, 1, 2);
    142 }
    143 
    144 }  // namespace dbus_utils
    145 }  // namespace brillo
    146