blob: 5c69e07b5fce0b89a8120168db2a20932bc2a850 [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
Tao Bao3c892732018-06-18 09:44:33 -070017#include <algorithm>
Tao Baoc3901232018-05-21 16:05:56 -070018#include <string>
19
20#include <gtest/gtest.h>
Tao Bao3c892732018-06-18 09:44:33 -070021#include <openssl/sha.h>
Tao Baoc3901232018-05-21 16:05:56 -070022
Tao Bao3c892732018-06-18 09:44:33 -070023#include "otautil/print_sha1.h"
Tao Bao6a7e4af2018-06-14 21:57:43 -070024#include "otautil/rangeset.h"
Tao Baoc3901232018-05-21 16:05:56 -070025#include "private/commands.h"
26
27TEST(CommandsTest, ParseType) {
28 ASSERT_EQ(Command::Type::ZERO, Command::ParseType("zero"));
29 ASSERT_EQ(Command::Type::NEW, Command::ParseType("new"));
30 ASSERT_EQ(Command::Type::ERASE, Command::ParseType("erase"));
31 ASSERT_EQ(Command::Type::MOVE, Command::ParseType("move"));
32 ASSERT_EQ(Command::Type::BSDIFF, Command::ParseType("bsdiff"));
33 ASSERT_EQ(Command::Type::IMGDIFF, Command::ParseType("imgdiff"));
34 ASSERT_EQ(Command::Type::STASH, Command::ParseType("stash"));
35 ASSERT_EQ(Command::Type::FREE, Command::ParseType("free"));
Tianjie Xu69ffa152018-08-01 16:40:00 -070036 ASSERT_EQ(Command::Type::COMPUTE_HASH_TREE, Command::ParseType("compute_hash_tree"));
Tao Baoc3901232018-05-21 16:05:56 -070037}
38
39TEST(CommandsTest, ParseType_InvalidCommand) {
40 ASSERT_EQ(Command::Type::LAST, Command::ParseType("foo"));
41 ASSERT_EQ(Command::Type::LAST, Command::ParseType("bar"));
42}
Tao Bao6a7e4af2018-06-14 21:57:43 -070043
44TEST(CommandsTest, ParseTargetInfoAndSourceInfo_SourceBlocksOnly) {
45 const std::vector<std::string> tokens{
46 "4,569884,569904,591946,592043",
47 "117",
48 "4,566779,566799,591946,592043",
49 };
50 TargetInfo target;
51 SourceInfo source;
52 std::string err;
53 ASSERT_TRUE(Command::ParseTargetInfoAndSourceInfo(
54 tokens, "1d74d1a60332fd38cf9405f1bae67917888da6cb", &target,
55 "1d74d1a60332fd38cf9405f1bae67917888da6cb", &source, &err));
56 ASSERT_EQ(TargetInfo("1d74d1a60332fd38cf9405f1bae67917888da6cb",
57 RangeSet({ { 569884, 569904 }, { 591946, 592043 } })),
58 target);
59 ASSERT_EQ(SourceInfo("1d74d1a60332fd38cf9405f1bae67917888da6cb",
60 RangeSet({ { 566779, 566799 }, { 591946, 592043 } }), {}, {}),
61 source);
62 ASSERT_EQ(117, source.blocks());
63}
64
65TEST(CommandsTest, ParseTargetInfoAndSourceInfo_StashesOnly) {
66 const std::vector<std::string> tokens{
67 "2,350729,350731",
68 "2",
69 "-",
70 "6ebcf8cf1f6be0bc49e7d4a864214251925d1d15:2,0,2",
71 };
72 TargetInfo target;
73 SourceInfo source;
74 std::string err;
75 ASSERT_TRUE(Command::ParseTargetInfoAndSourceInfo(
76 tokens, "6ebcf8cf1f6be0bc49e7d4a864214251925d1d15", &target,
77 "1c25ba04d3278d6b65a1b9f17abac78425ec8b8d", &source, &err));
78 ASSERT_EQ(
79 TargetInfo("6ebcf8cf1f6be0bc49e7d4a864214251925d1d15", RangeSet({ { 350729, 350731 } })),
80 target);
81 ASSERT_EQ(
82 SourceInfo("1c25ba04d3278d6b65a1b9f17abac78425ec8b8d", {}, {},
83 {
84 StashInfo("6ebcf8cf1f6be0bc49e7d4a864214251925d1d15", RangeSet({ { 0, 2 } })),
85 }),
86 source);
87 ASSERT_EQ(2, source.blocks());
88}
89
90TEST(CommandsTest, ParseTargetInfoAndSourceInfo_SourceBlocksAndStashes) {
91 const std::vector<std::string> tokens{
92 "4,611641,611643,636981,637075",
93 "96",
94 "4,636981,637075,770665,770666",
95 "4,0,94,95,96",
96 "9eedf00d11061549e32503cadf054ec6fbfa7a23:2,94,95",
97 };
98 TargetInfo target;
99 SourceInfo source;
100 std::string err;
101 ASSERT_TRUE(Command::ParseTargetInfoAndSourceInfo(
102 tokens, "4734d1b241eb3d0f993714aaf7d665fae43772b6", &target,
103 "a6cbdf3f416960f02189d3a814ec7e9e95c44a0d", &source, &err));
104 ASSERT_EQ(TargetInfo("4734d1b241eb3d0f993714aaf7d665fae43772b6",
105 RangeSet({ { 611641, 611643 }, { 636981, 637075 } })),
106 target);
107 ASSERT_EQ(SourceInfo(
108 "a6cbdf3f416960f02189d3a814ec7e9e95c44a0d",
109 RangeSet({ { 636981, 637075 }, { 770665, 770666 } }), // source ranges
110 RangeSet({ { 0, 94 }, { 95, 96 } }), // source location
111 {
112 StashInfo("9eedf00d11061549e32503cadf054ec6fbfa7a23", RangeSet({ { 94, 95 } })),
113 }),
114 source);
115 ASSERT_EQ(96, source.blocks());
116}
117
118TEST(CommandsTest, ParseTargetInfoAndSourceInfo_InvalidInput) {
119 const std::vector<std::string> tokens{
120 "4,611641,611643,636981,637075",
121 "96",
122 "4,636981,637075,770665,770666",
123 "4,0,94,95,96",
124 "9eedf00d11061549e32503cadf054ec6fbfa7a23:2,94,95",
125 };
126 TargetInfo target;
127 SourceInfo source;
128 std::string err;
129
130 // Mismatching block count.
131 {
132 std::vector<std::string> tokens_copy(tokens);
133 tokens_copy[1] = "97";
134 ASSERT_FALSE(Command::ParseTargetInfoAndSourceInfo(
135 tokens_copy, "1d74d1a60332fd38cf9405f1bae67917888da6cb", &target,
136 "1d74d1a60332fd38cf9405f1bae67917888da6cb", &source, &err));
137 }
138
139 // Excess stashes (causing block count mismatch).
140 {
141 std::vector<std::string> tokens_copy(tokens);
142 tokens_copy.push_back("e145a2f83a33334714ac65e34969c1f115e54a6f:2,0,22");
143 ASSERT_FALSE(Command::ParseTargetInfoAndSourceInfo(
144 tokens_copy, "1d74d1a60332fd38cf9405f1bae67917888da6cb", &target,
145 "1d74d1a60332fd38cf9405f1bae67917888da6cb", &source, &err));
146 }
147
148 // Invalid args.
149 for (size_t i = 0; i < tokens.size(); i++) {
150 TargetInfo target;
151 SourceInfo source;
152 std::string err;
153 ASSERT_FALSE(Command::ParseTargetInfoAndSourceInfo(
154 std::vector<std::string>(tokens.cbegin() + i + 1, tokens.cend()),
155 "1d74d1a60332fd38cf9405f1bae67917888da6cb", &target,
156 "1d74d1a60332fd38cf9405f1bae67917888da6cb", &source, &err));
157 }
158}
159
160TEST(CommandsTest, Parse_EmptyInput) {
161 std::string err;
162 ASSERT_FALSE(Command::Parse("", 0, &err));
163 ASSERT_EQ("invalid type", err);
164}
165
Tao Bao91a649a2018-05-21 16:05:56 -0700166TEST(CommandsTest, Parse_ABORT_Allowed) {
167 Command::abort_allowed_ = true;
168
169 const std::string input{ "abort" };
170 std::string err;
171 Command command = Command::Parse(input, 0, &err);
172 ASSERT_TRUE(command);
173
174 ASSERT_EQ(TargetInfo(), command.target());
175 ASSERT_EQ(SourceInfo(), command.source());
176 ASSERT_EQ(StashInfo(), command.stash());
177 ASSERT_EQ(PatchInfo(), command.patch());
178}
179
180TEST(CommandsTest, Parse_ABORT_NotAllowed) {
181 const std::string input{ "abort" };
182 std::string err;
183 Command command = Command::Parse(input, 0, &err);
184 ASSERT_FALSE(command);
185}
186
Tao Bao6a7e4af2018-06-14 21:57:43 -0700187TEST(CommandsTest, Parse_BSDIFF) {
188 const std::string input{
189 "bsdiff 0 148 "
190 "f201a4e04bd3860da6ad47b957ef424d58a58f8c 9d5d223b4bc5c45dbd25a799c4f1a98466731599 "
191 "4,565704,565752,566779,566799 "
192 "68 4,64525,64545,565704,565752"
193 };
194 std::string err;
195 Command command = Command::Parse(input, 1, &err);
196 ASSERT_TRUE(command);
197
198 ASSERT_EQ(Command::Type::BSDIFF, command.type());
199 ASSERT_EQ(1, command.index());
200 ASSERT_EQ(input, command.cmdline());
201
202 ASSERT_EQ(TargetInfo("9d5d223b4bc5c45dbd25a799c4f1a98466731599",
203 RangeSet({ { 565704, 565752 }, { 566779, 566799 } })),
204 command.target());
205 ASSERT_EQ(SourceInfo("f201a4e04bd3860da6ad47b957ef424d58a58f8c",
206 RangeSet({ { 64525, 64545 }, { 565704, 565752 } }), RangeSet(), {}),
207 command.source());
208 ASSERT_EQ(StashInfo(), command.stash());
209 ASSERT_EQ(PatchInfo(0, 148), command.patch());
210}
211
212TEST(CommandsTest, Parse_ERASE) {
213 const std::string input{ "erase 2,5,10" };
214 std::string err;
215 Command command = Command::Parse(input, 2, &err);
216 ASSERT_TRUE(command);
217
218 ASSERT_EQ(Command::Type::ERASE, command.type());
219 ASSERT_EQ(2, command.index());
220 ASSERT_EQ(input, command.cmdline());
221
222 ASSERT_EQ(TargetInfo("unknown-hash", RangeSet({ { 5, 10 } })), command.target());
223 ASSERT_EQ(SourceInfo(), command.source());
224 ASSERT_EQ(StashInfo(), command.stash());
225 ASSERT_EQ(PatchInfo(), command.patch());
226}
227
228TEST(CommandsTest, Parse_FREE) {
229 const std::string input{ "free hash1" };
230 std::string err;
231 Command command = Command::Parse(input, 3, &err);
232 ASSERT_TRUE(command);
233
234 ASSERT_EQ(Command::Type::FREE, command.type());
235 ASSERT_EQ(3, command.index());
236 ASSERT_EQ(input, command.cmdline());
237
238 ASSERT_EQ(TargetInfo(), command.target());
239 ASSERT_EQ(SourceInfo(), command.source());
240 ASSERT_EQ(StashInfo("hash1", RangeSet()), command.stash());
241 ASSERT_EQ(PatchInfo(), command.patch());
242}
243
244TEST(CommandsTest, Parse_IMGDIFF) {
245 const std::string input{
246 "imgdiff 29629269 185 "
247 "a6b1c49aed1b57a2aab1ec3e1505b945540cd8db 51978f65035f584a8ef7afa941dacb6d5e862164 "
248 "2,90851,90852 "
249 "1 2,90851,90852"
250 };
251 std::string err;
252 Command command = Command::Parse(input, 4, &err);
253 ASSERT_TRUE(command);
254
255 ASSERT_EQ(Command::Type::IMGDIFF, command.type());
256 ASSERT_EQ(4, command.index());
257 ASSERT_EQ(input, command.cmdline());
258
259 ASSERT_EQ(TargetInfo("51978f65035f584a8ef7afa941dacb6d5e862164", RangeSet({ { 90851, 90852 } })),
260 command.target());
261 ASSERT_EQ(SourceInfo("a6b1c49aed1b57a2aab1ec3e1505b945540cd8db", RangeSet({ { 90851, 90852 } }),
262 RangeSet(), {}),
263 command.source());
264 ASSERT_EQ(StashInfo(), command.stash());
265 ASSERT_EQ(PatchInfo(29629269, 185), command.patch());
266}
267
268TEST(CommandsTest, Parse_MOVE) {
269 const std::string input{
270 "move 1d74d1a60332fd38cf9405f1bae67917888da6cb "
271 "4,569884,569904,591946,592043 117 4,566779,566799,591946,592043"
272 };
273 std::string err;
274 Command command = Command::Parse(input, 5, &err);
275 ASSERT_TRUE(command);
276
277 ASSERT_EQ(Command::Type::MOVE, command.type());
278 ASSERT_EQ(5, command.index());
279 ASSERT_EQ(input, command.cmdline());
280
281 ASSERT_EQ(TargetInfo("1d74d1a60332fd38cf9405f1bae67917888da6cb",
282 RangeSet({ { 569884, 569904 }, { 591946, 592043 } })),
283 command.target());
284 ASSERT_EQ(SourceInfo("1d74d1a60332fd38cf9405f1bae67917888da6cb",
285 RangeSet({ { 566779, 566799 }, { 591946, 592043 } }), RangeSet(), {}),
286 command.source());
287 ASSERT_EQ(StashInfo(), command.stash());
288 ASSERT_EQ(PatchInfo(), command.patch());
289}
290
291TEST(CommandsTest, Parse_NEW) {
292 const std::string input{ "new 4,3,5,10,12" };
293 std::string err;
294 Command command = Command::Parse(input, 6, &err);
295 ASSERT_TRUE(command);
296
297 ASSERT_EQ(Command::Type::NEW, command.type());
298 ASSERT_EQ(6, command.index());
299 ASSERT_EQ(input, command.cmdline());
300
301 ASSERT_EQ(TargetInfo("unknown-hash", RangeSet({ { 3, 5 }, { 10, 12 } })), command.target());
302 ASSERT_EQ(SourceInfo(), command.source());
303 ASSERT_EQ(StashInfo(), command.stash());
304 ASSERT_EQ(PatchInfo(), command.patch());
305}
306
307TEST(CommandsTest, Parse_STASH) {
308 const std::string input{ "stash hash1 2,5,10" };
309 std::string err;
310 Command command = Command::Parse(input, 7, &err);
311 ASSERT_TRUE(command);
312
313 ASSERT_EQ(Command::Type::STASH, command.type());
314 ASSERT_EQ(7, command.index());
315 ASSERT_EQ(input, command.cmdline());
316
317 ASSERT_EQ(TargetInfo(), command.target());
318 ASSERT_EQ(SourceInfo(), command.source());
319 ASSERT_EQ(StashInfo("hash1", RangeSet({ { 5, 10 } })), command.stash());
320 ASSERT_EQ(PatchInfo(), command.patch());
321}
322
323TEST(CommandsTest, Parse_ZERO) {
324 const std::string input{ "zero 2,1,5" };
325 std::string err;
326 Command command = Command::Parse(input, 8, &err);
327 ASSERT_TRUE(command);
328
329 ASSERT_EQ(Command::Type::ZERO, command.type());
330 ASSERT_EQ(8, command.index());
331 ASSERT_EQ(input, command.cmdline());
332
333 ASSERT_EQ(TargetInfo("unknown-hash", RangeSet({ { 1, 5 } })), command.target());
334 ASSERT_EQ(SourceInfo(), command.source());
335 ASSERT_EQ(StashInfo(), command.stash());
336 ASSERT_EQ(PatchInfo(), command.patch());
337}
Tao Bao92f33932018-06-25 12:11:53 -0700338
Tianjie Xu8f64bf62018-08-07 00:22:19 -0700339TEST(CommandsTest, Parse_COMPUTE_HASH_TREE) {
340 const std::string input{ "compute_hash_tree 2,0,1 2,3,4 sha1 unknown-salt unknown-root-hash" };
341 std::string err;
342 Command command = Command::Parse(input, 9, &err);
343 ASSERT_TRUE(command);
344
345 ASSERT_EQ(Command::Type::COMPUTE_HASH_TREE, command.type());
346 ASSERT_EQ(9, command.index());
347 ASSERT_EQ(input, command.cmdline());
348
349 HashTreeInfo expected_info(RangeSet({ { 0, 1 } }), RangeSet({ { 3, 4 } }), "sha1", "unknown-salt",
350 "unknown-root-hash");
351 ASSERT_EQ(expected_info, command.hash_tree_info());
352 ASSERT_EQ(TargetInfo(), command.target());
353 ASSERT_EQ(SourceInfo(), command.source());
354 ASSERT_EQ(StashInfo(), command.stash());
355 ASSERT_EQ(PatchInfo(), command.patch());
356}
357
Tao Bao92f33932018-06-25 12:11:53 -0700358TEST(CommandsTest, Parse_InvalidNumberOfArgs) {
Tao Bao91a649a2018-05-21 16:05:56 -0700359 Command::abort_allowed_ = true;
360
Tao Bao92f33932018-06-25 12:11:53 -0700361 // Note that the case of having excess args in BSDIFF, IMGDIFF and MOVE is covered by
362 // ParseTargetInfoAndSourceInfo_InvalidInput.
363 std::vector<std::string> inputs{
Tao Bao91a649a2018-05-21 16:05:56 -0700364 "abort foo",
Tao Bao92f33932018-06-25 12:11:53 -0700365 "bsdiff",
Tianjie Xu8f64bf62018-08-07 00:22:19 -0700366 "compute_hash_tree, 2,0,1 2,0,1 unknown-algorithm unknown-salt",
Tao Bao92f33932018-06-25 12:11:53 -0700367 "erase",
368 "erase 4,3,5,10,12 hash1",
369 "free",
370 "free id1 id2",
371 "imgdiff",
372 "move",
373 "new",
374 "new 4,3,5,10,12 hash1",
375 "stash",
376 "stash id1",
377 "stash id1 4,3,5,10,12 id2",
378 "zero",
379 "zero 4,3,5,10,12 hash2",
380 };
381 for (const auto& input : inputs) {
382 std::string err;
383 ASSERT_FALSE(Command::Parse(input, 0, &err));
384 }
385}
Tao Bao3c892732018-06-18 09:44:33 -0700386
387TEST(SourceInfoTest, Overlaps) {
388 ASSERT_TRUE(SourceInfo("1d74d1a60332fd38cf9405f1bae67917888da6cb",
389 RangeSet({ { 7, 9 }, { 16, 20 } }), {}, {})
390 .Overlaps(TargetInfo("1d74d1a60332fd38cf9405f1bae67917888da6cb",
391 RangeSet({ { 7, 9 }, { 16, 20 } }))));
392
393 ASSERT_TRUE(SourceInfo("1d74d1a60332fd38cf9405f1bae67917888da6cb",
394 RangeSet({ { 7, 9 }, { 16, 20 } }), {}, {})
395 .Overlaps(TargetInfo("1d74d1a60332fd38cf9405f1bae67917888da6cb",
396 RangeSet({ { 4, 7 }, { 16, 23 } }))));
397
398 ASSERT_FALSE(SourceInfo("1d74d1a60332fd38cf9405f1bae67917888da6cb",
399 RangeSet({ { 7, 9 }, { 16, 20 } }), {}, {})
400 .Overlaps(TargetInfo("1d74d1a60332fd38cf9405f1bae67917888da6cb",
401 RangeSet({ { 9, 16 } }))));
402}
403
404TEST(SourceInfoTest, Overlaps_EmptySourceOrTarget) {
405 ASSERT_FALSE(SourceInfo().Overlaps(TargetInfo()));
406
407 ASSERT_FALSE(SourceInfo().Overlaps(
408 TargetInfo("1d74d1a60332fd38cf9405f1bae67917888da6cb", RangeSet({ { 7, 9 }, { 16, 20 } }))));
409
410 ASSERT_FALSE(SourceInfo("1d74d1a60332fd38cf9405f1bae67917888da6cb",
411 RangeSet({ { 7, 9 }, { 16, 20 } }), {}, {})
412 .Overlaps(TargetInfo()));
413}
414
415TEST(SourceInfoTest, Overlaps_WithStashes) {
416 ASSERT_FALSE(SourceInfo("a6cbdf3f416960f02189d3a814ec7e9e95c44a0d",
417 RangeSet({ { 81, 175 }, { 265, 266 } }), // source ranges
418 RangeSet({ { 0, 94 }, { 95, 96 } }), // source location
419 { StashInfo("9eedf00d11061549e32503cadf054ec6fbfa7a23",
420 RangeSet({ { 94, 95 } })) })
421 .Overlaps(TargetInfo("1d74d1a60332fd38cf9405f1bae67917888da6cb",
422 RangeSet({ { 175, 265 } }))));
423
424 ASSERT_TRUE(SourceInfo("a6cbdf3f416960f02189d3a814ec7e9e95c44a0d",
425 RangeSet({ { 81, 175 }, { 265, 266 } }), // source ranges
426 RangeSet({ { 0, 94 }, { 95, 96 } }), // source location
427 { StashInfo("9eedf00d11061549e32503cadf054ec6fbfa7a23",
428 RangeSet({ { 94, 95 } })) })
429 .Overlaps(TargetInfo("1d74d1a60332fd38cf9405f1bae67917888da6cb",
430 RangeSet({ { 265, 266 } }))));
431}
432
433// The block size should be specified by the caller of ReadAll (i.e. from Command instance during
434// normal run).
435constexpr size_t kBlockSize = 4096;
436
437TEST(SourceInfoTest, ReadAll) {
438 // "2727756cfee3fbfe24bf5650123fd7743d7b3465" is the SHA-1 hex digest of 8192 * 'a'.
439 const SourceInfo source("2727756cfee3fbfe24bf5650123fd7743d7b3465", RangeSet({ { 0, 2 } }), {},
440 {});
441 auto block_reader = [](const RangeSet& src, std::vector<uint8_t>* block_buffer) -> int {
442 std::fill_n(block_buffer->begin(), src.blocks() * kBlockSize, 'a');
443 return 0;
444 };
445 auto stash_reader = [](const std::string&, std::vector<uint8_t>*) -> int { return 0; };
446 std::vector<uint8_t> buffer(source.blocks() * kBlockSize);
447 ASSERT_TRUE(source.ReadAll(&buffer, kBlockSize, block_reader, stash_reader));
448 ASSERT_EQ(source.blocks() * kBlockSize, buffer.size());
449
450 uint8_t digest[SHA_DIGEST_LENGTH];
451 SHA1(buffer.data(), buffer.size(), digest);
452 ASSERT_EQ(source.hash(), print_sha1(digest));
453}
454
455TEST(SourceInfoTest, ReadAll_WithStashes) {
456 const SourceInfo source(
457 // SHA-1 hex digest of 8192 * 'a' + 4096 * 'b'.
458 "ee3ebea26130769c10ad13604712100346d48660", RangeSet({ { 0, 2 } }), RangeSet({ { 0, 2 } }),
459 { StashInfo("1e41f7a59e80c6eb4dc043caae80d273f130bed8", RangeSet({ { 2, 3 } })) });
460 auto block_reader = [](const RangeSet& src, std::vector<uint8_t>* block_buffer) -> int {
461 std::fill_n(block_buffer->begin(), src.blocks() * kBlockSize, 'a');
462 return 0;
463 };
464 auto stash_reader = [](const std::string&, std::vector<uint8_t>* stash_buffer) -> int {
465 std::fill_n(stash_buffer->begin(), kBlockSize, 'b');
466 return 0;
467 };
468 std::vector<uint8_t> buffer(source.blocks() * kBlockSize);
469 ASSERT_TRUE(source.ReadAll(&buffer, kBlockSize, block_reader, stash_reader));
470 ASSERT_EQ(source.blocks() * kBlockSize, buffer.size());
471
472 uint8_t digest[SHA_DIGEST_LENGTH];
473 SHA1(buffer.data(), buffer.size(), digest);
474 ASSERT_EQ(source.hash(), print_sha1(digest));
475}
476
477TEST(SourceInfoTest, ReadAll_BufferTooSmall) {
478 const SourceInfo source("2727756cfee3fbfe24bf5650123fd7743d7b3465", RangeSet({ { 0, 2 } }), {},
479 {});
480 auto block_reader = [](const RangeSet&, std::vector<uint8_t>*) -> int { return 0; };
481 auto stash_reader = [](const std::string&, std::vector<uint8_t>*) -> int { return 0; };
482 std::vector<uint8_t> buffer(source.blocks() * kBlockSize - 1);
483 ASSERT_FALSE(source.ReadAll(&buffer, kBlockSize, block_reader, stash_reader));
484}
485
486TEST(SourceInfoTest, ReadAll_FailingReader) {
487 const SourceInfo source(
488 "ee3ebea26130769c10ad13604712100346d48660", RangeSet({ { 0, 2 } }), RangeSet({ { 0, 2 } }),
489 { StashInfo("1e41f7a59e80c6eb4dc043caae80d273f130bed8", RangeSet({ { 2, 3 } })) });
490 std::vector<uint8_t> buffer(source.blocks() * kBlockSize);
491 auto failing_block_reader = [](const RangeSet&, std::vector<uint8_t>*) -> int { return -1; };
492 auto stash_reader = [](const std::string&, std::vector<uint8_t>*) -> int { return 0; };
493 ASSERT_FALSE(source.ReadAll(&buffer, kBlockSize, failing_block_reader, stash_reader));
494
495 auto block_reader = [](const RangeSet&, std::vector<uint8_t>*) -> int { return 0; };
496 auto failing_stash_reader = [](const std::string&, std::vector<uint8_t>*) -> int { return -1; };
497 ASSERT_FALSE(source.ReadAll(&buffer, kBlockSize, block_reader, failing_stash_reader));
498}