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
24namespace open_vcdiff {
25namespace {  // anonymous
26
27using std::vector;
28
29class VCDiffHeaderParserTest : public testing::Test {
30 protected:
31  typedef std::string string;
32
33  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
211