1// Copyright 2008 Google Inc.
2// Author: Lincoln Smith
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8//      http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16#ifndef OPEN_VCDIFF_VCDECODER_TEST_H_
17#define OPEN_VCDIFF_VCDECODER_TEST_H_
18
19#include "google/vcdecoder.h"
20#include <string>
21#include "checksum.h"
22#include "testing.h"
23
24namespace open_vcdiff {
25
26// A base class used for all the decoder tests.  Most tests use the same
27// dictionary and target and construct the delta file in the same way.
28// Those elements are provided as string members and can be modified or
29// overwritten by each specific decoder test as needed.
30class VCDiffDecoderTest : public testing::Test {
31 protected:
32  typedef std::string string;
33
34  static const char kDictionary[];
35  static const char kExpectedTarget[];
36
37  VCDiffDecoderTest();
38
39  virtual ~VCDiffDecoderTest() {}
40
41  virtual void SetUp();
42
43  // These functions populate delta_file_header_ with a standard or interleaved
44  // file header.
45  void UseStandardFileHeader();
46  void UseInterleavedFileHeader();
47
48  // This function is called by SetUp().  It populates delta_file_ with the
49  // concatenated delta file header, delta window header, and delta window
50  // body, plus (if UseChecksum() is true) the corresponding checksum.
51  // It can be called again by a test that has modified the contents of
52  // delta_file_ and needs to restore them to their original state.
53  virtual void InitializeDeltaFile();
54
55  // This function adds an Adler32 checksum to the delta window header.
56  void AddChecksum(VCDChecksum checksum);
57
58  // This function computes the Adler32 checksum for the expected target
59  // and adds it to the delta window header.
60  void ComputeAndAddChecksum();
61
62  // Write the maximum expressible positive 32-bit VarintBE
63  // (0x7FFFFFFF) at the given offset in the delta window.
64  void WriteMaxVarintAtOffset(int offset, int bytes_to_replace);
65
66  // Write a negative 32-bit VarintBE (0x80000000) at the given offset
67  // in the delta window.
68  void WriteNegativeVarintAtOffset(int offset, int bytes_to_replace);
69
70  // Write a VarintBE that has too many continuation bytes
71  // at the given offset in the delta window.
72  void WriteInvalidVarintAtOffset(int offset, int bytes_to_replace);
73
74  // This function iterates through a list of fuzzers (bit masks used to corrupt
75  // bytes) and through positions in the delta file.  Each time it is called, it
76  // attempts to corrupt a different byte in delta_file_ in a different way.  If
77  // successful, it returns true. Once it exhausts the list of fuzzers and of
78  // byte positions in delta_file_, it returns false.
79  bool FuzzOneByteInDeltaFile();
80
81  // Assuming the length of the given string can be expressed as a VarintBE
82  // of length N, this function returns the byte at position which_byte, where
83  // 0 <= which_byte < N.
84  static char GetByteFromStringLength(const char* s, int which_byte);
85
86  // Assuming the length of the given string can be expressed as a one-byte
87  // VarintBE, this function returns that byte value.
88  static char StringLengthAsByte(const char* s) {
89    return GetByteFromStringLength(s, 0);
90  }
91
92  // Assuming the length of the given string can be expressed as a two-byte
93  // VarintBE, this function returns the first byte of its representation.
94  static char FirstByteOfStringLength(const char* s) {
95    return GetByteFromStringLength(s, 0);
96  }
97
98  // Assuming the length of the given string can be expressed as a two-byte
99  // VarintBE, this function returns the second byte of its representation.
100  static char SecondByteOfStringLength(const char* s) {
101    return GetByteFromStringLength(s, 1);
102  }
103
104  VCDiffStreamingDecoder decoder_;
105
106  // delta_file_ will be populated by InitializeDeltaFile() using the components
107  // delta_file_header_, delta_window_header_, and delta_window_body_.
108  string delta_file_;
109
110  // This string is not populated during setup, but is used to receive the
111  // decoded target file in each test.
112  string output_;
113
114  // Test fixtures that inherit from VCDiffDecoderTest can set these strings in
115  // their constructors to override their default values (which come from
116  // kDictionary, kExpectedTarget, etc.)
117  string dictionary_;
118  string expected_target_;
119
120  // The components that will be used to construct delta_file_.
121  string delta_file_header_;
122  string delta_window_header_;
123  string delta_window_body_;
124
125 private:
126  // These values should only be accessed via UseStandardFileHeader() and
127  // UseInterleavedFileHeader().
128  static const char kStandardFileHeader[];
129  static const char kInterleavedFileHeader[];
130
131  // These two counters are used by FuzzOneByteInDeltaFile() to iterate through
132  // different ways to corrupt the delta file.
133  size_t fuzzer_;
134  size_t fuzzed_byte_position_;
135};
136
137// The "standard" decoder test, which decodes a delta file that uses the
138// standard VCDIFF (RFC 3284) format with no extensions.
139class VCDiffStandardDecoderTest : public VCDiffDecoderTest {
140 protected:
141  VCDiffStandardDecoderTest();
142  virtual ~VCDiffStandardDecoderTest() {}
143
144 private:
145  static const char kWindowHeader[];
146  static const char kWindowBody[];
147};
148
149class VCDiffInterleavedDecoderTest : public VCDiffDecoderTest {
150 protected:
151  VCDiffInterleavedDecoderTest();
152  virtual ~VCDiffInterleavedDecoderTest() {}
153
154 private:
155  static const char kWindowHeader[];
156  static const char kWindowBody[];
157};
158
159}  // namespace open_vcdiff
160
161#endif  // OPEN_VCDIFF_VCDECODER_TEST_H_
162