blob: 76a3246578682b552164dcce885af480e1f4cbd8 [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
Vitaly Buka32005de2015-05-01 12:33:31 -070015namespace buffet {
16
17using unittests::CreateDictionaryValue;
Alex Vakulenkofd448692014-07-22 07:46:53 -070018
Christopher Wileybb5b8482015-02-12 13:42:16 -080019namespace {
20
21const char kTestBaseCommands[] = R"({
22 'base': {
23 'reboot': {
24 'parameters': {'delay': 'integer'},
25 'results': {}
26 },
27 'shutdown': {
28 'parameters': {},
29 'results': {}
30 }
31 }
32})";
33
34const char kTestVendorCommands[] = R"({
35 'robot': {
36 '_jump': {
37 'parameters': {'height': 'integer'},
38 'results': {}
39 },
40 '_speak': {
41 'parameters': {'phrase': 'string'},
42 'results': {}
43 }
44 }
45})";
46
47const char kTestTestCommands[] = R"({
48 'test': {
49 '_yo': {
50 'parameters': {'name': 'string'},
51 'results': {}
52 }
53 }
54})";
55
56static void SaveJsonToFile(const base::DictionaryValue& dict,
57 const base::FilePath& file_path) {
Alex Vakulenkofd448692014-07-22 07:46:53 -070058 std::string json;
59 base::JSONWriter::Write(&dict, &json);
Christopher Wileybb5b8482015-02-12 13:42:16 -080060 const int bytes_to_write = static_cast<int>(json.size());
61 CHECK_EQ(bytes_to_write, WriteFile(file_path, json.data(), bytes_to_write));
62}
63
64static base::FilePath SaveJsonToTempFile(const base::DictionaryValue& dict) {
Alex Vakulenkofd448692014-07-22 07:46:53 -070065 base::FilePath temp_file;
66 base::CreateTemporaryFile(&temp_file);
Christopher Wileybb5b8482015-02-12 13:42:16 -080067 SaveJsonToFile(dict, temp_file);
Alex Vakulenkofd448692014-07-22 07:46:53 -070068 return temp_file;
69}
Alex Vakulenko7c36b672014-07-16 14:50:58 -070070
Christopher Wileybb5b8482015-02-12 13:42:16 -080071} // namespace
72
Alex Vakulenko7c36b672014-07-16 14:50:58 -070073TEST(CommandManager, Empty) {
Vitaly Buka32005de2015-05-01 12:33:31 -070074 CommandManager manager;
Alex Vakulenko7c36b672014-07-16 14:50:58 -070075 EXPECT_TRUE(manager.GetCommandDictionary().IsEmpty());
76}
Alex Vakulenkofd448692014-07-22 07:46:53 -070077
78TEST(CommandManager, LoadBaseCommandsJSON) {
Vitaly Buka32005de2015-05-01 12:33:31 -070079 CommandManager manager;
Christopher Wileybb5b8482015-02-12 13:42:16 -080080 auto json = CreateDictionaryValue(kTestBaseCommands);
Alex Vakulenkofd448692014-07-22 07:46:53 -070081 EXPECT_TRUE(manager.LoadBaseCommands(*json, nullptr));
82}
83
84TEST(CommandManager, LoadBaseCommandsFile) {
Vitaly Buka32005de2015-05-01 12:33:31 -070085 CommandManager manager;
Christopher Wileybb5b8482015-02-12 13:42:16 -080086 auto json = CreateDictionaryValue(kTestBaseCommands);
Alex Vakulenkofd448692014-07-22 07:46:53 -070087 base::FilePath temp_file = SaveJsonToTempFile(*json);
88 EXPECT_TRUE(manager.LoadBaseCommands(temp_file, nullptr));
89 base::DeleteFile(temp_file, false);
90}
91
92TEST(CommandManager, LoadCommandsJSON) {
Vitaly Buka32005de2015-05-01 12:33:31 -070093 CommandManager manager;
Christopher Wileybb5b8482015-02-12 13:42:16 -080094 auto json = CreateDictionaryValue(kTestVendorCommands);
Alex Vakulenkofd448692014-07-22 07:46:53 -070095 EXPECT_TRUE(manager.LoadCommands(*json, "category", nullptr));
96}
97
98TEST(CommandManager, LoadCommandsFile) {
Vitaly Buka32005de2015-05-01 12:33:31 -070099 CommandManager manager;
Alex Vakulenkofd448692014-07-22 07:46:53 -0700100 // Load some standard command definitions first.
101 auto json = CreateDictionaryValue(R"({
102 'base': {
103 'reboot': {
Anton Muhin71fb9d52014-11-21 22:22:39 +0400104 'parameters': {'delay': 'integer'},
105 'results': {}
Alex Vakulenkofd448692014-07-22 07:46:53 -0700106 },
107 'shutdown': {
Anton Muhin71fb9d52014-11-21 22:22:39 +0400108 'parameters': {},
109 'results': {}
Alex Vakulenkofd448692014-07-22 07:46:53 -0700110 }
111 }
112 })");
113 manager.LoadBaseCommands(*json, nullptr);
114 // Load device-supported commands.
115 json = CreateDictionaryValue(R"({
116 'base': {
117 'reboot': {
Anton Muhin71fb9d52014-11-21 22:22:39 +0400118 'parameters': {'delay': 'integer'},
119 'results': {}
Alex Vakulenkofd448692014-07-22 07:46:53 -0700120 }
121 },
122 'robot': {
123 '_jump': {
Anton Muhin71fb9d52014-11-21 22:22:39 +0400124 'parameters': {'height': 'integer'},
125 'results': {}
Alex Vakulenkofd448692014-07-22 07:46:53 -0700126 }
127 }
128 })");
129 base::FilePath temp_file = SaveJsonToTempFile(*json);
130 EXPECT_TRUE(manager.LoadCommands(temp_file, nullptr));
131 base::DeleteFile(temp_file, false);
132 EXPECT_EQ(2, manager.GetCommandDictionary().GetSize());
133 EXPECT_NE(nullptr, manager.GetCommandDictionary().FindCommand("base.reboot"));
134 EXPECT_NE(nullptr, manager.GetCommandDictionary().FindCommand("robot._jump"));
135}
Christopher Wileybb5b8482015-02-12 13:42:16 -0800136
137TEST(CommandManager, ShouldLoadStandardAndTestDefinitions) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700138 CommandManager manager;
Christopher Wileybb5b8482015-02-12 13:42:16 -0800139 base::ScopedTempDir temp;
140 CHECK(temp.CreateUniqueTempDir());
141 base::FilePath base_path{temp.path().Append("base_defs")};
142 base::FilePath test_path{temp.path().Append("test_defs")};
143 base::FilePath base_commands_path{base_path.Append("commands")};
144 base::FilePath test_commands_path{test_path.Append("commands")};
145 CHECK(CreateDirectory(base_commands_path));
146 CHECK(CreateDirectory(test_commands_path));
147 SaveJsonToFile(*CreateDictionaryValue(kTestBaseCommands),
148 base_path.Append("gcd.json"));
149 SaveJsonToFile(*CreateDictionaryValue(kTestVendorCommands),
150 base_commands_path.Append("category.json"));
151 SaveJsonToFile(*CreateDictionaryValue(kTestTestCommands),
152 test_commands_path.Append("test.json"));
153 manager.Startup(base_path, test_path);
154 EXPECT_EQ(3, manager.GetCommandDictionary().GetSize());
155 EXPECT_NE(nullptr,
156 manager.GetCommandDictionary().FindCommand("robot._jump"));
157 EXPECT_NE(nullptr,
158 manager.GetCommandDictionary().FindCommand("robot._speak"));
159 EXPECT_NE(nullptr,
160 manager.GetCommandDictionary().FindCommand("test._yo"));
161}
Alex Vakulenkoe03af6d2015-04-20 11:00:54 -0700162
163TEST(CommandManager, UpdateCommandVisibility) {
Vitaly Buka32005de2015-05-01 12:33:31 -0700164 CommandManager manager;
Alex Vakulenkoe03af6d2015-04-20 11:00:54 -0700165 int update_count = 0;
166 auto on_command_change = [&update_count]() { update_count++; };
Vitaly Buka5e6ff6c2015-05-11 15:41:33 -0700167 manager.AddOnCommandDefChanged(base::Bind(on_command_change));
Alex Vakulenkoe03af6d2015-04-20 11:00:54 -0700168
169 auto json = CreateDictionaryValue(R"({
170 'foo': {
171 '_baz': {
172 'parameters': {},
173 'results': {}
174 },
175 '_bar': {
176 'parameters': {},
177 'results': {}
178 }
179 },
180 'bar': {
181 '_quux': {
182 'parameters': {},
183 'results': {},
184 'visibility': 'none'
185 }
186 }
187 })");
188 ASSERT_TRUE(manager.LoadCommands(*json, "test", nullptr));
189 EXPECT_EQ(1, update_count);
Vitaly Buka32005de2015-05-01 12:33:31 -0700190 const CommandDictionary& dict = manager.GetCommandDictionary();
Alex Vakulenkoe03af6d2015-04-20 11:00:54 -0700191 EXPECT_TRUE(manager.SetCommandVisibility(
Vitaly Buka32005de2015-05-01 12:33:31 -0700192 {"foo._baz"}, CommandDefinition::Visibility::GetLocal(), nullptr));
Alex Vakulenkoe03af6d2015-04-20 11:00:54 -0700193 EXPECT_EQ(2, update_count);
194 EXPECT_EQ("local", dict.FindCommand("foo._baz")->GetVisibility().ToString());
195 EXPECT_EQ("all", dict.FindCommand("foo._bar")->GetVisibility().ToString());
196 EXPECT_EQ("none", dict.FindCommand("bar._quux")->GetVisibility().ToString());
197
198 chromeos::ErrorPtr error;
199 ASSERT_FALSE(manager.SetCommandVisibility(
200 {"foo._baz", "foo._bar", "test.cmd"},
Vitaly Buka32005de2015-05-01 12:33:31 -0700201 CommandDefinition::Visibility::GetLocal(), &error));
202 EXPECT_EQ(errors::commands::kInvalidCommandName, error->GetCode());
Alex Vakulenkoe03af6d2015-04-20 11:00:54 -0700203 EXPECT_EQ("Command 'test.cmd' is unknown", error->GetMessage());
204 // The visibility state of commands shouldn't have changed.
205 EXPECT_EQ(2, update_count);
206 EXPECT_EQ("local", dict.FindCommand("foo._baz")->GetVisibility().ToString());
207 EXPECT_EQ("all", dict.FindCommand("foo._bar")->GetVisibility().ToString());
208 EXPECT_EQ("none", dict.FindCommand("bar._quux")->GetVisibility().ToString());
209
210 EXPECT_TRUE(manager.SetCommandVisibility(
Vitaly Buka32005de2015-05-01 12:33:31 -0700211 {"foo._baz", "bar._quux"}, CommandDefinition::Visibility::GetCloud(),
212 nullptr));
Alex Vakulenkoe03af6d2015-04-20 11:00:54 -0700213 EXPECT_EQ(3, update_count);
214 EXPECT_EQ("cloud", dict.FindCommand("foo._baz")->GetVisibility().ToString());
215 EXPECT_EQ("all", dict.FindCommand("foo._bar")->GetVisibility().ToString());
216 EXPECT_EQ("cloud", dict.FindCommand("bar._quux")->GetVisibility().ToString());
217}
218
Vitaly Buka32005de2015-05-01 12:33:31 -0700219} // namespace buffet