Home | History | Annotate | Download | only in src
      1 // Copyright 2007 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 "addrcache.h"
     18 #include <limits.h>  // INT_MAX, INT_MIN
     19 #include <stdint.h>  // uint32_t
     20 #include <stdlib.h>  // rand, srand
     21 #include <iostream>
     22 #include <string>
     23 #include <vector>
     24 #include "testing.h"
     25 #include "varint_bigendian.h"
     26 #include "vcdiff_defs.h"  // RESULT_ERROR
     27 
     28 namespace open_vcdiff {
     29 namespace {
     30 
     31 // Provides an address_stream_ buffer and functions to manually encode
     32 // values into the buffer, and to manually decode and verify test results
     33 // from the buffer.
     34 //
     35 class VCDiffAddressCacheTest : public testing::Test {
     36  public:
     37   typedef std::string string;
     38 
     39   VCDiffAddressCacheTest() : decode_position_(NULL),
     40                              decode_position_end_(NULL),
     41                              verify_encode_position_(NULL),
     42                              last_encode_size_(0),
     43                              last_decode_position_(NULL) { }
     44 
     45   virtual ~VCDiffAddressCacheTest() { }
     46 
     47   virtual void SetUp() {
     48     EXPECT_TRUE(cache_.Init());
     49   }
     50 
     51   // Benchmarks for timing encode/decode operations
     52   void BM_Setup(int test_size);
     53   void BM_CacheEncode(int iterations, int test_size);
     54   void BM_CacheDecode(int iterations, int test_size);
     55 
     56  protected:
     57   virtual void TestBody() { }  // to allow instantiation of this class
     58 
     59   void BeginDecode() {
     60     decode_position_ = address_stream_.data();
     61     EXPECT_TRUE(decode_position_ != NULL);
     62     last_decode_position_ = decode_position_;
     63     decode_position_end_ = decode_position_ + address_stream_.size();
     64   }
     65 
     66   void ExpectEncodedSizeInBytes(int n) {
     67     EXPECT_EQ(last_encode_size_ + n, address_stream_.size());
     68     last_encode_size_ = address_stream_.size();
     69   }
     70 
     71   void ExpectDecodedSizeInBytes(int n) {
     72     EXPECT_EQ(last_decode_position_ + n, decode_position_);
     73     last_decode_position_ = decode_position_;
     74   }
     75 
     76   void ManualEncodeVarint(VCDAddress value) {
     77     VarintBE<VCDAddress>::AppendToString(value, &address_stream_);
     78   }
     79 
     80   void ManualEncodeByte(unsigned char byte) {
     81     address_stream_.push_back(byte);
     82   }
     83 
     84   void ExpectEncodedVarint(VCDAddress expected_value, int expected_size) {
     85     if (!verify_encode_position_) {
     86       verify_encode_position_ = address_stream_.data();
     87     }
     88     EXPECT_EQ(expected_size, VarintBE<VCDAddress>::Length(expected_value));
     89     VCDAddress output_val = VarintBE<VCDAddress>::Parse(
     90         address_stream_.data() + address_stream_.size(),
     91         &verify_encode_position_);
     92     EXPECT_EQ(expected_value, output_val);
     93   }
     94 
     95   void ExpectEncodedByte(unsigned char expected_value) {
     96     if (!verify_encode_position_) {
     97       verify_encode_position_ = address_stream_.data();
     98     }
     99     EXPECT_EQ(expected_value, *verify_encode_position_);
    100     ++verify_encode_position_;
    101   }
    102 
    103   void TestEncode(VCDAddress address,
    104                   VCDAddress here_address,
    105                   unsigned char mode,
    106                   int size) {
    107     VCDAddress encoded_addr = 0;
    108     EXPECT_EQ(mode, cache_.EncodeAddress(address, here_address, &encoded_addr));
    109     if (cache_.WriteAddressAsVarintForMode(mode)) {
    110       ManualEncodeVarint(encoded_addr);
    111     } else {
    112       EXPECT_GT(256, encoded_addr);
    113       ManualEncodeByte(static_cast<unsigned char>(encoded_addr));
    114     }
    115     ExpectEncodedSizeInBytes(size);
    116   }
    117 
    118   VCDiffAddressCache cache_;
    119   string address_stream_;
    120   const char* decode_position_;
    121   const char* decode_position_end_;
    122   string large_address_stream_;
    123   std::vector<unsigned char> mode_stream_;
    124   std::vector<VCDAddress> verify_stream_;
    125 
    126  private:
    127   const char* verify_encode_position_;
    128   string::size_type last_encode_size_;
    129   const char*       last_decode_position_;
    130 };
    131 
    132 #ifdef GTEST_HAS_DEATH_TEST
    133 // This synonym is needed for the tests that use ASSERT_DEATH
    134 typedef VCDiffAddressCacheTest VCDiffAddressCacheDeathTest;
    135 #endif  // GTEST_HAS_DEATH_TEST
    136 
    137 // Having either or both cache size == 0 is acceptable
    138 TEST_F(VCDiffAddressCacheTest, ZeroCacheSizes) {
    139   VCDiffAddressCache zero_cache(0, 0);
    140   EXPECT_TRUE(zero_cache.Init());
    141 }
    142 
    143 TEST_F(VCDiffAddressCacheTest, NegativeCacheSizes) {
    144   VCDiffAddressCache negative_cache(-1, -1);   // The constructor must not fail
    145   EXPECT_FALSE(negative_cache.Init());
    146 }
    147 
    148 TEST_F(VCDiffAddressCacheTest, OnlySameCacheSizeIsNegative) {
    149   VCDiffAddressCache negative_cache(0, -1);   // The constructor must not fail
    150   EXPECT_FALSE(negative_cache.Init());
    151 }
    152 
    153 TEST_F(VCDiffAddressCacheTest, ExtremePositiveCacheSizes) {
    154   // The constructor must not fail
    155   VCDiffAddressCache int_max_cache(INT_MAX, INT_MAX);
    156   EXPECT_FALSE(int_max_cache.Init());
    157 }
    158 
    159 TEST_F(VCDiffAddressCacheTest, ExtremeNegativeCacheSizes) {
    160   // The constructor must not fail
    161   VCDiffAddressCache int_min_cache(INT_MIN, INT_MIN);
    162   EXPECT_FALSE(int_min_cache.Init());
    163 }
    164 
    165 // VCD_MAX_MODES is the maximum number of modes, including SAME and HERE modes.
    166 // So neither the SAME cache nor the HERE cache can be larger than
    167 // (VCD_MAX_MODES - 2).
    168 TEST_F(VCDiffAddressCacheTest, NearCacheSizeIsTooBig) {
    169   VCDiffAddressCache negative_cache(VCD_MAX_MODES - 1, 0);
    170   EXPECT_FALSE(negative_cache.Init());
    171 }
    172 
    173 TEST_F(VCDiffAddressCacheTest, SameCacheSizeIsTooBig) {
    174   VCDiffAddressCache negative_cache(0, VCD_MAX_MODES - 1);
    175   EXPECT_FALSE(negative_cache.Init());
    176 }
    177 
    178 TEST_F(VCDiffAddressCacheTest, CombinedSizesAreTooBig) {
    179   VCDiffAddressCache negative_cache((VCD_MAX_MODES / 2),
    180                                     (VCD_MAX_MODES / 2) - 1);
    181   EXPECT_FALSE(negative_cache.Init());
    182 }
    183 
    184 TEST_F(VCDiffAddressCacheTest, MaxLegalNearCacheSize) {
    185   VCDiffAddressCache negative_cache(VCD_MAX_MODES - 2, 0);
    186   EXPECT_TRUE(negative_cache.Init());
    187 }
    188 
    189 TEST_F(VCDiffAddressCacheTest, MaxLegalSameCacheSize) {
    190   VCDiffAddressCache negative_cache(0, VCD_MAX_MODES - 2);
    191   EXPECT_TRUE(negative_cache.Init());
    192 }
    193 
    194 TEST_F(VCDiffAddressCacheTest, MaxLegalCombinedSizes) {
    195   VCDiffAddressCache negative_cache((VCD_MAX_MODES / 2) - 1,
    196                                     (VCD_MAX_MODES / 2) - 1);
    197   EXPECT_TRUE(negative_cache.Init());
    198 }
    199 
    200 TEST_F(VCDiffAddressCacheTest, DestroyWithoutInitialization) {
    201   VCDiffAddressCache no_init_cache(4, 3);
    202   // Should be destroyed without crashing
    203 }
    204 
    205 TEST_F(VCDiffAddressCacheTest, DestroyDefaultWithoutInitialization) {
    206   VCDiffAddressCache no_init_cache;
    207   // Should be destroyed without crashing
    208 }
    209 
    210 TEST_F(VCDiffAddressCacheTest, CacheContentsInitiallyZero) {
    211   VCDAddress test_address = 0;
    212   // Check that caches are initially set to zero
    213   for (test_address = 0; test_address < 4; ++test_address) {
    214     EXPECT_EQ(0, cache_.NearAddress(test_address));
    215   }
    216   for (test_address = 0; test_address < 256 * 3; ++test_address) {
    217     EXPECT_EQ(0, cache_.SameAddress(test_address));
    218   }
    219 }
    220 
    221 // Inserts values 1, 2, ... , 10 into the cache and tests its entire
    222 // contents for consistency.
    223 //
    224 TEST_F(VCDiffAddressCacheTest, InsertFirstTen) {
    225   VCDAddress test_address = 0;
    226   for (test_address = 1; test_address <= 10; ++test_address) {
    227     cache_.UpdateCache(test_address);
    228   }
    229   EXPECT_EQ(9, cache_.NearAddress(0));   // slot 0: 1 => 5 => 9
    230   EXPECT_EQ(10, cache_.NearAddress(1));  // slot 1: 2 => 6 => 10
    231   EXPECT_EQ(7, cache_.NearAddress(2));   // slot 2: 3 => 7
    232   EXPECT_EQ(8, cache_.NearAddress(3));   // slot 3: 4 => 8
    233   EXPECT_EQ(0, cache_.SameAddress(0));
    234   for (test_address = 1; test_address <= 10; ++test_address) {
    235     EXPECT_EQ(test_address, cache_.SameAddress(test_address));
    236   }
    237   for (test_address = 11; test_address < 256 * 3; ++test_address) {
    238     EXPECT_EQ(0, cache_.SameAddress(test_address));
    239   }
    240 }
    241 
    242 TEST_F(VCDiffAddressCacheTest, InsertIntMax) {
    243   cache_.UpdateCache(INT_MAX);
    244   EXPECT_EQ(INT_MAX, cache_.NearAddress(0));
    245   EXPECT_EQ(INT_MAX, cache_.SameAddress(INT_MAX % (256 * 3)));
    246   EXPECT_EQ(0, cache_.SameAddress((INT_MAX - 256) % (256 * 3)));
    247   EXPECT_EQ(0, cache_.SameAddress((INT_MAX - 512) % (256 * 3)));
    248 }
    249 
    250 // Exercises all four addressing mode types by encoding five values
    251 // with EncodeAddress.
    252 // Checks to see that the proper mode was selected in each case,
    253 // and that the encoding is correct.
    254 //
    255 TEST_F(VCDiffAddressCacheTest, EncodeAddressModes) {
    256   TestEncode(0x0000FFFF, 0x10000000,  VCD_SELF_MODE, 3);
    257   TestEncode(0x10000000, 0x10000010,  VCD_HERE_MODE, 1);
    258   TestEncode(0x10000004, 0x10000020,  cache_.FirstNearMode() + 0x01, 1);
    259   TestEncode(0x0FFFFFFE, 0x10000030,  VCD_HERE_MODE, 1);
    260   TestEncode(0x10000004, 0x10000040,  cache_.FirstSameMode() + 0x01, 1);
    261   ExpectEncodedVarint(0xFFFF, 3);  // SELF mode: addr 0x0000FFFF
    262   ExpectEncodedVarint(0x10, 1);    // HERE mode: here - 0x10 = 0x10000000
    263   ExpectEncodedVarint(0x04, 1);    // NEAR cache #1:
    264                                    // last addr + 0x4 = 0x10000004
    265   ExpectEncodedVarint(0x32, 1);    // HERE mode: here - 0x32 = 0x0FFFFFFE
    266   ExpectEncodedByte(0x04);         // SAME cache #1: 0x10000004 hits
    267 }
    268 
    269 // Exercises all four addressing mode types by manually encoding six values
    270 // and calling DecodeAddress on each one.
    271 //
    272 TEST_F(VCDiffAddressCacheTest, DecodeAddressModes) {
    273   ManualEncodeVarint(0xCAFE);
    274   ManualEncodeVarint(0xCAFE);
    275   ManualEncodeVarint(0x1000);
    276   ManualEncodeByte(0xFE);   // SAME mode uses a byte, not a Varint
    277   ManualEncodeVarint(0xFE);
    278   ManualEncodeVarint(0x1000);
    279   BeginDecode();
    280   EXPECT_EQ(0xCAFE,
    281             cache_.DecodeAddress(0x10000,
    282                                  VCD_SELF_MODE,
    283                                  &decode_position_,
    284                                  decode_position_end_));
    285   ExpectDecodedSizeInBytes(VarintBE<VCDAddress>::Length(0xCAFE));
    286   EXPECT_EQ(0x20000 - 0xCAFE,
    287             cache_.DecodeAddress(0x20000,
    288                                  VCD_HERE_MODE,
    289                                  &decode_position_,
    290                                  decode_position_end_));
    291   ExpectDecodedSizeInBytes(VarintBE<VCDAddress>::Length(0xCAFE));
    292   EXPECT_EQ(0xDAFE,
    293             cache_.DecodeAddress(0x30000,
    294                                  cache_.FirstNearMode(),
    295                                  &decode_position_,
    296                                  decode_position_end_));
    297   ExpectDecodedSizeInBytes(VarintBE<VCDAddress>::Length(0x1000));
    298   EXPECT_EQ(0xCAFE,
    299             cache_.DecodeAddress(0x40000,
    300                                  cache_.FirstSameMode() + (0xCA % 3),
    301                                  &decode_position_,
    302                                  decode_position_end_));
    303   ExpectDecodedSizeInBytes(sizeof(unsigned char));  // a byte, not a Varint
    304   EXPECT_EQ(0xFE,
    305             cache_.DecodeAddress(0x50000,
    306                                  VCD_SELF_MODE,
    307                                  &decode_position_,
    308                                  decode_position_end_));
    309   ExpectDecodedSizeInBytes(VarintBE<VCDAddress>::Length(0xFE));
    310   // NEAR mode #0 has been overwritten by fifth computed addr (wrap around)
    311   EXPECT_EQ(0x10FE,
    312             cache_.DecodeAddress(0x60000,
    313                                  cache_.FirstNearMode(),
    314                                  &decode_position_,
    315                                  decode_position_end_));
    316   ExpectDecodedSizeInBytes(VarintBE<VCDAddress>::Length(0x1000));
    317 }
    318 
    319 // Test with both cache sizes == 0.  The encoder should not choose
    320 // a SAME or NEAR mode under these conditions.
    321 TEST_F(VCDiffAddressCacheTest, EncodeAddressZeroCacheSizes) {
    322   VCDAddress encoded_addr = 0;
    323   VCDiffAddressCache zero_cache(0, 0);
    324   EXPECT_TRUE(zero_cache.Init());
    325   EXPECT_EQ(VCD_SELF_MODE,
    326             zero_cache.EncodeAddress(0x0000FFFF, 0x10000000, &encoded_addr));
    327   EXPECT_EQ(0xFFFF, encoded_addr);
    328   EXPECT_EQ(VCD_HERE_MODE,
    329             zero_cache.EncodeAddress(0x10000000, 0x10000010, &encoded_addr));
    330   EXPECT_EQ(0x10, encoded_addr);
    331   EXPECT_EQ(VCD_HERE_MODE,
    332             zero_cache.EncodeAddress(0x10000004, 0x10000020, &encoded_addr));
    333   EXPECT_EQ(0x1C, encoded_addr);
    334   EXPECT_EQ(VCD_HERE_MODE,
    335             zero_cache.EncodeAddress(0x0FFFFFFE, 0x10000030, &encoded_addr));
    336   EXPECT_EQ(0x32, encoded_addr);
    337   EXPECT_EQ(VCD_HERE_MODE,
    338             zero_cache.EncodeAddress(0x10000004, 0x10000040, &encoded_addr));
    339   EXPECT_EQ(0x3C, encoded_addr);
    340 }
    341 
    342 TEST_F(VCDiffAddressCacheTest, DecodeAddressZeroCacheSizes) {
    343   VCDiffAddressCache zero_cache(0, 0);
    344   EXPECT_TRUE(zero_cache.Init());
    345   ManualEncodeVarint(0xCAFE);
    346   ManualEncodeVarint(0xCAFE);
    347   ManualEncodeVarint(0xDAFE);
    348   BeginDecode();
    349   EXPECT_EQ(0xCAFE, zero_cache.DecodeAddress(0x10000,
    350                                              VCD_SELF_MODE,
    351                                              &decode_position_,
    352                                              decode_position_end_));
    353   ExpectDecodedSizeInBytes(VarintBE<VCDAddress>::Length(0xCAFE));
    354   EXPECT_EQ(0x20000 - 0xCAFE, zero_cache.DecodeAddress(0x20000,
    355                                                        VCD_HERE_MODE,
    356                                                        &decode_position_,
    357                                                        decode_position_end_));
    358   ExpectDecodedSizeInBytes(VarintBE<VCDAddress>::Length(0xCAFE));
    359   EXPECT_EQ(0xDAFE, zero_cache.DecodeAddress(0x30000,
    360                                              VCD_SELF_MODE,
    361                                              &decode_position_,
    362                                              decode_position_end_));
    363   ExpectDecodedSizeInBytes(VarintBE<VCDAddress>::Length(0xDAFE));
    364 }
    365 
    366 #ifdef GTEST_HAS_DEATH_TEST
    367 TEST_F(VCDiffAddressCacheDeathTest, EncodeNegativeAddress) {
    368   VCDAddress dummy_encoded_address = 0;
    369   EXPECT_DEBUG_DEATH(cache_.EncodeAddress(-1, -1, &dummy_encoded_address),
    370                      "negative");
    371 }
    372 
    373 TEST_F(VCDiffAddressCacheDeathTest, EncodeAddressPastHereAddress) {
    374   VCDAddress dummy_encoded_address = 0;
    375   EXPECT_DEBUG_DEATH(cache_.EncodeAddress(0x100, 0x100, &dummy_encoded_address),
    376                      "address.*<.*here_address");
    377   EXPECT_DEBUG_DEATH(cache_.EncodeAddress(0x200, 0x100, &dummy_encoded_address),
    378                      "address.*<.*here_address");
    379 }
    380 
    381 TEST_F(VCDiffAddressCacheDeathTest, DecodeInvalidMode) {
    382   ManualEncodeVarint(0xCAFE);
    383   BeginDecode();
    384   EXPECT_DEBUG_DEATH(EXPECT_EQ(RESULT_ERROR,
    385                                cache_.DecodeAddress(0x10000000,
    386                                                     cache_.LastMode() + 1,
    387                                                     &decode_position_,
    388                                                     decode_position_end_)),
    389                      "mode");
    390   EXPECT_DEBUG_DEATH(EXPECT_EQ(RESULT_ERROR,
    391                                cache_.DecodeAddress(0x10000000,
    392                                                     0xFF,
    393                                                     &decode_position_,
    394                                                     decode_position_end_)),
    395                      "mode");
    396   ExpectDecodedSizeInBytes(0);  // Should not modify decode_position_
    397 }
    398 
    399 TEST_F(VCDiffAddressCacheDeathTest, DecodeZeroOrNegativeHereAddress) {
    400   ManualEncodeVarint(0xCAFE);
    401   ManualEncodeVarint(0xCAFE);
    402   BeginDecode();
    403   // Using a Debug build, the check will fail; using a Release build,
    404   // the check will not occur, and the SELF mode does not depend on
    405   // the value of here_address, so DecodeAddress() will succeed.
    406   EXPECT_DEBUG_DEATH(cache_.DecodeAddress(-1,
    407                                           VCD_SELF_MODE,
    408                                           &decode_position_,
    409                                           decode_position_end_),
    410                      "negative");
    411   // A zero value for here_address should not kill the decoder,
    412   // but instead should return an error value.  A delta file may contain
    413   // a window that has no source segment and that (erroneously)
    414   // uses a COPY instruction as its first instruction.  This should
    415   // cause an error to be reported, not a debug check failure.
    416   EXPECT_EQ(RESULT_ERROR, cache_.DecodeAddress(0,
    417                                          VCD_SELF_MODE,
    418                                          &decode_position_,
    419                                          decode_position_end_));
    420 }
    421 #endif  // GTEST_HAS_DEATH_TEST
    422 
    423 TEST_F(VCDiffAddressCacheTest, DecodeAddressPastHereAddress) {
    424   ManualEncodeVarint(0xCAFE);
    425   BeginDecode();
    426   EXPECT_EQ(RESULT_ERROR, cache_.DecodeAddress(0x1000,
    427                                          VCD_SELF_MODE,
    428                                          &decode_position_,
    429                                          decode_position_end_));
    430   ExpectDecodedSizeInBytes(0);  // Should not modify decode_position_
    431 }
    432 
    433 TEST_F(VCDiffAddressCacheTest, HereModeAddressTooLarge) {
    434   ManualEncodeVarint(0x10001);  // here_address + 1
    435   BeginDecode();
    436   EXPECT_EQ(RESULT_ERROR, cache_.DecodeAddress(0x10000,
    437                                          VCD_HERE_MODE,
    438                                          &decode_position_,
    439                                          decode_position_end_));
    440   ExpectDecodedSizeInBytes(0);  // Should not modify decode_position_
    441 }
    442 
    443 TEST_F(VCDiffAddressCacheTest, NearModeAddressOverflow) {
    444   ManualEncodeVarint(0xCAFE);
    445   ManualEncodeVarint(0x7FFFFFFF);
    446   BeginDecode();
    447   EXPECT_EQ(0xCAFE, cache_.DecodeAddress(0x10000,
    448                                          VCD_SELF_MODE,
    449                                          &decode_position_,
    450                                          decode_position_end_));
    451   ExpectDecodedSizeInBytes(VarintBE<VCDAddress>::Length(0xCAFE));
    452   // Now decode a NEAR mode address of base address 0xCAFE
    453   // (the first decoded address) + offset 0x7FFFFFFF.  This will cause
    454   // an integer overflow and should signal an error.
    455   EXPECT_EQ(RESULT_ERROR, cache_.DecodeAddress(0x10000000,
    456                                          cache_.FirstNearMode(),
    457                                          &decode_position_,
    458                                          decode_position_end_));
    459   ExpectDecodedSizeInBytes(0);  // Should not modify decode_position_
    460 }
    461 
    462 // A Varint should contain at most 9 bytes that have their continuation bit
    463 // (the uppermost, or 7 bit) set.  A longer string of bytes that all have
    464 // bit 7 set is not a valid Varint.  Try to parse such a string as a Varint
    465 // and confirm that it does not run off the end of the input buffer and
    466 // it returns an error value (RESULT_ERROR).
    467 //
    468 TEST_F(VCDiffAddressCacheTest, DecodeInvalidVarint) {
    469   address_stream_.clear();
    470   // Write 512 0xFE bytes
    471   address_stream_.append(512, static_cast<char>(0xFE));
    472   BeginDecode();
    473   EXPECT_EQ(RESULT_ERROR, cache_.DecodeAddress(0x10000000,
    474                                          VCD_SELF_MODE,
    475                                          &decode_position_,
    476                                          decode_position_end_));
    477   ExpectDecodedSizeInBytes(0);  // Should not modify decode_position_
    478 }
    479 
    480 // If only part of a Varint appears in the data to be decoded,
    481 // then DecodeAddress should return RESULT_END_OF_DATA,
    482 // which means that the Varint *may* be valid if there is more
    483 // data expected to be returned.
    484 //
    485 TEST_F(VCDiffAddressCacheTest, DecodePartialVarint) {
    486   address_stream_.clear();
    487   ManualEncodeByte(0xFE);
    488   ManualEncodeByte(0xFE);
    489   ManualEncodeByte(0xFE);
    490   BeginDecode();
    491   EXPECT_EQ(RESULT_END_OF_DATA,
    492             cache_.DecodeAddress(0x10000000,
    493                                  VCD_SELF_MODE,
    494                                  &decode_position_,
    495                                  decode_position_end_));
    496   ExpectDecodedSizeInBytes(0);  // Should not modify decode_position_
    497   // Now add the missing last byte (supposedly read from a stream of data)
    498   // and verify that the Varint is now valid.
    499   ManualEncodeByte(0x01);  // End the Varint with an additional byte
    500   BeginDecode();  // Reset read position to start of data
    501   EXPECT_EQ(0xFDFBF01,
    502             cache_.DecodeAddress(0x10000000,
    503                                  VCD_SELF_MODE,
    504                                  &decode_position_,
    505                                  decode_position_end_));
    506   ExpectDecodedSizeInBytes(4);  // ManualEncodeByte was called for 4 byte values
    507 }
    508 
    509 #ifdef GTEST_HAS_DEATH_TEST
    510 TEST_F(VCDiffAddressCacheDeathTest, DecodeBadMode) {
    511   ManualEncodeVarint(0xCAFE);
    512   BeginDecode();
    513   EXPECT_DEBUG_DEATH(EXPECT_EQ(RESULT_ERROR,
    514                                cache_.DecodeAddress(0x10000,
    515                                                     cache_.LastMode() + 1,
    516                                                     &decode_position_,
    517                                                     decode_position_end_)),
    518                      "maximum");
    519   ExpectDecodedSizeInBytes(0);
    520 }
    521 #endif  // GTEST_HAS_DEATH_TEST
    522 
    523 TEST_F(VCDiffAddressCacheTest, DecodeInvalidHereAddress) {
    524   ManualEncodeVarint(0x10001);  // offset larger than here_address
    525   BeginDecode();
    526   EXPECT_EQ(RESULT_ERROR, cache_.DecodeAddress(0x10000,
    527                                          VCD_HERE_MODE,
    528                                          &decode_position_,
    529                                          decode_position_end_));
    530   ExpectDecodedSizeInBytes(0);
    531 }
    532 
    533 TEST_F(VCDiffAddressCacheTest, DecodeInvalidNearAddress) {
    534   ManualEncodeVarint(0xCAFE);
    535   ManualEncodeVarint(INT_MAX);  // offset will cause integer overflow
    536   BeginDecode();
    537   EXPECT_EQ(0xCAFE,
    538             cache_.DecodeAddress(0x10000,
    539                                  VCD_SELF_MODE,
    540                                  &decode_position_,
    541                                  decode_position_end_));
    542   ExpectDecodedSizeInBytes(VarintBE<VCDAddress>::Length(0xCAFE));
    543   EXPECT_EQ(RESULT_ERROR, cache_.DecodeAddress(0x10000,
    544                                          cache_.FirstNearMode(),
    545                                          &decode_position_,
    546                                          decode_position_end_));
    547   ExpectDecodedSizeInBytes(0);
    548 }
    549 
    550 void VCDiffAddressCacheTest::BM_Setup(int test_size) {
    551   mode_stream_.resize(test_size);
    552   verify_stream_.resize(test_size);
    553   VCDAddress here_address = 1;
    554   srand(1);
    555   for (int i = 0; i < test_size; ++i) {
    556     verify_stream_[i] = PortableRandomInRange(here_address - 1);
    557     here_address += 4;
    558   }
    559   BM_CacheEncode(1, test_size);  // populate large_address_stream_, mode_stream_
    560 }
    561 
    562 void VCDiffAddressCacheTest::BM_CacheEncode(int iterations, int test_size) {
    563   VCDAddress here_address = 1;
    564   VCDAddress encoded_addr = 0;
    565   for (int test_iteration = 0; test_iteration < iterations; ++test_iteration) {
    566     cache_.Init();
    567     large_address_stream_.clear();
    568     here_address = 1;
    569     for (int i = 0; i < test_size; ++i) {
    570       const unsigned char mode = cache_.EncodeAddress(verify_stream_[i],
    571                                                       here_address,
    572                                                       &encoded_addr);
    573       if (cache_.WriteAddressAsVarintForMode(mode)) {
    574         VarintBE<VCDAddress>::AppendToString(encoded_addr,
    575                                              &large_address_stream_);
    576       } else {
    577         EXPECT_GT(256, encoded_addr);
    578         large_address_stream_.push_back(
    579             static_cast<unsigned char>(encoded_addr));
    580       }
    581       mode_stream_[i] = mode;
    582       here_address += 4;
    583     }
    584   }
    585 }
    586 
    587 void VCDiffAddressCacheTest::BM_CacheDecode(int iterations, int test_size) {
    588   VCDAddress here_address = 1;
    589   for (int test_iteration = 0; test_iteration < iterations; ++test_iteration) {
    590     cache_.Init();
    591     const char* large_decode_pointer = large_address_stream_.data();
    592     const char* const end_of_encoded_data =
    593         large_decode_pointer + large_address_stream_.size();
    594     here_address = 1;
    595     for (int i = 0; i < test_size; ++i) {
    596       EXPECT_EQ(verify_stream_[i],
    597                 cache_.DecodeAddress(here_address,
    598                                      mode_stream_[i],
    599                                      &large_decode_pointer,
    600                                      end_of_encoded_data));
    601       here_address += 4;
    602     }
    603     EXPECT_EQ(end_of_encoded_data, large_decode_pointer);
    604   }
    605 }
    606 
    607 TEST_F(VCDiffAddressCacheTest, PerformanceTest) {
    608   const int test_size = 20 * 1024;  // 20K random encode/decode operations
    609   const int num_iterations = 40;  // run test 40 times and take average
    610   BM_Setup(test_size);
    611   {
    612     CycleTimer encode_timer;
    613     encode_timer.Start();
    614     BM_CacheEncode(num_iterations, test_size);
    615     encode_timer.Stop();
    616     double encode_time_in_ms =
    617         static_cast<double>(encode_timer.GetInUsec()) / 1000;
    618     std::cout << "Time to encode: "
    619               << (encode_time_in_ms / num_iterations) << " ms" << std::endl;
    620   }
    621   {
    622     CycleTimer decode_timer;
    623     decode_timer.Start();
    624     BM_CacheDecode(num_iterations, test_size);
    625     decode_timer.Stop();
    626     double decode_time_in_ms =
    627         static_cast<double>(decode_timer.GetInUsec()) / 1000;
    628     std::cout << "Time to decode: "
    629               << (decode_time_in_ms / num_iterations) << " ms" << std::endl;
    630   }
    631 }
    632 
    633 }  // unnamed namespace
    634 }  // namespace open_vcdiff
    635