xref: /aosp_15_r20/external/bsdiff/diff_encoder_unittest.cc (revision a3a45f308bd90ef1a6e6a5e8fb92fe449b895909)
1*a3a45f30SXin Li // Copyright 2017 The Chromium OS Authors. All rights reserved.
2*a3a45f30SXin Li // Use of this source code is governed by a BSD-style license that can be
3*a3a45f30SXin Li // found in the LICENSE file.
4*a3a45f30SXin Li 
5*a3a45f30SXin Li #include "bsdiff/diff_encoder.h"
6*a3a45f30SXin Li 
7*a3a45f30SXin Li #include <memory>
8*a3a45f30SXin Li #include <vector>
9*a3a45f30SXin Li 
10*a3a45f30SXin Li #include <gtest/gtest.h>
11*a3a45f30SXin Li 
12*a3a45f30SXin Li #include "bsdiff/fake_patch_writer.h"
13*a3a45f30SXin Li #include "bsdiff/test_utils.h"
14*a3a45f30SXin Li 
15*a3a45f30SXin Li namespace {
16*a3a45f30SXin Li 
17*a3a45f30SXin Li // Generated with:
18*a3a45f30SXin Li // echo 'Hello World' | hexdump -v -e '"    " 12/1 "0x%02x, " "\n"'
19*a3a45f30SXin Li const uint8_t kHelloWorld[] = {
20*a3a45f30SXin Li     0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x0a,
21*a3a45f30SXin Li };
22*a3a45f30SXin Li 
23*a3a45f30SXin Li }  // namespace
24*a3a45f30SXin Li 
25*a3a45f30SXin Li namespace bsdiff {
26*a3a45f30SXin Li 
27*a3a45f30SXin Li class DiffEncoderTest : public testing::Test {
28*a3a45f30SXin Li  protected:
SetUp()29*a3a45f30SXin Li   void SetUp() {
30*a3a45f30SXin Li     // By default, set the encoder to kHelloWorld to kHelloWorld.
31*a3a45f30SXin Li     diff_encoder_.reset(new DiffEncoder(&fake_patch_, kHelloWorld,
32*a3a45f30SXin Li                                         sizeof(kHelloWorld), kHelloWorld,
33*a3a45f30SXin Li                                         sizeof(kHelloWorld)));
34*a3a45f30SXin Li   }
35*a3a45f30SXin Li 
36*a3a45f30SXin Li   FakePatchWriter fake_patch_;
37*a3a45f30SXin Li   std::unique_ptr<DiffEncoder> diff_encoder_;
38*a3a45f30SXin Li };
39*a3a45f30SXin Li 
TEST_F(DiffEncoderTest,CreateEmptyPatchTest)40*a3a45f30SXin Li TEST_F(DiffEncoderTest, CreateEmptyPatchTest) {
41*a3a45f30SXin Li   diff_encoder_.reset(new DiffEncoder(&fake_patch_, nullptr, 0, nullptr, 0));
42*a3a45f30SXin Li   EXPECT_TRUE(diff_encoder_->Init());
43*a3a45f30SXin Li   EXPECT_TRUE(diff_encoder_->Close());
44*a3a45f30SXin Li 
45*a3a45f30SXin Li   // Both diff and extra stream must be empty stream, and not control entries.
46*a3a45f30SXin Li   EXPECT_EQ(0U, fake_patch_.entries().size());
47*a3a45f30SXin Li   EXPECT_TRUE(fake_patch_.diff_stream().empty());
48*a3a45f30SXin Li   EXPECT_TRUE(fake_patch_.extra_stream().empty());
49*a3a45f30SXin Li }
50*a3a45f30SXin Li 
TEST_F(DiffEncoderTest,AllInExtraStreamTest)51*a3a45f30SXin Li TEST_F(DiffEncoderTest, AllInExtraStreamTest) {
52*a3a45f30SXin Li   diff_encoder_.reset(new DiffEncoder(&fake_patch_, nullptr, 0, kHelloWorld,
53*a3a45f30SXin Li                                       sizeof(kHelloWorld)));
54*a3a45f30SXin Li   EXPECT_TRUE(diff_encoder_->Init());
55*a3a45f30SXin Li 
56*a3a45f30SXin Li   // Write to the extra stream in two parts: first 5 bytes, then the rest.
57*a3a45f30SXin Li   EXPECT_TRUE(diff_encoder_->AddControlEntry(ControlEntry(0, 5, 0)));
58*a3a45f30SXin Li   EXPECT_TRUE(diff_encoder_->AddControlEntry(
59*a3a45f30SXin Li       ControlEntry(0, sizeof(kHelloWorld) - 5, 0)));
60*a3a45f30SXin Li   EXPECT_TRUE(diff_encoder_->Close());
61*a3a45f30SXin Li 
62*a3a45f30SXin Li   EXPECT_EQ(2U, fake_patch_.entries().size());
63*a3a45f30SXin Li   EXPECT_TRUE(fake_patch_.diff_stream().empty());
64*a3a45f30SXin Li   std::vector<uint8_t> hello_world(kHelloWorld,
65*a3a45f30SXin Li                                    kHelloWorld + sizeof(kHelloWorld));
66*a3a45f30SXin Li   EXPECT_EQ(hello_world, fake_patch_.extra_stream());
67*a3a45f30SXin Li }
68*a3a45f30SXin Li 
TEST_F(DiffEncoderTest,AllInDiffStreamTest)69*a3a45f30SXin Li TEST_F(DiffEncoderTest, AllInDiffStreamTest) {
70*a3a45f30SXin Li   EXPECT_TRUE(diff_encoder_->Init());
71*a3a45f30SXin Li   EXPECT_TRUE(
72*a3a45f30SXin Li       diff_encoder_->AddControlEntry(ControlEntry(sizeof(kHelloWorld), 0, 0)));
73*a3a45f30SXin Li   EXPECT_TRUE(diff_encoder_->Close());
74*a3a45f30SXin Li 
75*a3a45f30SXin Li   EXPECT_EQ(std::vector<uint8_t>(sizeof(kHelloWorld), 0),
76*a3a45f30SXin Li             fake_patch_.diff_stream());
77*a3a45f30SXin Li   EXPECT_TRUE(fake_patch_.extra_stream().empty());
78*a3a45f30SXin Li }
79*a3a45f30SXin Li 
TEST_F(DiffEncoderTest,OldPosNegativeErrorTest)80*a3a45f30SXin Li TEST_F(DiffEncoderTest, OldPosNegativeErrorTest) {
81*a3a45f30SXin Li   EXPECT_TRUE(diff_encoder_->Init());
82*a3a45f30SXin Li   // Referencing negative values in oldpos is fine, until you use them.
83*a3a45f30SXin Li   EXPECT_TRUE(diff_encoder_->AddControlEntry(ControlEntry(0, 0, -5)));
84*a3a45f30SXin Li   EXPECT_TRUE(diff_encoder_->AddControlEntry(ControlEntry(0, 0, 2)));
85*a3a45f30SXin Li   EXPECT_FALSE(diff_encoder_->AddControlEntry(ControlEntry(1, 0, 0)));
86*a3a45f30SXin Li }
87*a3a45f30SXin Li 
88*a3a45f30SXin Li // Test that using an oldpos past the end of the file fails.
TEST_F(DiffEncoderTest,OldPosTooBigErrorTest)89*a3a45f30SXin Li TEST_F(DiffEncoderTest, OldPosTooBigErrorTest) {
90*a3a45f30SXin Li   EXPECT_TRUE(diff_encoder_->Init());
91*a3a45f30SXin Li   EXPECT_TRUE(
92*a3a45f30SXin Li       diff_encoder_->AddControlEntry(ControlEntry(0, 0, sizeof(kHelloWorld))));
93*a3a45f30SXin Li   EXPECT_FALSE(diff_encoder_->AddControlEntry(ControlEntry(1, 0, 0)));
94*a3a45f30SXin Li }
95*a3a45f30SXin Li 
96*a3a45f30SXin Li // Test that diffing against a section of the old file past the end of the file
97*a3a45f30SXin Li // fails.
TEST_F(DiffEncoderTest,OldPosPlusSizeTooBigErrorTest)98*a3a45f30SXin Li TEST_F(DiffEncoderTest, OldPosPlusSizeTooBigErrorTest) {
99*a3a45f30SXin Li   EXPECT_TRUE(diff_encoder_->Init());
100*a3a45f30SXin Li   // The oldpos is set to a range inside the word, the we try to copy past the
101*a3a45f30SXin Li   // end of it.
102*a3a45f30SXin Li   EXPECT_TRUE(diff_encoder_->AddControlEntry(
103*a3a45f30SXin Li       ControlEntry(0, 0, sizeof(kHelloWorld) - 3)));
104*a3a45f30SXin Li   EXPECT_FALSE(
105*a3a45f30SXin Li       diff_encoder_->AddControlEntry(ControlEntry(sizeof(kHelloWorld), 0, 0)));
106*a3a45f30SXin Li }
107*a3a45f30SXin Li 
TEST_F(DiffEncoderTest,ExtraStreamTooBigErrorTest)108*a3a45f30SXin Li TEST_F(DiffEncoderTest, ExtraStreamTooBigErrorTest) {
109*a3a45f30SXin Li   EXPECT_TRUE(diff_encoder_->Init());
110*a3a45f30SXin Li   EXPECT_TRUE(diff_encoder_->AddControlEntry(ControlEntry(3, 0, 0)));
111*a3a45f30SXin Li   // This writes too many bytes in the stream because we already have 3 bytes.
112*a3a45f30SXin Li   EXPECT_FALSE(
113*a3a45f30SXin Li       diff_encoder_->AddControlEntry(ControlEntry(0, sizeof(kHelloWorld), 0)));
114*a3a45f30SXin Li }
115*a3a45f30SXin Li 
116*a3a45f30SXin Li }  // namespace bsdiff
117