1 // Copyright 2015 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/bsdiff.h" 6 7 #include <gtest/gtest.h> 8 #include <algorithm> 9 #include <random> 10 #include <string> 11 #include <vector> 12 13 #include "bsdiff/fake_patch_writer.h" 14 15 namespace { 16 17 // Generate deterministic random data in the output buffer. The buffer must be 18 // already allocated with the desired size. The data generated depends on the 19 // selected size. 20 void GenerateRandomBuffer(std::vector<uint8_t>* buffer) { 21 std::minstd_rand prng(1234 + buffer->size()); 22 std::generate(buffer->begin(), buffer->end(), prng); 23 } 24 25 } // namespace 26 27 namespace bsdiff { 28 29 class BsdiffTest : public testing::Test { 30 protected: 31 BsdiffTest() = default; 32 ~BsdiffTest() override = default; 33 34 void RunBsdiff() { 35 EXPECT_EQ(0, bsdiff(old_file_.data(), old_file_.size(), new_file_.data(), 36 new_file_.size(), min_len_, &patch_writer_, nullptr)); 37 } 38 39 std::vector<uint8_t> old_file_; 40 std::vector<uint8_t> new_file_; 41 size_t min_len_ = 0; // 0 means the default. 42 FakePatchWriter patch_writer_; 43 }; 44 45 // Check that a file with no changes has a very small patch (no extra data). 46 TEST_F(BsdiffTest, EqualEmptyFiles) { 47 // Empty old and new files. 48 RunBsdiff(); 49 50 // No entries should be generated on an empty new file. 51 EXPECT_TRUE(patch_writer_.entries().empty()); 52 } 53 54 TEST_F(BsdiffTest, EqualSmallFiles) { 55 std::string some_text = "Hello world!"; 56 old_file_.insert(old_file_.begin(), some_text.begin(), some_text.end()); 57 new_file_.insert(new_file_.begin(), some_text.begin(), some_text.end()); 58 RunBsdiff(); 59 60 EXPECT_EQ(1U, patch_writer_.entries().size()); 61 ControlEntry entry = patch_writer_.entries()[0]; 62 EXPECT_EQ(some_text.size(), entry.diff_size); 63 EXPECT_EQ(0U, entry.extra_size); 64 } 65 66 TEST_F(BsdiffTest, FileWithSmallErrorsTest) { 67 old_file_.resize(100); 68 GenerateRandomBuffer(&old_file_); 69 new_file_ = old_file_; 70 // Break a few bytes somewhere in the middle. 71 new_file_[20]++; 72 new_file_[30] += 2; 73 new_file_[31] += 2; 74 75 RunBsdiff(); 76 77 // We expect that the result has only one entry with all in the diff stream 78 // since the two files are very similar. 79 EXPECT_EQ(1U, patch_writer_.entries().size()); 80 ControlEntry entry = patch_writer_.entries()[0]; 81 EXPECT_EQ(100U, entry.diff_size); 82 EXPECT_EQ(0U, entry.extra_size); 83 } 84 85 TEST_F(BsdiffTest, MinLengthConsideredTest) { 86 old_file_.resize(100); 87 GenerateRandomBuffer(&old_file_); 88 new_file_ = old_file_; 89 // Copy the first 10 bytes to the middle. 90 for (size_t i = 0; i < 10; i++) { 91 new_file_[50 + i] = old_file_[i]; 92 } 93 94 min_len_ = 12; 95 RunBsdiff(); 96 97 // We expect that the 10 bytes in the middle that match the beginning are 98 // ignored and just emitted as diff data because the min_len is bigger than 99 // 10. 100 EXPECT_EQ(1U, patch_writer_.entries().size()); 101 ControlEntry entry = patch_writer_.entries()[0]; 102 EXPECT_EQ(100U, entry.diff_size); 103 EXPECT_EQ(0U, entry.extra_size); 104 } 105 106 } // namespace bsdiff 107