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/split_patch_writer.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 bsdiff {
     16 
     17 class SplitPatchWriterTest : public testing::Test {
     18  protected:
     19   void SetUpForSize(size_t num_chunks,
     20                     uint64_t new_chunk_size,
     21                     size_t new_size) {
     22     fake_patches_.resize(num_chunks);
     23     std::vector<PatchWriterInterface*> patches;
     24     for (auto& fake_patch : fake_patches_)
     25       patches.push_back(&fake_patch);
     26 
     27     patch_writer_.reset(new SplitPatchWriter(new_chunk_size, patches));
     28     EXPECT_TRUE(patch_writer_->Init(new_size));
     29   }
     30 
     31   std::vector<FakePatchWriter> fake_patches_;
     32   std::unique_ptr<SplitPatchWriter> patch_writer_;
     33 };
     34 
     35 TEST_F(SplitPatchWriterTest, InvalidNumberOfPatchesForSizeTest) {
     36   FakePatchWriter p;
     37   std::vector<PatchWriterInterface*> patches = {&p};
     38   patch_writer_.reset(new SplitPatchWriter(10, patches));
     39   // We should have pass two patches.
     40   EXPECT_FALSE(patch_writer_->Init(15));
     41 }
     42 
     43 // A single empty patch is allowed.
     44 TEST_F(SplitPatchWriterTest, NonSplitEmptyPatchTest) {
     45   SetUpForSize(1, 100, 0);
     46   EXPECT_TRUE(patch_writer_->Close());
     47 
     48   EXPECT_TRUE(fake_patches_[0].entries().empty());
     49 }
     50 
     51 // Leaving patches at the end that are empty is considered an error.
     52 TEST_F(SplitPatchWriterTest, NotAllPatchesWrittenErrorTest) {
     53   SetUpForSize(2, 100, 200);
     54   // We write less than the amount needed for two patches, which should fail.
     55   EXPECT_FALSE(patch_writer_->Close());
     56 }
     57 
     58 TEST_F(SplitPatchWriterTest, MissingDiffBytesErrorTest) {
     59   SetUpForSize(2, 10, 20);
     60 
     61   EXPECT_TRUE(patch_writer_->AddControlEntry(ControlEntry(15, 5, 0)));
     62   std::vector<uint8_t> zeros(20, 0);
     63   // We write 12 diff bytes instead of the expected 15. This should fail on
     64   // Close().
     65   EXPECT_TRUE(patch_writer_->WriteDiffStream(zeros.data(), 12));
     66   EXPECT_TRUE(patch_writer_->WriteExtraStream(zeros.data(), 5));
     67   EXPECT_FALSE(patch_writer_->Close());
     68 }
     69 
     70 TEST_F(SplitPatchWriterTest, MissingExtraBytesErrorTest) {
     71   SetUpForSize(2, 10, 20);
     72 
     73   std::vector<uint8_t> zeros(20, 0);
     74   EXPECT_TRUE(patch_writer_->AddControlEntry(ControlEntry(5, 15, -5)));
     75   EXPECT_TRUE(patch_writer_->WriteDiffStream(zeros.data(), 5));
     76   // We write a little less than the expected 15. This operation should succeed,
     77   // since we could write the rest later.
     78   EXPECT_TRUE(patch_writer_->WriteExtraStream(zeros.data(), 10));
     79   EXPECT_FALSE(patch_writer_->Close());
     80 }
     81 
     82 // Test all sort of corner cases when splitting the ControlEntry across multiple
     83 // patches
     84 TEST_F(SplitPatchWriterTest, SplitControlAcrossSeveralPatchesTest) {
     85   SetUpForSize(4, 10, 40);
     86   // The middle control entry would be split in tree different patches.
     87   EXPECT_TRUE(patch_writer_->AddControlEntry(ControlEntry(5, 1, -5)));
     88   EXPECT_TRUE(patch_writer_->AddControlEntry(ControlEntry(4, 0, -4)));
     89   // old_pos at this point is 0. This is the end of the first patch.
     90   EXPECT_TRUE(patch_writer_->AddControlEntry(ControlEntry(6, 0, -1)));
     91   // old_pos at this point is 5.
     92   EXPECT_TRUE(patch_writer_->AddControlEntry(ControlEntry(1, 18, 2)));
     93   // old_pos at this point is 8.
     94   EXPECT_TRUE(patch_writer_->AddControlEntry(ControlEntry(1, 0, 1)));
     95   EXPECT_TRUE(patch_writer_->AddControlEntry(ControlEntry(4, 0, -5)));
     96 
     97   std::vector<uint8_t> zeros(40, 0);
     98   EXPECT_TRUE(
     99       patch_writer_->WriteDiffStream(zeros.data(), 5 + 4 + 6 + 1 + 1 + 4));
    100   EXPECT_TRUE(patch_writer_->WriteExtraStream(zeros.data(), 1 + 18));
    101   EXPECT_TRUE(patch_writer_->Close());
    102 
    103   EXPECT_EQ((std::vector<ControlEntry>{
    104                 ControlEntry(5, 1, -5),
    105                 ControlEntry(4, 0, 0),  // (4, 0, -4) but the -4 is not needed.
    106             }),
    107             fake_patches_[0].entries());
    108   EXPECT_EQ((std::vector<ControlEntry>{
    109                 // No need for dummy entry because the old_pos is already at 0.
    110                 ControlEntry(6, 0, -1),
    111                 ControlEntry(1, 3, 0),  // the first part of (1, 18, 2)
    112             }),
    113             fake_patches_[1].entries());
    114   EXPECT_EQ((std::vector<ControlEntry>{
    115                 // No need for dummy entry because the first entry is all in
    116                 // the extra stream and this is the last entry.
    117                 ControlEntry(0, 10, 0),  // the middle part of (1, 18, 2)
    118             }),
    119             fake_patches_[2].entries());
    120   EXPECT_EQ((std::vector<ControlEntry>{
    121                 // No need for dummy entry because the first entry is all in
    122                 // the extra stream, so use that.
    123                 ControlEntry(0, 5, 8),  // the last part of (1, 18, 2), plus the
    124                                         // old_pos 5. 8 = 1 + 2 + 5.
    125                 ControlEntry(1, 0, 1),  // (1, 0, 1) copied
    126                 ControlEntry(4, 0, 0),  // (4, 0, -5) ignoring the offset.
    127             }),
    128             fake_patches_[3].entries());
    129 
    130   for (size_t i = 0; i < fake_patches_.size(); ++i) {
    131     EXPECT_EQ(10U, fake_patches_[i].new_size()) << "where i = " << i;
    132   }
    133 }
    134 
    135 TEST_F(SplitPatchWriterTest, WriteStreamsAfterControlAcrossPatchesTest) {
    136   std::vector<uint8_t> numbers(40);
    137   for (size_t i = 0; i < numbers.size(); ++i)
    138     numbers[i] = 'A' + i;
    139 
    140   SetUpForSize(4, 10, 40);
    141   // The sequence is 15 diff, 10 extra, 15 diff.
    142   EXPECT_TRUE(patch_writer_->AddControlEntry(ControlEntry(15, 10, 0)));
    143   EXPECT_TRUE(patch_writer_->AddControlEntry(ControlEntry(15, 0, 0)));
    144   // Numbers [0, 30) for the diff stream, and [30, 40) for the extra stream.
    145   EXPECT_TRUE(patch_writer_->WriteDiffStream(numbers.data(), 30));
    146   EXPECT_TRUE(patch_writer_->WriteExtraStream(numbers.data() + 30, 10));
    147   EXPECT_TRUE(patch_writer_->Close());
    148 
    149   EXPECT_EQ(std::vector<uint8_t>(numbers.begin(), numbers.begin() + 10),
    150             fake_patches_[0].diff_stream());
    151   EXPECT_TRUE(fake_patches_[0].extra_stream().empty());
    152 
    153   // 5 diff, then 5 extra.
    154   EXPECT_EQ(std::vector<uint8_t>(numbers.begin() + 10, numbers.begin() + 15),
    155             fake_patches_[1].diff_stream());
    156   EXPECT_EQ(std::vector<uint8_t>(numbers.begin() + 30, numbers.begin() + 35),
    157             fake_patches_[1].extra_stream());
    158 
    159   // 5 extra, then 5 diff.
    160   EXPECT_EQ(std::vector<uint8_t>(numbers.begin() + 15, numbers.begin() + 20),
    161             fake_patches_[2].diff_stream());
    162   EXPECT_EQ(std::vector<uint8_t>(numbers.begin() + 35, numbers.begin() + 40),
    163             fake_patches_[2].extra_stream());
    164 
    165   EXPECT_EQ(std::vector<uint8_t>(numbers.begin() + 20, numbers.begin() + 30),
    166             fake_patches_[3].diff_stream());
    167   EXPECT_TRUE(fake_patches_[3].extra_stream().empty());
    168 }
    169 
    170 }  // namespace bsdiff
    171