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