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