Skip to content

Commit 022e20e

Browse files
Add a case to cover repeatedelly running fs verification am: 81eb075 am: e75db4f
Original change: https://android-review.googlesource.com/c/platform/system/update_engine/+/1696828 Change-Id: Ie2571255ff81aced6ef728695e34d44824931d85
2 parents a083a4a + e75db4f commit 022e20e

File tree

1 file changed

+80
-51
lines changed

1 file changed

+80
-51
lines changed

payload_consumer/filesystem_verifier_action_unittest.cc

Lines changed: 80 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -76,17 +76,17 @@ class FilesystemVerifierActionTest : public ::testing::Test {
7676
utils::DivRoundUp(fec_data_size / BLOCK_SIZE, FEC_RSM - FEC_ROOTS);
7777
fec_size = fec_rounds * FEC_ROOTS * BLOCK_SIZE;
7878

79-
fec_data.resize(fec_size);
80-
hash_tree_data.resize(hash_tree_size);
79+
fec_data_.resize(fec_size);
80+
hash_tree_data_.resize(hash_tree_size);
8181
brillo::Blob part_data(PARTITION_SIZE);
8282
test_utils::FillWithData(&part_data);
8383
ASSERT_TRUE(utils::WriteFile(
84-
source_part.path().c_str(), part_data.data(), part_data.size()));
84+
source_part_.path().c_str(), part_data.data(), part_data.size()));
8585
// FillWithData() will fill with different data next call. We want
8686
// source/target partitions to contain different data for testing.
8787
test_utils::FillWithData(&part_data);
8888
ASSERT_TRUE(utils::WriteFile(
89-
target_part.path().c_str(), part_data.data(), part_data.size()));
89+
target_part_.path().c_str(), part_data.data(), part_data.size()));
9090
loop_.SetAsCurrent();
9191
}
9292

