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