blob: 15e43318f336fe74750edb79d4d6235382bdae86 [file] [log] [blame]
Alex Deymo68c0e7f2017-10-02 20:38:12 +02001// 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
Alex Deymoaefc2532017-10-11 17:50:12 +02007#include <memory>
Alex Deymo68c0e7f2017-10-02 20:38:12 +02008#include <vector>
9
10#include <gtest/gtest.h>
11
12#include "bsdiff/fake_patch_writer.h"
13#include "bsdiff/test_utils.h"
14
15namespace {
16
17// Generated with:
18// echo 'Hello World' | hexdump -v -e '" " 12/1 "0x%02x, " "\n"'
19const uint8_t kHelloWorld[] = {
20 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x0a,
21};
22
23} // namespace
24
25namespace bsdiff {
26
27class DiffEncoderTest : public testing::Test {
28 protected:
Alex Deymoaefc2532017-10-11 17:50:12 +020029 void SetUp() {
Alex Deymoaefc2532017-10-11 17:50:12 +020030 // 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 }
Alex Deymo68c0e7f2017-10-02 20:38:12 +020035
36 FakePatchWriter fake_patch_;
37 std::unique_ptr<DiffEncoder> diff_encoder_;
38};
39
40TEST_F(DiffEncoderTest, CreateEmptyPatchTest) {
41 diff_encoder_.reset(new DiffEncoder(&fake_patch_, nullptr, 0, nullptr, 0));
Alex Deymo4dadd8b2017-10-26 16:19:33 +020042 EXPECT_TRUE(diff_encoder_->Init());
Alex Deymo68c0e7f2017-10-02 20:38:12 +020043 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
51TEST_F(DiffEncoderTest, AllInExtraStreamTest) {
52 diff_encoder_.reset(new DiffEncoder(&fake_patch_, nullptr, 0, kHelloWorld,
53 sizeof(kHelloWorld)));
Alex Deymo4dadd8b2017-10-26 16:19:33 +020054 EXPECT_TRUE(diff_encoder_->Init());
Alex Deymo68c0e7f2017-10-02 20:38:12 +020055
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
69TEST_F(DiffEncoderTest, AllInDiffStreamTest) {
Alex Deymo4dadd8b2017-10-26 16:19:33 +020070 EXPECT_TRUE(diff_encoder_->Init());
Alex Deymo68c0e7f2017-10-02 20:38:12 +020071 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
Alex Deymoaefc2532017-10-11 17:50:12 +020080TEST_F(DiffEncoderTest, OldPosNegativeErrorTest) {
Alex Deymo4dadd8b2017-10-26 16:19:33 +020081 EXPECT_TRUE(diff_encoder_->Init());
Alex Deymoaefc2532017-10-11 17:50:12 +020082 // 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.
89TEST_F(DiffEncoderTest, OldPosTooBigErrorTest) {
Alex Deymo4dadd8b2017-10-26 16:19:33 +020090 EXPECT_TRUE(diff_encoder_->Init());
Alex Deymoaefc2532017-10-11 17:50:12 +020091 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.
98TEST_F(DiffEncoderTest, OldPosPlusSizeTooBigErrorTest) {
Alex Deymo4dadd8b2017-10-26 16:19:33 +020099 EXPECT_TRUE(diff_encoder_->Init());
Alex Deymoaefc2532017-10-11 17:50:12 +0200100 // 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
108TEST_F(DiffEncoderTest, ExtraStreamTooBigErrorTest) {
Alex Deymo4dadd8b2017-10-26 16:19:33 +0200109 EXPECT_TRUE(diff_encoder_->Init());
Alex Deymoaefc2532017-10-11 17:50:12 +0200110 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
Alex Deymo68c0e7f2017-10-02 20:38:12 +0200116} // namespace bsdiff