| // Copyright 2015 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "bsdiff/bsdiff.h" |
| |
| #include <gtest/gtest.h> |
| #include <algorithm> |
| #include <random> |
| #include <string> |
| #include <vector> |
| |
| #include "bsdiff/fake_patch_writer.h" |
| |
| namespace { |
| |
| // Generate deterministic random data in the output buffer. The buffer must be |
| // already allocated with the desired size. The data generated depends on the |
| // selected size. |
| void GenerateRandomBuffer(std::vector<uint8_t>* buffer) { |
| std::minstd_rand prng(1234 + buffer->size()); |
| std::generate(buffer->begin(), buffer->end(), prng); |
| } |
| |
| } // namespace |
| |
| namespace bsdiff { |
| |
| class BsdiffTest : public testing::Test { |
| protected: |
| BsdiffTest() = default; |
| ~BsdiffTest() override = default; |
| |
| void RunBsdiff() { |
| EXPECT_EQ(0, bsdiff(old_file_.data(), old_file_.size(), new_file_.data(), |
| new_file_.size(), min_len_, &patch_writer_, nullptr)); |
| } |
| |
| std::vector<uint8_t> old_file_; |
| std::vector<uint8_t> new_file_; |
| size_t min_len_ = 0; // 0 means the default. |
| FakePatchWriter patch_writer_; |
| }; |
| |
| // Check that a file with no changes has a very small patch (no extra data). |
| TEST_F(BsdiffTest, EqualEmptyFiles) { |
| // Empty old and new files. |
| RunBsdiff(); |
| |
| // No entries should be generated on an empty new file. |
| EXPECT_TRUE(patch_writer_.entries().empty()); |
| } |
| |
| TEST_F(BsdiffTest, EqualSmallFiles) { |
| std::string some_text = "Hello world!"; |
| old_file_.insert(old_file_.begin(), some_text.begin(), some_text.end()); |
| new_file_.insert(new_file_.begin(), some_text.begin(), some_text.end()); |
| RunBsdiff(); |
| |
| EXPECT_EQ(1U, patch_writer_.entries().size()); |
| ControlEntry entry = patch_writer_.entries()[0]; |
| EXPECT_EQ(some_text.size(), entry.diff_size); |
| EXPECT_EQ(0U, entry.extra_size); |
| } |
| |
| TEST_F(BsdiffTest, FileWithSmallErrorsTest) { |
| old_file_.resize(100); |
| GenerateRandomBuffer(&old_file_); |
| new_file_ = old_file_; |
| // Break a few bytes somewhere in the middle. |
| new_file_[20]++; |
| new_file_[30] += 2; |
| new_file_[31] += 2; |
| |
| RunBsdiff(); |
| |
| // We expect that the result has only one entry with all in the diff stream |
| // since the two files are very similar. |
| EXPECT_EQ(1U, patch_writer_.entries().size()); |
| ControlEntry entry = patch_writer_.entries()[0]; |
| EXPECT_EQ(100U, entry.diff_size); |
| EXPECT_EQ(0U, entry.extra_size); |
| } |
| |
| TEST_F(BsdiffTest, MinLengthConsideredTest) { |
| old_file_.resize(100); |
| GenerateRandomBuffer(&old_file_); |
| new_file_ = old_file_; |
| // Copy the first 10 bytes to the middle. |
| for (size_t i = 0; i < 10; i++) { |
| new_file_[50 + i] = old_file_[i]; |
| } |
| |
| min_len_ = 12; |
| RunBsdiff(); |
| |
| // We expect that the 10 bytes in the middle that match the beginning are |
| // ignored and just emitted as diff data because the min_len is bigger than |
| // 10. |
| EXPECT_EQ(1U, patch_writer_.entries().size()); |
| ControlEntry entry = patch_writer_.entries()[0]; |
| EXPECT_EQ(100U, entry.diff_size); |
| EXPECT_EQ(0U, entry.extra_size); |
| } |
| |
| } // namespace bsdiff |