@@ -107,16 +107,16 @@ class FilesystemVerifierActionTest : public ::testing::Test {
107107
std::string name = "fake_part") {
108108
InstallPlan::Partition& part = install_plan->partitions.emplace_back();
109109
part.name = name;
110-
part.target_path = target_part.path();
110+
part.target_path = target_part_.path();
111111
part.readonly_target_path = part.target_path;
112112
part.target_size = PARTITION_SIZE;
113113
part.block_size = BLOCK_SIZE;
114-
part.source_path = source_part.path();
114+
part.source_path = source_part_.path();
115115
part.source_size = PARTITION_SIZE;
116116
EXPECT_TRUE(
117-
HashCalculator::RawHashOfFile(source_part.path(), &part.source_hash));
117+
HashCalculator::RawHashOfFile(source_part_.path(), &part.source_hash));
118118
EXPECT_TRUE(
119-
HashCalculator::RawHashOfFile(target_part.path(), &part.target_hash));
119+
HashCalculator::RawHashOfFile(target_part_.path(), &part.target_hash));
120120
return ∂
121121
}
122122
static void ZeroRange(FileDescriptorPtr fd,
@@ -164,16 +164,16 @@ class FilesystemVerifierActionTest : public ::testing::Test {
164164
}
165165
ASSERT_TRUE(verity_writer.Finalize(fd, fd));
166166
ASSERT_TRUE(fd->IsOpen());
167-
ASSERT_TRUE(HashCalculator::RawHashOfFile(target_part.path(),
167+
ASSERT_TRUE(HashCalculator::RawHashOfFile(target_part_.path(),
168168
&partition->target_hash));
169169

170170
ASSERT_TRUE(fd->Seek(HASH_TREE_START_OFFSET, SEEK_SET));
171-
ASSERT_EQ(fd->Read(hash_tree_data.data(), hash_tree_data.size()),
172-
static_cast<ssize_t>(hash_tree_data.size()))
171+
ASSERT_EQ(fd->Read(hash_tree_data_.data(), hash_tree_data_.size()),
172+
static_cast<ssize_t>(hash_tree_data_.size()))
173173
<< "Failed to read hashtree " << strerror(errno);
174174
ASSERT_TRUE(fd->Seek(fec_start_offset, SEEK_SET));
175-
ASSERT_EQ(fd->Read(fec_data.data(), fec_data.size()),
176-
static_cast<ssize_t>(fec_data.size()))
175+
ASSERT_EQ(fd->Read(fec_data_.data(), fec_data_.size()),
176+
static_cast<ssize_t>(fec_data_.size()))
177177
<< "Failed to read FEC " << strerror(errno);
178178
// Fs verification action is expected to write them, so clear verity data to
179179
// ensure that they are re-created correctly.
@@ -185,17 +185,28 @@ class FilesystemVerifierActionTest : public ::testing::Test {
185185
brillo::FakeMessageLoop loop_{nullptr};
186186
ActionProcessor processor_;
187187
DynamicPartitionControlStub dynamic_control_stub_;
188-
std::vector<unsigned char> fec_data;
189-
std::vector<unsigned char> hash_tree_data;
190-
static ScopedTempFile source_part;
191-
static ScopedTempFile target_part;
188+
std::vector<unsigned char> fec_data_;
189+
std::vector<unsigned char> hash_tree_data_;
190+
static ScopedTempFile source_part_;
191+
static ScopedTempFile target_part_;
192+
InstallPlan install_plan_;
192193
};
193194

194-
ScopedTempFile FilesystemVerifierActionTest::source_part{
195+
ScopedTempFile FilesystemVerifierActionTest::source_part_{
195196
"source_part.XXXXXX", false, PARTITION_SIZE};
196-
ScopedTempFile FilesystemVerifierActionTest::target_part{
197+
ScopedTempFile FilesystemVerifierActionTest::target_part_{
197198
"target_part.XXXXXX", false, PARTITION_SIZE};
198199

200+
static void EnableVABC(MockDynamicPartitionControl* dynamic_control,
201+
const std::string& part_name) {
202+
ON_CALL(*dynamic_control, GetDynamicPartitionsFeatureFlag())
203+
.WillByDefault(Return(FeatureFlag(FeatureFlag::Value::LAUNCH)));
204+
ON_CALL(*dynamic_control, UpdateUsesSnapshotCompression())
205+
.WillByDefault(Return(true));
206+
ON_CALL(*dynamic_control, IsDynamicPartition(part_name, _))
207+
.WillByDefault(Return(true));
208+
}
209+
199210
class FilesystemVerifierActionTestDelegate : public ActionProcessorDelegate {
200211
public:
201212
FilesystemVerifierActionTestDelegate()
@@ -261,9 +272,8 @@ bool FilesystemVerifierActionTest::DoTest(bool terminate_early,
261272
bool success = true;
262273

263274
// Set up the action objects
264-
InstallPlan install_plan;
265-
install_plan.source_slot = 0;
266-
install_plan.target_slot = 1;
275+
install_plan_.source_slot = 0;
276+
install_plan_.target_slot = 1;
267277
InstallPlan::Partition part;
268278
part.name = "part";
269279
part.target_size = kLoopFileSize - (hash_fail ? 1 : 0);
@@ -278,9 +288,9 @@ bool FilesystemVerifierActionTest::DoTest(bool terminate_early,
278288
ADD_FAILURE();
279289
success = false;
280290
}
281-
install_plan.partitions = {part};
291+
install_plan_.partitions = {part};
282292

283-
BuildActions(install_plan);
293+
BuildActions(install_plan_);
284294

285295
FilesystemVerifierActionTestDelegate delegate;
286296
processor_.set_delegate(&delegate);
@@ -323,7 +333,7 @@ bool FilesystemVerifierActionTest::DoTest(bool terminate_early,
323333
EXPECT_TRUE(is_a_file_reading_eq);
324334
success = success && is_a_file_reading_eq;
325335

326-
bool is_install_plan_eq = (*delegate.install_plan_ == install_plan);
336+
bool is_install_plan_eq = (*delegate.install_plan_ == install_plan_);
327337
EXPECT_TRUE(is_install_plan_eq);
328338
success = success && is_install_plan_eq;
329339
return success;
@@ -388,14 +398,13 @@ TEST_F(FilesystemVerifierActionTest, MissingInputObjectTest) {
388398
}
389399

390400
TEST_F(FilesystemVerifierActionTest, NonExistentDriveTest) {
391-
InstallPlan install_plan;
392401
InstallPlan::Partition part;
393402
part.name = "nope";
394403
part.source_path = "/no/such/file";
395404
part.target_path = "/no/such/file";
396-
install_plan.partitions = {part};
405+
install_plan_.partitions = {part};
397406

398-
BuildActions(install_plan);
407+
BuildActions(install_plan_);
399408

400409
FilesystemVerifierActionTest2Delegate delegate;
401410
processor_.set_delegate(&delegate);
@@ -436,7 +445,6 @@ TEST_F(FilesystemVerifierActionTest, RunAsRootWriteVerityTest) {
436445
test_utils::ScopedLoopbackDeviceBinder target_device(
437446
part_file.path(), true, &target_path);
438447

439-
InstallPlan install_plan;
440448
InstallPlan::Partition part;
441449
part.name = "part";
442450
part.target_path = target_path;
@@ -467,9 +475,9 @@ TEST_F(FilesystemVerifierActionTest, RunAsRootWriteVerityTest) {
467475
part.hash_tree_salt = {0x9e, 0xcb, 0xf8, 0xd5, 0x0b, 0xb4, 0x43,
468476
0x0a, 0x7a, 0x10, 0xad, 0x96, 0xd7, 0x15,
469477
0x70, 0xba, 0xed, 0x27, 0xe2, 0xae};
470-
install_plan.partitions = {part};
478+
install_plan_.partitions = {part};
471479

472-
BuildActions(install_plan);
480+
BuildActions(install_plan_);
473481

474482
FilesystemVerifierActionTestDelegate delegate;
475483
processor_.set_delegate(&delegate);
@@ -498,8 +506,7 @@ TEST_F(FilesystemVerifierActionTest, RunAsRootSkipWriteVerityTest) {
498506
test_utils::ScopedLoopbackDeviceBinder target_device(
499507
part_file.path(), true, &target_path);
500508

501-
InstallPlan install_plan;
502-
install_plan.write_verity = false;
509+
install_plan_.write_verity = false;
503510
InstallPlan::Partition part;
504511
part.name = "part";
505512
part.target_path = target_path;
@@ -514,9 +521,9 @@ TEST_F(FilesystemVerifierActionTest, RunAsRootSkipWriteVerityTest) {
514521
part.fec_offset = part.fec_data_size;
515522
part.fec_size = 2 * 4096;
516523
EXPECT_TRUE(HashCalculator::RawHashOfData(part_data, &part.target_hash));
517-
install_plan.partitions = {part};
524+
install_plan_.partitions = {part};
518525

519-
BuildActions(install_plan);
526+
BuildActions(install_plan_);
520527

521528
FilesystemVerifierActionTestDelegate delegate;
522529
processor_.set_delegate(&delegate);
@@ -535,33 +542,24 @@ TEST_F(FilesystemVerifierActionTest, RunAsRootSkipWriteVerityTest) {
535542

536543
void FilesystemVerifierActionTest::DoTestVABC(bool clear_target_hash,
537544
bool enable_verity) {
538-
InstallPlan install_plan;
539-
auto part_ptr = AddFakePartition(&install_plan);
545+
auto part_ptr = AddFakePartition(&install_plan_);
540546
if (::testing::Test::HasFailure()) {
541547
return;
542548
}
543549
ASSERT_NE(part_ptr, nullptr);
544550
InstallPlan::Partition& part = *part_ptr;
545551
part.target_path = "Shouldn't attempt to open this path";
546552
if (enable_verity) {
547-
install_plan.write_verity = true;
548-
SetHashWithVerity(&part);
549-
if (::testing::Test::HasFailure()) {
550-
return;
551-
}
553+
install_plan_.write_verity = true;
554+
ASSERT_NO_FATAL_FAILURE(SetHashWithVerity(&part));
552555
}
553556
if (clear_target_hash) {
554557
part.target_hash.clear();
555558
}
556559

557560
NiceMock<MockDynamicPartitionControl> dynamic_control;
558561

559-
ON_CALL(dynamic_control, GetDynamicPartitionsFeatureFlag())
560-
.WillByDefault(Return(FeatureFlag(FeatureFlag::Value::LAUNCH)));
561-
ON_CALL(dynamic_control, UpdateUsesSnapshotCompression())
562-
.WillByDefault(Return(true));
563-
ON_CALL(dynamic_control, IsDynamicPartition(part.name, _))
564-
.WillByDefault(Return(true));
562+
EnableVABC(&dynamic_control, part.name);
565563

566564
EXPECT_CALL(dynamic_control, UpdateUsesSnapshotCompression())
567565
.Times(AtLeast(1));
@@ -589,7 +587,7 @@ void FilesystemVerifierActionTest::DoTestVABC(bool clear_target_hash,
589587
DoAll(SetArgPointee<2, std::vector<std::string>>({part.name}),
590588
Return(true)));
591589

592-
BuildActions(install_plan, &dynamic_control);
590+
BuildActions(install_plan_, &dynamic_control);
593591

594592
FilesystemVerifierActionTestDelegate delegate;
595593
processor_.set_delegate(&delegate);
@@ -611,14 +609,14 @@ void FilesystemVerifierActionTest::DoTestVABC(bool clear_target_hash,
611609
actual_fec.size(),
612610
fec_start_offset,
613611
&bytes_read));
614-
ASSERT_EQ(actual_fec, fec_data);
612+
ASSERT_EQ(actual_fec, fec_data_);
615613
std::vector<unsigned char> actual_hash_tree(hash_tree_size);
616614
ASSERT_TRUE(utils::PReadAll(cow_fd,
617615
actual_hash_tree.data(),
618616
actual_hash_tree.size(),
619617
HASH_TREE_START_OFFSET,
620618
&bytes_read));
621-
ASSERT_EQ(actual_hash_tree, hash_tree_data);
619+
ASSERT_EQ(actual_hash_tree, hash_tree_data_);
622620
}
623621
if (clear_target_hash) {
624622
ASSERT_EQ(ErrorCode::kNewRootfsVerificationError, delegate.code());
@@ -639,6 +637,37 @@ TEST_F(FilesystemVerifierActionTest, VABC_Verity_Success) {
639637
DoTestVABC(false, true);
640638
}
641639

640+
TEST_F(FilesystemVerifierActionTest, VABC_Verity_ReadAfterWrite) {
641+
ASSERT_NO_FATAL_FAILURE(DoTestVABC(false, true));
642+
// Run FS verification again, w/o writing verity. We have seen a bug where
643+
// attempting to run fs again will cause previously written verity data to be
644+
// dropped, so cover this scenario.
645+
ASSERT_GE(install_plan_.partitions.size(), 1UL);
646+
auto& part = install_plan_.partitions[0];
647+
install_plan_.write_verity = false;
648+
part.readonly_target_path = target_part_.path();
649+
NiceMock<MockDynamicPartitionControl> dynamic_control;
650+
EnableVABC(&dynamic_control, part.name);
651+
652+
// b/186196758 is only visible if we repeatedely run FS verification w/o
653+
// writing verity
654+
for (int i = 0; i < 3; i++) {
655+
BuildActions(install_plan_, &dynamic_control);
656+
657+
FilesystemVerifierActionTestDelegate delegate;
658+
processor_.set_delegate(&delegate);
659+
loop_.PostTask(
660+
FROM_HERE,
661+
base::Bind(
662+
[](ActionProcessor* processor) { processor->StartProcessing(); },
663+
base::Unretained(&processor_)));
664+
loop_.Run();
665+
ASSERT_FALSE(processor_.IsRunning());
666+
ASSERT_TRUE(delegate.ran());
667+
ASSERT_EQ(ErrorCode::kSuccess, delegate.code());
668+
}
669+
}
670+
642671
TEST_F(FilesystemVerifierActionTest, VABC_Verity_Target_Mismatch) {
643672
DoTestVABC(true, true);
644673
}

0 commit comments

Comments
 (0)