// Copyright 2008 Google Inc. // Author: Lincoln Smith // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef OPEN_VCDIFF_VCDECODER_TEST_H_ #define OPEN_VCDIFF_VCDECODER_TEST_H_ #include "google/vcdecoder.h" #include <string> #include "checksum.h" #include "testing.h" namespace open_vcdiff { // A base class used for all the decoder tests. Most tests use the same // dictionary and target and construct the delta file in the same way. // Those elements are provided as string members and can be modified or // overwritten by each specific decoder test as needed. class VCDiffDecoderTest : public testing::Test { protected: typedef std::string string; static const char kDictionary[]; static const char kExpectedTarget[]; VCDiffDecoderTest(); virtual ~VCDiffDecoderTest() {} virtual void SetUp(); // These functions populate delta_file_header_ with a standard or interleaved // file header. void UseStandardFileHeader(); void UseInterleavedFileHeader(); // This function is called by SetUp(). It populates delta_file_ with the // concatenated delta file header, delta window header, and delta window // body, plus (if UseChecksum() is true) the corresponding checksum. // It can be called again by a test that has modified the contents of // delta_file_ and needs to restore them to their original state. virtual void InitializeDeltaFile(); // This function adds an Adler32 checksum to the delta window header. void AddChecksum(VCDChecksum checksum); // This function computes the Adler32 checksum for the expected target // and adds it to the delta window header. void ComputeAndAddChecksum(); // Write the maximum expressible positive 32-bit VarintBE // (0x7FFFFFFF) at the given offset in the delta window. void WriteMaxVarintAtOffset(int offset, int bytes_to_replace); // Write a negative 32-bit VarintBE (0x80000000) at the given offset // in the delta window. void WriteNegativeVarintAtOffset(int offset, int bytes_to_replace); // Write a VarintBE that has too many continuation bytes // at the given offset in the delta window. void WriteInvalidVarintAtOffset(int offset, int bytes_to_replace); // This function iterates through a list of fuzzers (bit masks used to corrupt // bytes) and through positions in the delta file. Each time it is called, it // attempts to corrupt a different byte in delta_file_ in a different way. If // successful, it returns true. Once it exhausts the list of fuzzers and of // byte positions in delta_file_, it returns false. bool FuzzOneByteInDeltaFile(); // Assuming the length of the given string can be expressed as a VarintBE // of length N, this function returns the byte at position which_byte, where // 0 <= which_byte < N. static char GetByteFromStringLength(const char* s, int which_byte); // Assuming the length of the given string can be expressed as a one-byte // VarintBE, this function returns that byte value. static char StringLengthAsByte(const char* s) { return GetByteFromStringLength(s, 0); } // Assuming the length of the given string can be expressed as a two-byte // VarintBE, this function returns the first byte of its representation. static char FirstByteOfStringLength(const char* s) { return GetByteFromStringLength(s, 0); } // Assuming the length of the given string can be expressed as a two-byte // VarintBE, this function returns the second byte of its representation. static char SecondByteOfStringLength(const char* s) { return GetByteFromStringLength(s, 1); } VCDiffStreamingDecoder decoder_; // delta_file_ will be populated by InitializeDeltaFile() using the components // delta_file_header_, delta_window_header_, and delta_window_body_. string delta_file_; // This string is not populated during setup, but is used to receive the // decoded target file in each test. string output_; // Test fixtures that inherit from VCDiffDecoderTest can set these strings in // their constructors to override their default values (which come from // kDictionary, kExpectedTarget, etc.) string dictionary_; string expected_target_; // The components that will be used to construct delta_file_. string delta_file_header_; string delta_window_header_; string delta_window_body_; private: // These values should only be accessed via UseStandardFileHeader() and // UseInterleavedFileHeader(). static const char kStandardFileHeader[]; static const char kInterleavedFileHeader[]; // These two counters are used by FuzzOneByteInDeltaFile() to iterate through // different ways to corrupt the delta file. size_t fuzzer_; size_t fuzzed_byte_position_; }; // The "standard" decoder test, which decodes a delta file that uses the // standard VCDIFF (RFC 3284) format with no extensions. class VCDiffStandardDecoderTest : public VCDiffDecoderTest { protected: VCDiffStandardDecoderTest(); virtual ~VCDiffStandardDecoderTest() {} private: static const char kWindowHeader[]; static const char kWindowBody[]; }; class VCDiffInterleavedDecoderTest : public VCDiffDecoderTest { protected: VCDiffInterleavedDecoderTest(); virtual ~VCDiffInterleavedDecoderTest() {} private: static const char kWindowHeader[]; static const char kWindowBody[]; }; } // namespace open_vcdiff #endif // OPEN_VCDIFF_VCDECODER_TEST_H_