summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Stewart <pstew@chromium.org>2014-08-19 21:18:12 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-09-05 01:16:38 +0000
commit2b1c6124a7c74225e231132a68e1a92723a26da9 (patch)
tree082bcc8fa57d88b8a8ab2d45b791d27ef92feff1
parent4a4c706fa989e4643cb5b3d675656586b42d8950 (diff)
downloaddbus-binding-generator-2b1c6124a7c74225e231132a68e1a92723a26da9.tar.gz
chromeos-dbus-bindings: XML parser
Add an expat-based XML parser to parse an XML interface description into a structure. BUG=chromium:404505 TEST=New unit tests Change-Id: Ibc8e2b50d7e33ff209158962db3f6f97b8cfac97 Reviewed-on: https://chromium-review.googlesource.com/213242 Reviewed-by: Alex Vakulenko <avakulenko@chromium.org> Commit-Queue: Paul Stewart <pstew@chromium.org> Tested-by: Paul Stewart <pstew@chromium.org>
-rw-r--r--chromeos-dbus-bindings/chromeos-dbus-bindings.gyp44
-rw-r--r--chromeos-dbus-bindings/generate_chromeos_dbus_bindings.cc9
-rw-r--r--chromeos-dbus-bindings/interface.h57
-rw-r--r--chromeos-dbus-bindings/testrunner.cc16
-rw-r--r--chromeos-dbus-bindings/xml_interface_parser.cc194
-rw-r--r--chromeos-dbus-bindings/xml_interface_parser.h105
-rw-r--r--chromeos-dbus-bindings/xml_interface_parser_unittest.cc115
7 files changed, 540 insertions, 0 deletions
diff --git a/chromeos-dbus-bindings/chromeos-dbus-bindings.gyp b/chromeos-dbus-bindings/chromeos-dbus-bindings.gyp
index fafc408..3633561 100644
--- a/chromeos-dbus-bindings/chromeos-dbus-bindings.gyp
+++ b/chromeos-dbus-bindings/chromeos-dbus-bindings.gyp
@@ -20,11 +20,55 @@
},
'targets': [
{
+ 'target_name': 'libchromeos-dbus-bindings',
+ 'type': 'static_library',
+ 'sources': [
+ 'xml_interface_parser.cc',
+ ],
+ 'variables': {
+ 'exported_deps': [
+ 'expat',
+ ],
+ 'deps': ['<@(exported_deps)'],
+ },
+ 'all_dependent_settings': {
+ 'variables': {
+ 'deps': [
+ '<@(exported_deps)',
+ ],
+ },
+ },
+ 'link_settings': {
+ 'variables': {
+ 'deps': [
+ 'expat',
+ ],
+ },
+ },
+ },
+ {
'target_name': 'generate-chromeos-dbus-bindings',
'type': 'executable',
+ 'dependencies': ['libchromeos-dbus-bindings'],
'sources': [
'generate_chromeos_dbus_bindings.cc',
]
},
],
+ 'conditions': [
+ ['USE_test == 1', {
+ 'targets': [
+ {
+ 'target_name': 'chromeos_dbus_bindings_unittest',
+ 'type': 'executable',
+ 'dependencies': ['libchromeos-dbus-bindings'],
+ 'includes': ['../../platform2/common-mk/common_test.gypi'],
+ 'sources': [
+ 'testrunner.cc',
+ 'xml_interface_parser_unittest.cc',
+ ],
+ },
+ ],
+ }],
+ ],
}
diff --git a/chromeos-dbus-bindings/generate_chromeos_dbus_bindings.cc b/chromeos-dbus-bindings/generate_chromeos_dbus_bindings.cc
index b7836ba..c043079 100644
--- a/chromeos-dbus-bindings/generate_chromeos_dbus_bindings.cc
+++ b/chromeos-dbus-bindings/generate_chromeos_dbus_bindings.cc
@@ -5,8 +5,11 @@
#include <string>
#include <base/command_line.h>
+#include <base/files/file_path.h>
#include <base/logging.h>
+#include "chromeos-dbus-bindings/xml_interface_parser.h"
+
namespace switches {
static const char kHelp[] = "help";
@@ -35,5 +38,11 @@ int main(int argc, char** argv) {
std::string input = cl->GetSwitchValueASCII(switches::kInput);
+ chromeos_dbus_bindings::XmlInterfaceParser parser;
+ if (!parser.ParseXmlInterfaceFile(base::FilePath(input))) {
+ LOG(ERROR) << "Failed to parse interface file.";
+ return 1;
+ }
+
return 0;
}
diff --git a/chromeos-dbus-bindings/interface.h b/chromeos-dbus-bindings/interface.h
new file mode 100644
index 0000000..04de002
--- /dev/null
+++ b/chromeos-dbus-bindings/interface.h
@@ -0,0 +1,57 @@
+// 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.
+
+#ifndef CHROMEOS_DBUS_BINDINGS_INTERFACE_H_
+#define CHROMEOS_DBUS_BINDINGS_INTERFACE_H_
+
+#include <string>
+#include <vector>
+
+namespace chromeos_dbus_bindings {
+
+struct Interface {
+ struct Argument {
+ Argument(const std::string& name_in,
+ const std::string& type_in) : name(name_in), type(type_in) {}
+ std::string name;
+ std::string type;
+ };
+ struct Method {
+ Method(const std::string& name_in,
+ const std::vector<Argument>& input_arguments_in,
+ const std::vector<Argument>& output_arguments_in)
+ : name(name_in),
+ input_arguments(input_arguments_in),
+ output_arguments(output_arguments_in) {}
+ Method(const std::string& name_in,
+ const std::vector<Argument>& input_arguments_in)
+ : name(name_in),
+ input_arguments(input_arguments_in) {}
+ explicit Method(const std::string& name_in) : name(name_in) {}
+ std::string name;
+ std::vector<Argument> input_arguments;
+ std::vector<Argument> output_arguments;
+ };
+ struct Signal {
+ Signal(const std::string& name_in,
+ const std::vector<Argument>& arguments_in)
+ : name(name_in), arguments(arguments_in) {}
+ explicit Signal(const std::string& name_in) : name(name_in) {}
+ std::string name;
+ std::vector<Argument> arguments;
+ };
+
+ Interface() = default;
+ Interface(const std::string& name_in,
+ const std::vector<Method>& methods_in,
+ const std::vector<Signal>& signals_in)
+ : name(name_in), methods(methods_in), signals(signals_in) {}
+ std::string name;
+ std::vector<Method> methods;
+ std::vector<Signal> signals;
+};
+
+} // namespace chromeos_dbus_bindings
+
+#endif // CHROMEOS_DBUS_BINDINGS_INTERFACE_H_
diff --git a/chromeos-dbus-bindings/testrunner.cc b/chromeos-dbus-bindings/testrunner.cc
new file mode 100644
index 0000000..766c3f2
--- /dev/null
+++ b/chromeos-dbus-bindings/testrunner.cc
@@ -0,0 +1,16 @@
+// Copyright (c) 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 <base/at_exit.h>
+#include <base/command_line.h>
+#include <chromeos/syslog_logging.h>
+#include <gtest/gtest.h>
+
+int main(int argc, char** argv) {
+ base::AtExitManager exit_manager;
+ CommandLine::Init(argc, argv);
+ chromeos::InitLog(chromeos::kLogToStderr);
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/chromeos-dbus-bindings/xml_interface_parser.cc b/chromeos-dbus-bindings/xml_interface_parser.cc
new file mode 100644
index 0000000..d75c2a7
--- /dev/null
+++ b/chromeos-dbus-bindings/xml_interface_parser.cc
@@ -0,0 +1,194 @@
+// 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 "chromeos-dbus-bindings/xml_interface_parser.h"
+
+#include <utility>
+
+#include <base/file_util.h>
+#include <base/files/file_path.h>
+#include <base/logging.h>
+#include <base/stl_util.h>
+
+using std::string;
+using std::vector;
+
+namespace chromeos_dbus_bindings {
+
+// static
+const char XmlInterfaceParser::kArgumentTag[] = "arg";
+const char XmlInterfaceParser::kInterfaceTag[] = "interface";
+const char XmlInterfaceParser::kMethodTag[] = "method";
+const char XmlInterfaceParser::kNodeTag[] = "node";
+const char XmlInterfaceParser::kSignalTag[] = "signal";
+const char XmlInterfaceParser::kNameAttribute[] = "name";
+const char XmlInterfaceParser::kTypeAttribute[] = "type";
+const char XmlInterfaceParser::kDirectionAttribute[] = "direction";
+const char XmlInterfaceParser::kArgumentDirectionIn[] = "in";
+const char XmlInterfaceParser::kArgumentDirectionOut[] = "out";
+
+bool XmlInterfaceParser::ParseXmlInterfaceFile(
+ const base::FilePath& interface_file) {
+ string contents;
+ if (!base::ReadFileToString(interface_file, &contents)) {
+ LOG(ERROR) << "Failed to read file " << interface_file.value();
+ return false;
+ }
+ auto parser = XML_ParserCreate(nullptr);
+ XML_SetUserData(parser, this);
+ XML_SetElementHandler(parser,
+ &XmlInterfaceParser::HandleElementStart,
+ &XmlInterfaceParser::HandleElementEnd);
+ const int kIsFinal = XML_TRUE;
+
+ element_path_.clear();
+ XML_Status res = XML_Parse(parser,
+ contents.c_str(),
+ contents.size(),
+ kIsFinal);
+ XML_ParserFree(parser);
+
+ if (res != XML_STATUS_OK) {
+ LOG(ERROR) << "XML parse failure";
+ return false;
+ }
+
+ CHECK(element_path_.empty());
+ return true;
+}
+
+void XmlInterfaceParser::OnOpenElement(
+ const string& element_name, const XmlAttributeMap& attributes) {
+ element_path_.push_back(element_name);
+ if (element_path_ == vector<string> { kNodeTag, kInterfaceTag }) {
+ string interface_name = GetValidatedElementName(attributes, kInterfaceTag);
+ CHECK(interface_.name.empty())
+ << "Found a second interface named " << interface_name << ". "
+ << "Interface " << interface_.name << " has already been parsed.";
+ interface_.name = interface_name;
+ } else if (element_path_ == vector<string> {
+ kNodeTag, kInterfaceTag, kMethodTag }) {
+ interface_.methods.push_back(
+ Interface::Method(GetValidatedElementName(attributes, kMethodTag)));
+ } else if (element_path_ == vector<string> {
+ kNodeTag, kInterfaceTag, kMethodTag, kArgumentTag }) {
+ AddMethodArgument(attributes);
+ } else if (element_path_ == vector<string> {
+ kNodeTag, kInterfaceTag, kSignalTag }) {
+ interface_.signals.push_back(
+ Interface::Signal(GetValidatedElementName(attributes, kSignalTag)));
+ } else if (element_path_ == vector<string> {
+ kNodeTag, kInterfaceTag, kSignalTag, kArgumentTag }) {
+ AddSignalArgument(attributes);
+ }
+}
+
+void XmlInterfaceParser::AddMethodArgument(const XmlAttributeMap& attributes) {
+ CHECK(!interface_.methods.empty())
+ << " we have a method argument but the interface has no methods";
+ const string& argument_direction = GetValidatedElementAttribute(
+ attributes, kArgumentTag, kDirectionAttribute);
+ vector<Interface::Argument>* argument_list;
+ if (argument_direction == kArgumentDirectionIn) {
+ argument_list = &interface_.methods.back().input_arguments;
+ } else if (argument_direction == kArgumentDirectionOut) {
+ argument_list = &interface_.methods.back().output_arguments;
+ } else {
+ LOG(FATAL) << "Unknown method argument direction " << argument_direction;
+ }
+ argument_list->push_back(ParseArgument(attributes, kMethodTag));
+}
+
+void XmlInterfaceParser::AddSignalArgument(const XmlAttributeMap& attributes) {
+ CHECK(interface_.signals.size())
+ << " we have a signal argument but the interface has no signals";
+ interface_.signals.back().arguments.push_back(
+ ParseArgument(attributes, kSignalTag));
+}
+
+void XmlInterfaceParser::OnCloseElement(const string& element_name) {
+ LOG(INFO) << "Close Element " << element_name;
+ CHECK(!element_path_.empty());
+ CHECK_EQ(element_path_.back(), element_name);
+ element_path_.pop_back();
+}
+
+// static
+bool XmlInterfaceParser::GetElementAttribute(
+ const XmlAttributeMap& attributes,
+ const string& element_type,
+ const string& element_key,
+ string* element_value) {
+ if (!ContainsKey(attributes, element_key)) {
+ return false;
+ }
+ *element_value = attributes.find(element_key)->second;
+ LOG(INFO) << "Got " << element_type << " element with "
+ << element_key << " = " << *element_value;
+ return true;
+}
+
+// static
+string XmlInterfaceParser::GetValidatedElementAttribute(
+ const XmlAttributeMap& attributes,
+ const string& element_type,
+ const string& element_key) {
+ string element_value;
+ CHECK(GetElementAttribute(attributes,
+ element_type,
+ element_key,
+ &element_value))
+ << element_type << " does not contain a " << element_key << " attribute";
+ CHECK(!element_value.empty()) << element_type << " " << element_key
+ << " attribute is empty";
+ return element_value;
+}
+
+// static
+string XmlInterfaceParser::GetValidatedElementName(
+ const XmlAttributeMap& attributes,
+ const string& element_type) {
+ return GetValidatedElementAttribute(attributes, element_type, kNameAttribute);
+}
+
+// static
+Interface::Argument XmlInterfaceParser::ParseArgument(
+ const XmlAttributeMap& attributes, const string& element_type) {
+ string element_and_argument = element_type + " " + kArgumentTag;
+ string argument_name;
+ // Since the "name" field is optional, use the un-validated variant.
+ GetElementAttribute(attributes,
+ element_and_argument,
+ kNameAttribute,
+ &argument_name);
+
+ string argument_type = GetValidatedElementAttribute(
+ attributes, element_and_argument, kTypeAttribute);
+ return Interface::Argument(argument_name, argument_type);
+}
+
+// static
+void XmlInterfaceParser::HandleElementStart(void* user_data,
+ const XML_Char* element,
+ const XML_Char** attr) {
+ XmlAttributeMap attributes;
+ if (attr != nullptr) {
+ for (size_t n = 0; attr[n] != nullptr && attr[n+1] != nullptr; n += 2) {
+ auto key = attr[n];
+ auto value = attr[n + 1];
+ attributes.insert(std::make_pair(key, value));
+ }
+ }
+ auto parser = reinterpret_cast<XmlInterfaceParser*>(user_data);
+ parser->OnOpenElement(element, attributes);
+}
+
+// static
+void XmlInterfaceParser::HandleElementEnd(void* user_data,
+ const XML_Char* element) {
+ auto parser = reinterpret_cast<XmlInterfaceParser*>(user_data);
+ parser->OnCloseElement(element);
+}
+
+} // namespace chromeos_dbus_bindings
diff --git a/chromeos-dbus-bindings/xml_interface_parser.h b/chromeos-dbus-bindings/xml_interface_parser.h
new file mode 100644
index 0000000..84c7dd8
--- /dev/null
+++ b/chromeos-dbus-bindings/xml_interface_parser.h
@@ -0,0 +1,105 @@
+// 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.
+
+#ifndef CHROMEOS_DBUS_BINDINGS_XML_INTERFACE_PARSER_H_
+#define CHROMEOS_DBUS_BINDINGS_XML_INTERFACE_PARSER_H_
+
+#include <expat.h>
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include <base/macros.h>
+
+#include "chromeos-dbus-bindings/interface.h"
+
+namespace base {
+
+class FilePath;
+
+} // namespace base
+
+namespace chromeos_dbus_bindings {
+
+class XmlInterfaceParser {
+ public:
+ using XmlAttributeMap = std::map<std::string, std::string>;
+
+ XmlInterfaceParser() = default;
+ virtual ~XmlInterfaceParser() = default;
+
+ virtual bool ParseXmlInterfaceFile(const base::FilePath& interface_file);
+ const Interface& interface() const { return interface_; }
+
+ private:
+ friend class XmlInterfaceParserTest;
+
+ // XML tag names.
+ static const char kArgumentTag[];
+ static const char kInterfaceTag[];
+ static const char kMethodTag[];
+ static const char kNodeTag[];
+ static const char kSignalTag[];
+
+ // XML attribute names.
+ static const char kNameAttribute[];
+ static const char kTypeAttribute[];
+ static const char kDirectionAttribute[];
+
+ // XML argument directions.
+ static const char kArgumentDirectionIn[];
+ static const char kArgumentDirectionOut[];
+
+ // Element callbacks on |this| called by HandleElementStart() and
+ // HandleElementEnd(), respectively.
+ void OnOpenElement(const std::string& element_name,
+ const XmlAttributeMap& attributes);
+ void OnCloseElement(const std::string& element_name);
+
+ // Methods for appending individual argument elements to the parser.
+ void AddMethodArgument(const XmlAttributeMap& attributes);
+ void AddSignalArgument(const XmlAttributeMap& attributes);
+
+ // Finds the |element_key| element in |attributes|. Returns true and sets
+ // |element_value| on success. Returns false otherwise.
+ static bool GetElementAttribute(const XmlAttributeMap& attributes,
+ const std::string& element_type,
+ const std::string& element_key,
+ std::string* element_value);
+
+ // Asserts that a non-empty |element_key| attribute appears in |attributes|.
+ // Returns the name on success, triggers a CHECK() otherwise.
+ static std::string GetValidatedElementAttribute(
+ const XmlAttributeMap& attributes,
+ const std::string& element_type,
+ const std::string& element_key);
+
+ // Calls GetValidatedElementAttribute() for for the "name" property.
+ static std::string GetValidatedElementName(
+ const XmlAttributeMap& attributes,
+ const std::string& element_type);
+
+ // Method for extracting signal/method tag attributes to a struct.
+ static Interface::Argument ParseArgument(const XmlAttributeMap& attributes,
+ const std::string& element_type);
+
+ // Expat element callback functions.
+ static void HandleElementStart(void* user_data,
+ const XML_Char* element,
+ const XML_Char** attr);
+ static void HandleElementEnd(void* user_data, const XML_Char* element);
+
+ // The output of the parse.
+ Interface interface_;
+
+ // Tracks where in the element traversal our parse has taken us.
+ std::vector<std::string> element_path_;
+
+ DISALLOW_COPY_AND_ASSIGN(XmlInterfaceParser);
+};
+
+} // namespace chromeos_dbus_bindings
+
+#endif // CHROMEOS_DBUS_BINDINGS_XML_INTERFACE_PARSER_H_
diff --git a/chromeos-dbus-bindings/xml_interface_parser_unittest.cc b/chromeos-dbus-bindings/xml_interface_parser_unittest.cc
new file mode 100644
index 0000000..4add88b
--- /dev/null
+++ b/chromeos-dbus-bindings/xml_interface_parser_unittest.cc
@@ -0,0 +1,115 @@
+// 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 "chromeos-dbus-bindings/xml_interface_parser.h"
+
+#include <base/file_util.h>
+#include <base/files/file_path.h>
+#include <base/files/scoped_temp_dir.h>
+#include <gtest/gtest.h>
+
+#include "chromeos-dbus-bindings/interface.h"
+
+using std::string;
+using testing::Test;
+
+namespace chromeos_dbus_bindings {
+
+namespace {
+
+const char kBadInterfaceFileContents0[] = "This has no resemblance to XML";
+const char kBadInterfaceFileContents1[] = "<node>";
+const char kGoodInterfaceFileContents[] =
+ "<node>\n"
+ " <interface name=\"fi.w1.wpa_supplicant1.Interface\">\n"
+ " <method name=\"Scan\">\n"
+ " <arg name=\"args\" type=\"a{sv}\" direction=\"in\"/>\n"
+ " </method>\n"
+ " <method name=\"GetBlob\">\n"
+ " <arg name=\"name\" type=\"s\" direction=\"in\"/>\n"
+ " <arg name=\"data\" type=\"ay\" direction=\"out\"/>\n"
+ " </method>\n"
+ " <property name=\"Capabilities\" type=\"a{sv}\" access=\"read\"/>\n"
+ " <signal name=\"BSSRemoved\">\n"
+ " <arg name=\"BSS\" type=\"o\"/>\n"
+ " </signal>\n"
+ " </interface>\n"
+ "</node>\n";
+const char kInterfaceName[] = "fi.w1.wpa_supplicant1.Interface";
+const char kScanMethod[] = "Scan";
+const char kArgsArgument[] = "args";
+const char kArrayStringVariantType[] = "a{sv}";
+const char kGetBlobMethod[] = "GetBlob";
+const char kNameArgument[] = "name";
+const char kDataArgument[] = "data";
+const char kStringType[] = "s";
+const char kArrayByteType[] = "ay";
+const char kBssRemovedSignal[] = "BSSRemoved";
+const char kBssArgument[] = "BSS";
+const char kObjectType[] = "o";
+} // namespace
+
+class XmlInterfaceParserTest : public Test {
+ public:
+ void SetUp() override {
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ }
+
+ protected:
+ bool ParseXmlContents(const string& contents) {
+ base::FilePath path = temp_dir_.path().Append("interface.xml");
+ EXPECT_TRUE(base::WriteFile(path, contents.c_str(), contents.size()));
+ return parser_.ParseXmlInterfaceFile(path);
+ }
+
+ base::ScopedTempDir temp_dir_;
+ XmlInterfaceParser parser_;
+};
+
+TEST_F(XmlInterfaceParserTest, BadInputFile) {
+ EXPECT_FALSE(parser_.ParseXmlInterfaceFile(base::FilePath()));
+ EXPECT_FALSE(ParseXmlContents(kBadInterfaceFileContents0));
+ EXPECT_FALSE(ParseXmlContents(kBadInterfaceFileContents1));
+}
+
+TEST_F(XmlInterfaceParserTest, GoodInputFile) {
+ EXPECT_TRUE(ParseXmlContents(kGoodInterfaceFileContents));
+ const Interface& interface = parser_.interface();
+ EXPECT_EQ(kInterfaceName, interface.name);
+ ASSERT_EQ(2, interface.methods.size());
+ ASSERT_EQ(1, interface.signals.size());
+
+ // <method name="Scan">
+ EXPECT_EQ(kScanMethod, interface.methods[0].name);
+ ASSERT_EQ(1, interface.methods[0].input_arguments.size());
+
+ // <arg name="args" type="a{sv}" direction="in"/>
+ EXPECT_EQ(kArgsArgument, interface.methods[0].input_arguments[0].name);
+ EXPECT_EQ(kArrayStringVariantType,
+ interface.methods[0].input_arguments[0].type);
+ EXPECT_EQ(0, interface.methods[0].output_arguments.size());
+
+ // <method name="GetBlob">
+ EXPECT_EQ(kGetBlobMethod, interface.methods[1].name);
+ EXPECT_EQ(1, interface.methods[1].input_arguments.size());
+ EXPECT_EQ(1, interface.methods[1].output_arguments.size());
+
+ // <arg name="name" type="s" direction="in"/>
+ EXPECT_EQ(kNameArgument, interface.methods[1].input_arguments[0].name);
+ EXPECT_EQ(kStringType, interface.methods[1].input_arguments[0].type);
+
+ // <arg name="data" type="ay" direction="out"/>
+ EXPECT_EQ(kDataArgument, interface.methods[1].output_arguments[0].name);
+ EXPECT_EQ(kArrayByteType, interface.methods[1].output_arguments[0].type);
+
+ // <signal name="BSSRemoved">
+ EXPECT_EQ(kBssRemovedSignal, interface.signals[0].name);
+ EXPECT_EQ(1, interface.signals[0].arguments.size());
+
+ // <arg name="BSS" type="o"/>
+ EXPECT_EQ(kBssArgument, interface.signals[0].arguments[0].name);
+ EXPECT_EQ(kObjectType, interface.signals[0].arguments[0].type);
+}
+
+} // namespace chromeos_dbus_bindings