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 "bzip2_adapter.h"
18#include "diffpatch.h"
19#include "lz4_adapter.h"
20#include "unittest_comm.h"
21#include "update_patch.h"
22#include "zip_adapter.h"
23
24using namespace std;
25using namespace Hpackage;
26using namespace UpdatePatch;
27using namespace testing::ext;
28
29namespace {
30#define LZ4_BLOCK_SIZE(blockId) (1 << (8 + (2 * (blockId))))
31
32class TestPatchWriter : public UpdatePatchWriter {
33public:
34    explicit TestPatchWriter(std::vector<uint8_t> &buffer) : UpdatePatchWriter(), buffer_(buffer) {}
35    ~TestPatchWriter() override {}
36
37    int32_t Init() override
38    {
39        return 0;
40    };
41    int32_t Finish() override
42    {
43        return 0;
44    };
45    int32_t Write(size_t start, const BlockBuffer &data, size_t len) override
46    {
47        if (len == 0) {
48            return 0;
49        }
50        bufferSize += len;
51        if ((start + bufferSize) > buffer_.size()) {
52            buffer_.resize(IGMDIFF_LIMIT_UNIT * ((start + bufferSize) / IGMDIFF_LIMIT_UNIT + 1));
53        }
54        return memcpy_s(buffer_.data() + start, buffer_.size(), data.buffer, len);
55    }
56private:
57    size_t bufferSize {0};
58    std::vector<uint8_t> &buffer_;
59};
60
61class BZip2AdapterUnitTest : public testing::Test {
62public:
63    BZip2AdapterUnitTest() {}
64    ~BZip2AdapterUnitTest() {}
65
66    static void SetUpTestCase(void) {}
67    static void TearDownTestCase(void) {}
68    void SetUp() {}
69    void TearDown() {}
70    void TestBody() {}
71public:
72    int BZip2AdapterBufferTest() const
73    {
74        MemMapInfo data {};
75        std::string fileName = TEST_PATH_FROM;
76        fileName += "test_script.us";
77        int32_t ret = PatchMapFile(fileName, data);
78        EXPECT_EQ(0, ret);
79
80        std::vector<uint8_t> compressedData;
81        BZipBuffer2Adapter adapter(compressedData, 0);
82        adapter.Open();
83        // compress data 1
84        BlockBuffer srcData = {data.memory, data.length};
85        ret = adapter.WriteData(srcData);
86        EXPECT_EQ(0, ret);
87        size_t compressedData1 = 0;
88        ret = adapter.FlushData(compressedData1);
89        EXPECT_EQ(0, ret);
90        adapter.Close();
91
92        // compress data 2
93        BZipBuffer2Adapter adapter2(compressedData, compressedData1);
94        adapter2.Open();
95        ret = adapter2.WriteData(srcData);
96        EXPECT_EQ(0, ret);
97        size_t compressedData2 = 0;
98        ret = adapter2.FlushData(compressedData2);
99        EXPECT_EQ(0, ret);
100        adapter2.Close();
101
102        PATCH_LOGI("compressedData size %zu %zu %zu", compressedData.size(), compressedData1, compressedData2);
103        // decompress data 1
104        BlockBuffer compressedInfo = {compressedData.data(), compressedData.size()};
105        BZip2BufferReadAdapter readAdapter(0, compressedData1, compressedInfo);
106        readAdapter.Open();
107
108        std::vector<uint8_t> dataArray(data.length);
109        BlockBuffer data1 = {dataArray.data(), data.length};
110        ret = readAdapter.ReadData(data1);
111        EXPECT_EQ(0, ret);
112        EXPECT_EQ(0, memcmp(data1.buffer, data.memory, data1.length));
113
114        // decompress data 2
115        BZip2BufferReadAdapter readAdapter2(compressedData1, compressedData2, compressedInfo);
116        readAdapter2.Open();
117        ret = readAdapter2.ReadData(data1);
118        EXPECT_EQ(0, ret);
119        EXPECT_EQ(0, memcmp(data1.buffer, data.memory, data1.length));
120
121        adapter.Close();
122        readAdapter.Close();
123        return 0;
124    }
125
126    int BZip2AdapterAddMoreTest() const
127    {
128        MemMapInfo data {};
129        std::string fileName = TEST_PATH_FROM;
130        fileName += "test_script.us";
131        int32_t ret = PatchMapFile(fileName, data);
132        EXPECT_EQ(0, ret);
133
134        std::vector<uint8_t> compressedData;
135        BZipBuffer2Adapter adapter(compressedData, 0);
136        adapter.Open();
137        // compress data 1
138        BlockBuffer srcData = {data.memory, data.length};
139        ret = adapter.WriteData(srcData);
140        EXPECT_EQ(0, ret);
141        // compress data 2
142        ret = adapter.WriteData(srcData);
143        EXPECT_EQ(0, ret);
144        // compress data 3
145        ret = adapter.WriteData(srcData);
146        EXPECT_EQ(0, ret);
147        size_t compressedData1 = 0;
148        ret = adapter.FlushData(compressedData1);
149        EXPECT_EQ(0, ret);
150        adapter.Close();
151
152        PATCH_LOGI("compressedData size %zu %zu", compressedData.size(), compressedData1);
153
154        BlockBuffer compressedInfo = {compressedData.data(), compressedData.size()};
155        BZip2BufferReadAdapter readAdapter(0, compressedData1, compressedInfo);
156        readAdapter.Open();
157
158        // decompress data 1
159        std::vector<uint8_t> dataArray(data.length);
160        BlockBuffer data1 = {dataArray.data(), data.length};
161        ret = readAdapter.ReadData(data1);
162        EXPECT_EQ(0, ret);
163        EXPECT_EQ(0, memcmp(data1.buffer, data.memory, data1.length));
164
165        // decompress data 2
166        ret = readAdapter.ReadData(data1);
167        EXPECT_EQ(0, ret);
168        EXPECT_EQ(0, memcmp(data1.buffer, data.memory, data1.length));
169
170        // decompress data 3
171        ret = readAdapter.ReadData(data1);
172        EXPECT_EQ(0, ret);
173        EXPECT_EQ(0, memcmp(data1.buffer, data.memory, data1.length));
174
175        adapter.Close();
176        readAdapter.Close();
177        return 0;
178    }
179
180    int32_t CompressData(Hpackage::PkgManager::FileInfoPtr info,
181        const BlockBuffer &buffer, std::vector<uint8_t> &outData, size_t &bufferSize)
182    {
183        Hpackage::PkgManager *pkgManager = Hpackage::PkgManager::CreatePackageInstance();
184        if (pkgManager == nullptr) {
185            PATCH_LOGE("Can not get manager ");
186            return -1;
187        }
188        Hpackage::PkgManager::StreamPtr stream1 = nullptr;
189        pkgManager->CreatePkgStream(stream1, "gzip", [&outData, &bufferSize](const PkgBuffer &data,
190            size_t size, size_t start, bool isFinish, const void *context) ->int {
191                if (isFinish) {
192                    return 0;
193                }
194                bufferSize += size;
195                if ((start + bufferSize) > outData.size()) {
196                    outData.resize(IGMDIFF_LIMIT_UNIT * ((start + bufferSize) / IGMDIFF_LIMIT_UNIT + 1));
197                }
198                return memcpy_s(outData.data() + start, outData.size(), data.buffer, size);
199            }, nullptr);
200        if (pkgManager->CompressBuffer(info, {buffer.buffer, buffer.length}, stream1) != 0) {
201            PATCH_LOGE("Can not Compress buff ");
202            Hpackage::PkgManager::ReleasePackageInstance(pkgManager);
203            return -1;
204        }
205        PATCH_DEBUG("UpdateDiff::MakePatch totalSize: %zu", bufferSize);
206        Hpackage::PkgManager::ReleasePackageInstance(pkgManager);
207        return 0;
208    }
209
210    int DeflateAdapterTest(const std::string &fileName, Hpackage::PkgManager::FileInfoPtr info)
211    {
212        std::vector<uint8_t> outData;
213        size_t dataSize = 0;
214        std::unique_ptr<TestPatchWriter> testPatchWriter(new TestPatchWriter(outData));
215        if (testPatchWriter == nullptr) {
216            PATCH_LOGE("Failed to create data writer");
217            return -1;
218        }
219
220        MemMapInfo memInfo {};
221        if (PatchMapFile(TEST_PATH_FROM + fileName, memInfo) != 0) {
222            PATCH_LOGE("Failed to map file");
223            return -1;
224        }
225
226        std::vector<uint8_t> outData1;
227        size_t dataSize1 = 0;
228        if (CompressData(info, {memInfo.memory, memInfo.length}, outData1, dataSize1) != 0) {
229            PATCH_LOGE("Failed to compress file");
230            return -1;
231        }
232
233        info->unpackedSize = memInfo.length;
234
235        std::unique_ptr<DeflateAdapter> deflateAdapter;
236        if (info->packMethod == PKG_COMPRESS_METHOD_ZIP) {
237            deflateAdapter.reset(new ZipAdapter(testPatchWriter.get(), 0, info));
238        } else if (info->packMethod == PKG_COMPRESS_METHOD_LZ4) {
239            deflateAdapter.reset(new Lz4FrameAdapter(testPatchWriter.get(), 0, info));
240        } else if (info->packMethod == PKG_COMPRESS_METHOD_LZ4_BLOCK) {
241            deflateAdapter.reset(new Lz4BlockAdapter(testPatchWriter.get(), 0, info));
242        }
243        if (deflateAdapter == nullptr) {
244            PATCH_LOGE("Failed to create deflate adapter");
245            return -1;
246        }
247        deflateAdapter->Open();
248
249        size_t offset = 0;
250        while (offset < memInfo.length) {
251            size_t writeSize = (memInfo.length > (offset + DeflateAdapter::BUFFER_SIZE)) ?
252                DeflateAdapter::BUFFER_SIZE : (memInfo.length - offset);
253            BlockBuffer data = {memInfo.memory + offset, writeSize};
254            if (deflateAdapter->WriteData(data) != 0) {
255                PATCH_LOGE("Failed to compress data");
256                return -1;
257            }
258            offset += writeSize;
259        }
260        deflateAdapter->FlushData(dataSize);
261
262        // compare
263        if (dataSize == dataSize1 && memcmp(outData.data(), outData1.data(), dataSize1) == 0) {
264            return 0;
265        }
266        return 1;
267    }
268};
269
270HWTEST_F(BZip2AdapterUnitTest, BZip2AdapterBufferTest, TestSize.Level1)
271{
272    BZip2AdapterUnitTest test;
273    EXPECT_EQ(0, test.BZip2AdapterBufferTest());
274}
275
276HWTEST_F(BZip2AdapterUnitTest, BZip2AdapterAddMoreTest, TestSize.Level1)
277{
278    BZip2AdapterUnitTest test;
279    EXPECT_EQ(0, test.BZip2AdapterAddMoreTest());
280}
281
282HWTEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForZip, TestSize.Level1)
283{
284    ZipFileInfo zipInfo {};
285    zipInfo.fileInfo.packMethod = PKG_COMPRESS_METHOD_ZIP;
286    zipInfo.method = 8;
287    zipInfo.level = 6;
288    zipInfo.windowBits = -15;
289    zipInfo.memLevel = 8;
290    zipInfo.strategy = 0;
291    BZip2AdapterUnitTest test;
292    EXPECT_EQ(0, test.DeflateAdapterTest("../diffpatch/patchtest.new", &zipInfo.fileInfo));
293}
294
295HWTEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4, TestSize.Level1)
296{
297    Lz4FileInfo lz4Info {};
298    lz4Info.fileInfo.packMethod = PKG_COMPRESS_METHOD_LZ4;
299    lz4Info.compressionLevel = 2;
300    lz4Info.blockIndependence = 0;
301    lz4Info.contentChecksumFlag = 0;
302    lz4Info.blockSizeID = 0;
303    BZip2AdapterUnitTest test;
304    EXPECT_EQ(0, test.DeflateAdapterTest("../diffpatch/patchtest.test", &lz4Info.fileInfo));
305}
306
307HWTEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4_2, TestSize.Level1)
308{
309    Lz4FileInfo lz4Info {};
310    lz4Info.fileInfo.packMethod = PKG_COMPRESS_METHOD_LZ4;
311    lz4Info.compressionLevel = 2;
312    lz4Info.blockIndependence = 0;
313    lz4Info.contentChecksumFlag = 0;
314    lz4Info.blockSizeID = 7;
315    BZip2AdapterUnitTest test;
316    EXPECT_EQ(0, test.DeflateAdapterTest("../diffpatch/patchtest.test", &lz4Info.fileInfo));
317}
318
319HWTEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4_3, TestSize.Level1)
320{
321    Lz4FileInfo lz4Info {};
322    lz4Info.fileInfo.packMethod = PKG_COMPRESS_METHOD_LZ4;
323    lz4Info.compressionLevel = 2;
324    lz4Info.blockIndependence = 0;
325    lz4Info.contentChecksumFlag = 0;
326    lz4Info.blockSizeID = 4;
327    BZip2AdapterUnitTest test;
328    EXPECT_EQ(0, test.DeflateAdapterTest("../diffpatch/patchtest.test", &lz4Info.fileInfo));
329}
330
331HWTEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4_4, TestSize.Level1)
332{
333    Lz4FileInfo lz4Info {};
334    lz4Info.fileInfo.packMethod = PKG_COMPRESS_METHOD_LZ4;
335    lz4Info.compressionLevel = 2;
336    lz4Info.blockIndependence = 0;
337    lz4Info.contentChecksumFlag = 0;
338    lz4Info.blockSizeID = 5;
339    BZip2AdapterUnitTest test;
340    EXPECT_EQ(0, test.DeflateAdapterTest("../diffpatch/patchtest.test", &lz4Info.fileInfo));
341}
342
343HWTEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4_5, TestSize.Level1)
344{
345    Lz4FileInfo lz4Info {};
346    lz4Info.fileInfo.packMethod = PKG_COMPRESS_METHOD_LZ4;
347    lz4Info.compressionLevel = 2;
348    lz4Info.blockIndependence = 0;
349    lz4Info.contentChecksumFlag = 0;
350    lz4Info.blockSizeID = 5;
351    lz4Info.autoFlush = 0;
352    BZip2AdapterUnitTest test;
353    EXPECT_EQ(0, test.DeflateAdapterTest("../diffpatch/patchtest.test", &lz4Info.fileInfo));
354}
355
356HWTEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4Block, TestSize.Level1)
357{
358    Lz4FileInfo lz4Info {};
359    lz4Info.fileInfo.packMethod = PKG_COMPRESS_METHOD_LZ4_BLOCK;
360    lz4Info.compressionLevel = 2;
361    lz4Info.blockIndependence = 1;
362    lz4Info.contentChecksumFlag = 1;
363    lz4Info.blockSizeID = 5;
364    BZip2AdapterUnitTest test;
365    EXPECT_EQ(0, test.DeflateAdapterTest("../diffpatch/patchtest.test", &lz4Info.fileInfo));
366}
367
368HWTEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4Block_2, TestSize.Level1)
369{
370    Lz4FileInfo lz4Info {};
371    lz4Info.fileInfo.packMethod = PKG_COMPRESS_METHOD_LZ4_BLOCK;
372    lz4Info.compressionLevel = 5;
373    lz4Info.blockIndependence = 1;
374    lz4Info.contentChecksumFlag = 1;
375    lz4Info.blockSizeID = 5;
376    BZip2AdapterUnitTest test;
377    EXPECT_EQ(0, test.DeflateAdapterTest("../diffpatch/patchtest.test", &lz4Info.fileInfo));
378}
379
380HWTEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4Block_3, TestSize.Level1)
381{
382    Lz4FileInfo lz4Info {};
383    lz4Info.fileInfo.packMethod = PKG_COMPRESS_METHOD_LZ4_BLOCK;
384    lz4Info.compressionLevel = 5;
385    lz4Info.blockIndependence = 1;
386    lz4Info.contentChecksumFlag = 1;
387    lz4Info.blockSizeID = 0;
388    BZip2AdapterUnitTest test;
389    EXPECT_EQ(0, test.DeflateAdapterTest("../diffpatch/patchtest.test", &lz4Info.fileInfo));
390}
391
392HWTEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4Block_4, TestSize.Level1)
393{
394    DeflateAdapter adapterTest;
395    BlockBuffer srcTestData;
396    size_t offTest = 0;
397    adapterTest.Open();
398    EXPECT_EQ(0, adapterTest.WriteData(srcTestData));
399    EXPECT_EQ(0, adapterTest.FlushData(offTest));
400}
401}
402