blob: 6eb8ff055a4fbf2298ea7ded20047593f5fc528f [file] [log] [blame]
openvcdiff311c7142008-08-26 19:29:25 +00001// 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#include <config.h>
17#include "varint_bigendian.h"
openvcdiff28db8072008-10-10 23:29:11 +000018#include <stdlib.h> // rand, srand
19#include <string.h> // strlen
openvcdiff311c7142008-08-26 19:29:25 +000020#include <string>
21#include <vector>
22#include "logging.h"
23#include "testing.h"
24
25namespace open_vcdiff {
26namespace {
27
openvcdiff311c7142008-08-26 19:29:25 +000028class VarintBETestCommon : public testing::Test {
29 protected:
openvcdiff28db8072008-10-10 23:29:11 +000030#ifndef VCDIFF_HAS_GLOBAL_STRING
31 typedef std::string string;
32#endif // !VCDIFF_HAS_GLOBAL_STRING
33
openvcdiff311c7142008-08-26 19:29:25 +000034 VarintBETestCommon()
35 : varint_buf_(VarintBE<int64_t>::kMaxBytes),
36 verify_encoded_byte_index_(0),
37 verify_expected_length_(0),
38 parse_data_ptr_(parse_data_all_FFs) {
39 }
40
41 virtual ~VarintBETestCommon() { }
42
43 void ExpectEncodedByte(char expected_byte) {
44 EXPECT_EQ(expected_byte, varint_buf_[verify_encoded_byte_index_]);
45 EXPECT_EQ(expected_byte, s_[verify_encoded_byte_index_]);
46 ++verify_encoded_byte_index_;
47 }
48
49 static const char parse_data_all_FFs[];
50 static const char parse_data_CADA1[];
51
52 std::vector<char> varint_buf_;
53 string s_;
54 int verify_encoded_byte_index_;
55 int verify_expected_length_;
56 const char* parse_data_ptr_;
57};
58
59template <typename SignedIntegerType>
60class VarintBETestTemplate : public VarintBETestCommon {
61 protected:
62 VarintBETestTemplate() { }
63
64 virtual ~VarintBETestTemplate() { }
65
66 typedef SignedIntegerType SignedIntType;
67 typedef VarintBE<SignedIntegerType> VarintType;
68
69 void StartEncodingTest(SignedIntegerType v, int expected_length) {
70 verify_expected_length_ = expected_length;
71 EXPECT_EQ(expected_length, VarintType::Length(v));
72 EXPECT_EQ(expected_length, VarintType::Encode(v, &varint_buf_[0]));
73 VarintType::AppendToString(v, &s_);
74 EXPECT_EQ(static_cast<size_t>(expected_length), s_.length());
75 }
76
77 void TestEncodeInvalid(SignedIntegerType v) {
78 EXPECT_DEATH(VarintType::Length(v), "v >= 0");
79 EXPECT_DEATH(VarintType::Encode(v, &varint_buf_[0]), "v >= 0");
80 EXPECT_DEATH(VarintType::AppendToString(v, &s_), ">= 0");
81 }
82
83 // Need one function for each test type that will be applied to
84 // multiple classes
85 void TemplateTestDISABLED_EncodeNegative();
86 void TemplateTestEncodeZero();
87 void TemplateTestEncodeEightBits();
88 void TemplateTestEncodeCADAD1A();
89 void TemplateTestEncode32BitMaxInt();
90 void TemplateTestEncodeDoesNotOverwriteExistingString();
91 void TemplateTestParseNullPointer();
92 void TemplateTestEndPointerPrecedesBeginning();
93 void TemplateTestParseVarintTooLong();
94 void TemplateTestParseIncompleteVarint();
95 void TemplateTestParseZero();
96 void TemplateTestParseCADA1();
97 void TemplateTestParseEmpty();
98 void TemplateTestParse123456789();
99 void TemplateTestDecode31Bits();
100 void TemplateTestEncodeDecodeRandom();
101};
102
103typedef VarintBETestTemplate<int32_t> VarintBEInt32Test;
104typedef VarintBETestTemplate<int64_t> VarintBEInt64Test;
105
106#ifdef GTEST_HAS_DEATH_TEST
107// These synonyms are needed for the tests that use ASSERT_DEATH
108typedef VarintBEInt32Test VarintBEInt32DeathTest;
109typedef VarintBEInt64Test VarintBEInt64DeathTest;
110#endif // GTEST_HAS_DEATH_TEST
111
112const char VarintBETestCommon::parse_data_all_FFs[] =
113 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
114
115const char VarintBETestCommon::parse_data_CADA1[] =
116 { 0xCA, 0xDA, 0x01 };
117
118// A macro to allow defining tests once and having them run against
119// both VarintBE<int32_t> and VarintBE<int64_t>.
120//
121#define TEMPLATE_TEST_F(TEST_TYPE, TEST_NAME) \
122 TEST_F(VarintBEInt32##TEST_TYPE, TEST_NAME) { \
123 TemplateTest##TEST_NAME(); \
124 } \
125 TEST_F(VarintBEInt64##TEST_TYPE, TEST_NAME) { \
126 TemplateTest##TEST_NAME(); \
127 } \
128 template <class CacheType> \
129 void VarintBETestTemplate<CacheType>::TemplateTest##TEST_NAME()
130
131// Encoding tests: Length(), Encode(), AppendToString(), AppendToBuffer()
132
133#ifdef GTEST_HAS_DEATH_TEST
134// This test hangs for non-debug build (DeathTest threading problem)
135TEMPLATE_TEST_F(DeathTest, DISABLED_EncodeNegative) {
136 TestEncodeInvalid(-1);
137}
138#endif // GTEST_HAS_DEATH_TEST
139
140TEMPLATE_TEST_F(Test, EncodeZero) {
141 StartEncodingTest(/* value */ 0x00, /* expected length */ 1);
142 ExpectEncodedByte(0x00);
143 EXPECT_EQ(verify_expected_length_, verify_encoded_byte_index_);
144}
145
146TEMPLATE_TEST_F(Test, EncodeEightBits) {
147 StartEncodingTest(/* value */ 0xFF, /* expected length */ 2);
148 ExpectEncodedByte(0x81);
149 ExpectEncodedByte(0x7F);
150 EXPECT_EQ(verify_expected_length_, verify_encoded_byte_index_);
151}
152
153TEMPLATE_TEST_F(Test, EncodeCADAD1A) {
154 StartEncodingTest(/* value */ 0x0CADAD1A, /* expected length */ 4);
155 ExpectEncodedByte(0xE5);
156 ExpectEncodedByte(0xB6);
157 ExpectEncodedByte(0xDA);
158 ExpectEncodedByte(0x1A);
159 EXPECT_EQ(verify_expected_length_, verify_encoded_byte_index_);
160}
161
162TEMPLATE_TEST_F(Test, Encode32BitMaxInt) {
163 StartEncodingTest(/* value */ 0x7FFFFFFF, /* expected length */ 5);
164 ExpectEncodedByte(0x87);
165 ExpectEncodedByte(0xFF);
166 ExpectEncodedByte(0xFF);
167 ExpectEncodedByte(0xFF);
168 ExpectEncodedByte(0x7F);
169 EXPECT_EQ(verify_expected_length_, verify_encoded_byte_index_);
170}
171
172#ifdef GTEST_HAS_DEATH_TEST
173// This test hangs for non-debug build (DeathTest threading problem)
174TEST_F(VarintBEInt32DeathTest, DISABLED_Encode32BitsTooBig) {
175 TestEncodeInvalid(0x80000000);
176}
177#endif // GTEST_HAS_DEATH_TEST
178
179TEST_F(VarintBEInt64Test, Encode32Bits) {
180 StartEncodingTest(/* value */ 0x80000000, /* expected length */ 5);
181 ExpectEncodedByte(0x88);
182 ExpectEncodedByte(0x80);
183 ExpectEncodedByte(0x80);
184 ExpectEncodedByte(0x80);
185 ExpectEncodedByte(0x00);
186 EXPECT_EQ(verify_expected_length_, verify_encoded_byte_index_);
187}
188
189TEST_F(VarintBEInt64Test, Encode63Bits) {
190 StartEncodingTest(/* value */ 0x7FFFFFFFFFFFFFFFULL, /* expected length */ 9);
191 ExpectEncodedByte(0xFF);
192 ExpectEncodedByte(0xFF);
193 ExpectEncodedByte(0xFF);
194 ExpectEncodedByte(0xFF);
195 ExpectEncodedByte(0xFF);
196 ExpectEncodedByte(0xFF);
197 ExpectEncodedByte(0xFF);
198 ExpectEncodedByte(0xFF);
199 ExpectEncodedByte(0x7F);
200 EXPECT_EQ(verify_expected_length_, verify_encoded_byte_index_);
201}
202
203#ifdef GTEST_HAS_DEATH_TEST
204// This test hangs for non-debug build (DeathTest threading problem)
205TEST_F(VarintBEInt64DeathTest, DISABLED_Encode64BitsTooBig) {
206 TestEncodeInvalid(0x8000000000000000ULL);
207}
208#endif // GTEST_HAS_DEATH_TEST
209
210TEMPLATE_TEST_F(Test, EncodeDoesNotOverwriteExistingString) {
211 s_.append("Test");
212 VarintType::AppendToString('1', &s_);
213 EXPECT_EQ(strlen("Test1"), s_.length());
214 EXPECT_EQ("Test1", s_);
215}
216
217// Decoding tests: Parse(), ParseFromBuffer()
218
219TEMPLATE_TEST_F(Test, ParseVarintTooLong) {
220 EXPECT_EQ(RESULT_ERROR,
221 VarintType::Parse(parse_data_ptr_ + VarintType::kMaxBytes,
222 &parse_data_ptr_));
223}
224
225TEMPLATE_TEST_F(Test, ParseIncompleteVarint) {
226 EXPECT_EQ(RESULT_END_OF_DATA,
227 VarintType::Parse(parse_data_ptr_ + VarintType::kMaxBytes - 1,
228 &parse_data_ptr_));
229}
230
231TEMPLATE_TEST_F(Test, ParseZero) {
232 const char zero_data[] = { 0x00 };
233 parse_data_ptr_ = zero_data;
234 EXPECT_EQ(0x00, VarintType::Parse(parse_data_ptr_ + 1, &parse_data_ptr_));
235 EXPECT_EQ(zero_data + 1, parse_data_ptr_);
236}
237
238TEMPLATE_TEST_F(Test, ParseCADA1) {
239 parse_data_ptr_ = parse_data_CADA1;
240 EXPECT_EQ(0x12AD01,
241 VarintType::Parse(parse_data_CADA1 + sizeof(parse_data_CADA1),
242 &parse_data_ptr_));
243 EXPECT_EQ(parse_data_CADA1 + 3, parse_data_ptr_);
244}
245
246#ifdef GTEST_HAS_DEATH_TEST
247TEMPLATE_TEST_F(DeathTest, ParseNullPointer) {
248 // limit == NULL is not an error
249 parse_data_ptr_ = parse_data_CADA1;
250 EXPECT_EQ(0x12AD01, VarintType::Parse((const char*) NULL, &parse_data_ptr_));
251}
252#endif // GTEST_HAS_DEATH_TEST
253
254TEMPLATE_TEST_F(Test, EndPointerPrecedesBeginning) {
255 // This is not an error.
256 parse_data_ptr_ = parse_data_CADA1;
257 EXPECT_EQ(0x12AD01, VarintType::Parse(parse_data_ptr_ - 1, &parse_data_ptr_));
258}
259
260TEMPLATE_TEST_F(Test, ParseEmpty) {
261 EXPECT_EQ(RESULT_END_OF_DATA,
262 VarintType::Parse(parse_data_ptr_, &parse_data_ptr_));
263}
264
265// This example is taken from the Varint description in RFC 3284, section 2.
266TEMPLATE_TEST_F(Test, Parse123456789) {
267 const char parse_data_123456789[] = { 0x80 + 58, 0x80 + 111, 0x80 + 26, 21 };
268 parse_data_ptr_ = parse_data_123456789;
269 EXPECT_EQ(123456789, VarintType::Parse(parse_data_123456789
270 + sizeof(parse_data_123456789),
271 &parse_data_ptr_));
272}
273
274TEMPLATE_TEST_F(Test, Decode31Bits) {
275 const char parse_data_31_bits[] = { 0x87, 0xFF, 0xFF, 0xFF, 0x7F };
276 parse_data_ptr_ = parse_data_31_bits;
277 EXPECT_EQ(0x7FFFFFFF,
278 VarintType::Parse(parse_data_31_bits + sizeof(parse_data_31_bits),
279 &parse_data_ptr_));
280}
281
282TEST_F(VarintBEInt32Test, Decode32Bits) {
283 const char parse_data_32_bits[] = { 0x88, 0x80, 0x80, 0x80, 0x00 };
284 parse_data_ptr_ = parse_data_32_bits;
285 EXPECT_EQ(RESULT_ERROR,
286 VarintType::Parse(parse_data_32_bits + sizeof(parse_data_32_bits),
287 &parse_data_ptr_));
288}
289
290TEST_F(VarintBEInt64Test, Decode32Bits) {
291 const char parse_data_32_bits[] = { 0x88, 0x80, 0x80, 0x80, 0x00 };
292 parse_data_ptr_ = parse_data_32_bits;
293 EXPECT_EQ(0x80000000,
294 VarintType::Parse(parse_data_32_bits + sizeof(parse_data_32_bits),
295 &parse_data_ptr_));
296}
297
298TEMPLATE_TEST_F(Test, EncodeDecodeRandom) {
299 const int test_size = 1024; // 1K random encode/decode operations
300 char encode_buffer[VarintType::kMaxBytes];
301 srand(1);
302 for (int i = 0; i < test_size; ++i) {
303 SignedIntType value = PortableRandomInRange(VarintType::kMaxVal);
304 int length = VarintType::Encode(value, encode_buffer);
305 EXPECT_EQ(length, VarintType::Length(value));
306 const char* parse_pointer = encode_buffer;
307 EXPECT_EQ(value, VarintType::Parse(encode_buffer + sizeof(encode_buffer),
308 &parse_pointer));
309 EXPECT_EQ(encode_buffer + length, parse_pointer);
310 }
311 for (int i = 0; i < test_size; ++i) {
312 s_.clear();
313 SignedIntType value = PortableRandomInRange(VarintType::kMaxVal);
314 VarintType::AppendToString(value, &s_);
315 const int varint_length = static_cast<int>(s_.length());
316 EXPECT_EQ(VarintType::Length(value), varint_length);
317 const char* parse_pointer = s_.c_str();
318 const char* const buffer_end_pointer = s_.c_str() + s_.length();
319 EXPECT_EQ(value, VarintType::Parse(buffer_end_pointer, &parse_pointer));
320 EXPECT_EQ(buffer_end_pointer, parse_pointer);
321 }
322}
323
324} // anonymous namespace
325} // namespace open_vcdiff