// 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_