You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
147 lines
4.2 KiB
147 lines
4.2 KiB
// Copyright 2014 The Chromium OS Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include <brillo/dbus/dbus_signal_handler.h>
|
|
|
|
#include <string>
|
|
|
|
#include <base/bind.h>
|
|
#include <brillo/dbus/dbus_param_writer.h>
|
|
#include <dbus/mock_bus.h>
|
|
#include <dbus/mock_object_proxy.h>
|
|
#include <gmock/gmock.h>
|
|
#include <gtest/gtest.h>
|
|
|
|
using testing::AnyNumber;
|
|
using testing::Return;
|
|
using testing::SaveArg;
|
|
using testing::_;
|
|
|
|
namespace brillo {
|
|
namespace dbus_utils {
|
|
|
|
const char kTestPath[] = "/test/path";
|
|
const char kTestServiceName[] = "org.test.Object";
|
|
const char kInterface[] = "org.test.Object.TestInterface";
|
|
const char kSignal[] = "TestSignal";
|
|
|
|
class DBusSignalHandlerTest : public testing::Test {
|
|
public:
|
|
void SetUp() override {
|
|
dbus::Bus::Options options;
|
|
options.bus_type = dbus::Bus::SYSTEM;
|
|
bus_ = new dbus::MockBus(options);
|
|
// By default, don't worry about threading assertions.
|
|
EXPECT_CALL(*bus_, AssertOnOriginThread()).Times(AnyNumber());
|
|
EXPECT_CALL(*bus_, AssertOnDBusThread()).Times(AnyNumber());
|
|
// Use a mock object proxy.
|
|
mock_object_proxy_ = new dbus::MockObjectProxy(
|
|
bus_.get(), kTestServiceName, dbus::ObjectPath(kTestPath));
|
|
EXPECT_CALL(*bus_,
|
|
GetObjectProxy(kTestServiceName, dbus::ObjectPath(kTestPath)))
|
|
.WillRepeatedly(Return(mock_object_proxy_.get()));
|
|
}
|
|
|
|
void TearDown() override { bus_ = nullptr; }
|
|
|
|
protected:
|
|
template<typename SignalHandlerSink, typename... Args>
|
|
void CallSignal(SignalHandlerSink* sink, Args... args) {
|
|
dbus::ObjectProxy::SignalCallback signal_callback;
|
|
EXPECT_CALL(*mock_object_proxy_,
|
|
DoConnectToSignal(kInterface, kSignal, _, _))
|
|
.WillOnce(SaveArg<2>(&signal_callback));
|
|
|
|
brillo::dbus_utils::ConnectToSignal(
|
|
mock_object_proxy_.get(),
|
|
kInterface,
|
|
kSignal,
|
|
base::Bind(&SignalHandlerSink::Handler, base::Unretained(sink)),
|
|
{});
|
|
|
|
dbus::Signal signal(kInterface, kSignal);
|
|
dbus::MessageWriter writer(&signal);
|
|
DBusParamWriter::Append(&writer, args...);
|
|
signal_callback.Run(&signal);
|
|
}
|
|
|
|
scoped_refptr<dbus::MockBus> bus_;
|
|
scoped_refptr<dbus::MockObjectProxy> mock_object_proxy_;
|
|
};
|
|
|
|
TEST_F(DBusSignalHandlerTest, ConnectToSignal) {
|
|
EXPECT_CALL(*mock_object_proxy_, DoConnectToSignal(kInterface, kSignal, _, _))
|
|
.Times(1);
|
|
|
|
brillo::dbus_utils::ConnectToSignal(
|
|
mock_object_proxy_.get(), kInterface, kSignal, base::Closure{}, {});
|
|
}
|
|
|
|
TEST_F(DBusSignalHandlerTest, CallSignal_3Args) {
|
|
class SignalHandlerSink {
|
|
public:
|
|
MOCK_METHOD(void, Handler, (int, int, double));
|
|
} sink;
|
|
|
|
EXPECT_CALL(sink, Handler(10, 20, 30.5)).Times(1);
|
|
CallSignal(&sink, 10, 20, 30.5);
|
|
}
|
|
|
|
TEST_F(DBusSignalHandlerTest, CallSignal_2Args) {
|
|
class SignalHandlerSink {
|
|
public:
|
|
// Take string both by reference and by value to make sure this works too.
|
|
MOCK_METHOD(void, Handler, (const std::string&, std::string));
|
|
} sink;
|
|
|
|
EXPECT_CALL(sink, Handler(std::string{"foo"}, std::string{"bar"})).Times(1);
|
|
CallSignal(&sink, std::string{"foo"}, std::string{"bar"});
|
|
}
|
|
|
|
TEST_F(DBusSignalHandlerTest, CallSignal_NoArgs) {
|
|
class SignalHandlerSink {
|
|
public:
|
|
MOCK_METHOD(void, Handler, ());
|
|
} sink;
|
|
|
|
EXPECT_CALL(sink, Handler()).Times(1);
|
|
CallSignal(&sink);
|
|
}
|
|
|
|
TEST_F(DBusSignalHandlerTest, CallSignal_Error_TooManyArgs) {
|
|
class SignalHandlerSink {
|
|
public:
|
|
MOCK_METHOD(void, Handler, ());
|
|
} sink;
|
|
|
|
// Handler() expects no args, but we send an int.
|
|
EXPECT_CALL(sink, Handler()).Times(0);
|
|
CallSignal(&sink, 5);
|
|
}
|
|
|
|
TEST_F(DBusSignalHandlerTest, CallSignal_Error_TooFewArgs) {
|
|
class SignalHandlerSink {
|
|
public:
|
|
MOCK_METHOD(void, Handler, (std::string, bool));
|
|
} sink;
|
|
|
|
// Handler() expects 2 args while we send it just one.
|
|
EXPECT_CALL(sink, Handler(_, _)).Times(0);
|
|
CallSignal(&sink, std::string{"bar"});
|
|
}
|
|
|
|
TEST_F(DBusSignalHandlerTest, CallSignal_Error_TypeMismatchArgs) {
|
|
class SignalHandlerSink {
|
|
public:
|
|
MOCK_METHOD(void, Handler, (std::string, bool));
|
|
} sink;
|
|
|
|
// Handler() expects "sb" while we send it "ii".
|
|
EXPECT_CALL(sink, Handler(_, _)).Times(0);
|
|
CallSignal(&sink, 1, 2);
|
|
}
|
|
|
|
} // namespace dbus_utils
|
|
} // namespace brillo
|