blob: 1e156e4ee9bb0b035fa625368d6c9d36291853a7 [file] [log] [blame]
Vitaly Bukaa0305d32015-07-27 16:08:51 -07001// Copyright 2014 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "buffet/dbus_command_proxy.h"
6
7#include <functional>
8#include <memory>
9#include <vector>
10
11#include <dbus/mock_bus.h>
12#include <dbus/mock_exported_object.h>
13#include <dbus/property.h>
14#include <chromeos/dbus/dbus_object.h>
15#include <chromeos/dbus/dbus_object_test_helpers.h>
16#include <gtest/gtest.h>
Vitaly Bukae2713ac2015-08-03 13:50:01 -070017#include <weave/command.h>
18#include <weave/enum_to_string.h>
Vitaly Bukaea2f1e22015-08-20 15:35:19 -070019#include <weave/test/mock_command.h>
Vitaly Bukaea2f1e22015-08-20 15:35:19 -070020#include <weave/test/unittest_utils.h>
Vitaly Bukaa0305d32015-07-27 16:08:51 -070021
22#include "buffet/dbus_constants.h"
Vitaly Bukaa0305d32015-07-27 16:08:51 -070023
24namespace buffet {
25
Vitaly Buka3a58bb92015-08-05 23:16:13 -070026using ::testing::_;
Vitaly Bukaa0305d32015-07-27 16:08:51 -070027using ::testing::AnyNumber;
28using ::testing::Return;
29using ::testing::ReturnRefOfCopy;
Vitaly Buka3a58bb92015-08-05 23:16:13 -070030using ::testing::StrictMock;
Vitaly Bukaa0305d32015-07-27 16:08:51 -070031
32using chromeos::VariantDictionary;
33using chromeos::dbus_utils::AsyncEventSequencer;
Vitaly Bukaea2f1e22015-08-20 15:35:19 -070034using weave::test::CreateDictionaryValue;
35using weave::test::IsEqualValue;
Vitaly Bukaa0305d32015-07-27 16:08:51 -070036
37namespace {
38
Vitaly Bukaa0305d32015-07-27 16:08:51 -070039const char kTestCommandId[] = "cmd_1";
40
41MATCHER_P(EqualToJson, json, "") {
42 auto json_value = CreateDictionaryValue(json);
43 return IsEqualValue(*json_value, arg);
44}
45
46} // namespace
47
48class DBusCommandProxyTest : public ::testing::Test {
49 public:
50 void SetUp() override {
Alex Vakulenko2915a7b2015-10-07 17:04:00 -070051 command_ = std::make_shared<StrictMock<weave::test::MockCommand>>();
Vitaly Bukaa0305d32015-07-27 16:08:51 -070052 // Set up a mock DBus bus object.
53 dbus::Bus::Options options;
54 options.bus_type = dbus::Bus::SYSTEM;
55 bus_ = new dbus::MockBus(options);
56 // By default, don't worry about threading assertions.
57 EXPECT_CALL(*bus_, AssertOnOriginThread()).Times(AnyNumber());
58 EXPECT_CALL(*bus_, AssertOnDBusThread()).Times(AnyNumber());
59
Alex Vakulenko2915a7b2015-10-07 17:04:00 -070060 EXPECT_CALL(*command_, GetID())
Vitaly Bukaa0305d32015-07-27 16:08:51 -070061 .WillOnce(ReturnRefOfCopy<std::string>(kTestCommandId));
Alex Vakulenko2915a7b2015-10-07 17:04:00 -070062 // Use WillRepeatedly because GetName is used for logging.
63 EXPECT_CALL(*command_, GetName())
Vitaly Bukaa0305d32015-07-27 16:08:51 -070064 .WillRepeatedly(ReturnRefOfCopy<std::string>("robot.jump"));
Alex Vakulenko2915a7b2015-10-07 17:04:00 -070065 EXPECT_CALL(*command_, GetStatus())
66 .WillRepeatedly(Return(weave::CommandStatus::kQueued));
67 EXPECT_CALL(*command_, GetOrigin())
Vitaly Bukaa0305d32015-07-27 16:08:51 -070068 .WillOnce(Return(weave::CommandOrigin::kLocal));
Alex Vakulenko2915a7b2015-10-07 17:04:00 -070069 EXPECT_CALL(*command_, MockGetParameters())
Vitaly Bukaa0305d32015-07-27 16:08:51 -070070 .WillOnce(ReturnRefOfCopy<std::string>(R"({
71 'height': 53,
72 '_jumpType': '_withKick'
73 })"));
Alex Vakulenko2915a7b2015-10-07 17:04:00 -070074 EXPECT_CALL(*command_, MockGetProgress())
75 .WillRepeatedly(ReturnRefOfCopy<std::string>("{}"));
76 EXPECT_CALL(*command_, MockGetResults())
Vitaly Bukaa0305d32015-07-27 16:08:51 -070077 .WillOnce(ReturnRefOfCopy<std::string>("{}"));
78
79 // Set up a mock ExportedObject to be used with the DBus command proxy.
Robert Gindacf92c662015-08-20 09:30:11 -070080 std::string cmd_path = buffet::dbus_constants::kCommandServicePathPrefix;
Vitaly Bukaa0305d32015-07-27 16:08:51 -070081 cmd_path += kTestCommandId;
82 const dbus::ObjectPath kCmdObjPath(cmd_path);
83 // Use a mock exported object for the exported object manager.
84 mock_exported_object_command_ =
85 new dbus::MockExportedObject(bus_.get(), kCmdObjPath);
86 EXPECT_CALL(*bus_, GetExportedObject(kCmdObjPath))
87 .Times(AnyNumber())
88 .WillRepeatedly(Return(mock_exported_object_command_.get()));
89 EXPECT_CALL(*mock_exported_object_command_, ExportMethod(_, _, _, _))
90 .Times(AnyNumber());
91
Alex Vakulenko2915a7b2015-10-07 17:04:00 -070092 proxy_.reset(new DBusCommandProxy{
93 nullptr, bus_, std::weak_ptr<weave::Command>{command_}, cmd_path});
Vitaly Bukaa0305d32015-07-27 16:08:51 -070094 GetCommandProxy()->RegisterAsync(
95 AsyncEventSequencer::GetDefaultCompletionAction());
96 }
97
98 void TearDown() override {
99 EXPECT_CALL(*mock_exported_object_command_, Unregister()).Times(1);
100 bus_ = nullptr;
101 }
102
103 DBusCommandProxy* GetCommandProxy() const { return proxy_.get(); }
104
Alex Vakulenko63bdf082015-08-21 09:27:12 -0700105 com::android::Weave::CommandAdaptor* GetCommandAdaptor() const {
Vitaly Bukaa0305d32015-07-27 16:08:51 -0700106 return &GetCommandProxy()->dbus_adaptor_;
107 }
108
Alex Vakulenko63bdf082015-08-21 09:27:12 -0700109 com::android::Weave::CommandInterface* GetCommandInterface() const {
Vitaly Bukaa0305d32015-07-27 16:08:51 -0700110 // DBusCommandProxy also implements CommandInterface.
111 return GetCommandProxy();
112 }
113
114 weave::CommandStatus GetCommandStatus() const {
115 weave::CommandStatus status;
116 EXPECT_TRUE(StringToEnum(GetCommandAdaptor()->GetStatus(), &status));
117 return status;
118 }
119
120 scoped_refptr<dbus::MockExportedObject> mock_exported_object_command_;
121 scoped_refptr<dbus::MockBus> bus_;
122
Alex Vakulenko2915a7b2015-10-07 17:04:00 -0700123 std::shared_ptr<StrictMock<weave::test::MockCommand>> command_;
Vitaly Bukaa0305d32015-07-27 16:08:51 -0700124 std::unique_ptr<DBusCommandProxy> proxy_;
125};
126
127TEST_F(DBusCommandProxyTest, Init) {
128 VariantDictionary params = {
129 {"height", int32_t{53}}, {"_jumpType", std::string{"_withKick"}},
130 };
131 EXPECT_EQ(weave::CommandStatus::kQueued, GetCommandStatus());
132 EXPECT_EQ(params, GetCommandAdaptor()->GetParameters());
133 EXPECT_EQ(VariantDictionary{}, GetCommandAdaptor()->GetProgress());
134 EXPECT_EQ(VariantDictionary{}, GetCommandAdaptor()->GetResults());
135 EXPECT_EQ("robot.jump", GetCommandAdaptor()->GetName());
Vitaly Bukaa0305d32015-07-27 16:08:51 -0700136 EXPECT_EQ(kTestCommandId, GetCommandAdaptor()->GetId());
137}
138
Vitaly Bukaa0305d32015-07-27 16:08:51 -0700139TEST_F(DBusCommandProxyTest, SetProgress) {
Alex Vakulenko2915a7b2015-10-07 17:04:00 -0700140 EXPECT_CALL(*command_, SetProgress(EqualToJson("{'progress': 10}"), _))
Vitaly Bukaa0305d32015-07-27 16:08:51 -0700141 .WillOnce(Return(true));
142 EXPECT_TRUE(
143 GetCommandInterface()->SetProgress(nullptr, {{"progress", int32_t{10}}}));
144}
145
146TEST_F(DBusCommandProxyTest, SetResults) {
147 EXPECT_CALL(
Alex Vakulenko2915a7b2015-10-07 17:04:00 -0700148 *command_,
Vitaly Bukaa0305d32015-07-27 16:08:51 -0700149 SetResults(
150 EqualToJson("{'foo': 42, 'bar': 'foobar', 'resultList': [1, 2, 3]}"),
151 _))
152 .WillOnce(Return(true));
153 EXPECT_TRUE(GetCommandInterface()->SetResults(
154 nullptr, VariantDictionary{{"foo", int32_t{42}},
155 {"bar", std::string{"foobar"}},
156 {"resultList", std::vector<int>{1, 2, 3}}}));
157}
158
159TEST_F(DBusCommandProxyTest, Abort) {
Alex Vakulenko2915a7b2015-10-07 17:04:00 -0700160 EXPECT_CALL(*command_, Abort());
161 EXPECT_TRUE(GetCommandInterface()->Abort(nullptr));
Vitaly Bukaa0305d32015-07-27 16:08:51 -0700162}
163
164TEST_F(DBusCommandProxyTest, Cancel) {
Alex Vakulenko2915a7b2015-10-07 17:04:00 -0700165 EXPECT_CALL(*command_, Cancel());
166 EXPECT_TRUE(GetCommandInterface()->Cancel(nullptr));
Vitaly Bukaa0305d32015-07-27 16:08:51 -0700167}
168
169TEST_F(DBusCommandProxyTest, Done) {
Alex Vakulenko2915a7b2015-10-07 17:04:00 -0700170 EXPECT_CALL(*command_, Done());
171 EXPECT_TRUE(GetCommandInterface()->Done(nullptr));
Vitaly Bukaa0305d32015-07-27 16:08:51 -0700172}
173
174} // namespace buffet