blob: 1f94ca7913d016fc6f8c6d6b98f9f98decec2d22 [file] [log] [blame]
Alex Vakulenko4866ac92014-08-20 12:53:33 -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
Alex Deymof6cbe322014-11-10 19:55:35 -08005#include "buffet/commands/dbus_command_proxy.h"
6
Alex Vakulenko4866ac92014-08-20 12:53:33 -07007#include <functional>
8#include <memory>
9
10#include <dbus/mock_bus.h>
11#include <dbus/mock_exported_object.h>
12#include <dbus/property.h>
13#include <chromeos/dbus/dbus_object.h>
Alex Vakulenko5c7bf012014-10-30 16:28:38 -070014#include <chromeos/dbus/dbus_object_test_helpers.h>
Alex Vakulenko4866ac92014-08-20 12:53:33 -070015#include <gtest/gtest.h>
16
17#include "buffet/commands/command_dictionary.h"
18#include "buffet/commands/command_instance.h"
Alex Vakulenko4866ac92014-08-20 12:53:33 -070019#include "buffet/commands/unittest_utils.h"
Alex Vakulenko420e49f2014-12-01 17:53:27 -080020#include "buffet/dbus_constants.h"
Alex Vakulenko4866ac92014-08-20 12:53:33 -070021
Vitaly Buka32005de2015-05-01 12:33:31 -070022namespace buffet {
23
Alex Vakulenko4866ac92014-08-20 12:53:33 -070024using ::testing::AnyNumber;
Alex Vakulenko4866ac92014-08-20 12:53:33 -070025using ::testing::Invoke;
Vitaly Buka32005de2015-05-01 12:33:31 -070026using ::testing::Return;
Alex Vakulenko4866ac92014-08-20 12:53:33 -070027using ::testing::_;
28
Alex Vakulenko576c9792014-09-22 16:49:45 -070029using chromeos::VariantDictionary;
Vitaly Buka32005de2015-05-01 12:33:31 -070030using chromeos::dbus_utils::AsyncEventSequencer;
31using unittests::CreateDictionaryValue;
Alex Vakulenko4866ac92014-08-20 12:53:33 -070032
33namespace {
34
35const char kTestCommandCategoty[] = "test_command_category";
36const char kTestCommandId[] = "cmd_1";
37
Alex Vakulenko4866ac92014-08-20 12:53:33 -070038} // namespace
39
40class DBusCommandProxyTest : public ::testing::Test {
41 public:
42 void SetUp() override {
43 // Set up a mock DBus bus object.
44 dbus::Bus::Options options;
45 options.bus_type = dbus::Bus::SYSTEM;
46 bus_ = new dbus::MockBus(options);
47 // By default, don't worry about threading assertions.
48 EXPECT_CALL(*bus_, AssertOnOriginThread()).Times(AnyNumber());
49 EXPECT_CALL(*bus_, AssertOnDBusThread()).Times(AnyNumber());
50
51 // Command instance.
Anton Muhin71fb9d52014-11-21 22:22:39 +040052 // TODO(antonm): Test results.
Alex Vakulenko4866ac92014-08-20 12:53:33 -070053 auto json = CreateDictionaryValue(R"({
54 'robot': {
55 'jump': {
56 'parameters': {
57 'height': {
58 'type': 'integer',
59 'minimum': 0,
60 'maximum': 100
61 },
62 '_jumpType': {
63 'type': 'string',
64 'enum': ['_withAirFlip', '_withSpin', '_withKick']
65 }
Anton Muhin71fb9d52014-11-21 22:22:39 +040066 },
Anton Muhincfde8692014-11-25 03:36:59 +040067 'results': {
68 'foo': {
69 'type': 'integer'
70 },
71 'bar': {
72 'type': 'string'
73 }
Vitaly Buka4129dfa2015-04-29 12:16:58 -070074 },
75 'progress': {
76 'progress': {
77 'type': 'integer',
78 'minimum': 0,
79 'maximum': 100
80 }
Anton Muhincfde8692014-11-25 03:36:59 +040081 }
Alex Vakulenko4866ac92014-08-20 12:53:33 -070082 }
83 }
84 })");
85 CHECK(dict_.LoadCommands(*json, kTestCommandCategoty, nullptr, nullptr))
86 << "Failed to parse test command dictionary";
87
88 json = CreateDictionaryValue(R"({
89 'name': 'robot.jump',
90 'parameters': {
91 'height': 53,
92 '_jumpType': '_withKick'
93 }
94 })");
Alex Vakulenkof784e212015-04-20 12:33:52 -070095 command_instance_ =
Alex Vakulenkod1978d32015-04-29 17:33:26 -070096 CommandInstance::FromJson(json.get(), "local", dict_, nullptr, nullptr);
Alex Vakulenko4866ac92014-08-20 12:53:33 -070097 command_instance_->SetID(kTestCommandId);
98
99 // Set up a mock ExportedObject to be used with the DBus command proxy.
100 std::string cmd_path = dbus_constants::kCommandServicePathPrefix;
101 cmd_path += kTestCommandId;
102 const dbus::ObjectPath kCmdObjPath(cmd_path);
103 // Use a mock exported object for the exported object manager.
104 mock_exported_object_command_ =
105 new dbus::MockExportedObject(bus_.get(), kCmdObjPath);
106 EXPECT_CALL(*bus_, GetExportedObject(kCmdObjPath)).Times(AnyNumber())
107 .WillRepeatedly(Return(mock_exported_object_command_.get()));
108 EXPECT_CALL(*mock_exported_object_command_,
109 ExportMethod(_, _, _, _)).Times(AnyNumber());
110
Anton Muhinb66a9302014-11-10 22:15:22 +0400111 std::unique_ptr<CommandProxyInterface> command_proxy(
112 new DBusCommandProxy(nullptr, bus_, command_instance_.get(), cmd_path));
113 command_instance_->AddProxy(std::move(command_proxy));
114 GetCommandProxy()->RegisterAsync(
Alex Vakulenkof6b38712014-09-03 16:23:38 -0700115 AsyncEventSequencer::GetDefaultCompletionAction());
Alex Vakulenko4866ac92014-08-20 12:53:33 -0700116 }
117
118 void TearDown() override {
119 EXPECT_CALL(*mock_exported_object_command_, Unregister()).Times(1);
Alex Vakulenko4866ac92014-08-20 12:53:33 -0700120 command_instance_.reset();
121 dict_.Clear();
122 bus_ = nullptr;
123 }
124
Anton Muhinb66a9302014-11-10 22:15:22 +0400125 DBusCommandProxy* GetCommandProxy() const {
Mike Frysinger42e3a722014-11-15 06:48:08 -0500126 CHECK_EQ(command_instance_->proxies_.size(), 1U);
Anton Muhinb66a9302014-11-10 22:15:22 +0400127 return static_cast<DBusCommandProxy*>(command_instance_->proxies_[0].get());
128 }
129
Alex Vakulenko420e49f2014-12-01 17:53:27 -0800130 org::chromium::Buffet::CommandAdaptor* GetCommandAdaptor() const {
131 return &GetCommandProxy()->dbus_adaptor_;
Alex Vakulenko4866ac92014-08-20 12:53:33 -0700132 }
133
Alex Vakulenko420e49f2014-12-01 17:53:27 -0800134 org::chromium::Buffet::CommandInterface* GetCommandInterface() const {
135 // DBusCommandProxy also implements CommandInterface.
136 return GetCommandProxy();
Alex Vakulenko4866ac92014-08-20 12:53:33 -0700137 }
138
Alex Vakulenko4866ac92014-08-20 12:53:33 -0700139 std::unique_ptr<CommandInstance> command_instance_;
140 CommandDictionary dict_;
141
142 scoped_refptr<dbus::MockExportedObject> mock_exported_object_command_;
143 scoped_refptr<dbus::MockBus> bus_;
144};
145
146TEST_F(DBusCommandProxyTest, Init) {
Alex Vakulenko576c9792014-09-22 16:49:45 -0700147 VariantDictionary params = {
Alex Vakulenkof6b38712014-09-03 16:23:38 -0700148 {"height", int32_t{53}},
149 {"_jumpType", std::string{"_withKick"}},
150 };
Alex Vakulenko420e49f2014-12-01 17:53:27 -0800151 EXPECT_EQ(CommandInstance::kStatusQueued, GetCommandAdaptor()->GetStatus());
Alex Vakulenko420e49f2014-12-01 17:53:27 -0800152 EXPECT_EQ(params, GetCommandAdaptor()->GetParameters());
Vitaly Buka4129dfa2015-04-29 12:16:58 -0700153 EXPECT_EQ(VariantDictionary{}, GetCommandAdaptor()->GetProgress());
154 EXPECT_EQ(VariantDictionary{}, GetCommandAdaptor()->GetResults());
Alex Vakulenko420e49f2014-12-01 17:53:27 -0800155 EXPECT_EQ("robot.jump", GetCommandAdaptor()->GetName());
156 EXPECT_EQ(kTestCommandCategoty, GetCommandAdaptor()->GetCategory());
157 EXPECT_EQ(kTestCommandId, GetCommandAdaptor()->GetId());
Alex Vakulenko4866ac92014-08-20 12:53:33 -0700158}
159
160TEST_F(DBusCommandProxyTest, SetProgress) {
161 EXPECT_CALL(*mock_exported_object_command_, SendSignal(_)).Times(2);
Vitaly Buka4129dfa2015-04-29 12:16:58 -0700162 EXPECT_TRUE(
163 GetCommandInterface()->SetProgress(nullptr, {{"progress", int32_t{10}}}));
Alex Vakulenkof6b38712014-09-03 16:23:38 -0700164 EXPECT_EQ(CommandInstance::kStatusInProgress,
Alex Vakulenko420e49f2014-12-01 17:53:27 -0800165 GetCommandAdaptor()->GetStatus());
Vitaly Buka4129dfa2015-04-29 12:16:58 -0700166
167 VariantDictionary progress{{"progress", int32_t{10}}};
168 EXPECT_EQ(progress, GetCommandAdaptor()->GetProgress());
Alex Vakulenko4866ac92014-08-20 12:53:33 -0700169}
170
171TEST_F(DBusCommandProxyTest, SetProgress_OutOfRange) {
Vitaly Buka4129dfa2015-04-29 12:16:58 -0700172 EXPECT_FALSE(GetCommandInterface()->SetProgress(
173 nullptr, {{"progress", int32_t{110}}}));
Alex Vakulenko420e49f2014-12-01 17:53:27 -0800174 EXPECT_EQ(CommandInstance::kStatusQueued, GetCommandAdaptor()->GetStatus());
Vitaly Buka4129dfa2015-04-29 12:16:58 -0700175 EXPECT_EQ(VariantDictionary{}, GetCommandAdaptor()->GetProgress());
Alex Vakulenko4866ac92014-08-20 12:53:33 -0700176}
177
Anton Muhincfde8692014-11-25 03:36:59 +0400178TEST_F(DBusCommandProxyTest, SetResults) {
179 EXPECT_CALL(*mock_exported_object_command_, SendSignal(_)).Times(1);
180 const VariantDictionary results = {
181 {"foo", int32_t{42}},
182 {"bar", std::string{"foobar"}},
183 };
Alex Vakulenko420e49f2014-12-01 17:53:27 -0800184 EXPECT_TRUE(GetCommandInterface()->SetResults(nullptr, results));
185 EXPECT_EQ(results, GetCommandAdaptor()->GetResults());
Anton Muhincfde8692014-11-25 03:36:59 +0400186}
187
188TEST_F(DBusCommandProxyTest, SetResults_UnknownProperty) {
189 EXPECT_CALL(*mock_exported_object_command_, SendSignal(_)).Times(0);
190 const VariantDictionary results = {
191 {"quux", int32_t{42}},
192 };
Alex Vakulenko420e49f2014-12-01 17:53:27 -0800193 EXPECT_FALSE(GetCommandInterface()->SetResults(nullptr, results));
Anton Muhincfde8692014-11-25 03:36:59 +0400194}
195
Alex Vakulenko4866ac92014-08-20 12:53:33 -0700196TEST_F(DBusCommandProxyTest, Abort) {
197 EXPECT_CALL(*mock_exported_object_command_, SendSignal(_)).Times(1);
Alex Vakulenko420e49f2014-12-01 17:53:27 -0800198 GetCommandInterface()->Abort();
199 EXPECT_EQ(CommandInstance::kStatusAborted,
200 GetCommandAdaptor()->GetStatus());
Alex Vakulenko4866ac92014-08-20 12:53:33 -0700201}
202
203TEST_F(DBusCommandProxyTest, Cancel) {
204 EXPECT_CALL(*mock_exported_object_command_, SendSignal(_)).Times(1);
Alex Vakulenko420e49f2014-12-01 17:53:27 -0800205 GetCommandInterface()->Cancel();
Alex Vakulenkodb221242015-03-13 14:02:46 -0700206 EXPECT_EQ(CommandInstance::kStatusCancelled,
Alex Vakulenko420e49f2014-12-01 17:53:27 -0800207 GetCommandAdaptor()->GetStatus());
Alex Vakulenko4866ac92014-08-20 12:53:33 -0700208}
209
210TEST_F(DBusCommandProxyTest, Done) {
Vitaly Buka4129dfa2015-04-29 12:16:58 -0700211 // 1 property update:
212 // status: queued -> done
213 EXPECT_CALL(*mock_exported_object_command_, SendSignal(_)).Times(1);
Alex Vakulenko420e49f2014-12-01 17:53:27 -0800214 GetCommandInterface()->Done();
215 EXPECT_EQ(CommandInstance::kStatusDone, GetCommandAdaptor()->GetStatus());
Alex Vakulenko4866ac92014-08-20 12:53:33 -0700216}
217
218} // namespace buffet