mirror of
https://github.com/expo/bsdiff.git
synced 2026-11-13 20:11:27 -10:00
Most patch formats include the size of the new file in the header. To help streaming the patch to disk while generating it, this CL passes the size of the new file to the patch writer on initialization. To do this, we also move the Init() call to the patch writer to the DiffEncoder, which makes more sense since the Close() call is also made from the DiffEnconder. Bug: None Test: Updated tests to check for this value. Change-Id: Idfaedbd492d68ab6e6cb2c1cb3883947f068c3aa
117 lines
4.0 KiB
C++
117 lines
4.0 KiB
C++
// Copyright 2017 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/diff_encoder.h"
|
|
|
|
#include <memory>
|
|
#include <vector>
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
#include "bsdiff/fake_patch_writer.h"
|
|
#include "bsdiff/test_utils.h"
|
|
|
|
namespace {
|
|
|
|
// Generated with:
|
|
// echo 'Hello World' | hexdump -v -e '" " 12/1 "0x%02x, " "\n"'
|
|
const uint8_t kHelloWorld[] = {
|
|
0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x0a,
|
|
};
|
|
|
|
} // namespace
|
|
|
|
namespace bsdiff {
|
|
|
|
class DiffEncoderTest : public testing::Test {
|
|
protected:
|
|
void SetUp() {
|
|
// By default, set the encoder to kHelloWorld to kHelloWorld.
|
|
diff_encoder_.reset(new DiffEncoder(&fake_patch_, kHelloWorld,
|
|
sizeof(kHelloWorld), kHelloWorld,
|
|
sizeof(kHelloWorld)));
|
|
}
|
|
|
|
FakePatchWriter fake_patch_;
|
|
std::unique_ptr<DiffEncoder> diff_encoder_;
|
|
};
|
|
|
|
TEST_F(DiffEncoderTest, CreateEmptyPatchTest) {
|
|
diff_encoder_.reset(new DiffEncoder(&fake_patch_, nullptr, 0, nullptr, 0));
|
|
EXPECT_TRUE(diff_encoder_->Init());
|
|
EXPECT_TRUE(diff_encoder_->Close());
|
|
|
|
// Both diff and extra stream must be empty stream, and not control entries.
|
|
EXPECT_EQ(0U, fake_patch_.entries().size());
|
|
EXPECT_TRUE(fake_patch_.diff_stream().empty());
|
|
EXPECT_TRUE(fake_patch_.extra_stream().empty());
|
|
}
|
|
|
|
TEST_F(DiffEncoderTest, AllInExtraStreamTest) {
|
|
diff_encoder_.reset(new DiffEncoder(&fake_patch_, nullptr, 0, kHelloWorld,
|
|
sizeof(kHelloWorld)));
|
|
EXPECT_TRUE(diff_encoder_->Init());
|
|
|
|
// Write to the extra stream in two parts: first 5 bytes, then the rest.
|
|
EXPECT_TRUE(diff_encoder_->AddControlEntry(ControlEntry(0, 5, 0)));
|
|
EXPECT_TRUE(diff_encoder_->AddControlEntry(
|
|
ControlEntry(0, sizeof(kHelloWorld) - 5, 0)));
|
|
EXPECT_TRUE(diff_encoder_->Close());
|
|
|
|
EXPECT_EQ(2U, fake_patch_.entries().size());
|
|
EXPECT_TRUE(fake_patch_.diff_stream().empty());
|
|
std::vector<uint8_t> hello_world(kHelloWorld,
|
|
kHelloWorld + sizeof(kHelloWorld));
|
|
EXPECT_EQ(hello_world, fake_patch_.extra_stream());
|
|
}
|
|
|
|
TEST_F(DiffEncoderTest, AllInDiffStreamTest) {
|
|
EXPECT_TRUE(diff_encoder_->Init());
|
|
EXPECT_TRUE(
|
|
diff_encoder_->AddControlEntry(ControlEntry(sizeof(kHelloWorld), 0, 0)));
|
|
EXPECT_TRUE(diff_encoder_->Close());
|
|
|
|
EXPECT_EQ(std::vector<uint8_t>(sizeof(kHelloWorld), 0),
|
|
fake_patch_.diff_stream());
|
|
EXPECT_TRUE(fake_patch_.extra_stream().empty());
|
|
}
|
|
|
|
TEST_F(DiffEncoderTest, OldPosNegativeErrorTest) {
|
|
EXPECT_TRUE(diff_encoder_->Init());
|
|
// Referencing negative values in oldpos is fine, until you use them.
|
|
EXPECT_TRUE(diff_encoder_->AddControlEntry(ControlEntry(0, 0, -5)));
|
|
EXPECT_TRUE(diff_encoder_->AddControlEntry(ControlEntry(0, 0, 2)));
|
|
EXPECT_FALSE(diff_encoder_->AddControlEntry(ControlEntry(1, 0, 0)));
|
|
}
|
|
|
|
// Test that using an oldpos past the end of the file fails.
|
|
TEST_F(DiffEncoderTest, OldPosTooBigErrorTest) {
|
|
EXPECT_TRUE(diff_encoder_->Init());
|
|
EXPECT_TRUE(
|
|
diff_encoder_->AddControlEntry(ControlEntry(0, 0, sizeof(kHelloWorld))));
|
|
EXPECT_FALSE(diff_encoder_->AddControlEntry(ControlEntry(1, 0, 0)));
|
|
}
|
|
|
|
// Test that diffing against a section of the old file past the end of the file
|
|
// fails.
|
|
TEST_F(DiffEncoderTest, OldPosPlusSizeTooBigErrorTest) {
|
|
EXPECT_TRUE(diff_encoder_->Init());
|
|
// The oldpos is set to a range inside the word, the we try to copy past the
|
|
// end of it.
|
|
EXPECT_TRUE(diff_encoder_->AddControlEntry(
|
|
ControlEntry(0, 0, sizeof(kHelloWorld) - 3)));
|
|
EXPECT_FALSE(
|
|
diff_encoder_->AddControlEntry(ControlEntry(sizeof(kHelloWorld), 0, 0)));
|
|
}
|
|
|
|
TEST_F(DiffEncoderTest, ExtraStreamTooBigErrorTest) {
|
|
EXPECT_TRUE(diff_encoder_->Init());
|
|
EXPECT_TRUE(diff_encoder_->AddControlEntry(ControlEntry(3, 0, 0)));
|
|
// This writes too many bytes in the stream because we already have 3 bytes.
|
|
EXPECT_FALSE(
|
|
diff_encoder_->AddControlEntry(ControlEntry(0, sizeof(kHelloWorld), 0)));
|
|
}
|
|
|
|
} // namespace bsdiff
|