blob: 66ed8249eeb25c3bb0428a72512f3cc3c83d8c7c [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 "headerparser.h"
openvcdiff28db8072008-10-10 23:29:11 +000018#include <stdlib.h> // rand, srand
openvcdiff311c7142008-08-26 19:29:25 +000019#include <string>
20#include <vector>
21#include "testing.h"
22#include "varint_bigendian.h"
23
24namespace open_vcdiff {
25namespace { // anonymous
26
openvcdiff311c7142008-08-26 19:29:25 +000027using std::vector;
28
29class VCDiffHeaderParserTest : public testing::Test {
30 protected:
openvcdiff28db8072008-10-10 23:29:11 +000031 typedef std::string string;
openvcdiff28db8072008-10-10 23:29:11 +000032
openvcdiff311c7142008-08-26 19:29:25 +000033 static const int kTestSize = 1024;
34
35 VCDiffHeaderParserTest() : parser(NULL) { }
36
37 virtual ~VCDiffHeaderParserTest() {
38 delete parser;
39 }
40
41 virtual void SetUp() {
42 srand(1); // make sure each test uses the same data set
43 }
44
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
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
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
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
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
96TEST_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
114TEST_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
132TEST_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
150TEST_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
169TEST_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
189TEST_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