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.
197 lines
7.5 KiB
197 lines
7.5 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/exported_object_manager.h>
|
|
|
|
#include <utility>
|
|
|
|
#include <base/bind.h>
|
|
#include <brillo/dbus/dbus_object_test_helpers.h>
|
|
#include <brillo/dbus/utils.h>
|
|
#include <dbus/mock_bus.h>
|
|
#include <dbus/mock_exported_object.h>
|
|
#include <dbus/object_manager.h>
|
|
#include <dbus/object_path.h>
|
|
#include <gtest/gtest.h>
|
|
|
|
using ::testing::AnyNumber;
|
|
using ::testing::InSequence;
|
|
using ::testing::Invoke;
|
|
using ::testing::Return;
|
|
using ::testing::_;
|
|
|
|
namespace brillo {
|
|
|
|
namespace dbus_utils {
|
|
|
|
namespace {
|
|
|
|
const dbus::ObjectPath kTestPath(std::string("/test/om_path"));
|
|
const dbus::ObjectPath kClaimedTestPath(std::string("/test/claimed_path"));
|
|
const std::string kClaimedInterface("claimed.interface");
|
|
const std::string kTestPropertyName("PropertyName");
|
|
const std::string kTestPropertyValue("PropertyValue");
|
|
|
|
void WriteTestPropertyDict(VariantDictionary* dict) {
|
|
dict->insert(std::make_pair(kTestPropertyName, Any(kTestPropertyValue)));
|
|
}
|
|
|
|
void ReadTestPropertyDict(dbus::MessageReader* reader) {
|
|
dbus::MessageReader all_properties(nullptr);
|
|
dbus::MessageReader each_property(nullptr);
|
|
ASSERT_TRUE(reader->PopArray(&all_properties));
|
|
ASSERT_TRUE(all_properties.PopDictEntry(&each_property));
|
|
std::string property_name;
|
|
std::string property_value;
|
|
ASSERT_TRUE(each_property.PopString(&property_name));
|
|
ASSERT_TRUE(each_property.PopVariantOfString(&property_value));
|
|
EXPECT_FALSE(each_property.HasMoreData());
|
|
EXPECT_FALSE(all_properties.HasMoreData());
|
|
EXPECT_EQ(property_name, kTestPropertyName);
|
|
EXPECT_EQ(property_value, kTestPropertyValue);
|
|
}
|
|
|
|
void VerifyInterfaceClaimSignal(dbus::Signal* signal) {
|
|
EXPECT_EQ(signal->GetInterface(), std::string(dbus::kObjectManagerInterface));
|
|
EXPECT_EQ(signal->GetMember(),
|
|
std::string(dbus::kObjectManagerInterfacesAdded));
|
|
// org.freedesktop.DBus.ObjectManager.InterfacesAdded (
|
|
// OBJPATH object_path,
|
|
// DICT<STRING,DICT<STRING,VARIANT>> interfaces_and_properties);
|
|
dbus::MessageReader reader(signal);
|
|
dbus::MessageReader all_interfaces(nullptr);
|
|
dbus::MessageReader each_interface(nullptr);
|
|
dbus::ObjectPath path;
|
|
ASSERT_TRUE(reader.PopObjectPath(&path));
|
|
ASSERT_TRUE(reader.PopArray(&all_interfaces));
|
|
ASSERT_TRUE(all_interfaces.PopDictEntry(&each_interface));
|
|
std::string interface_name;
|
|
ASSERT_TRUE(each_interface.PopString(&interface_name));
|
|
ReadTestPropertyDict(&each_interface);
|
|
EXPECT_FALSE(each_interface.HasMoreData());
|
|
EXPECT_FALSE(all_interfaces.HasMoreData());
|
|
EXPECT_FALSE(reader.HasMoreData());
|
|
EXPECT_EQ(interface_name, kClaimedInterface);
|
|
EXPECT_EQ(path, kClaimedTestPath);
|
|
}
|
|
|
|
void VerifyInterfaceDropSignal(dbus::Signal* signal) {
|
|
EXPECT_EQ(signal->GetInterface(), std::string(dbus::kObjectManagerInterface));
|
|
EXPECT_EQ(signal->GetMember(),
|
|
std::string(dbus::kObjectManagerInterfacesRemoved));
|
|
// org.freedesktop.DBus.ObjectManager.InterfacesRemoved (
|
|
// OBJPATH object_path, ARRAY<STRING> interfaces);
|
|
dbus::MessageReader reader(signal);
|
|
dbus::MessageReader each_interface(nullptr);
|
|
dbus::ObjectPath path;
|
|
ASSERT_TRUE(reader.PopObjectPath(&path));
|
|
ASSERT_TRUE(reader.PopArray(&each_interface));
|
|
std::string interface_name;
|
|
ASSERT_TRUE(each_interface.PopString(&interface_name));
|
|
EXPECT_FALSE(each_interface.HasMoreData());
|
|
EXPECT_FALSE(reader.HasMoreData());
|
|
EXPECT_EQ(interface_name, kClaimedInterface);
|
|
EXPECT_EQ(path, kClaimedTestPath);
|
|
}
|
|
|
|
} // namespace
|
|
|
|
class ExportedObjectManagerTest : 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 exported object.
|
|
mock_exported_object_ = new dbus::MockExportedObject(bus_.get(), kTestPath);
|
|
EXPECT_CALL(*bus_, GetExportedObject(kTestPath)).Times(1).WillOnce(
|
|
Return(mock_exported_object_.get()));
|
|
EXPECT_CALL(*mock_exported_object_, ExportMethod(_, _, _, _))
|
|
.Times(AnyNumber());
|
|
om_.reset(new ExportedObjectManager(bus_.get(), kTestPath));
|
|
property_writer_ = base::Bind(&WriteTestPropertyDict);
|
|
om_->RegisterAsync(AsyncEventSequencer::GetDefaultCompletionAction());
|
|
}
|
|
|
|
void TearDown() override {
|
|
EXPECT_CALL(*mock_exported_object_, Unregister()).Times(1);
|
|
om_.reset();
|
|
bus_ = nullptr;
|
|
}
|
|
|
|
std::unique_ptr<dbus::Response> CallHandleGetManagedObjects() {
|
|
dbus::MethodCall method_call(dbus::kObjectManagerInterface,
|
|
dbus::kObjectManagerGetManagedObjects);
|
|
method_call.SetSerial(1234);
|
|
return brillo::dbus_utils::testing::CallMethod(om_->dbus_object_,
|
|
&method_call);
|
|
}
|
|
|
|
scoped_refptr<dbus::MockBus> bus_;
|
|
scoped_refptr<dbus::MockExportedObject> mock_exported_object_;
|
|
std::unique_ptr<ExportedObjectManager> om_;
|
|
ExportedPropertySet::PropertyWriter property_writer_;
|
|
};
|
|
|
|
TEST_F(ExportedObjectManagerTest, ClaimInterfaceSendsSignals) {
|
|
EXPECT_CALL(*mock_exported_object_, SendSignal(_))
|
|
.Times(1).WillOnce(Invoke(&VerifyInterfaceClaimSignal));
|
|
om_->ClaimInterface(kClaimedTestPath, kClaimedInterface, property_writer_);
|
|
}
|
|
|
|
TEST_F(ExportedObjectManagerTest, ReleaseInterfaceSendsSignals) {
|
|
InSequence dummy;
|
|
EXPECT_CALL(*mock_exported_object_, SendSignal(_)).Times(1);
|
|
EXPECT_CALL(*mock_exported_object_, SendSignal(_))
|
|
.Times(1).WillOnce(Invoke(&VerifyInterfaceDropSignal));
|
|
om_->ClaimInterface(kClaimedTestPath, kClaimedInterface, property_writer_);
|
|
om_->ReleaseInterface(kClaimedTestPath, kClaimedInterface);
|
|
}
|
|
|
|
TEST_F(ExportedObjectManagerTest, GetManagedObjectsResponseEmptyCorrectness) {
|
|
auto response = CallHandleGetManagedObjects();
|
|
dbus::MessageReader reader(response.get());
|
|
dbus::MessageReader all_paths(nullptr);
|
|
ASSERT_TRUE(reader.PopArray(&all_paths));
|
|
EXPECT_FALSE(reader.HasMoreData());
|
|
}
|
|
|
|
TEST_F(ExportedObjectManagerTest, GetManagedObjectsResponseCorrectness) {
|
|
// org.freedesktop.DBus.ObjectManager.GetManagedObjects (
|
|
// out DICT<OBJPATH,
|
|
// DICT<STRING,
|
|
// DICT<STRING,VARIANT>>> )
|
|
EXPECT_CALL(*mock_exported_object_, SendSignal(_)).Times(1);
|
|
om_->ClaimInterface(kClaimedTestPath, kClaimedInterface, property_writer_);
|
|
auto response = CallHandleGetManagedObjects();
|
|
dbus::MessageReader reader(response.get());
|
|
dbus::MessageReader all_paths(nullptr);
|
|
dbus::MessageReader each_path(nullptr);
|
|
dbus::MessageReader all_interfaces(nullptr);
|
|
dbus::MessageReader each_interface(nullptr);
|
|
ASSERT_TRUE(reader.PopArray(&all_paths));
|
|
ASSERT_TRUE(all_paths.PopDictEntry(&each_path));
|
|
dbus::ObjectPath path;
|
|
ASSERT_TRUE(each_path.PopObjectPath(&path));
|
|
ASSERT_TRUE(each_path.PopArray(&all_interfaces));
|
|
ASSERT_TRUE(all_interfaces.PopDictEntry(&each_interface));
|
|
std::string interface_name;
|
|
ASSERT_TRUE(each_interface.PopString(&interface_name));
|
|
ReadTestPropertyDict(&each_interface);
|
|
EXPECT_FALSE(each_interface.HasMoreData());
|
|
EXPECT_FALSE(all_interfaces.HasMoreData());
|
|
EXPECT_FALSE(each_path.HasMoreData());
|
|
EXPECT_FALSE(all_paths.HasMoreData());
|
|
EXPECT_FALSE(reader.HasMoreData());
|
|
EXPECT_EQ(path, kClaimedTestPath);
|
|
EXPECT_EQ(interface_name, kClaimedInterface);
|
|
}
|
|
|
|
} // namespace dbus_utils
|
|
|
|
} // namespace brillo
|