blob: 19841d676bc490e4955e0f982c587861c7148007 [file] [log] [blame]
Tao Baoc3901232018-05-21 16:05:56 -07001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <string>
18
19#include <gtest/gtest.h>
20
Tao Bao6a7e4af2018-06-14 21:57:43 -070021#include "otautil/rangeset.h"
Tao Baoc3901232018-05-21 16:05:56 -070022#include "private/commands.h"
23
24TEST(CommandsTest, ParseType) {
25 ASSERT_EQ(Command::Type::ZERO, Command::ParseType("zero"));
26 ASSERT_EQ(Command::Type::NEW, Command::ParseType("new"));
27 ASSERT_EQ(Command::Type::ERASE, Command::ParseType("erase"));
28 ASSERT_EQ(Command::Type::MOVE, Command::ParseType("move"));
29 ASSERT_EQ(Command::Type::BSDIFF, Command::ParseType("bsdiff"));
30 ASSERT_EQ(Command::Type::IMGDIFF, Command::ParseType("imgdiff"));
31 ASSERT_EQ(Command::Type::STASH, Command::ParseType("stash"));
32 ASSERT_EQ(Command::Type::FREE, Command::ParseType("free"));
Tianjie Xu69ffa152018-08-01 16:40:00 -070033 ASSERT_EQ(Command::Type::COMPUTE_HASH_TREE, Command::ParseType("compute_hash_tree"));
Tao Baoc3901232018-05-21 16:05:56 -070034}
35
36TEST(CommandsTest, ParseType_InvalidCommand) {
37 ASSERT_EQ(Command::Type::LAST, Command::ParseType("foo"));
38 ASSERT_EQ(Command::Type::LAST, Command::ParseType("bar"));
39}
Tao Bao6a7e4af2018-06-14 21:57:43 -070040
41TEST(CommandsTest, ParseTargetInfoAndSourceInfo_SourceBlocksOnly) {
42 const std::vector<std::string> tokens{
43 "4,569884,569904,591946,592043",
44 "117",
45 "4,566779,566799,591946,592043",
46 };
47 TargetInfo target;
48 SourceInfo source;
49 std::string err;
50 ASSERT_TRUE(Command::ParseTargetInfoAndSourceInfo(
51 tokens, "1d74d1a60332fd38cf9405f1bae67917888da6cb", &target,
52 "1d74d1a60332fd38cf9405f1bae67917888da6cb", &source, &err));
53 ASSERT_EQ(TargetInfo("1d74d1a60332fd38cf9405f1bae67917888da6cb",
54 RangeSet({ { 569884, 569904 }, { 591946, 592043 } })),
55 target);
56 ASSERT_EQ(SourceInfo("1d74d1a60332fd38cf9405f1bae67917888da6cb",
57 RangeSet({ { 566779, 566799 }, { 591946, 592043 } }), {}, {}),
58 source);
59 ASSERT_EQ(117, source.blocks());
60}
61
62TEST(CommandsTest, ParseTargetInfoAndSourceInfo_StashesOnly) {
63 const std::vector<std::string> tokens{
64 "2,350729,350731",
65 "2",
66 "-",
67 "6ebcf8cf1f6be0bc49e7d4a864214251925d1d15:2,0,2",
68 };
69 TargetInfo target;
70 SourceInfo source;
71 std::string err;
72 ASSERT_TRUE(Command::ParseTargetInfoAndSourceInfo(
73 tokens, "6ebcf8cf1f6be0bc49e7d4a864214251925d1d15", &target,
74 "1c25ba04d3278d6b65a1b9f17abac78425ec8b8d", &source, &err));
75 ASSERT_EQ(
76 TargetInfo("6ebcf8cf1f6be0bc49e7d4a864214251925d1d15", RangeSet({ { 350729, 350731 } })),
77 target);
78 ASSERT_EQ(
79 SourceInfo("1c25ba04d3278d6b65a1b9f17abac78425ec8b8d", {}, {},
80 {
81 StashInfo("6ebcf8cf1f6be0bc49e7d4a864214251925d1d15", RangeSet({ { 0, 2 } })),
82 }),
83 source);
84 ASSERT_EQ(2, source.blocks());
85}
86
87TEST(CommandsTest, ParseTargetInfoAndSourceInfo_SourceBlocksAndStashes) {
88 const std::vector<std::string> tokens{
89 "4,611641,611643,636981,637075",
90 "96",
91 "4,636981,637075,770665,770666",
92 "4,0,94,95,96",
93 "9eedf00d11061549e32503cadf054ec6fbfa7a23:2,94,95",
94 };
95 TargetInfo target;
96 SourceInfo source;
97 std::string err;
98 ASSERT_TRUE(Command::ParseTargetInfoAndSourceInfo(
99 tokens, "4734d1b241eb3d0f993714aaf7d665fae43772b6", &target,
100 "a6cbdf3f416960f02189d3a814ec7e9e95c44a0d", &source, &err));
101 ASSERT_EQ(TargetInfo("4734d1b241eb3d0f993714aaf7d665fae43772b6",
102 RangeSet({ { 611641, 611643 }, { 636981, 637075 } })),
103 target);
104 ASSERT_EQ(SourceInfo(
105 "a6cbdf3f416960f02189d3a814ec7e9e95c44a0d",
106 RangeSet({ { 636981, 637075 }, { 770665, 770666 } }), // source ranges
107 RangeSet({ { 0, 94 }, { 95, 96 } }), // source location
108 {
109 StashInfo("9eedf00d11061549e32503cadf054ec6fbfa7a23", RangeSet({ { 94, 95 } })),
110 }),
111 source);
112 ASSERT_EQ(96, source.blocks());
113}
114
115TEST(CommandsTest, ParseTargetInfoAndSourceInfo_InvalidInput) {
116 const std::vector<std::string> tokens{
117 "4,611641,611643,636981,637075",
118 "96",
119 "4,636981,637075,770665,770666",
120 "4,0,94,95,96",
121 "9eedf00d11061549e32503cadf054ec6fbfa7a23:2,94,95",
122 };
123 TargetInfo target;
124 SourceInfo source;
125 std::string err;
126
127 // Mismatching block count.
128 {
129 std::vector<std::string> tokens_copy(tokens);
130 tokens_copy[1] = "97";
131 ASSERT_FALSE(Command::ParseTargetInfoAndSourceInfo(
132 tokens_copy, "1d74d1a60332fd38cf9405f1bae67917888da6cb", &target,
133 "1d74d1a60332fd38cf9405f1bae67917888da6cb", &source, &err));
134 }
135
136 // Excess stashes (causing block count mismatch).
137 {
138 std::vector<std::string> tokens_copy(tokens);
139 tokens_copy.push_back("e145a2f83a33334714ac65e34969c1f115e54a6f:2,0,22");
140 ASSERT_FALSE(Command::ParseTargetInfoAndSourceInfo(
141 tokens_copy, "1d74d1a60332fd38cf9405f1bae67917888da6cb", &target,
142 "1d74d1a60332fd38cf9405f1bae67917888da6cb", &source, &err));
143 }
144
145 // Invalid args.
146 for (size_t i = 0; i < tokens.size(); i++) {
147 TargetInfo target;
148 SourceInfo source;
149 std::string err;
150 ASSERT_FALSE(Command::ParseTargetInfoAndSourceInfo(
151 std::vector<std::string>(tokens.cbegin() + i + 1, tokens.cend()),
152 "1d74d1a60332fd38cf9405f1bae67917888da6cb", &target,
153 "1d74d1a60332fd38cf9405f1bae67917888da6cb", &source, &err));
154 }
155}
156
157TEST(CommandsTest, Parse_EmptyInput) {
158 std::string err;
159 ASSERT_FALSE(Command::Parse("", 0, &err));
160 ASSERT_EQ("invalid type", err);
161}
162
Tao Bao91a649a2018-05-21 16:05:56 -0700163TEST(CommandsTest, Parse_ABORT_Allowed) {
164 Command::abort_allowed_ = true;
165
166 const std::string input{ "abort" };
167 std::string err;
168 Command command = Command::Parse(input, 0, &err);
169 ASSERT_TRUE(command);
170
171 ASSERT_EQ(TargetInfo(), command.target());
172 ASSERT_EQ(SourceInfo(), command.source());
173 ASSERT_EQ(StashInfo(), command.stash());
174 ASSERT_EQ(PatchInfo(), command.patch());
175}
176
177TEST(CommandsTest, Parse_ABORT_NotAllowed) {
178 const std::string input{ "abort" };
179 std::string err;
180 Command command = Command::Parse(input, 0, &err);
181 ASSERT_FALSE(command);
182}
183
Tao Bao6a7e4af2018-06-14 21:57:43 -0700184TEST(CommandsTest, Parse_BSDIFF) {
185 const std::string input{
186 "bsdiff 0 148 "
187 "f201a4e04bd3860da6ad47b957ef424d58a58f8c 9d5d223b4bc5c45dbd25a799c4f1a98466731599 "
188 "4,565704,565752,566779,566799 "
189 "68 4,64525,64545,565704,565752"
190 };
191 std::string err;
192 Command command = Command::Parse(input, 1, &err);
193 ASSERT_TRUE(command);
194
195 ASSERT_EQ(Command::Type::BSDIFF, command.type());
196 ASSERT_EQ(1, command.index());
197 ASSERT_EQ(input, command.cmdline());
198
199 ASSERT_EQ(TargetInfo("9d5d223b4bc5c45dbd25a799c4f1a98466731599",
200 RangeSet({ { 565704, 565752 }, { 566779, 566799 } })),
201 command.target());
202 ASSERT_EQ(SourceInfo("f201a4e04bd3860da6ad47b957ef424d58a58f8c",
203 RangeSet({ { 64525, 64545 }, { 565704, 565752 } }), RangeSet(), {}),
204 command.source());
205 ASSERT_EQ(StashInfo(), command.stash());
206 ASSERT_EQ(PatchInfo(0, 148), command.patch());
207}
208
209TEST(CommandsTest, Parse_ERASE) {
210 const std::string input{ "erase 2,5,10" };
211 std::string err;
212 Command command = Command::Parse(input, 2, &err);
213 ASSERT_TRUE(command);
214
215 ASSERT_EQ(Command::Type::ERASE, command.type());
216 ASSERT_EQ(2, command.index());
217 ASSERT_EQ(input, command.cmdline());
218
219 ASSERT_EQ(TargetInfo("unknown-hash", RangeSet({ { 5, 10 } })), command.target());
220 ASSERT_EQ(SourceInfo(), command.source());
221 ASSERT_EQ(StashInfo(), command.stash());
222 ASSERT_EQ(PatchInfo(), command.patch());
223}
224
225TEST(CommandsTest, Parse_FREE) {
226 const std::string input{ "free hash1" };
227 std::string err;
228 Command command = Command::Parse(input, 3, &err);
229 ASSERT_TRUE(command);
230
231 ASSERT_EQ(Command::Type::FREE, command.type());
232 ASSERT_EQ(3, command.index());
233 ASSERT_EQ(input, command.cmdline());
234
235 ASSERT_EQ(TargetInfo(), command.target());
236 ASSERT_EQ(SourceInfo(), command.source());
237 ASSERT_EQ(StashInfo("hash1", RangeSet()), command.stash());
238 ASSERT_EQ(PatchInfo(), command.patch());
239}
240
241TEST(CommandsTest, Parse_IMGDIFF) {
242 const std::string input{
243 "imgdiff 29629269 185 "
244 "a6b1c49aed1b57a2aab1ec3e1505b945540cd8db 51978f65035f584a8ef7afa941dacb6d5e862164 "
245 "2,90851,90852 "
246 "1 2,90851,90852"
247 };
248 std::string err;
249 Command command = Command::Parse(input, 4, &err);
250 ASSERT_TRUE(command);
251
252 ASSERT_EQ(Command::Type::IMGDIFF, command.type());
253 ASSERT_EQ(4, command.index());
254 ASSERT_EQ(input, command.cmdline());
255
256 ASSERT_EQ(TargetInfo("51978f65035f584a8ef7afa941dacb6d5e862164", RangeSet({ { 90851, 90852 } })),
257 command.target());
258 ASSERT_EQ(SourceInfo("a6b1c49aed1b57a2aab1ec3e1505b945540cd8db", RangeSet({ { 90851, 90852 } }),
259 RangeSet(), {}),
260 command.source());
261 ASSERT_EQ(StashInfo(), command.stash());
262 ASSERT_EQ(PatchInfo(29629269, 185), command.patch());
263}
264
265TEST(CommandsTest, Parse_MOVE) {
266 const std::string input{
267 "move 1d74d1a60332fd38cf9405f1bae67917888da6cb "
268 "4,569884,569904,591946,592043 117 4,566779,566799,591946,592043"
269 };
270 std::string err;
271 Command command = Command::Parse(input, 5, &err);
272 ASSERT_TRUE(command);
273
274 ASSERT_EQ(Command::Type::MOVE, command.type());
275 ASSERT_EQ(5, command.index());
276 ASSERT_EQ(input, command.cmdline());
277
278 ASSERT_EQ(TargetInfo("1d74d1a60332fd38cf9405f1bae67917888da6cb",
279 RangeSet({ { 569884, 569904 }, { 591946, 592043 } })),
280 command.target());
281 ASSERT_EQ(SourceInfo("1d74d1a60332fd38cf9405f1bae67917888da6cb",
282 RangeSet({ { 566779, 566799 }, { 591946, 592043 } }), RangeSet(), {}),
283 command.source());
284 ASSERT_EQ(StashInfo(), command.stash());
285 ASSERT_EQ(PatchInfo(), command.patch());
286}
287
288TEST(CommandsTest, Parse_NEW) {
289 const std::string input{ "new 4,3,5,10,12" };
290 std::string err;
291 Command command = Command::Parse(input, 6, &err);
292 ASSERT_TRUE(command);
293
294 ASSERT_EQ(Command::Type::NEW, command.type());
295 ASSERT_EQ(6, command.index());
296 ASSERT_EQ(input, command.cmdline());
297
298 ASSERT_EQ(TargetInfo("unknown-hash", RangeSet({ { 3, 5 }, { 10, 12 } })), command.target());
299 ASSERT_EQ(SourceInfo(), command.source());
300 ASSERT_EQ(StashInfo(), command.stash());
301 ASSERT_EQ(PatchInfo(), command.patch());
302}
303
304TEST(CommandsTest, Parse_STASH) {
305 const std::string input{ "stash hash1 2,5,10" };
306 std::string err;
307 Command command = Command::Parse(input, 7, &err);
308 ASSERT_TRUE(command);
309
310 ASSERT_EQ(Command::Type::STASH, command.type());
311 ASSERT_EQ(7, command.index());
312 ASSERT_EQ(input, command.cmdline());
313
314 ASSERT_EQ(TargetInfo(), command.target());
315 ASSERT_EQ(SourceInfo(), command.source());
316 ASSERT_EQ(StashInfo("hash1", RangeSet({ { 5, 10 } })), command.stash());
317 ASSERT_EQ(PatchInfo(), command.patch());
318}
319
320TEST(CommandsTest, Parse_ZERO) {
321 const std::string input{ "zero 2,1,5" };
322 std::string err;
323 Command command = Command::Parse(input, 8, &err);
324 ASSERT_TRUE(command);
325
326 ASSERT_EQ(Command::Type::ZERO, command.type());
327 ASSERT_EQ(8, command.index());
328 ASSERT_EQ(input, command.cmdline());
329
330 ASSERT_EQ(TargetInfo("unknown-hash", RangeSet({ { 1, 5 } })), command.target());
331 ASSERT_EQ(SourceInfo(), command.source());
332 ASSERT_EQ(StashInfo(), command.stash());
333 ASSERT_EQ(PatchInfo(), command.patch());
334}
Tao Bao92f33932018-06-25 12:11:53 -0700335
Tianjie Xu8f64bf62018-08-07 00:22:19 -0700336TEST(CommandsTest, Parse_COMPUTE_HASH_TREE) {
337 const std::string input{ "compute_hash_tree 2,0,1 2,3,4 sha1 unknown-salt unknown-root-hash" };
338 std::string err;
339 Command command = Command::Parse(input, 9, &err);
340 ASSERT_TRUE(command);
341
342 ASSERT_EQ(Command::Type::COMPUTE_HASH_TREE, command.type());
343 ASSERT_EQ(9, command.index());
344 ASSERT_EQ(input, command.cmdline());
345
346 HashTreeInfo expected_info(RangeSet({ { 0, 1 } }), RangeSet({ { 3, 4 } }), "sha1", "unknown-salt",
347 "unknown-root-hash");
348 ASSERT_EQ(expected_info, command.hash_tree_info());
349 ASSERT_EQ(TargetInfo(), command.target());
350 ASSERT_EQ(SourceInfo(), command.source());
351 ASSERT_EQ(StashInfo(), command.stash());
352 ASSERT_EQ(PatchInfo(), command.patch());
353}
354
Tao Bao92f33932018-06-25 12:11:53 -0700355TEST(CommandsTest, Parse_InvalidNumberOfArgs) {
Tao Bao91a649a2018-05-21 16:05:56 -0700356 Command::abort_allowed_ = true;
357
Tao Bao92f33932018-06-25 12:11:53 -0700358 // Note that the case of having excess args in BSDIFF, IMGDIFF and MOVE is covered by
359 // ParseTargetInfoAndSourceInfo_InvalidInput.
360 std::vector<std::string> inputs{
Tao Bao91a649a2018-05-21 16:05:56 -0700361 "abort foo",
Tao Bao92f33932018-06-25 12:11:53 -0700362 "bsdiff",
Tianjie Xu8f64bf62018-08-07 00:22:19 -0700363 "compute_hash_tree, 2,0,1 2,0,1 unknown-algorithm unknown-salt",
Tao Bao92f33932018-06-25 12:11:53 -0700364 "erase",
365 "erase 4,3,5,10,12 hash1",
366 "free",
367 "free id1 id2",
368 "imgdiff",
369 "move",
370 "new",
371 "new 4,3,5,10,12 hash1",
372 "stash",
373 "stash id1",
374 "stash id1 4,3,5,10,12 id2",
375 "zero",
376 "zero 4,3,5,10,12 hash2",
377 };
378 for (const auto& input : inputs) {
379 std::string err;
380 ASSERT_FALSE(Command::Parse(input, 0, &err));
381 }
382}