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: 32 typedef std::string string; 33 34 static const char kDictionary[]; 35 static const char kExpectedTarget[]; 36 37 VCDiffDecoderTest(); 38 ~VCDiffDecoderTest()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. StringLengthAsByte(const char * s)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. FirstByteOfStringLength(const char * s)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. SecondByteOfStringLength(const char * s)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. 139 class VCDiffStandardDecoderTest : public VCDiffDecoderTest { 140 protected: 141 VCDiffStandardDecoderTest(); ~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(); ~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