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 #include <config.h>
17 #include "headerparser.h"
18 #include <stdlib.h> // rand, srand
19 #include <string>
20 #include <vector>
21 #include "testing.h"
22 #include "varint_bigendian.h"
23
24 namespace open_vcdiff {
25 namespace { // anonymous
26
27 using std::vector;
28
29 class VCDiffHeaderParserTest : public testing::Test {
30 protected:
31 typedef std::string string;
32
33 static const int kTestSize = 1024;
34
VCDiffHeaderParserTest()35 VCDiffHeaderParserTest() : parser(NULL) { }
36
~VCDiffHeaderParserTest()37 virtual ~VCDiffHeaderParserTest() {
38 delete parser;
39 }
40
SetUp()41 virtual void SetUp() {
42 srand(1); // make sure each test uses the same data set
43 }
44
StartParsing()45 void StartParsing() {
46 parser = new VCDiffHeaderParser(
47 encoded_buffer_.data(),
48 encoded_buffer_.data() + encoded_buffer_.size());
49 EXPECT_EQ(encoded_buffer_.data(), parser->UnparsedData());
50 }
51
VerifyByte(unsigned char expected_value)52 void VerifyByte(unsigned char expected_value) {
53 unsigned char decoded_byte = 0;
54 const char* prior_position = parser->UnparsedData();
55 EXPECT_TRUE(parser->ParseByte(&decoded_byte));
56 EXPECT_EQ(expected_value, decoded_byte);
57 EXPECT_EQ(RESULT_SUCCESS, parser->GetResult());
58 EXPECT_EQ(prior_position + sizeof(unsigned char),
59 parser->UnparsedData());
60 }
61
VerifyInt32(int32_t expected_value)62 void VerifyInt32(int32_t expected_value) {
63 int32_t decoded_integer = 0;
64 const char* prior_position = parser->UnparsedData();
65 EXPECT_TRUE(parser->ParseInt32("decoded int32", &decoded_integer));
66 EXPECT_EQ(expected_value, decoded_integer);
67 EXPECT_EQ(RESULT_SUCCESS, parser->GetResult());
68 EXPECT_EQ(prior_position + VarintBE<int32_t>::Length(decoded_integer),
69 parser->UnparsedData());
70 }
71
VerifyUInt32(uint32_t expected_value)72 void VerifyUInt32(uint32_t expected_value) {
73 uint32_t decoded_integer = 0;
74 const char* prior_position = parser->UnparsedData();
75 EXPECT_TRUE(parser->ParseUInt32("decoded uint32", &decoded_integer));
76 EXPECT_EQ(expected_value, decoded_integer);
77 EXPECT_EQ(RESULT_SUCCESS, parser->GetResult());
78 EXPECT_EQ(prior_position + VarintBE<int64_t>::Length(decoded_integer),
79 parser->UnparsedData());
80 }
81
VerifyChecksum(VCDChecksum expected_value)82 void VerifyChecksum(VCDChecksum expected_value) {
83 VCDChecksum decoded_checksum = 0;
84 const char* prior_position = parser->UnparsedData();
85 EXPECT_TRUE(parser->ParseChecksum("decoded checksum", &decoded_checksum));
86 EXPECT_EQ(expected_value, decoded_checksum);
87 EXPECT_EQ(RESULT_SUCCESS, parser->GetResult());
88 EXPECT_EQ(prior_position + VarintBE<int64_t>::Length(decoded_checksum),
89 parser->UnparsedData());
90 }
91
92 string encoded_buffer_;
93 VCDiffHeaderParser* parser;
94 };
95
TEST_F(VCDiffHeaderParserTest,ParseRandomBytes)96 TEST_F(VCDiffHeaderParserTest, ParseRandomBytes) {
97 vector<unsigned char> byte_values;
98 for (int i = 0; i < kTestSize; ++i) {
99 unsigned char random_byte = PortableRandomInRange<unsigned char>(0xFF);
100 encoded_buffer_.push_back(random_byte);
101 byte_values.push_back(random_byte);
102 }
103 StartParsing();
104 for (int position = 0; position < kTestSize; ++position) {
105 VerifyByte(byte_values[position]);
106 }
107 unsigned char decoded_byte = 0;
108 EXPECT_FALSE(parser->ParseByte(&decoded_byte));
109 EXPECT_EQ(RESULT_END_OF_DATA, parser->GetResult());
110 EXPECT_EQ(encoded_buffer_.data() + encoded_buffer_.size(),
111 parser->UnparsedData());
112 }
113
TEST_F(VCDiffHeaderParserTest,ParseRandomInt32)114 TEST_F(VCDiffHeaderParserTest, ParseRandomInt32) {
115 vector<int32_t> integer_values;
116 for (int i = 0; i < kTestSize; ++i) {
117 int32_t random_integer = PortableRandomInRange<int32_t>(0x7FFFFFFF);
118 VarintBE<int32_t>::AppendToString(random_integer, &encoded_buffer_);
119 integer_values.push_back(random_integer);
120 }
121 StartParsing();
122 for (int i = 0; i < kTestSize; ++i) {
123 VerifyInt32(integer_values[i]);
124 }
125 int32_t decoded_integer = 0;
126 EXPECT_FALSE(parser->ParseInt32("decoded integer", &decoded_integer));
127 EXPECT_EQ(RESULT_END_OF_DATA, parser->GetResult());
128 EXPECT_EQ(encoded_buffer_.data() + encoded_buffer_.size(),
129 parser->UnparsedData());
130 }
131
TEST_F(VCDiffHeaderParserTest,ParseRandomUInt32)132 TEST_F(VCDiffHeaderParserTest, ParseRandomUInt32) {
133 vector<uint32_t> integer_values;
134 for (int i = 0; i < kTestSize; ++i) {
135 uint32_t random_integer = PortableRandomInRange<uint32_t>(0xFFFFFFFF);
136 VarintBE<int64_t>::AppendToString(random_integer, &encoded_buffer_);
137 integer_values.push_back(random_integer);
138 }
139 StartParsing();
140 uint32_t decoded_integer = 0;
141 for (int i = 0; i < kTestSize; ++i) {
142 VerifyUInt32(integer_values[i]);
143 }
144 EXPECT_FALSE(parser->ParseUInt32("decoded integer", &decoded_integer));
145 EXPECT_EQ(RESULT_END_OF_DATA, parser->GetResult());
146 EXPECT_EQ(encoded_buffer_.data() + encoded_buffer_.size(),
147 parser->UnparsedData());
148 }
149
TEST_F(VCDiffHeaderParserTest,ParseRandomChecksum)150 TEST_F(VCDiffHeaderParserTest, ParseRandomChecksum) {
151 vector<VCDChecksum> checksum_values;
152 for (int i = 0; i < kTestSize; ++i) {
153 VCDChecksum random_checksum =
154 PortableRandomInRange<VCDChecksum>(0xFFFFFFFF);
155 VarintBE<int64_t>::AppendToString(random_checksum, &encoded_buffer_);
156 checksum_values.push_back(random_checksum);
157 }
158 StartParsing();
159 for (int i = 0; i < kTestSize; ++i) {
160 VerifyChecksum(checksum_values[i]);
161 }
162 VCDChecksum decoded_checksum = 0;
163 EXPECT_FALSE(parser->ParseChecksum("decoded checksum", &decoded_checksum));
164 EXPECT_EQ(RESULT_END_OF_DATA, parser->GetResult());
165 EXPECT_EQ(encoded_buffer_.data() + encoded_buffer_.size(),
166 parser->UnparsedData());
167 }
168
TEST_F(VCDiffHeaderParserTest,ParseMixed)169 TEST_F(VCDiffHeaderParserTest, ParseMixed) {
170 VarintBE<int64_t>::AppendToString(0xCAFECAFE, &encoded_buffer_);
171 encoded_buffer_.push_back(0xFF);
172 VarintBE<int32_t>::AppendToString(0x02020202, &encoded_buffer_);
173 VarintBE<int64_t>::AppendToString(0xCAFECAFE, &encoded_buffer_);
174 encoded_buffer_.push_back(0xFF);
175 encoded_buffer_.push_back(0xFF);
176 StartParsing();
177 VerifyUInt32(0xCAFECAFE);
178 VerifyByte(0xFF);
179 VerifyInt32(0x02020202);
180 VerifyChecksum(0xCAFECAFE);
181 int32_t incomplete_int32 = 0;
182 EXPECT_FALSE(parser->ParseInt32("incomplete Varint", &incomplete_int32));
183 EXPECT_EQ(0, incomplete_int32);
184 EXPECT_EQ(RESULT_END_OF_DATA, parser->GetResult());
185 EXPECT_EQ(encoded_buffer_.data() + encoded_buffer_.size() - 2,
186 parser->UnparsedData());
187 }
188
TEST_F(VCDiffHeaderParserTest,ParseInvalidVarint)189 TEST_F(VCDiffHeaderParserTest, ParseInvalidVarint) {
190 // Start with a byte that has the continuation bit plus a high-order bit set
191 encoded_buffer_.append(1, static_cast<char>(0xC0));
192 // Add too many bytes with continuation bits
193 encoded_buffer_.append(6, static_cast<char>(0x80));
194 StartParsing();
195 int32_t invalid_int32 = 0;
196 EXPECT_FALSE(parser->ParseInt32("invalid Varint", &invalid_int32));
197 EXPECT_EQ(0, invalid_int32);
198 EXPECT_EQ(RESULT_ERROR, parser->GetResult());
199 EXPECT_EQ(encoded_buffer_.data(), parser->UnparsedData());
200 // After the parse failure, any other call to Parse... should return an error,
201 // even though there is still a byte that could be read as valid.
202 unsigned char decoded_byte = 0;
203 EXPECT_FALSE(parser->ParseByte(&decoded_byte));
204 EXPECT_EQ(0, decoded_byte);
205 EXPECT_EQ(RESULT_ERROR, parser->GetResult());
206 EXPECT_EQ(encoded_buffer_.data(), parser->UnparsedData());
207 }
208
209 } // namespace open_vcdiff
210 } // anonymous namespace
211