blob: 57e0d0696774881e2dde0668c4d4a7d5323c2fd3 [file] [log] [blame]
Alex Vakulenko7c36b672014-07-16 14:50:58 -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/command_manager.h"
6
Ben Chan15260972014-09-05 08:21:06 -07007#include <base/files/file_util.h>
Christopher Wileybb5b8482015-02-12 13:42:16 -08008#include <base/files/scoped_temp_dir.h>
Alex Vakulenkofd448692014-07-22 07:46:53 -07009#include <base/json/json_writer.h>
Alex Vakulenkoe03af6d2015-04-20 11:00:54 -070010#include <chromeos/bind_lambda.h>
Alex Vakulenko7c36b672014-07-16 14:50:58 -070011#include <gtest/gtest.h>
12
Alex Vakulenkofd448692014-07-22 07:46:53 -070013#include "buffet/commands/unittest_utils.h"
14
15using buffet::unittests::CreateDictionaryValue;
16
Christopher Wileybb5b8482015-02-12 13:42:16 -080017namespace {
18
19const char kTestBaseCommands[] = R"({
20 'base': {
21 'reboot': {
22 'parameters': {'delay': 'integer'},
23 'results': {}
24 },
25 'shutdown': {
26 'parameters': {},
27 'results': {}
28 }
29 }
30})";
31
32const char kTestVendorCommands[] = R"({
33 'robot': {
34 '_jump': {
35 'parameters': {'height': 'integer'},
36 'results': {}
37 },
38 '_speak': {
39 'parameters': {'phrase': 'string'},
40 'results': {}
41 }
42 }
43})";
44
45const char kTestTestCommands[] = R"({
46 'test': {
47 '_yo': {
48 'parameters': {'name': 'string'},
49 'results': {}
50 }
51 }
52})";
53
54static void SaveJsonToFile(const base::DictionaryValue& dict,
55 const base::FilePath& file_path) {
Alex Vakulenkofd448692014-07-22 07:46:53 -070056 std::string json;
57 base::JSONWriter::Write(&dict, &json);
Christopher Wileybb5b8482015-02-12 13:42:16 -080058 const int bytes_to_write = static_cast<int>(json.size());
59 CHECK_EQ(bytes_to_write, WriteFile(file_path, json.data(), bytes_to_write));
60}
61
62static base::FilePath SaveJsonToTempFile(const base::DictionaryValue& dict) {
Alex Vakulenkofd448692014-07-22 07:46:53 -070063 base::FilePath temp_file;
64 base::CreateTemporaryFile(&temp_file);
Christopher Wileybb5b8482015-02-12 13:42:16 -080065 SaveJsonToFile(dict, temp_file);
Alex Vakulenkofd448692014-07-22 07:46:53 -070066 return temp_file;
67}
Alex Vakulenko7c36b672014-07-16 14:50:58 -070068
Christopher Wileybb5b8482015-02-12 13:42:16 -080069} // namespace
70
Alex Vakulenko7c36b672014-07-16 14:50:58 -070071TEST(CommandManager, Empty) {
72 buffet::CommandManager manager;
73 EXPECT_TRUE(manager.GetCommandDictionary().IsEmpty());
74}
Alex Vakulenkofd448692014-07-22 07:46:53 -070075
76TEST(CommandManager, LoadBaseCommandsJSON) {
77 buffet::CommandManager manager;
Christopher Wileybb5b8482015-02-12 13:42:16 -080078 auto json = CreateDictionaryValue(kTestBaseCommands);
Alex Vakulenkofd448692014-07-22 07:46:53 -070079 EXPECT_TRUE(manager.LoadBaseCommands(*json, nullptr));
80}
81
82TEST(CommandManager, LoadBaseCommandsFile) {
83 buffet::CommandManager manager;
Christopher Wileybb5b8482015-02-12 13:42:16 -080084 auto json = CreateDictionaryValue(kTestBaseCommands);
Alex Vakulenkofd448692014-07-22 07:46:53 -070085 base::FilePath temp_file = SaveJsonToTempFile(*json);
86 EXPECT_TRUE(manager.LoadBaseCommands(temp_file, nullptr));
87 base::DeleteFile(temp_file, false);
88}
89
90TEST(CommandManager, LoadCommandsJSON) {
91 buffet::CommandManager manager;
Christopher Wileybb5b8482015-02-12 13:42:16 -080092 auto json = CreateDictionaryValue(kTestVendorCommands);
Alex Vakulenkofd448692014-07-22 07:46:53 -070093 EXPECT_TRUE(manager.LoadCommands(*json, "category", nullptr));
94}
95
96TEST(CommandManager, LoadCommandsFile) {
97 buffet::CommandManager manager;
98 // Load some standard command definitions first.
99 auto json = CreateDictionaryValue(R"({
100 'base': {
101 'reboot': {
Anton Muhin71fb9d52014-11-21 22:22:39 +0400102 'parameters': {'delay': 'integer'},
103 'results': {}
Alex Vakulenkofd448692014-07-22 07:46:53 -0700104 },
105 'shutdown': {
Anton Muhin71fb9d52014-11-21 22:22:39 +0400106 'parameters': {},
107 'results': {}
Alex Vakulenkofd448692014-07-22 07:46:53 -0700108 }
109 }
110 })");
111 manager.LoadBaseCommands(*json, nullptr);
112 // Load device-supported commands.
113 json = CreateDictionaryValue(R"({
114 'base': {
115 'reboot': {
Anton Muhin71fb9d52014-11-21 22:22:39 +0400116 'parameters': {'delay': 'integer'},
117 'results': {}
Alex Vakulenkofd448692014-07-22 07:46:53 -0700118 }
119 },
120 'robot': {
121 '_jump': {
Anton Muhin71fb9d52014-11-21 22:22:39 +0400122 'parameters': {'height': 'integer'},
123 'results': {}
Alex Vakulenkofd448692014-07-22 07:46:53 -0700124 }
125 }
126 })");
127 base::FilePath temp_file = SaveJsonToTempFile(*json);
128 EXPECT_TRUE(manager.LoadCommands(temp_file, nullptr));
129 base::DeleteFile(temp_file, false);
130 EXPECT_EQ(2, manager.GetCommandDictionary().GetSize());
131 EXPECT_NE(nullptr, manager.GetCommandDictionary().FindCommand("base.reboot"));
132 EXPECT_NE(nullptr, manager.GetCommandDictionary().FindCommand("robot._jump"));
133}
Christopher Wileybb5b8482015-02-12 13:42:16 -0800134
135TEST(CommandManager, ShouldLoadStandardAndTestDefinitions) {
136 buffet::CommandManager manager;
137 base::ScopedTempDir temp;
138 CHECK(temp.CreateUniqueTempDir());
139 base::FilePath base_path{temp.path().Append("base_defs")};
140 base::FilePath test_path{temp.path().Append("test_defs")};
141 base::FilePath base_commands_path{base_path.Append("commands")};
142 base::FilePath test_commands_path{test_path.Append("commands")};
143 CHECK(CreateDirectory(base_commands_path));
144 CHECK(CreateDirectory(test_commands_path));
145 SaveJsonToFile(*CreateDictionaryValue(kTestBaseCommands),
146 base_path.Append("gcd.json"));
147 SaveJsonToFile(*CreateDictionaryValue(kTestVendorCommands),
148 base_commands_path.Append("category.json"));
149 SaveJsonToFile(*CreateDictionaryValue(kTestTestCommands),
150 test_commands_path.Append("test.json"));
151 manager.Startup(base_path, test_path);
152 EXPECT_EQ(3, manager.GetCommandDictionary().GetSize());
153 EXPECT_NE(nullptr,
154 manager.GetCommandDictionary().FindCommand("robot._jump"));
155 EXPECT_NE(nullptr,
156 manager.GetCommandDictionary().FindCommand("robot._speak"));
157 EXPECT_NE(nullptr,
158 manager.GetCommandDictionary().FindCommand("test._yo"));
159}
Alex Vakulenkoe03af6d2015-04-20 11:00:54 -0700160
161TEST(CommandManager, UpdateCommandVisibility) {
162 buffet::CommandManager manager;
163 int update_count = 0;
164 auto on_command_change = [&update_count]() { update_count++; };
165 auto token = manager.AddOnCommandDefChanged(base::Bind(on_command_change));
166
167 auto json = CreateDictionaryValue(R"({
168 'foo': {
169 '_baz': {
170 'parameters': {},
171 'results': {}
172 },
173 '_bar': {
174 'parameters': {},
175 'results': {}
176 }
177 },
178 'bar': {
179 '_quux': {
180 'parameters': {},
181 'results': {},
182 'visibility': 'none'
183 }
184 }
185 })");
186 ASSERT_TRUE(manager.LoadCommands(*json, "test", nullptr));
187 EXPECT_EQ(1, update_count);
188 const buffet::CommandDictionary& dict = manager.GetCommandDictionary();
189 EXPECT_TRUE(manager.SetCommandVisibility(
190 {"foo._baz"},
191 buffet::CommandDefinition::Visibility::GetLocal(), nullptr));
192 EXPECT_EQ(2, update_count);
193 EXPECT_EQ("local", dict.FindCommand("foo._baz")->GetVisibility().ToString());
194 EXPECT_EQ("all", dict.FindCommand("foo._bar")->GetVisibility().ToString());
195 EXPECT_EQ("none", dict.FindCommand("bar._quux")->GetVisibility().ToString());
196
197 chromeos::ErrorPtr error;
198 ASSERT_FALSE(manager.SetCommandVisibility(
199 {"foo._baz", "foo._bar", "test.cmd"},
200 buffet::CommandDefinition::Visibility::GetLocal(), &error));
201 EXPECT_EQ(buffet::errors::commands::kInvalidCommandName, error->GetCode());
202 EXPECT_EQ("Command 'test.cmd' is unknown", error->GetMessage());
203 // The visibility state of commands shouldn't have changed.
204 EXPECT_EQ(2, update_count);
205 EXPECT_EQ("local", dict.FindCommand("foo._baz")->GetVisibility().ToString());
206 EXPECT_EQ("all", dict.FindCommand("foo._bar")->GetVisibility().ToString());
207 EXPECT_EQ("none", dict.FindCommand("bar._quux")->GetVisibility().ToString());
208
209 EXPECT_TRUE(manager.SetCommandVisibility(
210 {"foo._baz", "bar._quux"},
211 buffet::CommandDefinition::Visibility::GetCloud(), nullptr));
212 EXPECT_EQ(3, update_count);
213 EXPECT_EQ("cloud", dict.FindCommand("foo._baz")->GetVisibility().ToString());
214 EXPECT_EQ("all", dict.FindCommand("foo._bar")->GetVisibility().ToString());
215 EXPECT_EQ("cloud", dict.FindCommand("bar._quux")->GetVisibility().ToString());
216}
217