diff options
Diffstat (limited to 'sdch/open-vcdiff/src/headerparser_test.cc')
-rw-r--r-- | sdch/open-vcdiff/src/headerparser_test.cc | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/sdch/open-vcdiff/src/headerparser_test.cc b/sdch/open-vcdiff/src/headerparser_test.cc new file mode 100644 index 0000000..66ed824 --- /dev/null +++ b/sdch/open-vcdiff/src/headerparser_test.cc @@ -0,0 +1,210 @@ +// Copyright 2008 Google Inc. +// Author: Lincoln Smith +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include <config.h> +#include "headerparser.h" +#include <stdlib.h> // rand, srand +#include <string> +#include <vector> +#include "testing.h" +#include "varint_bigendian.h" + +namespace open_vcdiff { +namespace { // anonymous + +using std::vector; + +class VCDiffHeaderParserTest : public testing::Test { + protected: + typedef std::string string; + + static const int kTestSize = 1024; + + VCDiffHeaderParserTest() : parser(NULL) { } + + virtual ~VCDiffHeaderParserTest() { + delete parser; + } + + virtual void SetUp() { + srand(1); // make sure each test uses the same data set + } + + void StartParsing() { + parser = new VCDiffHeaderParser( + encoded_buffer_.data(), + encoded_buffer_.data() + encoded_buffer_.size()); + EXPECT_EQ(encoded_buffer_.data(), parser->UnparsedData()); + } + + void VerifyByte(unsigned char expected_value) { + unsigned char decoded_byte = 0; + const char* prior_position = parser->UnparsedData(); + EXPECT_TRUE(parser->ParseByte(&decoded_byte)); + EXPECT_EQ(expected_value, decoded_byte); + EXPECT_EQ(RESULT_SUCCESS, parser->GetResult()); + EXPECT_EQ(prior_position + sizeof(unsigned char), + parser->UnparsedData()); + } + + void VerifyInt32(int32_t expected_value) { + int32_t decoded_integer = 0; + const char* prior_position = parser->UnparsedData(); + EXPECT_TRUE(parser->ParseInt32("decoded int32", &decoded_integer)); + EXPECT_EQ(expected_value, decoded_integer); + EXPECT_EQ(RESULT_SUCCESS, parser->GetResult()); + EXPECT_EQ(prior_position + VarintBE<int32_t>::Length(decoded_integer), + parser->UnparsedData()); + } + + void VerifyUInt32(uint32_t expected_value) { + uint32_t decoded_integer = 0; + const char* prior_position = parser->UnparsedData(); + EXPECT_TRUE(parser->ParseUInt32("decoded uint32", &decoded_integer)); + EXPECT_EQ(expected_value, decoded_integer); + EXPECT_EQ(RESULT_SUCCESS, parser->GetResult()); + EXPECT_EQ(prior_position + VarintBE<int64_t>::Length(decoded_integer), + parser->UnparsedData()); + } + + void VerifyChecksum(VCDChecksum expected_value) { + VCDChecksum decoded_checksum = 0; + const char* prior_position = parser->UnparsedData(); + EXPECT_TRUE(parser->ParseChecksum("decoded checksum", &decoded_checksum)); + EXPECT_EQ(expected_value, decoded_checksum); + EXPECT_EQ(RESULT_SUCCESS, parser->GetResult()); + EXPECT_EQ(prior_position + VarintBE<int64_t>::Length(decoded_checksum), + parser->UnparsedData()); + } + + string encoded_buffer_; + VCDiffHeaderParser* parser; +}; + +TEST_F(VCDiffHeaderParserTest, ParseRandomBytes) { + vector<unsigned char> byte_values; + for (int i = 0; i < kTestSize; ++i) { + unsigned char random_byte = PortableRandomInRange<unsigned char>(0xFF); + encoded_buffer_.push_back(random_byte); + byte_values.push_back(random_byte); + } + StartParsing(); + for (int position = 0; position < kTestSize; ++position) { + VerifyByte(byte_values[position]); + } + unsigned char decoded_byte = 0; + EXPECT_FALSE(parser->ParseByte(&decoded_byte)); + EXPECT_EQ(RESULT_END_OF_DATA, parser->GetResult()); + EXPECT_EQ(encoded_buffer_.data() + encoded_buffer_.size(), + parser->UnparsedData()); +} + +TEST_F(VCDiffHeaderParserTest, ParseRandomInt32) { + vector<int32_t> integer_values; + for (int i = 0; i < kTestSize; ++i) { + int32_t random_integer = PortableRandomInRange<int32_t>(0x7FFFFFFF); + VarintBE<int32_t>::AppendToString(random_integer, &encoded_buffer_); + integer_values.push_back(random_integer); + } + StartParsing(); + for (int i = 0; i < kTestSize; ++i) { + VerifyInt32(integer_values[i]); + } + int32_t decoded_integer = 0; + EXPECT_FALSE(parser->ParseInt32("decoded integer", &decoded_integer)); + EXPECT_EQ(RESULT_END_OF_DATA, parser->GetResult()); + EXPECT_EQ(encoded_buffer_.data() + encoded_buffer_.size(), + parser->UnparsedData()); +} + +TEST_F(VCDiffHeaderParserTest, ParseRandomUInt32) { + vector<uint32_t> integer_values; + for (int i = 0; i < kTestSize; ++i) { + uint32_t random_integer = PortableRandomInRange<uint32_t>(0xFFFFFFFF); + VarintBE<int64_t>::AppendToString(random_integer, &encoded_buffer_); + integer_values.push_back(random_integer); + } + StartParsing(); + uint32_t decoded_integer = 0; + for (int i = 0; i < kTestSize; ++i) { + VerifyUInt32(integer_values[i]); + } + EXPECT_FALSE(parser->ParseUInt32("decoded integer", &decoded_integer)); + EXPECT_EQ(RESULT_END_OF_DATA, parser->GetResult()); + EXPECT_EQ(encoded_buffer_.data() + encoded_buffer_.size(), + parser->UnparsedData()); +} + +TEST_F(VCDiffHeaderParserTest, ParseRandomChecksum) { + vector<VCDChecksum> checksum_values; + for (int i = 0; i < kTestSize; ++i) { + VCDChecksum random_checksum = + PortableRandomInRange<VCDChecksum>(0xFFFFFFFF); + VarintBE<int64_t>::AppendToString(random_checksum, &encoded_buffer_); + checksum_values.push_back(random_checksum); + } + StartParsing(); + for (int i = 0; i < kTestSize; ++i) { + VerifyChecksum(checksum_values[i]); + } + VCDChecksum decoded_checksum = 0; + EXPECT_FALSE(parser->ParseChecksum("decoded checksum", &decoded_checksum)); + EXPECT_EQ(RESULT_END_OF_DATA, parser->GetResult()); + EXPECT_EQ(encoded_buffer_.data() + encoded_buffer_.size(), + parser->UnparsedData()); +} + +TEST_F(VCDiffHeaderParserTest, ParseMixed) { + VarintBE<int64_t>::AppendToString(0xCAFECAFE, &encoded_buffer_); + encoded_buffer_.push_back(0xFF); + VarintBE<int32_t>::AppendToString(0x02020202, &encoded_buffer_); + VarintBE<int64_t>::AppendToString(0xCAFECAFE, &encoded_buffer_); + encoded_buffer_.push_back(0xFF); + encoded_buffer_.push_back(0xFF); + StartParsing(); + VerifyUInt32(0xCAFECAFE); + VerifyByte(0xFF); + VerifyInt32(0x02020202); + VerifyChecksum(0xCAFECAFE); + int32_t incomplete_int32 = 0; + EXPECT_FALSE(parser->ParseInt32("incomplete Varint", &incomplete_int32)); + EXPECT_EQ(0, incomplete_int32); + EXPECT_EQ(RESULT_END_OF_DATA, parser->GetResult()); + EXPECT_EQ(encoded_buffer_.data() + encoded_buffer_.size() - 2, + parser->UnparsedData()); +} + +TEST_F(VCDiffHeaderParserTest, ParseInvalidVarint) { + // Start with a byte that has the continuation bit plus a high-order bit set + encoded_buffer_.append(1, static_cast<char>(0xC0)); + // Add too many bytes with continuation bits + encoded_buffer_.append(6, static_cast<char>(0x80)); + StartParsing(); + int32_t invalid_int32 = 0; + EXPECT_FALSE(parser->ParseInt32("invalid Varint", &invalid_int32)); + EXPECT_EQ(0, invalid_int32); + EXPECT_EQ(RESULT_ERROR, parser->GetResult()); + EXPECT_EQ(encoded_buffer_.data(), parser->UnparsedData()); + // After the parse failure, any other call to Parse... should return an error, + // even though there is still a byte that could be read as valid. + unsigned char decoded_byte = 0; + EXPECT_FALSE(parser->ParseByte(&decoded_byte)); + EXPECT_EQ(0, decoded_byte); + EXPECT_EQ(RESULT_ERROR, parser->GetResult()); + EXPECT_EQ(encoded_buffer_.data(), parser->UnparsedData()); +} + +} // namespace open_vcdiff +} // anonymous namespace |