1 /* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #include <gtest/gtest.h> 17 #include "applypatch/data_writer.h" 18 #include "unittest_comm.h" 19 #include "update_diff.h" 20 #include "update_patch.h" 21 22 using namespace std; 23 using namespace Hpackage; 24 using namespace testing::ext; 25 26 namespace { 27 class DiffPatchUnitTest : public testing::Test { 28 public: DiffPatchUnitTest()29 DiffPatchUnitTest() {} ~DiffPatchUnitTest()30 ~DiffPatchUnitTest() {} 31 SetUpTestCase(void)32 static void SetUpTestCase(void) {} TearDownTestCase(void)33 static void TearDownTestCase(void) {} SetUp()34 void SetUp() {} TearDown()35 void TearDown() {} TestBody()36 void TestBody() {} 37 public: GeneraterHash(const std::string & fileName) const38 std::string GeneraterHash(const std::string &fileName) const 39 { 40 UpdatePatch::MemMapInfo data {}; 41 int32_t ret = PatchMapFile(fileName, data); 42 EXPECT_EQ(0, ret); 43 return UpdatePatch::GeneraterBufferHash({data.memory, data.length}); 44 } 45 BlockDiffPatchTest(const std::string & oldFile,const std::string & newFile,const std::string & patchFile,const std::string & restoreFile) const46 int BlockDiffPatchTest(const std::string &oldFile, 47 const std::string &newFile, const std::string &patchFile, const std::string &restoreFile) const 48 { 49 int32_t ret = UpdatePatch::UpdateDiff::DiffBlock(TEST_PATH_FROM + oldFile, 50 TEST_PATH_FROM + newFile, TEST_PATH_FROM + patchFile); 51 EXPECT_EQ(0, ret); 52 ret = UpdatePatch::UpdateApplyPatch::ApplyPatch(TEST_PATH_FROM + patchFile, 53 TEST_PATH_FROM + oldFile, TEST_PATH_FROM + restoreFile); 54 EXPECT_EQ(0, ret); 55 56 std::string expected = GeneraterHash(TEST_PATH_FROM + newFile); 57 std::string restoreHash = GeneraterHash(TEST_PATH_FROM + restoreFile); 58 EXPECT_EQ(0, memcmp(expected.c_str(), restoreHash.c_str(), restoreHash.size())); 59 return 0; 60 } 61 ImgageDiffPatchFileTest(size_t limit,const std::string & oldFile,const std::string & newFile,const std::string & patchFile,const std::string & restoreFile) const62 int ImgageDiffPatchFileTest(size_t limit, const std::string &oldFile, 63 const std::string &newFile, const std::string &patchFile, const std::string &restoreFile) const 64 { 65 int32_t ret = UpdatePatch::UpdateDiff::DiffImage(limit, TEST_PATH_FROM + oldFile, 66 TEST_PATH_FROM + newFile, TEST_PATH_FROM + patchFile); 67 EXPECT_EQ(0, ret); 68 ret = UpdatePatch::UpdateApplyPatch::ApplyPatch(TEST_PATH_FROM + patchFile, 69 TEST_PATH_FROM + oldFile, TEST_PATH_FROM + restoreFile); 70 EXPECT_EQ(0, ret); 71 72 // 生成新文件的hash值 73 std::string expected = GeneraterHash(TEST_PATH_FROM + newFile); 74 std::string restoreHash = GeneraterHash(TEST_PATH_FROM + restoreFile); 75 EXPECT_EQ(0, restoreHash.compare(expected)); 76 return 0; 77 } 78 TestApplyPatch(const std::string & patchName,const std::string & oldName,const std::string & expected,UpdatePatch::UpdateApplyPatch::ImageProcessor writer) const79 int32_t TestApplyPatch(const std::string &patchName, const std::string &oldName, 80 const std::string &expected, UpdatePatch::UpdateApplyPatch::ImageProcessor writer) const 81 { 82 PATCH_DEBUG("UpdateApplyPatch::ApplyPatch : %s ", patchName.c_str()); 83 std::vector<uint8_t> empty; 84 UpdatePatch::MemMapInfo patchData {}; 85 UpdatePatch::MemMapInfo oldData {}; 86 int32_t ret = PatchMapFile(patchName, patchData); 87 PATCH_CHECK(ret == 0, return -1, "Failed to read patch file"); 88 ret = PatchMapFile(oldName, oldData); 89 PATCH_CHECK(ret == 0, return -1, "Failed to read old file"); 90 91 PATCH_LOGI("UpdateApplyPatch::ApplyPatch patchData %zu oldData %zu ", patchData.length, oldData.length); 92 // check if image patch 93 if (memcmp(patchData.memory, UpdatePatch::PKGDIFF_MAGIC, 94 std::char_traits<char>::length(UpdatePatch::PKGDIFF_MAGIC)) == 0) { 95 UpdatePatch::PatchParam param {}; 96 param.patch = patchData.memory; 97 param.patchSize = patchData.length; 98 param.oldBuff = oldData.memory; 99 param.oldSize = oldData.length; 100 ret = UpdatePatch::UpdateApplyPatch::ApplyImagePatch(param, empty, writer, expected); 101 PATCH_CHECK(ret == 0, return -1, "Failed to apply image patch file"); 102 } 103 return 0; 104 } 105 ImgageDiffPatchFileTest2(size_t limit,const std::string & oldFile,const std::string & newFile,const std::string & patchFile,const std::string & restoreFile) const106 int ImgageDiffPatchFileTest2(size_t limit, const std::string &oldFile, 107 const std::string &newFile, const std::string &patchFile, const std::string &restoreFile) const 108 { 109 int32_t ret = UpdatePatch::UpdateDiff::DiffImage(limit, TEST_PATH_FROM + oldFile, 110 TEST_PATH_FROM + newFile, TEST_PATH_FROM + patchFile); 111 EXPECT_EQ(0, ret); 112 113 std::string expected = GeneraterHash(TEST_PATH_FROM + newFile); 114 std::unique_ptr<UpdatePatch::FilePatchWriter> writer = 115 std::make_unique<UpdatePatch::FilePatchWriter>(TEST_PATH_FROM + restoreFile); 116 PATCH_CHECK(writer != nullptr, return -1, "Failed to create writer"); 117 writer->Init(); 118 119 ret = TestApplyPatch(TEST_PATH_FROM + patchFile, TEST_PATH_FROM + oldFile, expected, 120 [&](size_t start, const UpdatePatch::BlockBuffer &data, size_t size) -> int { 121 return writer->Write(start, data, size); 122 }); 123 EXPECT_EQ(0, ret); 124 writer->Finish(); 125 std::string restoreHash = GeneraterHash(TEST_PATH_FROM + restoreFile); 126 EXPECT_EQ(0, restoreHash.compare(expected)); 127 return 0; 128 } 129 TestApplyBlockPatch(const std::string & patchName,const std::string & oldName,const std::string & newName,bool isBuffer) const130 int32_t TestApplyBlockPatch(const std::string &patchName, 131 const std::string &oldName, const std::string &newName, bool isBuffer) const 132 { 133 PATCH_DEBUG("UpdateApplyPatch::ApplyPatch : %s ", patchName.c_str()); 134 std::vector<uint8_t> empty; 135 UpdatePatch::MemMapInfo patchData {}; 136 UpdatePatch::MemMapInfo oldData {}; 137 int32_t ret = PatchMapFile(patchName, patchData); 138 PATCH_CHECK(ret == 0, return -1, "Failed to read patch file"); 139 ret = PatchMapFile(oldName, oldData); 140 PATCH_CHECK(ret == 0, return -1, "Failed to read old file"); 141 142 PATCH_LOGI("TestApplyBlockPatch patchData %zu oldData %zu ", patchData.length, oldData.length); 143 UpdatePatch::PatchBuffer patchInfo = {patchData.memory, 0, patchData.length}; 144 UpdatePatch::BlockBuffer oldInfo = {oldData.memory, oldData.length}; 145 if (isBuffer) { 146 std::vector<uint8_t> newData; 147 ret = UpdatePatch::UpdateApplyPatch::ApplyBlockPatch(patchInfo, oldInfo, newData); 148 PATCH_CHECK(ret == 0, return -1, "Failed to apply block patch file"); 149 std::ofstream stream(newName, std::ios::out | std::ios::binary); 150 PATCH_CHECK(!stream.fail(), return -1, "Failed to open %s", newName.c_str()); 151 stream.write(reinterpret_cast<const char*>(newData.data()), newData.size()); 152 } else { 153 std::unique_ptr<UpdatePatch::FilePatchWriter> writer = 154 std::make_unique<UpdatePatch::FilePatchWriter>(newName); 155 PATCH_CHECK(writer != nullptr, return -1, "Failed to create writer"); 156 writer->Init(); 157 158 ret = UpdatePatch::UpdateApplyPatch::ApplyBlockPatch(patchInfo, oldInfo, writer.get()); 159 EXPECT_EQ(0, ret); 160 writer->Finish(); 161 } 162 return 0; 163 } 164 BlockDiffPatchTest2(const std::string & oldFile,const std::string & newFile,const std::string & patchFile,const std::string & restoreFile,bool isBuffer) const165 int BlockDiffPatchTest2(const std::string &oldFile, 166 const std::string &newFile, const std::string &patchFile, const std::string &restoreFile, bool isBuffer) const 167 { 168 int32_t ret = UpdatePatch::UpdateDiff::DiffBlock(TEST_PATH_FROM + oldFile, 169 TEST_PATH_FROM + newFile, TEST_PATH_FROM + patchFile); 170 EXPECT_EQ(0, ret); 171 172 ret = TestApplyBlockPatch(TEST_PATH_FROM + patchFile, 173 TEST_PATH_FROM + oldFile, TEST_PATH_FROM + restoreFile, isBuffer); 174 EXPECT_EQ(0, ret); 175 176 std::string expected = GeneraterHash(TEST_PATH_FROM + newFile); 177 std::string restoreHash = GeneraterHash(TEST_PATH_FROM + restoreFile); 178 EXPECT_EQ(0, memcmp(expected.c_str(), restoreHash.c_str(), restoreHash.size())); 179 return 0; 180 } 181 }; 182 183 HWTEST_F(DiffPatchUnitTest, BlockDiffPatchTest, TestSize.Level1) 184 { 185 DiffPatchUnitTest test; 186 EXPECT_EQ(0, test.BlockDiffPatchTest( 187 "../diffpatch/patchtest.old", 188 "../diffpatch/patchtest.new", 189 "../diffpatch/patchtest.patch", 190 "../diffpatch/patchtest.new_1")); 191 } 192 193 HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchFileTest, TestSize.Level1) 194 { 195 DiffPatchUnitTest test; 196 EXPECT_EQ(0, test.ImgageDiffPatchFileTest(0, 197 "../diffpatch/patchtest.old", 198 "../diffpatch/patchtest.new", 199 "../diffpatch/patchtest.img_patch", 200 "../diffpatch/patchtest.new_2")); 201 } 202 203 HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchFileWithLimit, TestSize.Level1) 204 { 205 DiffPatchUnitTest test; 206 EXPECT_EQ(0, test.ImgageDiffPatchFileTest(16, 207 "../diffpatch/patchtest.old", 208 "../diffpatch/patchtest.new", 209 "../diffpatch/patchtest.img_patch", 210 "../diffpatch/patchtest.new_3")); 211 } 212 213 HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchGzFile, TestSize.Level1) 214 { 215 DiffPatchUnitTest test; 216 EXPECT_EQ(0, test.ImgageDiffPatchFileTest(0, 217 "../diffpatch/PatchGztest_old.gz", 218 "../diffpatch/PatchGztest_new.gz", 219 "../diffpatch/PatchGztest_gz.img_patch", 220 "../diffpatch/PatchGztest_gz_new.zip")); 221 } 222 223 HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchLz4File, TestSize.Level1) 224 { 225 DiffPatchUnitTest test; 226 EXPECT_EQ(0, test.ImgageDiffPatchFileTest(0, 227 "../diffpatch/PatchLz4test_old.lz4", 228 "../diffpatch/PatchLz4test_new.lz4", 229 "../diffpatch/PatchLz4test_lz4.img_patch", 230 "../diffpatch/PatchLz4test_lz4_new.lz")); 231 } 232 233 HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchLz4File_1, TestSize.Level1) 234 { 235 DiffPatchUnitTest test; 236 EXPECT_EQ(0, test.ImgageDiffPatchFileTest(0, 237 "../diffpatch/ImgageDiffPatchLz4File_1_old.lz", 238 "../diffpatch/ImgageDiffPatchLz4File_1_new.lz", 239 "../diffpatch/ImgageDiffPatchLz4File_1_lz4.img_patch", 240 "../diffpatch/ImgageDiffPatchLz4File_1_lz4_new.lz")); 241 } 242 243 HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchLz4File_2, TestSize.Level1) 244 { 245 DiffPatchUnitTest test; 246 EXPECT_EQ(0, test.ImgageDiffPatchFileTest(1, 247 "../diffpatch/ImgageDiffPatchLz4File_1_old.lz", 248 "../diffpatch/ImgageDiffPatchLz4File_1_new.lz", 249 "../diffpatch/ImgageDiffPatchLz4File_1_lz4.img_patch", 250 "../diffpatch/ImgageDiffPatchLz4File_1_lz4_new.lz")); 251 } 252 253 HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchLz4File_3, TestSize.Level1) 254 { 255 DiffPatchUnitTest test; 256 EXPECT_EQ(0, test.ImgageDiffPatchFileTest(0, 257 "../diffpatch/ImgageDiffPatchLz4File_3_old.lz4", 258 "../diffpatch/ImgageDiffPatchLz4File_3_new.lz4", 259 "../diffpatch/ImgageDiffPatchLz4File_3_lz4.img_patch", 260 "../diffpatch/ImgageDiffPatchLz4File_3_lz4_new.lz")); 261 } 262 263 // 测试包含一个文件时,新增一个文件 264 HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchZipFile, TestSize.Level1) 265 { 266 DiffPatchUnitTest test; 267 EXPECT_EQ(0, test.ImgageDiffPatchFileTest(0, 268 "../diffpatch/ImgageDiffPatchZipFile_old.zip", 269 "../diffpatch/ImgageDiffPatchZipFile_new.zip", 270 "../diffpatch/ImgageDiffPatchZipFile_zip.img_patch", 271 "../diffpatch/ImgageDiffPatchZipFile_zip_new.zip")); 272 } 273 274 // 测试使用winrar的压缩文件 275 HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchZipFile_1, TestSize.Level1) 276 { 277 DiffPatchUnitTest test; 278 EXPECT_EQ(0, test.ImgageDiffPatchFileTest(0, 279 "../diffpatch/ImgageDiffPatchZipFile_1_old.zip", 280 "../diffpatch/ImgageDiffPatchZipFile_1_new.zip", 281 "../diffpatch/ImgageDiffPatchZipFile_1_zip.img_patch", 282 "../diffpatch/ImgageDiffPatchZipFile_1_zip_new.zip")); 283 } 284 285 // 测试包含一个文件时,文件内容不相同 286 HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchZipFile_2, TestSize.Level1) 287 { 288 DiffPatchUnitTest test; 289 EXPECT_EQ(0, test.ImgageDiffPatchFileTest(0, 290 "../diffpatch/ImgageDiffPatchZipFile_2_old.zip", 291 "../diffpatch/ImgageDiffPatchZipFile_2_new.zip", 292 "../diffpatch/ImgageDiffPatchZipFile_2_zip.img_patch", 293 "../diffpatch/ImgageDiffPatchZipFile_2_zip_new.zip")); 294 } 295 296 // linux 上压缩,多文件测试 297 HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchZipFile_3, TestSize.Level1) 298 { 299 DiffPatchUnitTest test; 300 EXPECT_EQ(0, test.ImgageDiffPatchFileTest(0, 301 "../diffpatch/ImgageDiffPatchZipFile_3_old.zip", 302 "../diffpatch/ImgageDiffPatchZipFile_3_new.zip", 303 "../diffpatch/ImgageDiffPatchZipFile_3_zip.img_patch", 304 "../diffpatch/ImgageDiffPatchZipFile_3_zip_new.zip")); 305 } 306 307 // linux 上压缩,超大buffer length测试 308 HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchZipFile_4, TestSize.Level1) 309 { 310 DiffPatchUnitTest test; 311 EXPECT_EQ(0, test.ImgageDiffPatchFileTest(0, 312 "../diffpatch/ImgageDiffPatchZipFile_4_old.zip", 313 "../diffpatch/ImgageDiffPatchZipFile_4_new.zip", 314 "../diffpatch/ImgageDiffPatchZipFile_4_zip.img_patch", 315 "../diffpatch/ImgageDiffPatchZipFile_4_zip_new.zip")); 316 } 317 318 HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchGzFile2, TestSize.Level1) 319 { 320 DiffPatchUnitTest test; 321 EXPECT_EQ(0, test.ImgageDiffPatchFileTest2(0, 322 "../diffpatch/PatchGztest_old.gz", 323 "../diffpatch/PatchGztest_new.gz", 324 "../diffpatch/PatchGztest_gz.img_patch", 325 "../diffpatch/PatchGztest_gz_new.zip")); 326 } 327 328 HWTEST_F(DiffPatchUnitTest, BlockDiffPatchGzFile, TestSize.Level1) 329 { 330 DiffPatchUnitTest test; 331 EXPECT_EQ(0, test.BlockDiffPatchTest2( 332 "../diffpatch/PatchGztest_old.gz", 333 "../diffpatch/PatchGztest_new.gz", 334 "../diffpatch/PatchGztest_gz.img_patch", 335 "../diffpatch/PatchGztest_gz_new.zip", true)); 336 } 337 338 HWTEST_F(DiffPatchUnitTest, BlockDiffPatchGzFile_1, TestSize.Level1) 339 { 340 DiffPatchUnitTest test; 341 EXPECT_EQ(0, test.BlockDiffPatchTest2( 342 "../diffpatch/PatchGztest_old.gz", 343 "../diffpatch/PatchGztest_new.gz", 344 "../diffpatch/PatchGztest_gz.img_patch", 345 "../diffpatch/PatchGztest_gz_new.zip", false)); 346 } 347 348 HWTEST_F(DiffPatchUnitTest, BlockDiffPatchLz4File, TestSize.Level1) 349 { 350 DiffPatchUnitTest test; 351 EXPECT_EQ(0, test.BlockDiffPatchTest2( 352 "../diffpatch/PatchLz4test_old.lz4", 353 "../diffpatch/PatchLz4test_new.lz4", 354 "../diffpatch/PatchLz4test_lz4.img_patch", 355 "../diffpatch/PatchLz4test_lz4_new.lz", true)); 356 } 357 358 HWTEST_F(DiffPatchUnitTest, BlockDiffPatchLz4File_1, TestSize.Level1) 359 { 360 DiffPatchUnitTest test; 361 EXPECT_EQ(0, test.BlockDiffPatchTest2( 362 "../diffpatch/PatchLz4test_old.lz4", 363 "../diffpatch/PatchLz4test_new.lz4", 364 "../diffpatch/PatchLz4test_lz4.img_patch", 365 "../diffpatch/PatchLz4test_lz4_new.lz", false)); 366 } 367 368 HWTEST_F(DiffPatchUnitTest, BlockDiffPatchTest_0, TestSize.Level1) 369 { 370 DiffPatchUnitTest test; 371 EXPECT_EQ(0, test.BlockDiffPatchTest2( 372 "../diffpatch/patchtest.old", 373 "../diffpatch/patchtest.new", 374 "../diffpatch/patchtest.img_patch", 375 "../diffpatch/patchtest.new_2", true)); 376 } 377 378 HWTEST_F(DiffPatchUnitTest, BlockDiffPatchTest_1, TestSize.Level1) 379 { 380 DiffPatchUnitTest test; 381 EXPECT_EQ(0, test.BlockDiffPatchTest2( 382 "../diffpatch/patchtest.old", 383 "../diffpatch/patchtest.new", 384 "../diffpatch/patchtest.img_patch", 385 "../diffpatch/patchtest.new_2", false)); 386 } 387 388 HWTEST_F(DiffPatchUnitTest, BlockDiffPatchTest_2, TestSize.Level1) 389 { 390 std::vector<uint8_t> testDate; 391 testDate.push_back('a'); 392 EXPECT_EQ(0, UpdatePatch::WriteDataToFile("BlockDiffPatchTest_2.txt", testDate, testDate.size())); 393 } 394 395 HWTEST_F(DiffPatchUnitTest, PatchMapFileTest, TestSize.Level1) 396 { 397 UpdatePatch::MemMapInfo data{}; 398 string filePath = TEST_PATH_FROM + "diffpatch/non_exist.file"; 399 EXPECT_EQ(-1, UpdatePatch::PatchMapFile(filePath, data)); 400 } 401 } 402