blob: a37bcdcc079534e9e4dd055807273f212180aa3c [file] [log] [blame]
Alex Deymoe1140a22017-10-02 21:01:15 +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/split_patch_writer.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
15namespace bsdiff {
16
17class SplitPatchWriterTest : public testing::Test {
18 protected:
Alex Deymo4dadd8b2017-10-26 16:19:33 +020019 void SetUpForSize(size_t num_chunks,
20 uint64_t new_chunk_size,
21 size_t new_size) {
Alex Deymoe1140a22017-10-02 21:01:15 +020022 fake_patches_.resize(num_chunks);
23 std::vector<PatchWriterInterface*> patches;
24 for (auto& fake_patch : fake_patches_)
25 patches.push_back(&fake_patch);
26
27 patch_writer_.reset(new SplitPatchWriter(new_chunk_size, patches));
Alex Deymo4dadd8b2017-10-26 16:19:33 +020028 EXPECT_TRUE(patch_writer_->Init(new_size));
Alex Deymoe1140a22017-10-02 21:01:15 +020029 }
30
31 std::vector<FakePatchWriter> fake_patches_;
32 std::unique_ptr<SplitPatchWriter> patch_writer_;
33};
34
Alex Deymo4dadd8b2017-10-26 16:19:33 +020035TEST_F(SplitPatchWriterTest, InvalidNumberOfPatchesForSizeTest) {
36 FakePatchWriter p;
37 std::vector<PatchWriterInterface*> patches = {&p};
38 patch_writer_.reset(new SplitPatchWriter(10, patches));
39 // We should have pass two patches.
40 EXPECT_FALSE(patch_writer_->Init(15));
41}
42
Alex Deymoe1140a22017-10-02 21:01:15 +020043// A single empty patch is allowed.
44TEST_F(SplitPatchWriterTest, NonSplitEmptyPatchTest) {
Alex Deymo4dadd8b2017-10-26 16:19:33 +020045 SetUpForSize(1, 100, 0);
Alex Deymoe1140a22017-10-02 21:01:15 +020046 EXPECT_TRUE(patch_writer_->Close());
47
48 EXPECT_TRUE(fake_patches_[0].entries().empty());
49}
50
51// Leaving patches at the end that are empty is considered an error.
52TEST_F(SplitPatchWriterTest, NotAllPatchesWrittenErrorTest) {
Alex Deymo4dadd8b2017-10-26 16:19:33 +020053 SetUpForSize(2, 100, 200);
Alex Deymoe1140a22017-10-02 21:01:15 +020054 // We write less than the amount needed for two patches, which should fail.
55 EXPECT_FALSE(patch_writer_->Close());
56}
57
58TEST_F(SplitPatchWriterTest, MissingDiffBytesErrorTest) {
Alex Deymo4dadd8b2017-10-26 16:19:33 +020059 SetUpForSize(2, 10, 20);
Alex Deymoe1140a22017-10-02 21:01:15 +020060
61 EXPECT_TRUE(patch_writer_->AddControlEntry(ControlEntry(15, 5, 0)));
62 std::vector<uint8_t> zeros(20, 0);
63 // We write 12 diff bytes instead of the expected 15. This should fail on
64 // Close().
65 EXPECT_TRUE(patch_writer_->WriteDiffStream(zeros.data(), 12));
66 EXPECT_TRUE(patch_writer_->WriteExtraStream(zeros.data(), 5));
67 EXPECT_FALSE(patch_writer_->Close());
68}
69
70TEST_F(SplitPatchWriterTest, MissingExtraBytesErrorTest) {
Alex Deymo4dadd8b2017-10-26 16:19:33 +020071 SetUpForSize(2, 10, 20);
Alex Deymoe1140a22017-10-02 21:01:15 +020072
73 std::vector<uint8_t> zeros(20, 0);
74 EXPECT_TRUE(patch_writer_->AddControlEntry(ControlEntry(5, 15, -5)));
75 EXPECT_TRUE(patch_writer_->WriteDiffStream(zeros.data(), 5));
76 // We write a little less than the expected 15. This operation should succeed,
77 // since we could write the rest later.
78 EXPECT_TRUE(patch_writer_->WriteExtraStream(zeros.data(), 10));
79 EXPECT_FALSE(patch_writer_->Close());
80}
81
82// Test all sort of corner cases when splitting the ControlEntry across multiple
83// patches
84TEST_F(SplitPatchWriterTest, SplitControlAcrossSeveralPatchesTest) {
Alex Deymo4dadd8b2017-10-26 16:19:33 +020085 SetUpForSize(4, 10, 40);
Alex Deymoe1140a22017-10-02 21:01:15 +020086 // The middle control entry would be split in tree different patches.
87 EXPECT_TRUE(patch_writer_->AddControlEntry(ControlEntry(5, 1, -5)));
88 EXPECT_TRUE(patch_writer_->AddControlEntry(ControlEntry(4, 0, -4)));
89 // old_pos at this point is 0. This is the end of the first patch.
90 EXPECT_TRUE(patch_writer_->AddControlEntry(ControlEntry(6, 0, -1)));
91 // old_pos at this point is 5.
92 EXPECT_TRUE(patch_writer_->AddControlEntry(ControlEntry(1, 18, 2)));
93 // old_pos at this point is 8.
94 EXPECT_TRUE(patch_writer_->AddControlEntry(ControlEntry(1, 0, 1)));
95 EXPECT_TRUE(patch_writer_->AddControlEntry(ControlEntry(4, 0, -5)));
96
97 std::vector<uint8_t> zeros(40, 0);
98 EXPECT_TRUE(
99 patch_writer_->WriteDiffStream(zeros.data(), 5 + 4 + 6 + 1 + 1 + 4));
100 EXPECT_TRUE(patch_writer_->WriteExtraStream(zeros.data(), 1 + 18));
101 EXPECT_TRUE(patch_writer_->Close());
102
103 EXPECT_EQ((std::vector<ControlEntry>{
104 ControlEntry(5, 1, -5),
105 ControlEntry(4, 0, 0), // (4, 0, -4) but the -4 is not needed.
106 }),
107 fake_patches_[0].entries());
108 EXPECT_EQ((std::vector<ControlEntry>{
109 // No need for dummy entry because the old_pos is already at 0.
110 ControlEntry(6, 0, -1),
111 ControlEntry(1, 3, 0), // the first part of (1, 18, 2)
112 }),
113 fake_patches_[1].entries());
114 EXPECT_EQ((std::vector<ControlEntry>{
115 // No need for dummy entry because the first entry is all in
116 // the extra stream and this is the last entry.
117 ControlEntry(0, 10, 0), // the middle part of (1, 18, 2)
118 }),
119 fake_patches_[2].entries());
120 EXPECT_EQ((std::vector<ControlEntry>{
121 // No need for dummy entry because the first entry is all in
122 // the extra stream, so use that.
123 ControlEntry(0, 5, 8), // the last part of (1, 18, 2), plus the
124 // old_pos 5. 8 = 1 + 2 + 5.
125 ControlEntry(1, 0, 1), // (1, 0, 1) copied
126 ControlEntry(4, 0, 0), // (4, 0, -5) ignoring the offset.
127 }),
128 fake_patches_[3].entries());
Alex Deymo4dadd8b2017-10-26 16:19:33 +0200129
130 for (size_t i = 0; i < fake_patches_.size(); ++i) {
131 EXPECT_EQ(10U, fake_patches_[i].new_size()) << "where i = " << i;
132 }
Alex Deymoe1140a22017-10-02 21:01:15 +0200133}
134
135TEST_F(SplitPatchWriterTest, WriteStreamsAfterControlAcrossPatchesTest) {
136 std::vector<uint8_t> numbers(40);
137 for (size_t i = 0; i < numbers.size(); ++i)
138 numbers[i] = 'A' + i;
139
Alex Deymo4dadd8b2017-10-26 16:19:33 +0200140 SetUpForSize(4, 10, 40);
Alex Deymoe1140a22017-10-02 21:01:15 +0200141 // The sequence is 15 diff, 10 extra, 15 diff.
142 EXPECT_TRUE(patch_writer_->AddControlEntry(ControlEntry(15, 10, 0)));
143 EXPECT_TRUE(patch_writer_->AddControlEntry(ControlEntry(15, 0, 0)));
144 // Numbers [0, 30) for the diff stream, and [30, 40) for the extra stream.
145 EXPECT_TRUE(patch_writer_->WriteDiffStream(numbers.data(), 30));
146 EXPECT_TRUE(patch_writer_->WriteExtraStream(numbers.data() + 30, 10));
147 EXPECT_TRUE(patch_writer_->Close());
148
149 EXPECT_EQ(std::vector<uint8_t>(numbers.begin(), numbers.begin() + 10),
150 fake_patches_[0].diff_stream());
151 EXPECT_TRUE(fake_patches_[0].extra_stream().empty());
152
153 // 5 diff, then 5 extra.
154 EXPECT_EQ(std::vector<uint8_t>(numbers.begin() + 10, numbers.begin() + 15),
155 fake_patches_[1].diff_stream());
156 EXPECT_EQ(std::vector<uint8_t>(numbers.begin() + 30, numbers.begin() + 35),
157 fake_patches_[1].extra_stream());
158
159 // 5 extra, then 5 diff.
160 EXPECT_EQ(std::vector<uint8_t>(numbers.begin() + 15, numbers.begin() + 20),
161 fake_patches_[2].diff_stream());
162 EXPECT_EQ(std::vector<uint8_t>(numbers.begin() + 35, numbers.begin() + 40),
163 fake_patches_[2].extra_stream());
164
165 EXPECT_EQ(std::vector<uint8_t>(numbers.begin() + 20, numbers.begin() + 30),
166 fake_patches_[3].diff_stream());
167 EXPECT_TRUE(fake_patches_[3].extra_stream().empty());
168}
169
170} // namespace bsdiff