• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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