blob: 0aa701d5c1984ef4bab583d7a7bfc44d6eddb9df [file] [log] [blame]
Vitaly Bukacad20f02015-10-16 17:27:15 -07001// Copyright 2015 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
Vitaly Bukaa0305d32015-07-27 16:08:51 -070014
15#include "buffet/dbus_command_proxy.h"
16
17#include <functional>
18#include <memory>
19#include <vector>
20
21#include <dbus/mock_bus.h>
22#include <dbus/mock_exported_object.h>
23#include <dbus/property.h>
Alex Vakulenko41705852015-10-13 10:12:06 -070024#include <brillo/dbus/dbus_object.h>
25#include <brillo/dbus/dbus_object_test_helpers.h>
Vitaly Bukaa0305d32015-07-27 16:08:51 -070026#include <gtest/gtest.h>
Vitaly Bukae2713ac2015-08-03 13:50:01 -070027#include <weave/command.h>
28#include <weave/enum_to_string.h>
Vitaly Bukaea2f1e22015-08-20 15:35:19 -070029#include <weave/test/mock_command.h>
Vitaly Bukaea2f1e22015-08-20 15:35:19 -070030#include <weave/test/unittest_utils.h>
Vitaly Bukaa0305d32015-07-27 16:08:51 -070031
32#include "buffet/dbus_constants.h"
Vitaly Bukaa0305d32015-07-27 16:08:51 -070033
34namespace buffet {
35
Vitaly Buka3a58bb92015-08-05 23:16:13 -070036using ::testing::_;
Vitaly Bukaa0305d32015-07-27 16:08:51 -070037using ::testing::AnyNumber;
38using ::testing::Return;
Alex Vakulenkobae6c022015-12-08 13:22:07 -080039using ::testing::ReturnRef;
Vitaly Bukaa0305d32015-07-27 16:08:51 -070040using ::testing::ReturnRefOfCopy;
Vitaly Buka3a58bb92015-08-05 23:16:13 -070041using ::testing::StrictMock;
Vitaly Bukaa0305d32015-07-27 16:08:51 -070042
Alex Vakulenko41705852015-10-13 10:12:06 -070043using brillo::VariantDictionary;
44using brillo::dbus_utils::AsyncEventSequencer;
Vitaly Bukaea2f1e22015-08-20 15:35:19 -070045using weave::test::CreateDictionaryValue;
46using weave::test::IsEqualValue;
Vitaly Bukaa0305d32015-07-27 16:08:51 -070047
48namespace {
49
Vitaly Bukaa0305d32015-07-27 16:08:51 -070050const char kTestCommandId[] = "cmd_1";
51
52MATCHER_P(EqualToJson, json, "") {
53 auto json_value = CreateDictionaryValue(json);
54 return IsEqualValue(*json_value, arg);
55}
56
Alex Vakulenkobe39e932015-10-09 08:10:36 -070057MATCHER_P2(ExpectError, code, message, "") {
58 return arg->GetCode() == code && arg->GetMessage() == message;
59}
60
Vitaly Bukaa0305d32015-07-27 16:08:51 -070061} // namespace
62
63class DBusCommandProxyTest : public ::testing::Test {
64 public:
65 void SetUp() override {
Alex Vakulenko2915a7b2015-10-07 17:04:00 -070066 command_ = std::make_shared<StrictMock<weave::test::MockCommand>>();
Vitaly Bukaa0305d32015-07-27 16:08:51 -070067 // Set up a mock DBus bus object.
68 dbus::Bus::Options options;
69 options.bus_type = dbus::Bus::SYSTEM;
70 bus_ = new dbus::MockBus(options);
71 // By default, don't worry about threading assertions.
72 EXPECT_CALL(*bus_, AssertOnOriginThread()).Times(AnyNumber());
73 EXPECT_CALL(*bus_, AssertOnDBusThread()).Times(AnyNumber());
74
Alex Vakulenkobae6c022015-12-08 13:22:07 -080075 expected_result_dict_.SetInteger("height", 53);
76 expected_result_dict_.SetString("_jumpType", "_withKick");
Alex Vakulenko2915a7b2015-10-07 17:04:00 -070077 EXPECT_CALL(*command_, GetID())
Vitaly Bukaa0305d32015-07-27 16:08:51 -070078 .WillOnce(ReturnRefOfCopy<std::string>(kTestCommandId));
Alex Vakulenko2915a7b2015-10-07 17:04:00 -070079 // Use WillRepeatedly because GetName is used for logging.
80 EXPECT_CALL(*command_, GetName())
Vitaly Bukaa0305d32015-07-27 16:08:51 -070081 .WillRepeatedly(ReturnRefOfCopy<std::string>("robot.jump"));
Alex Vakulenkobe39e932015-10-09 08:10:36 -070082 EXPECT_CALL(*command_, GetState())
83 .WillRepeatedly(Return(weave::Command::State::kQueued));
Alex Vakulenko2915a7b2015-10-07 17:04:00 -070084 EXPECT_CALL(*command_, GetOrigin())
Alex Vakulenkobe39e932015-10-09 08:10:36 -070085 .WillOnce(Return(weave::Command::Origin::kLocal));
Alex Vakulenkobae6c022015-12-08 13:22:07 -080086 EXPECT_CALL(*command_, GetParameters())
87 .WillOnce(ReturnRef(expected_result_dict_));
88 EXPECT_CALL(*command_, GetProgress())
89 .WillRepeatedly(ReturnRef(empty_dict_));
90 EXPECT_CALL(*command_, GetResults())
91 .WillRepeatedly(ReturnRef(empty_dict_));
Vitaly Bukaa0305d32015-07-27 16:08:51 -070092
93 // Set up a mock ExportedObject to be used with the DBus command proxy.
Robert Gindacf92c662015-08-20 09:30:11 -070094 std::string cmd_path = buffet::dbus_constants::kCommandServicePathPrefix;
Vitaly Bukaa0305d32015-07-27 16:08:51 -070095 cmd_path += kTestCommandId;
96 const dbus::ObjectPath kCmdObjPath(cmd_path);
97 // Use a mock exported object for the exported object manager.
98 mock_exported_object_command_ =
99 new dbus::MockExportedObject(bus_.get(), kCmdObjPath);
100 EXPECT_CALL(*bus_, GetExportedObject(kCmdObjPath))
101 .Times(AnyNumber())
102 .WillRepeatedly(Return(mock_exported_object_command_.get()));
103 EXPECT_CALL(*mock_exported_object_command_, ExportMethod(_, _, _, _))
104 .Times(AnyNumber());
105
Alex Vakulenko2915a7b2015-10-07 17:04:00 -0700106 proxy_.reset(new DBusCommandProxy{
107 nullptr, bus_, std::weak_ptr<weave::Command>{command_}, cmd_path});
Vitaly Bukaa0305d32015-07-27 16:08:51 -0700108 GetCommandProxy()->RegisterAsync(
109 AsyncEventSequencer::GetDefaultCompletionAction());
110 }
111
112 void TearDown() override {
113 EXPECT_CALL(*mock_exported_object_command_, Unregister()).Times(1);
114 bus_ = nullptr;
115 }
116
117 DBusCommandProxy* GetCommandProxy() const { return proxy_.get(); }
118
Alex Vakulenko63bdf082015-08-21 09:27:12 -0700119 com::android::Weave::CommandAdaptor* GetCommandAdaptor() const {
Vitaly Bukaa0305d32015-07-27 16:08:51 -0700120 return &GetCommandProxy()->dbus_adaptor_;
121 }
122
Alex Vakulenko63bdf082015-08-21 09:27:12 -0700123 com::android::Weave::CommandInterface* GetCommandInterface() const {
Vitaly Bukaa0305d32015-07-27 16:08:51 -0700124 // DBusCommandProxy also implements CommandInterface.
125 return GetCommandProxy();
126 }
127
Alex Vakulenkobe39e932015-10-09 08:10:36 -0700128 weave::Command::State GetCommandState() const {
129 weave::Command::State state;
130 EXPECT_TRUE(StringToEnum(GetCommandAdaptor()->GetState(), &state));
131 return state;
Vitaly Bukaa0305d32015-07-27 16:08:51 -0700132 }
133
134 scoped_refptr<dbus::MockExportedObject> mock_exported_object_command_;
135 scoped_refptr<dbus::MockBus> bus_;
Alex Vakulenkobae6c022015-12-08 13:22:07 -0800136 base::DictionaryValue empty_dict_;
137 base::DictionaryValue expected_result_dict_;
Vitaly Bukaa0305d32015-07-27 16:08:51 -0700138
Alex Vakulenko2915a7b2015-10-07 17:04:00 -0700139 std::shared_ptr<StrictMock<weave::test::MockCommand>> command_;
Vitaly Bukaa0305d32015-07-27 16:08:51 -0700140 std::unique_ptr<DBusCommandProxy> proxy_;
141};
142
143TEST_F(DBusCommandProxyTest, Init) {
144 VariantDictionary params = {
145 {"height", int32_t{53}}, {"_jumpType", std::string{"_withKick"}},
146 };
Alex Vakulenkobe39e932015-10-09 08:10:36 -0700147 EXPECT_EQ(weave::Command::State::kQueued, GetCommandState());
Vitaly Bukaa0305d32015-07-27 16:08:51 -0700148 EXPECT_EQ(params, GetCommandAdaptor()->GetParameters());
149 EXPECT_EQ(VariantDictionary{}, GetCommandAdaptor()->GetProgress());
150 EXPECT_EQ(VariantDictionary{}, GetCommandAdaptor()->GetResults());
151 EXPECT_EQ("robot.jump", GetCommandAdaptor()->GetName());
Vitaly Bukaa0305d32015-07-27 16:08:51 -0700152 EXPECT_EQ(kTestCommandId, GetCommandAdaptor()->GetId());
153}
154
Vitaly Bukaa0305d32015-07-27 16:08:51 -0700155TEST_F(DBusCommandProxyTest, SetProgress) {
Alex Vakulenko2915a7b2015-10-07 17:04:00 -0700156 EXPECT_CALL(*command_, SetProgress(EqualToJson("{'progress': 10}"), _))
Vitaly Bukaa0305d32015-07-27 16:08:51 -0700157 .WillOnce(Return(true));
158 EXPECT_TRUE(
159 GetCommandInterface()->SetProgress(nullptr, {{"progress", int32_t{10}}}));
160}
161
Alex Vakulenkobe39e932015-10-09 08:10:36 -0700162TEST_F(DBusCommandProxyTest, Complete) {
Vitaly Bukaa0305d32015-07-27 16:08:51 -0700163 EXPECT_CALL(
Alex Vakulenko2915a7b2015-10-07 17:04:00 -0700164 *command_,
Alex Vakulenkobe39e932015-10-09 08:10:36 -0700165 Complete(
Vitaly Bukaa0305d32015-07-27 16:08:51 -0700166 EqualToJson("{'foo': 42, 'bar': 'foobar', 'resultList': [1, 2, 3]}"),
167 _))
168 .WillOnce(Return(true));
Alex Vakulenkobe39e932015-10-09 08:10:36 -0700169 EXPECT_TRUE(GetCommandInterface()->Complete(
Vitaly Bukaa0305d32015-07-27 16:08:51 -0700170 nullptr, VariantDictionary{{"foo", int32_t{42}},
171 {"bar", std::string{"foobar"}},
172 {"resultList", std::vector<int>{1, 2, 3}}}));
173}
174
175TEST_F(DBusCommandProxyTest, Abort) {
Alex Vakulenkobe39e932015-10-09 08:10:36 -0700176 EXPECT_CALL(*command_, Abort(ExpectError("foo", "bar"), _))
177 .WillOnce(Return(true));
178 EXPECT_TRUE(GetCommandInterface()->Abort(nullptr, "foo", "bar"));
Vitaly Bukaa0305d32015-07-27 16:08:51 -0700179}
180
181TEST_F(DBusCommandProxyTest, Cancel) {
Alex Vakulenkobe39e932015-10-09 08:10:36 -0700182 EXPECT_CALL(*command_, Cancel(_)).WillOnce(Return(true));
Alex Vakulenko2915a7b2015-10-07 17:04:00 -0700183 EXPECT_TRUE(GetCommandInterface()->Cancel(nullptr));
Vitaly Bukaa0305d32015-07-27 16:08:51 -0700184}
185
Vitaly Bukaa0305d32015-07-27 16:08:51 -0700186} // namespace buffet