Home | History | Annotate | Download | only in src
      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