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 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 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 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 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 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 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 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