xref: /aosp_15_r20/system/core/fastboot/vendor_boot_img_utils_test.cpp (revision 00c7fec1bb09f3284aad6a6f96d2f63dfc3650ad)
1 /*
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 
17 #include <string.h>
18 #include <sys/stat.h>
19 #include <sys/types.h>
20 #include <unistd.h>
21 
22 #include <filesystem>
23 #include <optional>
24 #include <string_view>
25 
26 #include <android-base/file.h>
27 #include <android-base/logging.h>
28 #include <android-base/result.h>
29 #include <android-base/strings.h>
30 #include <bootimg.h>
31 #include <gmock/gmock.h>
32 #include <gtest/gtest.h>
33 #include <libavb/libavb.h>
34 
35 #include "vendor_boot_img_utils.h"
36 
37 using android::base::borrowed_fd;
38 using android::base::ErrnoError;
39 using android::base::GetExecutableDirectory;
40 using android::base::ReadFdToString;
41 using android::base::Result;
42 using testing::AllOf;
43 using testing::Each;
44 using testing::Eq;
45 using testing::HasSubstr;
46 using testing::Not;
47 using testing::Property;
48 using std::string_literals::operator""s;
49 
50 // Expect that the Result<T> returned by |expr| is successful, and value matches |result_matcher|.
51 #define EXPECT_RESULT(expr, result_matcher)                          \
52     EXPECT_THAT(expr, AllOf(Property(&decltype(expr)::ok, Eq(true)), \
53                             Property(&decltype(expr)::value, result_matcher)))
54 
55 // Expect that the Result<T> returned by |expr| fails, and error message matches |error_matcher|.
56 #define EXPECT_ERROR(expr, error_matcher)                                                        \
57     do {                                                                                         \
58         EXPECT_THAT(                                                                             \
59                 expr,                                                                            \
60                 AllOf(Property(&decltype(expr)::ok, Eq(false)),                                  \
61                       Property(&decltype(expr)::error,                                           \
62                                Property(&decltype(expr)::error_type::message, error_matcher)))); \
63     } while (0)
64 
65 namespace {
66 
67 // Wrapper of fstat.
FileSize(borrowed_fd fd,std::filesystem::path path)68 Result<uint64_t> FileSize(borrowed_fd fd, std::filesystem::path path) {
69     struct stat sb;
70     if (fstat(fd.get(), &sb) == -1) return ErrnoError() << "fstat(" << path << ")";
71     return sb.st_size;
72 }
73 
74 // Seek to beginning then read the whole file.
ReadStartOfFdToString(borrowed_fd fd,std::filesystem::path path)75 Result<std::string> ReadStartOfFdToString(borrowed_fd fd, std::filesystem::path path) {
76     if (lseek(fd.get(), 0, SEEK_SET) != 0)
77         return ErrnoError() << "lseek(" << path << ", 0, SEEK_SET)";
78     std::string content;
79     if (!android::base::ReadFdToString(fd, &content)) return ErrnoError() << "read(" << path << ")";
80     return content;
81 }
82 
83 // Round |value| up to page boundary.
round_up(uint32_t value,uint32_t page_size)84 inline uint32_t round_up(uint32_t value, uint32_t page_size) {
85     return (value + page_size - 1) / page_size * page_size;
86 }
87 
88 // Match is successful if |arg| is a zero-padded version of |expected|.
89 MATCHER_P(IsPadded, expected, (negation ? "is" : "isn't") + " zero-padded of expected value"s) {
90     if (arg.size() < expected.size()) return false;
91     if (0 != memcmp(arg.data(), expected.data(), expected.size())) return false;
92     auto remainder = std::string_view(arg).substr(expected.size());
93     for (char e : remainder)
94         if (e != '\0') return false;
95     return true;
96 }
97 
98 // Same as Eq, but don't print the content to avoid spam.
99 MATCHER_P(MemEq, expected, (negation ? "is" : "isn't") + " expected value"s) {
100     if (arg.size() != expected.size()) return false;
101     return 0 == memcmp(arg.data(), expected.data(), expected.size());
102 }
103 
104 // Expect that |arg| and |expected| has the same AVB footer.
105 MATCHER_P(HasSameAvbFooter, expected,
106           (negation ? "has" : "does not have") + "expected AVB footer"s) {
107     if (expected.size() < AVB_FOOTER_SIZE || arg.size() < AVB_FOOTER_SIZE) return false;
108     return std::string_view(expected).substr(expected.size() - AVB_FOOTER_SIZE) ==
109            std::string_view(arg).substr(arg.size() - AVB_FOOTER_SIZE);
110 }
111 
112 // A lazy handle of a file.
113 struct TestFileHandle {
114     virtual ~TestFileHandle() = default;
115     // Lazily call OpenImpl(), cache result in open_result_.
Open__anonec0eb9cf0111::TestFileHandle116     android::base::Result<void> Open() {
117         if (!open_result_.has_value()) open_result_ = OpenImpl();
118         return open_result_.value();
119     }
120     // The original size at the time when the file is opened. If the file has been modified,
121     // this field is NOT updated.
size__anonec0eb9cf0111::TestFileHandle122     uint64_t size() {
123         CHECK(open_result_.has_value());
124         return size_;
125     }
126     // The current size of the file. If the file has been modified since opened,
127     // this is updated.
fsize__anonec0eb9cf0111::TestFileHandle128     Result<uint64_t> fsize() {
129         CHECK(open_result_.has_value());
130         return FileSize(fd_, abs_path_);
131     }
fd__anonec0eb9cf0111::TestFileHandle132     borrowed_fd fd() {
133         CHECK(open_result_.has_value());
134         return fd_;
135     }
Read__anonec0eb9cf0111::TestFileHandle136     Result<std::string> Read() {
137         CHECK(open_result_.has_value());
138         return ReadStartOfFdToString(fd_, abs_path_);
139     }
140 
141   private:
142     std::filesystem::path abs_path_;
143     uint64_t size_;
144     std::optional<android::base::Result<void>> open_result_;
145     borrowed_fd fd_{-1};
146     // Opens |rel_path_| as a readonly fd, pass it to Transform, and store result to
147     // |borrowed_fd_|.
OpenImpl__anonec0eb9cf0111::TestFileHandle148     android::base::Result<void> OpenImpl() {
149         android::base::unique_fd read_fd(TEMP_FAILURE_RETRY(
150                 open(abs_path_.c_str(), O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_BINARY)));
151         if (!read_fd.ok()) return ErrnoError() << "open(" << abs_path_ << ")";
152         auto size = FileSize(read_fd, abs_path_);
153         if (!size.ok()) return size.error();
154         size_ = *size;
155 
156         auto borrowed_fd = Transform(abs_path_, std::move(read_fd));
157         if (!borrowed_fd.ok()) return borrowed_fd.error();
158         fd_ = borrowed_fd.value();
159 
160         return {};
161     }
162 
163   protected:
164     // |rel_path| is the relative path under test data directory.
TestFileHandle__anonec0eb9cf0111::TestFileHandle165     TestFileHandle(const std::filesystem::path& rel_path)
166         : abs_path_(std::filesystem::path(GetExecutableDirectory()) / rel_path) {}
167     // Given |read_fd|, the readonly fd on the test file, return an fd that's suitable for client
168     // to use. Implementation is responsible for managing the lifetime of the returned fd.
169     virtual android::base::Result<borrowed_fd> Transform(const std::filesystem::path& abs_path,
170                                                          android::base::unique_fd read_fd) = 0;
171 };
172 
173 // A TestFileHandle where the file is readonly.
174 struct ReadOnlyTestFileHandle : TestFileHandle {
ReadOnlyTestFileHandle__anonec0eb9cf0111::ReadOnlyTestFileHandle175     ReadOnlyTestFileHandle(const std::filesystem::path& rel_path) : TestFileHandle(rel_path) {}
176 
177   private:
178     android::base::unique_fd owned_fd_;
Transform__anonec0eb9cf0111::ReadOnlyTestFileHandle179     android::base::Result<borrowed_fd> Transform(const std::filesystem::path&,
180                                                  android::base::unique_fd read_fd) override {
181         owned_fd_ = std::move(read_fd);
182         return owned_fd_;
183     }
184 };
185 
186 // A TestFileHandle where the test file is copies, hence read-writable.
187 struct ReadWriteTestFileHandle : TestFileHandle {
ReadWriteTestFileHandle__anonec0eb9cf0111::ReadWriteTestFileHandle188     ReadWriteTestFileHandle(const std::filesystem::path& rel_path) : TestFileHandle(rel_path) {}
189 
190   private:
191     std::unique_ptr<TemporaryFile> temp_file_;
192 
Transform__anonec0eb9cf0111::ReadWriteTestFileHandle193     android::base::Result<borrowed_fd> Transform(const std::filesystem::path& abs_path,
194                                                  android::base::unique_fd read_fd) override {
195         // Make a copy to avoid writing to test data. Test files are small, so it is okay
196         // to read the whole file.
197         auto content = ReadStartOfFdToString(read_fd, abs_path);
198         if (!content.ok()) return content.error();
199         temp_file_ = std::make_unique<TemporaryFile>();
200         if (temp_file_->fd == -1)
201             return ErrnoError() << "copy " << abs_path << ": open temp file failed";
202         if (!android::base::WriteStringToFd(*content, temp_file_->fd))
203             return ErrnoError() << "copy " << abs_path << ": write temp file failed";
204 
205         return temp_file_->fd;
206     }
207 };
208 
209 class RepackVendorBootImgTestEnv : public ::testing::Environment {
210   public:
SetUp()211     virtual void SetUp() {
212         OpenTestFile("test_dtb.img", &dtb, &dtb_content);
213         OpenTestFile("test_bootconfig.img", &bootconfig, &bootconfig_content);
214         OpenTestFile("test_vendor_ramdisk_none.img", &none, &none_content);
215         OpenTestFile("test_vendor_ramdisk_platform.img", &platform, &platform_content);
216         OpenTestFile("test_vendor_ramdisk_replace.img", &replace, &replace_content);
217     }
218 
219     std::unique_ptr<TestFileHandle> dtb;
220     std::string dtb_content;
221     std::unique_ptr<TestFileHandle> bootconfig;
222     std::string bootconfig_content;
223     std::unique_ptr<TestFileHandle> none;
224     std::string none_content;
225     std::unique_ptr<TestFileHandle> platform;
226     std::string platform_content;
227     std::unique_ptr<TestFileHandle> replace;
228     std::string replace_content;
229 
230   private:
OpenTestFile(const char * rel_path,std::unique_ptr<TestFileHandle> * handle,std::string * content)231     void OpenTestFile(const char* rel_path, std::unique_ptr<TestFileHandle>* handle,
232                       std::string* content) {
233         *handle = std::make_unique<ReadOnlyTestFileHandle>(rel_path);
234         ASSERT_RESULT_OK((*handle)->Open());
235         auto content_res = (*handle)->Read();
236         ASSERT_RESULT_OK(content_res);
237         *content = *content_res;
238     }
239 };
240 RepackVendorBootImgTestEnv* env = nullptr;
241 
242 struct RepackVendorBootImgTestParam {
243     std::string vendor_boot_file_name;
244     std::string dtb_file_name;
245     uint32_t expected_header_version;
operator <<(std::ostream & os,const RepackVendorBootImgTestParam & param)246     friend std::ostream& operator<<(std::ostream& os, const RepackVendorBootImgTestParam& param) {
247         return os << param.vendor_boot_file_name;
248     }
249 };
250 
251 class RepackVendorBootImgTest : public ::testing::TestWithParam<RepackVendorBootImgTestParam> {
252   public:
SetUp()253     virtual void SetUp() {
254         vboot = std::make_unique<ReadWriteTestFileHandle>(GetParam().vendor_boot_file_name);
255         ASSERT_RESULT_OK(vboot->Open());
256 
257         if (!GetParam().dtb_file_name.empty()) {
258             dtb_replacement = std::make_unique<ReadOnlyTestFileHandle>(GetParam().dtb_file_name);
259             ASSERT_RESULT_OK(dtb_replacement->Open());
260         }
261     }
262     std::unique_ptr<TestFileHandle> vboot;
263     std::unique_ptr<TestFileHandle> dtb_replacement;
264 };
265 
TEST_P(RepackVendorBootImgTest,InvalidSize)266 TEST_P(RepackVendorBootImgTest, InvalidSize) {
267     EXPECT_ERROR(
268             replace_vendor_ramdisk(vboot->fd(), vboot->size() + 1, "default", env->replace->fd(),
269                                    env->replace->size(),
270                                    !GetParam().dtb_file_name.empty() ? dtb_replacement->fd()
271                                                                      : android::base::unique_fd(-1),
272                                    !GetParam().dtb_file_name.empty() ? dtb_replacement->size() : 0),
273             HasSubstr("Size of vendor boot does not match"));
274     EXPECT_ERROR(
275             replace_vendor_ramdisk(vboot->fd(), vboot->size(), "default", env->replace->fd(),
276                                    env->replace->size() + 1,
277                                    !GetParam().dtb_file_name.empty() ? dtb_replacement->fd()
278                                                                      : android::base::unique_fd(-1),
279                                    !GetParam().dtb_file_name.empty() ? dtb_replacement->size() : 0),
280             HasSubstr("Size of new vendor ramdisk does not match"));
281     if (!GetParam().dtb_file_name.empty()) {
282         EXPECT_ERROR(replace_vendor_ramdisk(vboot->fd(), vboot->size(), "default",
283                                             env->replace->fd(), env->replace->size(),
284                                             dtb_replacement->fd(), dtb_replacement->size() + 1),
285                      HasSubstr("Size of new dtb does not match"));
286     }
287     EXPECT_ERROR(
288             replace_vendor_ramdisk(
289                     vboot->fd(), vboot->size(), "default", env->replace->fd(), env->replace->size(),
290                     android::base::unique_fd(std::numeric_limits<int32_t>::max()), 1),
291             HasSubstr("Can't seek to the beginning of new dtb image"));
292 }
293 
TEST_P(RepackVendorBootImgTest,ReplaceUnknown)294 TEST_P(RepackVendorBootImgTest, ReplaceUnknown) {
295     auto res = replace_vendor_ramdisk(
296             vboot->fd(), vboot->size(), "unknown", env->replace->fd(), env->replace->size(),
297             !GetParam().dtb_file_name.empty() ? dtb_replacement->fd()
298                                               : android::base::unique_fd(-1),
299             !GetParam().dtb_file_name.empty() ? dtb_replacement->size() : 0);
300     if (GetParam().expected_header_version == 3) {
301         EXPECT_ERROR(res, Eq("Require vendor boot header V4 but is V3"));
302     } else if (GetParam().expected_header_version == 4) {
303         EXPECT_ERROR(res, Eq("Vendor ramdisk 'unknown' not found"));
304     }
305 }
306 
TEST_P(RepackVendorBootImgTest,ReplaceDefault)307 TEST_P(RepackVendorBootImgTest, ReplaceDefault) {
308     auto old_content = vboot->Read();
309     ASSERT_RESULT_OK(old_content);
310 
311     ASSERT_RESULT_OK(replace_vendor_ramdisk(
312             vboot->fd(), vboot->size(), "default", env->replace->fd(), env->replace->size(),
313             !GetParam().dtb_file_name.empty() ? dtb_replacement->fd()
314                                               : android::base::unique_fd(-1),
315             !GetParam().dtb_file_name.empty() ? dtb_replacement->size() : 0));
316     EXPECT_RESULT(vboot->fsize(), vboot->size()) << "File size should not change after repack";
317 
318     auto new_content_res = vboot->Read();
319     ASSERT_RESULT_OK(new_content_res);
320     std::string_view new_content(*new_content_res);
321 
322     auto hdr = reinterpret_cast<const vendor_boot_img_hdr_v3*>(new_content.data());
323     ASSERT_EQ(0, memcmp(VENDOR_BOOT_MAGIC, hdr->magic, VENDOR_BOOT_MAGIC_SIZE));
324     ASSERT_EQ(GetParam().expected_header_version, hdr->header_version);
325     EXPECT_EQ(hdr->vendor_ramdisk_size, env->replace->size());
326     if (GetParam().dtb_file_name.empty()) {
327         EXPECT_EQ(hdr->dtb_size, env->dtb->size());
328     } else {
329         EXPECT_EQ(hdr->dtb_size, dtb_replacement->size());
330     }
331 
332     auto o = round_up(sizeof(vendor_boot_img_hdr_v3), hdr->page_size);
333     auto p = round_up(hdr->vendor_ramdisk_size, hdr->page_size);
334     auto q = round_up(hdr->dtb_size, hdr->page_size);
335 
336     EXPECT_THAT(new_content.substr(o, p), IsPadded(env->replace_content));
337     if (GetParam().dtb_file_name.empty()) {
338         EXPECT_THAT(new_content.substr(o + p, q), IsPadded(env->dtb_content));
339     } else {
340         auto dtb_content_res = dtb_replacement->Read();
341         EXPECT_THAT(new_content.substr(o + p, q), IsPadded(*dtb_content_res));
342     }
343 
344     if (hdr->header_version < 4) return;
345 
346     auto hdr_v4 = static_cast<const vendor_boot_img_hdr_v4*>(hdr);
347     EXPECT_EQ(hdr_v4->vendor_ramdisk_table_entry_num, 1);
348     EXPECT_EQ(hdr_v4->vendor_ramdisk_table_size, 1 * hdr_v4->vendor_ramdisk_table_entry_size);
349     EXPECT_GE(hdr_v4->vendor_ramdisk_table_entry_size, sizeof(vendor_ramdisk_table_entry_v4));
350     auto entry = reinterpret_cast<const vendor_ramdisk_table_entry_v4*>(&new_content[o + p + q]);
351     EXPECT_EQ(entry->ramdisk_offset, 0);
352     EXPECT_EQ(entry->ramdisk_size, hdr_v4->vendor_ramdisk_size);
353     EXPECT_EQ(entry->ramdisk_type, VENDOR_RAMDISK_TYPE_NONE);
354 
355     EXPECT_EQ(hdr_v4->bootconfig_size, env->bootconfig->size());
356     auto r = round_up(hdr_v4->vendor_ramdisk_table_size, hdr_v4->page_size);
357     auto s = round_up(hdr_v4->bootconfig_size, hdr_v4->page_size);
358     EXPECT_THAT(new_content.substr(o + p + q + r, s), IsPadded(env->bootconfig_content));
359 
360     EXPECT_THAT(new_content, HasSameAvbFooter(*old_content));
361 }
362 
363 INSTANTIATE_TEST_SUITE_P(
364         RepackVendorBootImgTest, RepackVendorBootImgTest,
365         ::testing::Values(RepackVendorBootImgTestParam{"vendor_boot_v3.img", "", 3},
366                           RepackVendorBootImgTestParam{"vendor_boot_v4_with_frag.img", "", 4},
367                           RepackVendorBootImgTestParam{"vendor_boot_v4_without_frag.img", "", 4},
368                           RepackVendorBootImgTestParam{"vendor_boot_v4_with_frag.img",
369                                                        "dtb_replace.img", 4},
370                           RepackVendorBootImgTestParam{"vendor_boot_v4_without_frag.img",
371                                                        "dtb_replace.img", 4}),
__anonec0eb9cf0202(const auto& info) 372         [](const auto& info) {
373             std::string test_name =
374                     android::base::StringReplace(info.param.vendor_boot_file_name, ".", "_", false);
375             return test_name + (!info.param.dtb_file_name.empty() ? "_replace_dtb" : "");
376         });
377 
GetRamdiskName(const vendor_ramdisk_table_entry_v4 * entry)378 std::string_view GetRamdiskName(const vendor_ramdisk_table_entry_v4* entry) {
379     auto ramdisk_name = reinterpret_cast<const char*>(entry->ramdisk_name);
380     return std::string_view(ramdisk_name, strnlen(ramdisk_name, VENDOR_RAMDISK_NAME_SIZE));
381 }
382 
383 class RepackVendorBootImgTestV4 : public ::testing::TestWithParam<uint32_t /* ramdisk type */> {
384   public:
SetUp()385     virtual void SetUp() {
386         vboot = std::make_unique<ReadWriteTestFileHandle>("vendor_boot_v4_with_frag.img");
387         ASSERT_RESULT_OK(vboot->Open());
388     }
389     std::unique_ptr<TestFileHandle> vboot;
390 };
391 
TEST_P(RepackVendorBootImgTestV4,Replace)392 TEST_P(RepackVendorBootImgTestV4, Replace) {
393     uint32_t replace_ramdisk_type = GetParam();
394     std::string replace_ramdisk_name;
395     std::string expect_new_ramdisk_content;
396     uint32_t expect_none_size = env->none->size();
397     uint32_t expect_platform_size = env->platform->size();
398     switch (replace_ramdisk_type) {
399         case VENDOR_RAMDISK_TYPE_NONE:
400             replace_ramdisk_name = "none_ramdisk";
401             expect_new_ramdisk_content = env->replace_content + env->platform_content;
402             expect_none_size = env->replace->size();
403             break;
404         case VENDOR_RAMDISK_TYPE_PLATFORM:
405             replace_ramdisk_name = "platform_ramdisk";
406             expect_new_ramdisk_content = env->none_content + env->replace_content;
407             expect_platform_size = env->replace->size();
408             break;
409         default:
410             LOG(FATAL) << "Ramdisk type " << replace_ramdisk_type
411                        << " is not supported by this test.";
412     }
413 
414     auto old_content = vboot->Read();
415     ASSERT_RESULT_OK(old_content);
416 
417     ASSERT_RESULT_OK(replace_vendor_ramdisk(vboot->fd(), vboot->size(), replace_ramdisk_name,
418                                             env->replace->fd(), env->replace->size(),
419                                             android::base::unique_fd(-1), 0));
420     EXPECT_RESULT(vboot->fsize(), vboot->size()) << "File size should not change after repack";
421 
422     auto new_content_res = vboot->Read();
423     ASSERT_RESULT_OK(new_content_res);
424     std::string_view new_content(*new_content_res);
425 
426     auto hdr = reinterpret_cast<const vendor_boot_img_hdr_v4*>(new_content.data());
427     ASSERT_EQ(0, memcmp(VENDOR_BOOT_MAGIC, hdr->magic, VENDOR_BOOT_MAGIC_SIZE));
428     ASSERT_EQ(4, hdr->header_version);
429     EXPECT_EQ(hdr->vendor_ramdisk_size, expect_none_size + expect_platform_size);
430     EXPECT_EQ(hdr->dtb_size, env->dtb->size());
431     EXPECT_EQ(hdr->bootconfig_size, env->bootconfig->size());
432 
433     auto o = round_up(sizeof(vendor_boot_img_hdr_v3), hdr->page_size);
434     auto p = round_up(hdr->vendor_ramdisk_size, hdr->page_size);
435     auto q = round_up(hdr->dtb_size, hdr->page_size);
436     auto r = round_up(hdr->vendor_ramdisk_table_size, hdr->page_size);
437     auto s = round_up(hdr->bootconfig_size, hdr->page_size);
438 
439     EXPECT_THAT(new_content.substr(o, p), IsPadded(expect_new_ramdisk_content));
440     EXPECT_THAT(new_content.substr(o + p, q), IsPadded(env->dtb_content));
441 
442     // Check changes in table.
443     EXPECT_EQ(hdr->vendor_ramdisk_table_entry_num, 2);
444     EXPECT_EQ(hdr->vendor_ramdisk_table_size, 2 * hdr->vendor_ramdisk_table_entry_size);
445     EXPECT_GE(hdr->vendor_ramdisk_table_entry_size, sizeof(vendor_ramdisk_table_entry_v4));
446     auto entry_none =
447             reinterpret_cast<const vendor_ramdisk_table_entry_v4*>(&new_content[o + p + q]);
448     EXPECT_EQ(entry_none->ramdisk_offset, 0);
449     EXPECT_EQ(entry_none->ramdisk_size, expect_none_size);
450     EXPECT_EQ(entry_none->ramdisk_type, VENDOR_RAMDISK_TYPE_NONE);
451     EXPECT_EQ(GetRamdiskName(entry_none), "none_ramdisk");
452 
453     auto entry_platform = reinterpret_cast<const vendor_ramdisk_table_entry_v4*>(
454             &new_content[o + p + q + hdr->vendor_ramdisk_table_entry_size]);
455     EXPECT_EQ(entry_platform->ramdisk_offset, expect_none_size);
456     EXPECT_EQ(entry_platform->ramdisk_size, expect_platform_size);
457     EXPECT_EQ(entry_platform->ramdisk_type, VENDOR_RAMDISK_TYPE_PLATFORM);
458     EXPECT_EQ(GetRamdiskName(entry_platform), "platform_ramdisk");
459 
460     EXPECT_THAT(new_content.substr(o + p + q + r, s), IsPadded(env->bootconfig_content));
461 
462     EXPECT_THAT(new_content, HasSameAvbFooter(*old_content));
463 }
464 INSTANTIATE_TEST_SUITE_P(RepackVendorBootImgTest, RepackVendorBootImgTestV4,
465                          ::testing::Values(VENDOR_RAMDISK_TYPE_NONE, VENDOR_RAMDISK_TYPE_PLATFORM),
__anonec0eb9cf0302(const auto& info) 466                          [](const auto& info) {
467                              return info.param == VENDOR_RAMDISK_TYPE_NONE ? "none" : "platform";
468                          });
469 
470 }  // namespace
471 
main(int argc,char * argv[])472 int main(int argc, char* argv[]) {
473     ::testing::InitGoogleTest(&argc, argv);
474     env = static_cast<RepackVendorBootImgTestEnv*>(
475             testing::AddGlobalTestEnvironment(new RepackVendorBootImgTestEnv));
476     return RUN_ALL_TESTS();
477 }
478