1 // Copyright 2021 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <string>
6 #include <vector>
7
8 #include "gtest/gtest.h"
9
10 #include "puffin/memory_stream.h"
11 #include "puffin/src/include/puffin/puffdiff.h"
12 #include "puffin/src/include/puffin/puffpatch.h"
13 #include "puffin/src/include/puffin/utils.h"
14 #include "puffin/src/puffin_stream.h"
15 #include "puffin/src/unittest_common.h"
16
17 namespace puffin {
18
19 namespace {
20 // xxd -i <name>.zip
21 const Buffer kTestZipA = {
22 0x50, 0x4b, 0x03, 0x04, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x79,
23 0x0d, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
24 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x31, 0x55, 0x54, 0x09, 0x00, 0x03,
25 0x5c, 0xed, 0x16, 0x61, 0x5c, 0xed, 0x16, 0x61, 0x75, 0x78, 0x0b, 0x00,
26 0x01, 0x04, 0x8f, 0x66, 0x05, 0x00, 0x04, 0x53, 0x5f, 0x01, 0x00, 0x50,
27 0x4b, 0x01, 0x02, 0x1e, 0x03, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e,
28 0x79, 0x0d, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
29 0x00, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
30 0x00, 0x00, 0x00, 0xa4, 0x81, 0x00, 0x00, 0x00, 0x00, 0x31, 0x55, 0x54,
31 0x05, 0x00, 0x03, 0x5c, 0xed, 0x16, 0x61, 0x75, 0x78, 0x0b, 0x00, 0x01,
32 0x04, 0x8f, 0x66, 0x05, 0x00, 0x04, 0x53, 0x5f, 0x01, 0x00, 0x50, 0x4b,
33 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x47, 0x00,
34 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00};
35
36 const Buffer kTestZipB = {
37 0x50, 0x4b, 0x03, 0x04, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x79,
38 0x0d, 0x53, 0x4e, 0x81, 0x88, 0x47, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00,
39 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x32, 0x55, 0x54, 0x09, 0x00, 0x03,
40 0x88, 0xed, 0x16, 0x61, 0x88, 0xed, 0x16, 0x61, 0x75, 0x78, 0x0b, 0x00,
41 0x01, 0x04, 0x8f, 0x66, 0x05, 0x00, 0x04, 0x53, 0x5f, 0x01, 0x00, 0x61,
42 0x62, 0x63, 0x0a, 0x50, 0x4b, 0x01, 0x02, 0x1e, 0x03, 0x0a, 0x00, 0x00,
43 0x00, 0x00, 0x00, 0x26, 0x79, 0x0d, 0x53, 0x4e, 0x81, 0x88, 0x47, 0x04,
44 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00,
45 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa4, 0x81, 0x00, 0x00, 0x00,
46 0x00, 0x32, 0x55, 0x54, 0x05, 0x00, 0x03, 0x88, 0xed, 0x16, 0x61, 0x75,
47 0x78, 0x0b, 0x00, 0x01, 0x04, 0x8f, 0x66, 0x05, 0x00, 0x04, 0x53, 0x5f,
48 0x01, 0x00, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
49 0x01, 0x00, 0x47, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00};
50
51 } // namespace
52
53 class PuffinIntegrationTest : public testing::TestWithParam<PatchAlgorithm> {
54 protected:
getPatchType()55 PatchAlgorithm getPatchType() { return GetParam(); }
56 };
57
TEST_P(PuffinIntegrationTest,PuffinDiffPatchTest)58 TEST_P(PuffinIntegrationTest, PuffinDiffPatchTest) {
59 std::vector<BitExtent> src_deflates;
60 ASSERT_TRUE(LocateDeflatesInZipArchive(kTestZipA, &src_deflates));
61
62 std::vector<BitExtent> dst_deflates;
63 ASSERT_TRUE(LocateDeflatesInZipArchive(kTestZipB, &dst_deflates));
64
65 std::string tmp_file;
66 ASSERT_TRUE(MakeTempFile(&tmp_file, nullptr));
67 Buffer patch;
68 ASSERT_TRUE(PuffDiff(MemoryStream::CreateForRead(kTestZipA),
69 MemoryStream::CreateForRead(kTestZipB), src_deflates,
70 dst_deflates, {bsdiff::CompressorType::kBrotli},
71 getPatchType(), tmp_file, &patch));
72
73 Buffer patched;
74 auto src_stream = MemoryStream::CreateForRead(kTestZipA);
75 auto dst_stream = MemoryStream::CreateForWrite(&patched);
76 ASSERT_TRUE(PuffPatch(MemoryStream::CreateForRead(kTestZipA),
77 MemoryStream::CreateForWrite(&patched), patch.data(),
78 patch.size()));
79
80 ASSERT_EQ(kTestZipB, patched);
81 }
82
83 INSTANTIATE_TEST_CASE_P(TestWithPatchType,
84 PuffinIntegrationTest,
85 testing::Values(PatchAlgorithm::kBsdiff,
86 PatchAlgorithm::kZucchini));
87
88 } // namespace puffin