Home | History | Annotate | Download | only in bsdiff
      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:
     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 
     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 
     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 
     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 
     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.
     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.
     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 
    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