libweave: Re-factor dbus_command_proxy_unittest.cc to public libweave Now dbus references could be moved out from libweave. BUG=brillo:1245 TEST='FEATURES=test emerge-gizmo buffet' Change-Id: I77b862895bc9a742586b3c24cbc4a223cffbbb11 Reviewed-on: https://chromium-review.googlesource.com/288805 Tested-by: Vitaly Buka <vitalybuka@chromium.org> Reviewed-by: Alex Vakulenko <avakulenko@chromium.org> Commit-Queue: Vitaly Buka <vitalybuka@chromium.org>
diff --git a/buffet/buffet.gyp b/buffet/buffet.gyp index 2e6cd91..d6fb0ad 100644 --- a/buffet/buffet.gyp +++ b/buffet/buffet.gyp
@@ -195,6 +195,7 @@ '../libweave/src/commands/command_queue_unittest.cc', '../libweave/src/commands/dbus_command_proxy_unittest.cc', '../libweave/src/commands/dbus_conversion_unittest.cc', + '../libweave/src/commands/mock_command.cc', '../libweave/src/commands/object_schema_unittest.cc', '../libweave/src/commands/schema_utils_unittest.cc', '../libweave/src/commands/unittest_utils.cc',
diff --git a/libweave/include/weave/mock_command.h b/libweave/include/weave/mock_command.h new file mode 100644 index 0000000..6298f99 --- /dev/null +++ b/libweave/include/weave/mock_command.h
@@ -0,0 +1,49 @@ +// Copyright 2015 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 LIBWEAVE_INCLUDE_WEAVE_MOCK_COMMAND_H_ +#define LIBWEAVE_INCLUDE_WEAVE_MOCK_COMMAND_H_ + +#include "weave/command.h" + +#include <memory> +#include <string> + +#include <base/values.h> + +#include <gmock/gmock.h> + +namespace weave { + +class MockCommand : public Command { + public: + ~MockCommand() override = default; + + MOCK_METHOD1(AddObserver, void(Observer*)); + MOCK_CONST_METHOD0(GetID, const std::string&()); + MOCK_CONST_METHOD0(GetName, const std::string&()); + MOCK_CONST_METHOD0(GetCategory, const std::string&()); + MOCK_CONST_METHOD0(GetStatus, CommandStatus()); + MOCK_CONST_METHOD0(GetOrigin, CommandOrigin()); + MOCK_CONST_METHOD0(MockGetParameters, const std::string&()); + MOCK_CONST_METHOD0(MockGetProgress, const std::string&()); + MOCK_CONST_METHOD0(MockGetResults, const std::string&()); + MOCK_METHOD2(SetProgress, + bool(const base::DictionaryValue&, chromeos::ErrorPtr*)); + MOCK_METHOD2(SetResults, + bool(const base::DictionaryValue&, chromeos::ErrorPtr*)); + MOCK_METHOD0(Abort, void()); + MOCK_METHOD0(Cancel, void()); + MOCK_METHOD0(Done, void()); + MOCK_CONST_METHOD0(MockToJson, const std::string&()); + + std::unique_ptr<base::DictionaryValue> GetParameters() const override; + std::unique_ptr<base::DictionaryValue> GetProgress() const override; + std::unique_ptr<base::DictionaryValue> GetResults() const override; + std::unique_ptr<base::DictionaryValue> ToJson() const override; +}; + +} // namespace weave + +#endif // LIBWEAVE_INCLUDE_WEAVE_MOCK_COMMAND_H_
diff --git a/libweave/include/weave/mock_commands.h b/libweave/include/weave/mock_commands.h new file mode 100644 index 0000000..12514c5 --- /dev/null +++ b/libweave/include/weave/mock_commands.h
@@ -0,0 +1,32 @@ +// Copyright 2015 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 LIBWEAVE_INCLUDE_WEAVE_MOCK_COMMANDS_H_ +#define LIBWEAVE_INCLUDE_WEAVE_MOCK_COMMANDS_H_ + +#include "weave/commands.h" + +#include <string> + +#include <gmock/gmock.h> + +namespace weave { + +class MockCommands : public Commands { + public: + ~MockCommands() override = default; + + MOCK_METHOD1(AddOnCommandAddedCallback, void(const OnCommandCallback&)); + MOCK_METHOD1(AddOnCommandRemovedCallback, void(const OnCommandCallback&)); + MOCK_METHOD4(AddCommand, + bool(const base::DictionaryValue&, + UserRole, + std::string*, + chromeos::ErrorPtr*)); + MOCK_METHOD1(FindCommand, Command*(const std::string&)); +}; + +} // namespace weave + +#endif // LIBWEAVE_INCLUDE_WEAVE_MOCK_COMMANDS_H_
diff --git a/libweave/src/commands/dbus_command_proxy_unittest.cc b/libweave/src/commands/dbus_command_proxy_unittest.cc index 7ae2b32..e8fa9ec 100644 --- a/libweave/src/commands/dbus_command_proxy_unittest.cc +++ b/libweave/src/commands/dbus_command_proxy_unittest.cc
@@ -16,17 +16,18 @@ #include <gtest/gtest.h> #include "buffet/dbus_constants.h" -#include "libweave/src/commands/command_dictionary.h" -#include "libweave/src/commands/command_instance.h" #include "libweave/src/commands/unittest_utils.h" +#include "weave/command.h" #include "weave/enum_to_string.h" +#include "weave/mock_command.h" +#include "weave/mock_commands.h" namespace weave { using ::testing::AnyNumber; -using ::testing::Invoke; using ::testing::Return; +using ::testing::ReturnRefOfCopy; using ::testing::_; using chromeos::VariantDictionary; @@ -38,6 +39,11 @@ const char kTestCommandCategoty[] = "test_command_category"; const char kTestCommandId[] = "cmd_1"; +MATCHER_P(EqualToJson, json, "") { + auto json_value = CreateDictionaryValue(json); + return unittests::IsEqualValue(*json_value, arg); +} + } // namespace class DBusCommandProxyTest : public ::testing::Test { @@ -51,59 +57,24 @@ EXPECT_CALL(*bus_, AssertOnOriginThread()).Times(AnyNumber()); EXPECT_CALL(*bus_, AssertOnDBusThread()).Times(AnyNumber()); - // Command instance. - // TODO(antonm): Test results. - auto json = CreateDictionaryValue(R"({ - 'robot': { - 'jump': { - 'parameters': { - 'height': { - 'type': 'integer', - 'minimum': 0, - 'maximum': 100 - }, - '_jumpType': { - 'type': 'string', - 'enum': ['_withAirFlip', '_withSpin', '_withKick'] - } - }, - 'results': { - 'foo': { - 'type': 'integer' - }, - 'bar': { - 'type': 'string' - }, - 'resultList': { - 'type': 'array', - 'items': { - 'type': 'integer' - } - } - }, - 'progress': { - 'progress': { - 'type': 'integer', - 'minimum': 0, - 'maximum': 100 - } - } - } - } - })"); - CHECK(dict_.LoadCommands(*json, kTestCommandCategoty, nullptr, nullptr)) - << "Failed to parse test command dictionary"; - - json = CreateDictionaryValue(R"({ - 'name': 'robot.jump', - 'parameters': { - 'height': 53, - '_jumpType': '_withKick' - } - })"); - command_instance_ = CommandInstance::FromJson( - json.get(), CommandOrigin::kLocal, dict_, nullptr, nullptr); - command_instance_->SetID(kTestCommandId); + EXPECT_CALL(command_, GetID()) + .WillOnce(ReturnRefOfCopy<std::string>(kTestCommandId)); + // Use WillRepeatedly becase GetName is used for logging. + EXPECT_CALL(command_, GetName()) + .WillRepeatedly(ReturnRefOfCopy<std::string>("robot.jump")); + EXPECT_CALL(command_, GetCategory()) + .WillOnce(ReturnRefOfCopy<std::string>(kTestCommandCategoty)); + EXPECT_CALL(command_, GetStatus()).WillOnce(Return(CommandStatus::kQueued)); + EXPECT_CALL(command_, GetOrigin()).WillOnce(Return(CommandOrigin::kLocal)); + EXPECT_CALL(command_, MockGetParameters()) + .WillOnce(ReturnRefOfCopy<std::string>(R"({ + 'height': 53, + '_jumpType': '_withKick' + })")); + EXPECT_CALL(command_, MockGetProgress()) + .WillOnce(ReturnRefOfCopy<std::string>("{}")); + EXPECT_CALL(command_, MockGetResults()) + .WillOnce(ReturnRefOfCopy<std::string>("{}")); // Set up a mock ExportedObject to be used with the DBus command proxy. std::string cmd_path = buffet::kCommandServicePathPrefix; @@ -118,24 +89,17 @@ EXPECT_CALL(*mock_exported_object_command_, ExportMethod(_, _, _, _)) .Times(AnyNumber()); - std::unique_ptr<Command::Observer> command_proxy( - new DBusCommandProxy(nullptr, bus_, command_instance_.get(), cmd_path)); - command_instance_->AddObserver(command_proxy.release()); + proxy_.reset(new DBusCommandProxy(nullptr, bus_, &command_, cmd_path)); GetCommandProxy()->RegisterAsync( AsyncEventSequencer::GetDefaultCompletionAction()); } void TearDown() override { EXPECT_CALL(*mock_exported_object_command_, Unregister()).Times(1); - command_instance_.reset(); - dict_.Clear(); bus_ = nullptr; } - DBusCommandProxy* GetCommandProxy() const { - CHECK_EQ(command_instance_->observers_.size(), 1U); - return static_cast<DBusCommandProxy*>(command_instance_->observers_[0]); - } + DBusCommandProxy* GetCommandProxy() const { return proxy_.get(); } org::chromium::Buffet::CommandAdaptor* GetCommandAdaptor() const { return &GetCommandProxy()->dbus_adaptor_; @@ -152,11 +116,11 @@ return status; } - std::unique_ptr<CommandInstance> command_instance_; - CommandDictionary dict_; - scoped_refptr<dbus::MockExportedObject> mock_exported_object_command_; scoped_refptr<dbus::MockBus> bus_; + + MockCommand command_; + std::unique_ptr<DBusCommandProxy> proxy_; }; TEST_F(DBusCommandProxyTest, Init) { @@ -172,72 +136,69 @@ EXPECT_EQ(kTestCommandId, GetCommandAdaptor()->GetId()); } -TEST_F(DBusCommandProxyTest, SetProgress) { - EXPECT_CALL(*mock_exported_object_command_, SendSignal(_)).Times(2); - EXPECT_TRUE( - GetCommandInterface()->SetProgress(nullptr, {{"progress", int32_t{10}}})); - EXPECT_EQ(CommandStatus::kInProgress, GetCommandStatus()); - - VariantDictionary progress{{"progress", int32_t{10}}}; - EXPECT_EQ(progress, GetCommandAdaptor()->GetProgress()); +TEST_F(DBusCommandProxyTest, OnProgressChanged) { + EXPECT_CALL(*mock_exported_object_command_, SendSignal(_)).Times(1); + EXPECT_CALL(command_, MockGetProgress()) + .WillOnce(ReturnRefOfCopy<std::string>("{'progress': 10}")); + proxy_->OnProgressChanged(); + EXPECT_EQ((VariantDictionary{{"progress", int32_t{10}}}), + GetCommandAdaptor()->GetProgress()); } -TEST_F(DBusCommandProxyTest, SetProgress_OutOfRange) { - EXPECT_FALSE(GetCommandInterface()->SetProgress( - nullptr, {{"progress", int32_t{110}}})); - EXPECT_EQ(CommandStatus::kQueued, GetCommandStatus()); - EXPECT_EQ(VariantDictionary{}, GetCommandAdaptor()->GetProgress()); +TEST_F(DBusCommandProxyTest, OnResultsChanged) { + EXPECT_CALL(*mock_exported_object_command_, SendSignal(_)).Times(1); + EXPECT_CALL(command_, MockGetResults()) + .WillOnce(ReturnRefOfCopy<std::string>( + "{'foo': 42, 'bar': 'foobar', 'resultList': [1, 2, 3]}")); + proxy_->OnResultsChanged(); + + EXPECT_EQ((VariantDictionary{{"foo", int32_t{42}}, + {"bar", std::string{"foobar"}}, + {"resultList", std::vector<int>{1, 2, 3}}}), + GetCommandAdaptor()->GetResults()); +} + +TEST_F(DBusCommandProxyTest, OnStatusChanged) { + EXPECT_CALL(*mock_exported_object_command_, SendSignal(_)).Times(1); + EXPECT_CALL(command_, GetStatus()) + .WillOnce(Return(CommandStatus::kInProgress)); + proxy_->OnStatusChanged(); + EXPECT_EQ(CommandStatus::kInProgress, GetCommandStatus()); +} + +TEST_F(DBusCommandProxyTest, SetProgress) { + EXPECT_CALL(command_, SetProgress(EqualToJson("{'progress': 10}"), _)) + .WillOnce(Return(true)); + EXPECT_TRUE( + GetCommandInterface()->SetProgress(nullptr, {{"progress", int32_t{10}}})); } TEST_F(DBusCommandProxyTest, SetResults) { - EXPECT_CALL(*mock_exported_object_command_, SendSignal(_)).Times(1); - VariantDictionary results = {{"foo", int32_t{42}}, - {"bar", std::string{"foobar"}}, - {"resultList", std::vector<int>{1, 2, 3}}}; - EXPECT_TRUE(GetCommandInterface()->SetResults(nullptr, results)); - EXPECT_EQ(results, GetCommandAdaptor()->GetResults()); - auto list = chromeos::GetVariantValueOrDefault<std::vector<int>>( - GetCommandAdaptor()->GetResults(), "resultList"); - EXPECT_EQ((std::vector<int>{1, 2, 3}), list); -} - -TEST_F(DBusCommandProxyTest, SetResults_WithEmptyList) { - EXPECT_CALL(*mock_exported_object_command_, SendSignal(_)).Times(1); - VariantDictionary results = {{"foo", int32_t{42}}, - {"bar", std::string{"foobar"}}, - {"resultList", std::vector<int>{}}}; - EXPECT_TRUE(GetCommandInterface()->SetResults(nullptr, results)); - auto list = chromeos::GetVariantValueOrDefault<std::vector<int>>( - GetCommandAdaptor()->GetResults(), "resultList"); - EXPECT_EQ(std::vector<int>(), list); -} - -TEST_F(DBusCommandProxyTest, SetResults_UnknownProperty) { - EXPECT_CALL(*mock_exported_object_command_, SendSignal(_)).Times(0); - const VariantDictionary results = { - {"quux", int32_t{42}}, - }; - EXPECT_FALSE(GetCommandInterface()->SetResults(nullptr, results)); + EXPECT_CALL( + command_, + SetResults( + EqualToJson("{'foo': 42, 'bar': 'foobar', 'resultList': [1, 2, 3]}"), + _)) + .WillOnce(Return(true)); + EXPECT_TRUE(GetCommandInterface()->SetResults( + nullptr, VariantDictionary{{"foo", int32_t{42}}, + {"bar", std::string{"foobar"}}, + {"resultList", std::vector<int>{1, 2, 3}}})); } TEST_F(DBusCommandProxyTest, Abort) { - EXPECT_CALL(*mock_exported_object_command_, SendSignal(_)).Times(1); + EXPECT_CALL(command_, Abort()); GetCommandInterface()->Abort(); - EXPECT_EQ(CommandStatus::kAborted, GetCommandStatus()); } TEST_F(DBusCommandProxyTest, Cancel) { - EXPECT_CALL(*mock_exported_object_command_, SendSignal(_)).Times(1); + EXPECT_CALL(command_, Cancel()); GetCommandInterface()->Cancel(); - EXPECT_EQ(CommandStatus::kCancelled, GetCommandStatus()); } TEST_F(DBusCommandProxyTest, Done) { - // 1 property update: - // status: queued -> done - EXPECT_CALL(*mock_exported_object_command_, SendSignal(_)).Times(1); + EXPECT_CALL(command_, Done()); GetCommandInterface()->Done(); - EXPECT_EQ(CommandStatus::kDone, GetCommandStatus()); } } // namespace weave
diff --git a/libweave/src/commands/mock_command.cc b/libweave/src/commands/mock_command.cc new file mode 100644 index 0000000..6b52b99 --- /dev/null +++ b/libweave/src/commands/mock_command.cc
@@ -0,0 +1,34 @@ +// Copyright 2015 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 "weave/mock_command.h" + +#include <memory> +#include <string> + +#include <base/values.h> + +#include "libweave/src/commands/unittest_utils.h" + +namespace weave { + +using unittests::CreateDictionaryValue; + +std::unique_ptr<base::DictionaryValue> MockCommand::GetParameters() const { + return CreateDictionaryValue(MockGetParameters()); +} + +std::unique_ptr<base::DictionaryValue> MockCommand::GetProgress() const { + return CreateDictionaryValue(MockGetProgress()); +} + +std::unique_ptr<base::DictionaryValue> MockCommand::GetResults() const { + return CreateDictionaryValue(MockGetResults()); +} + +std::unique_ptr<base::DictionaryValue> MockCommand::ToJson() const { + return CreateDictionaryValue(MockToJson()); +} + +} // namespace weave
diff --git a/libweave/src/commands/unittest_utils.cc b/libweave/src/commands/unittest_utils.cc index 85e63fc..18a7108 100644 --- a/libweave/src/commands/unittest_utils.cc +++ b/libweave/src/commands/unittest_utils.cc
@@ -10,7 +10,7 @@ namespace weave { namespace unittests { -std::unique_ptr<base::Value> CreateValue(const char* json) { +std::unique_ptr<base::Value> CreateValue(const std::string& json) { std::string json2(json); // Convert apostrophes to double-quotes so JSONReader can parse the string. std::replace(json2.begin(), json2.end(), '\'', '"'); @@ -24,7 +24,8 @@ return value; } -std::unique_ptr<base::DictionaryValue> CreateDictionaryValue(const char* json) { +std::unique_ptr<base::DictionaryValue> CreateDictionaryValue( + const std::string& json) { std::unique_ptr<base::Value> value = CreateValue(json); base::DictionaryValue* dict = nullptr; value->GetAsDictionary(&dict);
diff --git a/libweave/src/commands/unittest_utils.h b/libweave/src/commands/unittest_utils.h index 0e685d1..345e92d 100644 --- a/libweave/src/commands/unittest_utils.h +++ b/libweave/src/commands/unittest_utils.h
@@ -20,10 +20,11 @@ // Helper method to create base::Value from a string as a smart pointer. // For ease of definition in C++ code, double-quotes in the source definition // are replaced with apostrophes. -std::unique_ptr<base::Value> CreateValue(const char* json); +std::unique_ptr<base::Value> CreateValue(const std::string& json); // Helper method to create a JSON dictionary object from a string. -std::unique_ptr<base::DictionaryValue> CreateDictionaryValue(const char* json); +std::unique_ptr<base::DictionaryValue> CreateDictionaryValue( + const std::string& json); inline bool IsEqualValue(const base::Value& val1, const base::Value& val2) { return val1.Equals(&val2);