blob: 2466c82ac0e9f3d9e7d740c4576ca10728cecd8c [file] [log] [blame]
Kelvin Zhang55624032021-12-20 12:13:24 -08001//
2// Copyright (C) 2021 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
Kelvin Zhang8dd1ef12024-08-09 13:02:24 -070017#include <fcntl.h>
Kelvin Zhang55624032021-12-20 12:13:24 -080018#include <unistd.h>
19
20#include <algorithm>
Kelvin Zhang55624032021-12-20 12:13:24 -080021#include <string>
22#include <vector>
23
Kelvin Zhang55624032021-12-20 12:13:24 -080024#include <base/logging.h>
25#include <base/strings/string_number_conversions.h>
26#include <base/strings/string_util.h>
27#include <base/strings/stringprintf.h>
28#include <gtest/gtest.h>
29#include <erofs/internal.h>
30#include <erofs/io.h>
31
32#include "update_engine/common/test_utils.h"
33#include "update_engine/common/utils.h"
34#include "update_engine/lz4diff/lz4diff_compress.h"
35#include "update_engine/payload_generator/delta_diff_generator.h"
36#include "update_engine/payload_generator/erofs_filesystem.h"
Kelvin Zhang55624032021-12-20 12:13:24 -080037
38using std::string;
39using std::vector;
40
41namespace chromeos_update_engine {
42
43namespace {
44
45static void ExtractErofsImage(const char* erofs_image,
46 const char* inode_path,
47 Blob* output) {
Kelvin Zhang18e97e02023-09-25 09:54:16 -070048 struct erofs_sb_info sbi {};
Kelvin Zhang8dd1ef12024-08-09 13:02:24 -070049 auto err = erofs_dev_open(&sbi, erofs_image, O_RDONLY);
Kelvin Zhang55624032021-12-20 12:13:24 -080050 ASSERT_EQ(err, 0);
Kelvin Zhang18e97e02023-09-25 09:54:16 -070051 DEFER {
Kelvin Zhang8dd1ef12024-08-09 13:02:24 -070052 erofs_dev_close(&sbi);
Kelvin Zhang18e97e02023-09-25 09:54:16 -070053 };
Kelvin Zhang55624032021-12-20 12:13:24 -080054
Kelvin Zhang18e97e02023-09-25 09:54:16 -070055 err = erofs_read_superblock(&sbi);
Kelvin Zhang55624032021-12-20 12:13:24 -080056 ASSERT_EQ(err, 0);
Kelvin Zhang18e97e02023-09-25 09:54:16 -070057 struct erofs_inode inode {
58 .sbi = &sbi
59 };
Kelvin Zhang55624032021-12-20 12:13:24 -080060 err = erofs_ilookup(inode_path, &inode);
Kelvin Zhang18e97e02023-09-25 09:54:16 -070061 ASSERT_EQ(err, 0) << strerror(-err);
Kelvin Zhang55624032021-12-20 12:13:24 -080062 output->resize(inode.i_size);
63 err = erofs_pread(&inode,
64 reinterpret_cast<char*>(output->data()),
65 output->size(),
66 0 /* offset */);
67 ASSERT_EQ(err, 0);
68}
69
70class Lz4diffCompressTest : public ::testing::Test {};
71
72using test_utils::GetBuildArtifactsPath;
73
74// This test parses the sample images generated during build time with the
75// "generate_image.sh" script. The expected conditions of each file in these
76// images is encoded in the file name, as defined in the mentioned script.
77TEST_F(Lz4diffCompressTest, ExtractElfBinary) {
78 const auto build_path = GetBuildArtifactsPath("gen/erofs.img");
79 auto fs = ErofsFilesystem::CreateFromFile(build_path);
80 ASSERT_NE(fs, nullptr);
81 ASSERT_EQ(kBlockSize, fs->GetBlockSize());
82
83 vector<ErofsFilesystem::File> files;
84 ASSERT_TRUE(fs->GetFiles(&files));
85
86 const auto it =
87 std::find_if(files.begin(), files.end(), [](const auto& file) {
88 return file.name == "/delta_generator";
89 });
90 ASSERT_NE(it, files.end())
91 << "There should be a delta_generator entry in gen/erofs.img. Is the "
92 "generate_test_erofs_imgages.sh script implemented wrong?";
93
94 const auto delta_generator = *it;
95 Blob expected_blob;
96 ASSERT_NO_FATAL_FAILURE(ExtractErofsImage(
97 build_path.c_str(), "/delta_generator", &expected_blob));
98 Blob compressed_blob;
99 ASSERT_TRUE(utils::ReadExtents(
100 build_path, delta_generator.extents, &compressed_blob, kBlockSize));
101 auto decompressed_blob = TryDecompressBlob(
102 compressed_blob,
103 delta_generator.compressed_file_info.blocks,
104 delta_generator.compressed_file_info.zero_padding_enabled);
105 ASSERT_GT(decompressed_blob.size(), 0UL);
106 ASSERT_GE(decompressed_blob.size(),
107 static_cast<size_t>(delta_generator.file_stat.st_size));
108 decompressed_blob.resize(delta_generator.file_stat.st_size);
109 ASSERT_EQ(decompressed_blob, expected_blob);
110}
111
112} // namespace
113
114} // namespace chromeos_update_engine