/* * Copyright (c) 2021 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "bzip2_adapter.h" #include "diffpatch.h" #include "lz4_adapter.h" #include "unittest_comm.h" #include "update_patch.h" #include "zip_adapter.h" using namespace std; using namespace Hpackage; using namespace UpdatePatch; using namespace testing::ext; namespace { #define LZ4_BLOCK_SIZE(blockId) (1 << (8 + (2 * (blockId)))) class TestPatchWriter : public UpdatePatchWriter { public: explicit TestPatchWriter(std::vector &buffer) : UpdatePatchWriter(), buffer_(buffer) {} ~TestPatchWriter() override {} int32_t Init() override { return 0; }; int32_t Finish() override { return 0; }; int32_t Write(size_t start, const BlockBuffer &data, size_t len) override { if (len == 0) { return 0; } bufferSize += len; if ((start + bufferSize) > buffer_.size()) { buffer_.resize(IGMDIFF_LIMIT_UNIT * ((start + bufferSize) / IGMDIFF_LIMIT_UNIT + 1)); } return memcpy_s(buffer_.data() + start, buffer_.size(), data.buffer, len); } private: size_t bufferSize {0}; std::vector &buffer_; }; class BZip2AdapterUnitTest : public testing::Test { public: BZip2AdapterUnitTest() {} ~BZip2AdapterUnitTest() {} static void SetUpTestCase(void) {} static void TearDownTestCase(void) {} void SetUp() {} void TearDown() {} void TestBody() {} public: int BZip2AdapterBufferTest() const { MemMapInfo data {}; std::string fileName = TEST_PATH_FROM; fileName += "test_script.us"; int32_t ret = PatchMapFile(fileName, data); EXPECT_EQ(0, ret); std::vector compressedData; BZipBuffer2Adapter adapter(compressedData, 0); adapter.Open(); // compress data 1 BlockBuffer srcData = {data.memory, data.length}; ret = adapter.WriteData(srcData); EXPECT_EQ(0, ret); size_t compressedData1 = 0; ret = adapter.FlushData(compressedData1); EXPECT_EQ(0, ret); adapter.Close(); // compress data 2 BZipBuffer2Adapter adapter2(compressedData, compressedData1); adapter2.Open(); ret = adapter2.WriteData(srcData); EXPECT_EQ(0, ret); size_t compressedData2 = 0; ret = adapter2.FlushData(compressedData2); EXPECT_EQ(0, ret); adapter2.Close(); PATCH_LOGI("compressedData size %zu %zu %zu", compressedData.size(), compressedData1, compressedData2); // decompress data 1 BlockBuffer compressedInfo = {compressedData.data(), compressedData.size()}; BZip2BufferReadAdapter readAdapter(0, compressedData1, compressedInfo); readAdapter.Open(); std::vector dataArray(data.length); BlockBuffer data1 = {dataArray.data(), data.length}; ret = readAdapter.ReadData(data1); EXPECT_EQ(0, ret); EXPECT_EQ(0, memcmp(data1.buffer, data.memory, data1.length)); // decompress data 2 BZip2BufferReadAdapter readAdapter2(compressedData1, compressedData2, compressedInfo); readAdapter2.Open(); ret = readAdapter2.ReadData(data1); EXPECT_EQ(0, ret); EXPECT_EQ(0, memcmp(data1.buffer, data.memory, data1.length)); adapter.Close(); readAdapter.Close(); return 0; } int BZip2AdapterAddMoreTest() const { MemMapInfo data {}; std::string fileName = TEST_PATH_FROM; fileName += "test_script.us"; int32_t ret = PatchMapFile(fileName, data); EXPECT_EQ(0, ret); std::vector compressedData; BZipBuffer2Adapter adapter(compressedData, 0); adapter.Open(); // compress data 1 BlockBuffer srcData = {data.memory, data.length}; ret = adapter.WriteData(srcData); EXPECT_EQ(0, ret); // compress data 2 ret = adapter.WriteData(srcData); EXPECT_EQ(0, ret); // compress data 3 ret = adapter.WriteData(srcData); EXPECT_EQ(0, ret); size_t compressedData1 = 0; ret = adapter.FlushData(compressedData1); EXPECT_EQ(0, ret); adapter.Close(); PATCH_LOGI("compressedData size %zu %zu", compressedData.size(), compressedData1); BlockBuffer compressedInfo = {compressedData.data(), compressedData.size()}; BZip2BufferReadAdapter readAdapter(0, compressedData1, compressedInfo); readAdapter.Open(); // decompress data 1 std::vector dataArray(data.length); BlockBuffer data1 = {dataArray.data(), data.length}; ret = readAdapter.ReadData(data1); EXPECT_EQ(0, ret); EXPECT_EQ(0, memcmp(data1.buffer, data.memory, data1.length)); // decompress data 2 ret = readAdapter.ReadData(data1); EXPECT_EQ(0, ret); EXPECT_EQ(0, memcmp(data1.buffer, data.memory, data1.length)); // decompress data 3 ret = readAdapter.ReadData(data1); EXPECT_EQ(0, ret); EXPECT_EQ(0, memcmp(data1.buffer, data.memory, data1.length)); adapter.Close(); readAdapter.Close(); return 0; } int32_t CompressData(Hpackage::PkgManager::FileInfoPtr info, const BlockBuffer &buffer, std::vector &outData, size_t &bufferSize) { Hpackage::PkgManager *pkgManager = Hpackage::PkgManager::CreatePackageInstance(); if (pkgManager == nullptr) { PATCH_LOGE("Can not get manager "); return -1; } Hpackage::PkgManager::StreamPtr stream1 = nullptr; pkgManager->CreatePkgStream(stream1, "gzip", [&outData, &bufferSize](const PkgBuffer &data, size_t size, size_t start, bool isFinish, const void *context) ->int { if (isFinish) { return 0; } bufferSize += size; if ((start + bufferSize) > outData.size()) { outData.resize(IGMDIFF_LIMIT_UNIT * ((start + bufferSize) / IGMDIFF_LIMIT_UNIT + 1)); } return memcpy_s(outData.data() + start, outData.size(), data.buffer, size); }, nullptr); if (pkgManager->CompressBuffer(info, {buffer.buffer, buffer.length}, stream1) != 0) { PATCH_LOGE("Can not Compress buff "); Hpackage::PkgManager::ReleasePackageInstance(pkgManager); return -1; } PATCH_DEBUG("UpdateDiff::MakePatch totalSize: %zu", bufferSize); Hpackage::PkgManager::ReleasePackageInstance(pkgManager); return 0; } int DeflateAdapterTest(const std::string &fileName, Hpackage::PkgManager::FileInfoPtr info) { std::vector outData; size_t dataSize = 0; std::unique_ptr testPatchWriter(new TestPatchWriter(outData)); if (testPatchWriter == nullptr) { PATCH_LOGE("Failed to create data writer"); return -1; } MemMapInfo memInfo {}; if (PatchMapFile(TEST_PATH_FROM + fileName, memInfo) != 0) { PATCH_LOGE("Failed to map file"); return -1; } std::vector outData1; size_t dataSize1 = 0; if (CompressData(info, {memInfo.memory, memInfo.length}, outData1, dataSize1) != 0) { PATCH_LOGE("Failed to compress file"); return -1; } info->unpackedSize = memInfo.length; std::unique_ptr deflateAdapter; if (info->packMethod == PKG_COMPRESS_METHOD_ZIP) { deflateAdapter.reset(new ZipAdapter(testPatchWriter.get(), 0, info)); } else if (info->packMethod == PKG_COMPRESS_METHOD_LZ4) { deflateAdapter.reset(new Lz4FrameAdapter(testPatchWriter.get(), 0, info)); } else if (info->packMethod == PKG_COMPRESS_METHOD_LZ4_BLOCK) { deflateAdapter.reset(new Lz4BlockAdapter(testPatchWriter.get(), 0, info)); } if (deflateAdapter == nullptr) { PATCH_LOGE("Failed to create deflate adapter"); return -1; } deflateAdapter->Open(); size_t offset = 0; while (offset < memInfo.length) { size_t writeSize = (memInfo.length > (offset + DeflateAdapter::BUFFER_SIZE)) ? DeflateAdapter::BUFFER_SIZE : (memInfo.length - offset); BlockBuffer data = {memInfo.memory + offset, writeSize}; if (deflateAdapter->WriteData(data) != 0) { PATCH_LOGE("Failed to compress data"); return -1; } offset += writeSize; } deflateAdapter->FlushData(dataSize); // compare if (dataSize == dataSize1 && memcmp(outData.data(), outData1.data(), dataSize1) == 0) { return 0; } return 1; } }; HWTEST_F(BZip2AdapterUnitTest, BZip2AdapterBufferTest, TestSize.Level1) { BZip2AdapterUnitTest test; EXPECT_EQ(0, test.BZip2AdapterBufferTest()); } HWTEST_F(BZip2AdapterUnitTest, BZip2AdapterAddMoreTest, TestSize.Level1) { BZip2AdapterUnitTest test; EXPECT_EQ(0, test.BZip2AdapterAddMoreTest()); } HWTEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForZip, TestSize.Level1) { ZipFileInfo zipInfo {}; zipInfo.fileInfo.packMethod = PKG_COMPRESS_METHOD_ZIP; zipInfo.method = 8; zipInfo.level = 6; zipInfo.windowBits = -15; zipInfo.memLevel = 8; zipInfo.strategy = 0; BZip2AdapterUnitTest test; EXPECT_EQ(0, test.DeflateAdapterTest("../diffpatch/patchtest.new", &zipInfo.fileInfo)); } HWTEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4, TestSize.Level1) { Lz4FileInfo lz4Info {}; lz4Info.fileInfo.packMethod = PKG_COMPRESS_METHOD_LZ4; lz4Info.compressionLevel = 2; lz4Info.blockIndependence = 0; lz4Info.contentChecksumFlag = 0; lz4Info.blockSizeID = 0; BZip2AdapterUnitTest test; EXPECT_EQ(0, test.DeflateAdapterTest("../diffpatch/patchtest.test", &lz4Info.fileInfo)); } HWTEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4_2, TestSize.Level1) { Lz4FileInfo lz4Info {}; lz4Info.fileInfo.packMethod = PKG_COMPRESS_METHOD_LZ4; lz4Info.compressionLevel = 2; lz4Info.blockIndependence = 0; lz4Info.contentChecksumFlag = 0; lz4Info.blockSizeID = 7; BZip2AdapterUnitTest test; EXPECT_EQ(0, test.DeflateAdapterTest("../diffpatch/patchtest.test", &lz4Info.fileInfo)); } HWTEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4_3, TestSize.Level1) { Lz4FileInfo lz4Info {}; lz4Info.fileInfo.packMethod = PKG_COMPRESS_METHOD_LZ4; lz4Info.compressionLevel = 2; lz4Info.blockIndependence = 0; lz4Info.contentChecksumFlag = 0; lz4Info.blockSizeID = 4; BZip2AdapterUnitTest test; EXPECT_EQ(0, test.DeflateAdapterTest("../diffpatch/patchtest.test", &lz4Info.fileInfo)); } HWTEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4_4, TestSize.Level1) { Lz4FileInfo lz4Info {}; lz4Info.fileInfo.packMethod = PKG_COMPRESS_METHOD_LZ4; lz4Info.compressionLevel = 2; lz4Info.blockIndependence = 0; lz4Info.contentChecksumFlag = 0; lz4Info.blockSizeID = 5; BZip2AdapterUnitTest test; EXPECT_EQ(0, test.DeflateAdapterTest("../diffpatch/patchtest.test", &lz4Info.fileInfo)); } HWTEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4_5, TestSize.Level1) { Lz4FileInfo lz4Info {}; lz4Info.fileInfo.packMethod = PKG_COMPRESS_METHOD_LZ4; lz4Info.compressionLevel = 2; lz4Info.blockIndependence = 0; lz4Info.contentChecksumFlag = 0; lz4Info.blockSizeID = 5; lz4Info.autoFlush = 0; BZip2AdapterUnitTest test; EXPECT_EQ(0, test.DeflateAdapterTest("../diffpatch/patchtest.test", &lz4Info.fileInfo)); } HWTEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4Block, TestSize.Level1) { Lz4FileInfo lz4Info {}; lz4Info.fileInfo.packMethod = PKG_COMPRESS_METHOD_LZ4_BLOCK; lz4Info.compressionLevel = 2; lz4Info.blockIndependence = 1; lz4Info.contentChecksumFlag = 1; lz4Info.blockSizeID = 5; BZip2AdapterUnitTest test; EXPECT_EQ(0, test.DeflateAdapterTest("../diffpatch/patchtest.test", &lz4Info.fileInfo)); } HWTEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4Block_2, TestSize.Level1) { Lz4FileInfo lz4Info {}; lz4Info.fileInfo.packMethod = PKG_COMPRESS_METHOD_LZ4_BLOCK; lz4Info.compressionLevel = 5; lz4Info.blockIndependence = 1; lz4Info.contentChecksumFlag = 1; lz4Info.blockSizeID = 5; BZip2AdapterUnitTest test; EXPECT_EQ(0, test.DeflateAdapterTest("../diffpatch/patchtest.test", &lz4Info.fileInfo)); } HWTEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4Block_3, TestSize.Level1) { Lz4FileInfo lz4Info {}; lz4Info.fileInfo.packMethod = PKG_COMPRESS_METHOD_LZ4_BLOCK; lz4Info.compressionLevel = 5; lz4Info.blockIndependence = 1; lz4Info.contentChecksumFlag = 1; lz4Info.blockSizeID = 0; BZip2AdapterUnitTest test; EXPECT_EQ(0, test.DeflateAdapterTest("../diffpatch/patchtest.test", &lz4Info.fileInfo)); } HWTEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4Block_4, TestSize.Level1) { DeflateAdapter adapterTest; BlockBuffer srcTestData; size_t offTest = 0; adapterTest.Open(); EXPECT_EQ(0, adapterTest.WriteData(srcTestData)); EXPECT_EQ(0, adapterTest.FlushData(offTest)); } }