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 if (ret != 0) { 88 PATCH_LOGE("Failed to read patch file"); 89 return -1; 90 } 91 ret = PatchMapFile(oldName, oldData); 92 if (ret != 0) { 93 PATCH_LOGE("Failed to read old file"); 94 return -1; 95 } 96 97 PATCH_LOGI("UpdateApplyPatch::ApplyPatch patchData %zu oldData %zu ", patchData.length, oldData.length); 98 // check if image patch 99 if (memcmp(patchData.memory, UpdatePatch::PKGDIFF_MAGIC, 100 std::char_traits<char>::length(UpdatePatch::PKGDIFF_MAGIC)) == 0) { 101 UpdatePatch::PatchParam param {}; 102 param.patch = patchData.memory; 103 param.patchSize = patchData.length; 104 param.oldBuff = oldData.memory; 105 param.oldSize = oldData.length; 106 ret = UpdatePatch::UpdateApplyPatch::ApplyImagePatch(param, empty, writer, expected); 107 if (ret != 0) { 108 PATCH_LOGE("Failed to apply image patch file"); 109 return -1; 110 } 111 } 112 return 0; 113 } 114 ImgageDiffPatchFileTest2(size_t limit,const std::string & oldFile,const std::string & newFile,const std::string & patchFile,const std::string & restoreFile) const115 int ImgageDiffPatchFileTest2(size_t limit, const std::string &oldFile, 116 const std::string &newFile, const std::string &patchFile, const std::string &restoreFile) const 117 { 118 int32_t ret = UpdatePatch::UpdateDiff::DiffImage(limit, TEST_PATH_FROM + oldFile, 119 TEST_PATH_FROM + newFile, TEST_PATH_FROM + patchFile); 120 EXPECT_EQ(0, ret); 121 122 std::string expected = GeneraterHash(TEST_PATH_FROM + newFile); 123 std::unique_ptr<UpdatePatch::FilePatchWriter> writer = 124 std::make_unique<UpdatePatch::FilePatchWriter>(TEST_PATH_FROM + restoreFile); 125 if (writer == nullptr) { 126 PATCH_LOGE("Failed to create writer"); 127 return -1; 128 } 129 writer->Init(); 130 131 ret = TestApplyPatch(TEST_PATH_FROM + patchFile, TEST_PATH_FROM + oldFile, expected, 132 [&](size_t start, const UpdatePatch::BlockBuffer &data, size_t size) -> int { 133 return writer->Write(start, data, size); 134 }); 135 EXPECT_EQ(0, ret); 136 writer->Finish(); 137 std::string restoreHash = GeneraterHash(TEST_PATH_FROM + restoreFile); 138 EXPECT_EQ(0, restoreHash.compare(expected)); 139 return 0; 140 } 141 TestApplyBlockPatch(const std::string & patchName,const std::string & oldName,const std::string & newName,bool isBuffer) const142 int32_t TestApplyBlockPatch(const std::string &patchName, 143 const std::string &oldName, const std::string &newName, bool isBuffer) const 144 { 145 PATCH_DEBUG("UpdateApplyPatch::ApplyPatch : %s ", patchName.c_str()); 146 std::vector<uint8_t> empty; 147 UpdatePatch::MemMapInfo patchData {}; 148 UpdatePatch::MemMapInfo oldData {}; 149 int32_t ret = PatchMapFile(patchName, patchData); 150 if (ret != 0) { 151 PATCH_LOGE("Failed to read patch file"); 152 return -1; 153 } 154 ret = PatchMapFile(oldName, oldData); 155 if (ret != 0) { 156 PATCH_LOGE("Failed to read old file"); 157 return -1; 158 } 159 160 PATCH_LOGI("TestApplyBlockPatch patchData %zu oldData %zu ", patchData.length, oldData.length); 161 UpdatePatch::PatchBuffer patchInfo = {patchData.memory, 0, patchData.length}; 162 UpdatePatch::BlockBuffer oldInfo = {oldData.memory, oldData.length}; 163 if (isBuffer) { 164 std::vector<uint8_t> newData; 165 ret = UpdatePatch::UpdateApplyPatch::ApplyBlockPatch(patchInfo, oldInfo, newData); 166 if (ret != 0) { 167 PATCH_LOGE("Failed to apply block patch file"); 168 return -1; 169 } 170 std::ofstream stream(newName, std::ios::out | std::ios::binary); 171 if (stream.fail()) { 172 PATCH_LOGE("Failed to open %s", newName.c_str()); 173 return -1; 174 } 175 stream.write(reinterpret_cast<const char*>(newData.data()), newData.size()); 176 } else { 177 std::unique_ptr<UpdatePatch::FilePatchWriter> writer = 178 std::make_unique<UpdatePatch::FilePatchWriter>(newName); 179 if (writer == nullptr) { 180 PATCH_LOGE("Failed to create writer"); 181 return -1; 182 } 183 writer->Init(); 184 185 ret = UpdatePatch::UpdateApplyPatch::ApplyBlockPatch(patchInfo, oldInfo, writer.get()); 186 EXPECT_EQ(0, ret); 187 writer->Finish(); 188 } 189 return 0; 190 } 191 BlockDiffPatchTest2(const std::string & oldFile,const std::string & newFile,const std::string & patchFile,const std::string & restoreFile,bool isBuffer) const192 int BlockDiffPatchTest2(const std::string &oldFile, 193 const std::string &newFile, const std::string &patchFile, const std::string &restoreFile, bool isBuffer) const 194 { 195 int32_t ret = UpdatePatch::UpdateDiff::DiffBlock(TEST_PATH_FROM + oldFile, 196 TEST_PATH_FROM + newFile, TEST_PATH_FROM + patchFile); 197 EXPECT_EQ(0, ret); 198 199 ret = TestApplyBlockPatch(TEST_PATH_FROM + patchFile, 200 TEST_PATH_FROM + oldFile, TEST_PATH_FROM + restoreFile, isBuffer); 201 EXPECT_EQ(0, ret); 202 203 std::string expected = GeneraterHash(TEST_PATH_FROM + newFile); 204 std::string restoreHash = GeneraterHash(TEST_PATH_FROM + restoreFile); 205 EXPECT_EQ(0, memcmp(expected.c_str(), restoreHash.c_str(), restoreHash.size())); 206 return 0; 207 } 208 }; 209 210 HWTEST_F(DiffPatchUnitTest, BlockDiffPatchTest, TestSize.Level1) 211 { 212 DiffPatchUnitTest test; 213 EXPECT_EQ(0, test.BlockDiffPatchTest( 214 "../diffpatch/patchtest.old", 215 "../diffpatch/patchtest.new", 216 "../diffpatch/patchtest.patch", 217 "../diffpatch/patchtest.new_1")); 218 } 219 220 HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchFileTest, TestSize.Level1) 221 { 222 DiffPatchUnitTest test; 223 EXPECT_EQ(0, test.ImgageDiffPatchFileTest(0, 224 "../diffpatch/patchtest.old", 225 "../diffpatch/patchtest.new", 226 "../diffpatch/patchtest.img_patch", 227 "../diffpatch/patchtest.new_2")); 228 } 229 230 HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchFileWithLimit, TestSize.Level1) 231 { 232 DiffPatchUnitTest test; 233 EXPECT_EQ(0, test.ImgageDiffPatchFileTest(16, 234 "../diffpatch/patchtest.old", 235 "../diffpatch/patchtest.new", 236 "../diffpatch/patchtest.img_patch", 237 "../diffpatch/patchtest.new_3")); 238 } 239 240 HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchGzFile, TestSize.Level1) 241 { 242 DiffPatchUnitTest test; 243 EXPECT_EQ(0, test.ImgageDiffPatchFileTest(0, 244 "../diffpatch/PatchGztest_old.gz", 245 "../diffpatch/PatchGztest_new.gz", 246 "../diffpatch/PatchGztest_gz.img_patch", 247 "../diffpatch/PatchGztest_gz_new.zip")); 248 } 249 250 HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchLz4File, TestSize.Level1) 251 { 252 DiffPatchUnitTest test; 253 EXPECT_EQ(0, test.ImgageDiffPatchFileTest(0, 254 "../diffpatch/PatchLz4test_old.lz4", 255 "../diffpatch/PatchLz4test_new.lz4", 256 "../diffpatch/PatchLz4test_lz4.img_patch", 257 "../diffpatch/PatchLz4test_lz4_new.lz")); 258 } 259 260 HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchLz4File_1, TestSize.Level1) 261 { 262 DiffPatchUnitTest test; 263 EXPECT_EQ(0, test.ImgageDiffPatchFileTest(0, 264 "../diffpatch/ImgageDiffPatchLz4File_1_old.lz", 265 "../diffpatch/ImgageDiffPatchLz4File_1_new.lz", 266 "../diffpatch/ImgageDiffPatchLz4File_1_lz4.img_patch", 267 "../diffpatch/ImgageDiffPatchLz4File_1_lz4_new.lz")); 268 } 269 270 HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchLz4File_2, TestSize.Level1) 271 { 272 DiffPatchUnitTest test; 273 EXPECT_EQ(0, test.ImgageDiffPatchFileTest(1, 274 "../diffpatch/ImgageDiffPatchLz4File_1_old.lz", 275 "../diffpatch/ImgageDiffPatchLz4File_1_new.lz", 276 "../diffpatch/ImgageDiffPatchLz4File_1_lz4.img_patch", 277 "../diffpatch/ImgageDiffPatchLz4File_1_lz4_new.lz")); 278 } 279 280 HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchLz4File_3, TestSize.Level1) 281 { 282 DiffPatchUnitTest test; 283 EXPECT_EQ(0, test.ImgageDiffPatchFileTest(0, 284 "../diffpatch/ImgageDiffPatchLz4File_3_old.lz4", 285 "../diffpatch/ImgageDiffPatchLz4File_3_new.lz4", 286 "../diffpatch/ImgageDiffPatchLz4File_3_lz4.img_patch", 287 "../diffpatch/ImgageDiffPatchLz4File_3_lz4_new.lz")); 288 } 289 290 // 测试包含一个文件时,新增一个文件 291 HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchZipFile, TestSize.Level1) 292 { 293 DiffPatchUnitTest test; 294 EXPECT_EQ(0, test.ImgageDiffPatchFileTest(0, 295 "../diffpatch/ImgageDiffPatchZipFile_old.zip", 296 "../diffpatch/ImgageDiffPatchZipFile_new.zip", 297 "../diffpatch/ImgageDiffPatchZipFile_zip.img_patch", 298 "../diffpatch/ImgageDiffPatchZipFile_zip_new.zip")); 299 } 300 301 // 测试使用winrar的压缩文件 302 HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchZipFile_1, TestSize.Level1) 303 { 304 DiffPatchUnitTest test; 305 EXPECT_EQ(0, test.ImgageDiffPatchFileTest(0, 306 "../diffpatch/ImgageDiffPatchZipFile_1_old.zip", 307 "../diffpatch/ImgageDiffPatchZipFile_1_new.zip", 308 "../diffpatch/ImgageDiffPatchZipFile_1_zip.img_patch", 309 "../diffpatch/ImgageDiffPatchZipFile_1_zip_new.zip")); 310 } 311 312 // 测试包含一个文件时,文件内容不相同 313 HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchZipFile_2, TestSize.Level1) 314 { 315 DiffPatchUnitTest test; 316 EXPECT_EQ(0, test.ImgageDiffPatchFileTest(0, 317 "../diffpatch/ImgageDiffPatchZipFile_2_old.zip", 318 "../diffpatch/ImgageDiffPatchZipFile_2_new.zip", 319 "../diffpatch/ImgageDiffPatchZipFile_2_zip.img_patch", 320 "../diffpatch/ImgageDiffPatchZipFile_2_zip_new.zip")); 321 } 322 323 // linux 上压缩,多文件测试 324 HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchZipFile_3, TestSize.Level1) 325 { 326 DiffPatchUnitTest test; 327 EXPECT_EQ(0, test.ImgageDiffPatchFileTest(0, 328 "../diffpatch/ImgageDiffPatchZipFile_3_old.zip", 329 "../diffpatch/ImgageDiffPatchZipFile_3_new.zip", 330 "../diffpatch/ImgageDiffPatchZipFile_3_zip.img_patch", 331 "../diffpatch/ImgageDiffPatchZipFile_3_zip_new.zip")); 332 } 333 334 // linux 上压缩,超大buffer length测试 335 HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchZipFile_4, TestSize.Level1) 336 { 337 DiffPatchUnitTest test; 338 EXPECT_EQ(0, test.ImgageDiffPatchFileTest(0, 339 "../diffpatch/ImgageDiffPatchZipFile_4_old.zip", 340 "../diffpatch/ImgageDiffPatchZipFile_4_new.zip", 341 "../diffpatch/ImgageDiffPatchZipFile_4_zip.img_patch", 342 "../diffpatch/ImgageDiffPatchZipFile_4_zip_new.zip")); 343 } 344 345 HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchGzFile2, TestSize.Level1) 346 { 347 DiffPatchUnitTest test; 348 EXPECT_EQ(0, test.ImgageDiffPatchFileTest2(0, 349 "../diffpatch/PatchGztest_old.gz", 350 "../diffpatch/PatchGztest_new.gz", 351 "../diffpatch/PatchGztest_gz.img_patch", 352 "../diffpatch/PatchGztest_gz_new.zip")); 353 } 354 355 HWTEST_F(DiffPatchUnitTest, BlockDiffPatchGzFile, TestSize.Level1) 356 { 357 DiffPatchUnitTest test; 358 EXPECT_EQ(0, test.BlockDiffPatchTest2( 359 "../diffpatch/PatchGztest_old.gz", 360 "../diffpatch/PatchGztest_new.gz", 361 "../diffpatch/PatchGztest_gz.img_patch", 362 "../diffpatch/PatchGztest_gz_new.zip", true)); 363 } 364 365 HWTEST_F(DiffPatchUnitTest, BlockDiffPatchGzFile_1, TestSize.Level1) 366 { 367 DiffPatchUnitTest test; 368 EXPECT_EQ(0, test.BlockDiffPatchTest2( 369 "../diffpatch/PatchGztest_old.gz", 370 "../diffpatch/PatchGztest_new.gz", 371 "../diffpatch/PatchGztest_gz.img_patch", 372 "../diffpatch/PatchGztest_gz_new.zip", false)); 373 } 374 375 HWTEST_F(DiffPatchUnitTest, BlockDiffPatchLz4File, TestSize.Level1) 376 { 377 DiffPatchUnitTest test; 378 EXPECT_EQ(0, test.BlockDiffPatchTest2( 379 "../diffpatch/PatchLz4test_old.lz4", 380 "../diffpatch/PatchLz4test_new.lz4", 381 "../diffpatch/PatchLz4test_lz4.img_patch", 382 "../diffpatch/PatchLz4test_lz4_new.lz", true)); 383 } 384 385 HWTEST_F(DiffPatchUnitTest, BlockDiffPatchLz4File_1, TestSize.Level1) 386 { 387 DiffPatchUnitTest test; 388 EXPECT_EQ(0, test.BlockDiffPatchTest2( 389 "../diffpatch/PatchLz4test_old.lz4", 390 "../diffpatch/PatchLz4test_new.lz4", 391 "../diffpatch/PatchLz4test_lz4.img_patch", 392 "../diffpatch/PatchLz4test_lz4_new.lz", false)); 393 } 394 395 HWTEST_F(DiffPatchUnitTest, BlockDiffPatchTest_0, TestSize.Level1) 396 { 397 DiffPatchUnitTest test; 398 EXPECT_EQ(0, test.BlockDiffPatchTest2( 399 "../diffpatch/patchtest.old", 400 "../diffpatch/patchtest.new", 401 "../diffpatch/patchtest.img_patch", 402 "../diffpatch/patchtest.new_2", true)); 403 } 404 405 HWTEST_F(DiffPatchUnitTest, BlockDiffPatchTest_1, TestSize.Level1) 406 { 407 DiffPatchUnitTest test; 408 EXPECT_EQ(0, test.BlockDiffPatchTest2( 409 "../diffpatch/patchtest.old", 410 "../diffpatch/patchtest.new", 411 "../diffpatch/patchtest.img_patch", 412 "../diffpatch/patchtest.new_2", false)); 413 } 414 415 HWTEST_F(DiffPatchUnitTest, BlockDiffPatchTest_2, TestSize.Level1) 416 { 417 std::vector<uint8_t> testDate; 418 testDate.push_back('a'); 419 EXPECT_EQ(0, UpdatePatch::WriteDataToFile("BlockDiffPatchTest_2.txt", testDate, testDate.size())); 420 } 421 422 HWTEST_F(DiffPatchUnitTest, PatchMapFileTest, TestSize.Level1) 423 { 424 UpdatePatch::MemMapInfo data{}; 425 string filePath = TEST_PATH_FROM + "diffpatch/non_exist.file"; 426 EXPECT_EQ(-1, UpdatePatch::PatchMapFile(filePath, data)); 427 } 428 } 429