openvcdiff | 311c714 | 2008-08-26 19:29:25 +0000 | [diff] [blame] | 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 | |
| 24 | namespace 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. |
| 30 | class VCDiffDecoderTest : public testing::Test { |
| 31 | protected: |
openvcdiff | 28db807 | 2008-10-10 23:29:11 +0000 | [diff] [blame] | 32 | typedef std::string string; |
openvcdiff | 28db807 | 2008-10-10 23:29:11 +0000 | [diff] [blame] | 33 | |
openvcdiff | 311c714 | 2008-08-26 19:29:25 +0000 | [diff] [blame] | 34 | static const char kDictionary[]; |
| 35 | static const char kExpectedTarget[]; |
openvcdiff | 311c714 | 2008-08-26 19:29:25 +0000 | [diff] [blame] | 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_; |
openvcdiff | 311c714 | 2008-08-26 19:29:25 +0000 | [diff] [blame] | 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. |
| 139 | class 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 | |
| 149 | class 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_ |