summaryrefslogtreecommitdiffstats
path: root/chromium/sdch/open-vcdiff/src/vcdecoder_test.h
blob: 2967444ae9f72593d665a8d326297d1928bd8ed7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
// 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_