Home | History | Annotate | Download | only in src
      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 
     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.
    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_
    162