Coverage for /Syzygy/block_graph/block_graph_serializer_unittest.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
96.9%2492570.C++test

Line-by-line coverage:

   1    :  // Copyright 2012 Google Inc. All Rights Reserved.
   2    :  //
   3    :  // Licensed under the Apache License, Version 2.0 (the "License");
   4    :  // you may not use this file except in compliance with the License.
   5    :  // You may obtain a copy of the License at
   6    :  //
   7    :  //     http://www.apache.org/licenses/LICENSE-2.0
   8    :  //
   9    :  // Unless required by applicable law or agreed to in writing, software
  10    :  // distributed under the License is distributed on an "AS IS" BASIS,
  11    :  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12    :  // See the License for the specific language governing permissions and
  13    :  // limitations under the License.
  14    :  
  15    :  #include "syzygy/block_graph/block_graph_serializer.h"
  16    :  
  17    :  #include "base/bind.h"
  18    :  #include "gtest/gtest.h"
  19    :  #include "syzygy/block_graph/unittest_util.h"
  20    :  #include "syzygy/core/serialization.h"
  21    :  
  22    :  namespace block_graph {
  23    :  
  24    :  namespace {
  25    :  
  26    :  class TestBlockGraphSerializer : public BlockGraphSerializer {
  27    :   public:
  28    :    using BlockGraphSerializer::SaveUint32;
  29    :    using BlockGraphSerializer::LoadUint32;
  30    :    using BlockGraphSerializer::SaveInt32;
  31    :    using BlockGraphSerializer::LoadInt32;
  32    :  };
  33    :  
  34    :  class BlockGraphSerializerTest : public ::testing::Test {
  35    :   public:
  36  E :    BlockGraphSerializerTest() : block_data_loaded_by_callback_(0) { }
  37    :  
  38  E :    virtual void SetUp() override {}
  39    :  
  40  E :    void InitOutArchive() {
  41  E :      v_.clear();
  42  E :      os_.reset(core::CreateByteOutStream(std::back_inserter(v_)));
  43    :      oa_.reset(new core::NativeBinaryOutArchive(
  44  E :          os_.get()));
  45  E :    }
  46    :  
  47  E :    void InitInArchive() {
  48  E :      is_.reset(core::CreateByteInStream(v_.begin(), v_.end()));
  49    :      ia_.reset(new core::NativeBinaryInArchive(
  50  E :          is_.get()));
  51  E :    }
  52    :  
  53  E :    void InitBlockGraph() {
  54  E :      BlockGraph::Section* text = bg_.AddSection(".text", 1 | 4);
  55  E :      BlockGraph::Section* data = bg_.AddSection(".data", 2);
  56  E :      BlockGraph::Section* rdata = bg_.AddSection(".rdata", 2 | 4);
  57    :  
  58  E :      BlockGraph::Block* c1 = bg_.AddBlock(BlockGraph::CODE_BLOCK, 20, "code1");
  59  E :      BlockGraph::Block* c2 = bg_.AddBlock(BlockGraph::CODE_BLOCK, 16, "code2");
  60  E :      BlockGraph::Block* d1 = bg_.AddBlock(BlockGraph::DATA_BLOCK, 20, "data1");
  61  E :      BlockGraph::Block* rd1 = bg_.AddBlock(BlockGraph::DATA_BLOCK, 16, "rdata1");
  62  E :      BlockGraph::Block* rd2 = bg_.AddBlock(BlockGraph::DATA_BLOCK, 16, "rdata2");
  63    :  
  64  E :      c1->set_section(text->id());
  65  E :      c2->set_section(text->id());
  66  E :      d1->set_section(data->id());
  67  E :      rd1->set_section(rdata->id());
  68  E :      rd2->set_section(rdata->id());
  69    :  
  70    :      // Set compiland name.
  71  E :      c1->set_compiland_name("c.o");
  72  E :      c2->set_compiland_name("c.o");
  73  E :      d1->set_compiland_name("d.o");
  74  E :      rd1->set_compiland_name("d.o");
  75  E :      rd2->set_compiland_name("d.o");
  76    :  
  77    :      // Set up alignments and paddings.
  78  E :      c2->set_alignment(16);
  79  E :      c2->set_alignment_offset(-4);
  80  E :      c2->set_padding_before(1);
  81  E :      d1->set_alignment(16);
  82  E :      rd1->set_alignment(16);
  83  E :      rd1->set_alignment(16);
  84    :  
  85    :      // Some of the blocks own their own data, some don't. One has no data at
  86    :      // all.
  87  E :      c1->SetData(kCode1Data, sizeof(kCode1Data));
  88  E :      c2->CopyData(sizeof(kCode2Data), kCode2Data);
  89  E :      d1->SetData(kData1Data, sizeof(kData1Data));
  90  E :      rd1->CopyData(sizeof(kRdata1Data), kRdata1Data);
  91    :  
  92    :      // Given them all source ranges.
  93    :      c1->source_ranges().Push(BlockGraph::Block::DataRange(0, 20),
  94  E :          BlockGraph::Block::SourceRange(core::RelativeAddress(0), 20));
  95    :      c2->source_ranges().Push(BlockGraph::Block::DataRange(0, 16),
  96  E :          BlockGraph::Block::SourceRange(core::RelativeAddress(36), 48));
  97    :      d1->source_ranges().Push(BlockGraph::Block::DataRange(0, 20),
  98  E :          BlockGraph::Block::SourceRange(core::RelativeAddress(512), 532));
  99    :      rd1->source_ranges().Push(BlockGraph::Block::DataRange(0, 16),
 100  E :          BlockGraph::Block::SourceRange(core::RelativeAddress(1024), 1040));
 101    :      rd2->source_ranges().Push(BlockGraph::Block::DataRange(0, 16),
 102  E :          BlockGraph::Block::SourceRange(core::RelativeAddress(1040), 1056));
 103    :  
 104    :      // Set up labels.
 105    :      c1->SetLabel(0, BlockGraph::Label("code1",
 106  E :          BlockGraph::CODE_LABEL | BlockGraph::DEBUG_START_LABEL));
 107  E :      c1->SetLabel(8, BlockGraph::Label("label", BlockGraph::CODE_LABEL));
 108  E :      c1->SetLabel(11, BlockGraph::Label("debug", BlockGraph::DEBUG_END_LABEL));
 109    :      c1->SetLabel(12, BlockGraph::Label("jump",
 110  E :          BlockGraph::DATA_LABEL | BlockGraph::JUMP_TABLE_LABEL));
 111  E :      c2->SetLabel(0, BlockGraph::Label("code1", BlockGraph::CODE_LABEL));
 112    :      c2->SetLabel(8, BlockGraph::Label("jump",
 113  E :          BlockGraph::DATA_LABEL | BlockGraph::JUMP_TABLE_LABEL));
 114    :      c2->SetLabel(12, BlockGraph::Label("case",
 115  E :          BlockGraph::DATA_LABEL | BlockGraph::CASE_TABLE_LABEL));
 116  E :      d1->SetLabel(0, BlockGraph::Label("data", BlockGraph::DATA_LABEL));
 117    :  
 118    :      // Set up some references.
 119    :      c1->SetReference(4, BlockGraph::Reference(
 120  E :          BlockGraph::ABSOLUTE_REF, 4, d1, 0, 0));
 121    :      c1->SetReference(12, BlockGraph::Reference(
 122  E :          BlockGraph::ABSOLUTE_REF, 4, c2, 0, 0));
 123    :      c2->SetReference(8, BlockGraph::Reference(
 124  E :          BlockGraph::ABSOLUTE_REF, 4, c1, 0, 0));
 125    :      d1->SetReference(0, BlockGraph::Reference(
 126  E :          BlockGraph::ABSOLUTE_REF, 4, rd1, 0, 0));
 127    :      rd1->SetReference(0, BlockGraph::Reference(
 128  E :          BlockGraph::ABSOLUTE_REF, 4, rd2, 0, 0));
 129  E :    }
 130    :  
 131  E :    void InitBlockDataCallbacks1() {
 132    :      s_.set_load_block_data_callback(
 133    :          base::Bind(&BlockGraphSerializerTest::LoadBlockDataCallback1,
 134  E :                     base::Unretained(this)));
 135  E :    }
 136    :  
 137  E :    void InitBlockDataCallbacks2() {
 138    :      s_.set_save_block_data_callback(
 139    :          base::Bind(&BlockGraphSerializerTest::SaveBlockDataCallback2,
 140  E :                     base::Unretained(this)));
 141    :      s_.set_load_block_data_callback(
 142    :          base::Bind(&BlockGraphSerializerTest::LoadBlockDataCallback2,
 143  E :                     base::Unretained(this)));
 144  E :    }
 145    :  
 146    :    bool LoadBlockDataCallback1(bool need_to_set_data,
 147    :                                size_t size,
 148    :                                BlockGraph::Block* block,
 149  E :                                core::InArchive* in_archive) {
 150  E :      DCHECK(block != NULL);
 151  E :      DCHECK(in_archive != NULL);
 152    :  
 153    :      // We only have work to do if the data is not explicitly saved.
 154  E :      if (!need_to_set_data)
 155  E :        return true;
 156    :  
 157  E :      block_data_loaded_by_callback_++;
 158    :  
 159  E :      EXPECT_LT(0u, size);
 160  E :      if (size == 0)
 161  i :        return false;
 162    :  
 163  E :      EXPECT_EQ(1u, block->source_ranges().size());
 164  E :      if (block->source_ranges().size() != 1)
 165  i :        return false;
 166    :  
 167    :      // We use the source range to determine which block gets which data, as the
 168    :      // name is not always present.
 169  E :      size_t data_size = 0;
 170  E :      const uint8* data = NULL;
 171  E :      switch (block->source_ranges().range_pairs()[0].second.start().value()) {
 172    :        case 0:
 173  E :          data = kCode1Data;
 174  E :          data_size = sizeof(kCode1Data);
 175  E :          break;
 176    :  
 177    :        case 36:
 178  E :          data = kCode2Data;
 179  E :          data_size = sizeof(kCode2Data);
 180  E :          break;
 181    :  
 182    :        case 512:
 183  E :          data = kData1Data;
 184  E :          data_size = sizeof(kData1Data);
 185  E :          break;
 186    :  
 187    :        case 1024:
 188  E :          data = kRdata1Data;
 189  E :          data_size = sizeof(kRdata1Data);
 190    :          break;
 191    :  
 192    :        default:
 193    :          break;
 194    :      }
 195    :  
 196  E :      EXPECT_TRUE(data != NULL);
 197  E :      EXPECT_EQ(data_size, size);
 198  E :      if (data == NULL || data_size != size)
 199  i :        return false;
 200    :  
 201  E :      block->SetData(data, data_size);
 202  E :      return true;
 203  E :    }
 204    :  
 205    :    bool SaveBlockDataCallback2(bool data_already_saved,
 206    :                                const BlockGraph::Block& block,
 207  E :                                core::OutArchive* out_archive) {
 208  E :      DCHECK(out_archive != NULL);
 209    :  
 210    :      // If the data is already saved, do nothing.
 211  E :      if (data_already_saved)
 212  E :        return true;
 213    :  
 214  E :      EXPECT_LT(0u, block.data_size());
 215  E :      if (block.data_size() == 0)
 216  i :        return false;
 217    :  
 218    :      // Determine which data buffer the block holds, and save an index value
 219    :      // representing it.
 220  E :      char data_index = -1;
 221  E :      if (memcmp(kCode1Data, block.data(), block.data_size()) == 0)
 222  E :        data_index = 0;
 223  E :      else if (memcmp(kCode2Data, block.data(), block.data_size()) == 0)
 224  E :        data_index = 1;
 225  E :      else if (memcmp(kData1Data, block.data(), block.data_size()) == 0)
 226  E :        data_index = 2;
 227  E :      else if (memcmp(kRdata1Data, block.data(), block.data_size()) == 0)
 228  E :        data_index = 3;
 229    :  
 230  E :      EXPECT_NE(-1, data_index);
 231  E :      if (data_index == -1)
 232  i :        return false;
 233    :  
 234  E :      if (!out_archive->Save(data_index))
 235  i :        return false;
 236    :  
 237  E :      return true;
 238  E :    }
 239    :  
 240    :    bool LoadBlockDataCallback2(bool need_to_set_data,
 241    :                                size_t size,
 242    :                                BlockGraph::Block* block,
 243  E :                                core::InArchive* in_archive) {
 244  E :      DCHECK(block != NULL);
 245  E :      DCHECK(in_archive != NULL);
 246    :  
 247    :      // We only have work to do if the data is not explicitly saved.
 248  E :      if (!need_to_set_data)
 249  E :        return true;
 250    :  
 251  E :      block_data_loaded_by_callback_++;
 252    :  
 253  E :      EXPECT_LT(0u, size);
 254  E :      if (size == 0)
 255  i :        return false;
 256    :  
 257  E :      char data_index = -1;
 258  E :      if (!in_archive->Load(&data_index))
 259  i :        return false;
 260    :  
 261  E :      EXPECT_LE(0, data_index);
 262  E :      EXPECT_GT(4, data_index);
 263    :  
 264    :      static const uint8* kData[] = {
 265    :          kCode1Data, kCode2Data, kData1Data, kRdata1Data };
 266  E :      block->SetData(kData[data_index], size);
 267    :  
 268  E :      return true;
 269  E :    }
 270    :  
 271    :    enum InitCallbacksType {
 272    :      eNoBlockDataCallbacks,
 273    :      eInitBlockDataCallbacks1,
 274    :      eInitBlockDataCallbacks2
 275    :    };
 276    :  
 277    :    void TestRoundTrip(BlockGraphSerializer::DataMode data_mode,
 278    :                       BlockGraphSerializer::Attributes attributes,
 279    :                       InitCallbacksType init_callback,
 280  E :                       size_t expected_block_data_loaded_by_callback) {
 281  E :      InitBlockGraph();
 282  E :      InitOutArchive();
 283    :  
 284  E :      s_.set_data_mode(data_mode);
 285  E :      s_.set_attributes(attributes);
 286    :  
 287    :      // Initialize the callbacks.
 288  E :      switch (init_callback) {
 289    :        case eInitBlockDataCallbacks1: {
 290  E :          InitBlockDataCallbacks1();
 291  E :          break;
 292    :        }
 293    :  
 294    :        case eInitBlockDataCallbacks2: {
 295  E :          InitBlockDataCallbacks2();
 296    :          break;
 297    :        }
 298    :  
 299    :        case eNoBlockDataCallbacks:
 300    :        default:
 301    :          // Do nothing.
 302    :          break;
 303    :      }
 304    :  
 305  E :      ASSERT_TRUE(s_.Save(bg_, oa_.get()));
 306  E :      ASSERT_LT(0u, v_.size());
 307    :  
 308  E :      InitInArchive();
 309    :  
 310  E :      BlockGraph bg;
 311  E :      ASSERT_TRUE(s_.Load(&bg, ia_.get()));
 312  E :      ASSERT_EQ(data_mode, s_.data_mode());
 313  E :      ASSERT_EQ(attributes, s_.attributes());
 314  E :      ASSERT_EQ(expected_block_data_loaded_by_callback,
 315    :                block_data_loaded_by_callback_);
 316    :  
 317  E :      ASSERT_TRUE(testing::BlockGraphsEqual(bg_, bg, s_));
 318  E :    }
 319    :  
 320    :    TestBlockGraphSerializer s_;
 321    :  
 322    :    // A block-graph.
 323    :    BlockGraph bg_;
 324    :  
 325    :    // Streams and archives.
 326    :    std::vector<uint8> v_;
 327    :    scoped_ptr<core::OutStream> os_;
 328    :    scoped_ptr<core::InStream> is_;
 329    :    scoped_ptr<core::OutArchive> oa_;
 330    :    scoped_ptr<core::InArchive> ia_;
 331    :  
 332    :    static const uint8 kCode1Data[16];
 333    :    static const uint8 kCode2Data[16];
 334    :    static const uint8 kData1Data[16];
 335    :    static const uint8 kRdata1Data[16];
 336    :  
 337    :    size_t block_data_loaded_by_callback_;
 338    :  };
 339    :  
 340    :  const uint8 BlockGraphSerializerTest::kCode1Data[16] = {
 341    :       1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16 };
 342    :  const uint8 BlockGraphSerializerTest::kCode2Data[16] = {
 343    :      20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10,  9,  8,  7,  6,  5 };
 344    :  const uint8 BlockGraphSerializerTest::kData1Data[16] = {
 345    :      10, 30, 45, 63, 20, 23, 67, 20, 32, 40, 50, 10, 15, 10, 18, 19 };
 346    :  const uint8 BlockGraphSerializerTest::kRdata1Data[16] = {
 347    :      28, 28, 29, 30, 56, 28, 23, 78, 19, 99, 10, 10, 23, 54, 54, 12 };
 348    :  
 349    :  }  // namespace
 350    :  
 351  E :  TEST_F(BlockGraphSerializerTest, Construction) {
 352  E :    ASSERT_EQ(BlockGraphSerializer::DEFAULT_DATA_MODE, s_.data_mode());
 353  E :    ASSERT_EQ(BlockGraphSerializer::DEFAULT_ATTRIBUTES, s_.data_mode());
 354  E :  }
 355    :  
 356  E :  TEST_F(BlockGraphSerializerTest, SetDataMode) {
 357  E :    ASSERT_EQ(BlockGraphSerializer::DEFAULT_DATA_MODE, s_.data_mode());
 358    :  
 359  E :    s_.set_data_mode(BlockGraphSerializer::OUTPUT_NO_DATA);
 360  E :    ASSERT_EQ(BlockGraphSerializer::OUTPUT_NO_DATA, s_.data_mode());
 361    :  
 362  E :    s_.set_data_mode(BlockGraphSerializer::OUTPUT_ALL_DATA);
 363  E :    ASSERT_EQ(BlockGraphSerializer::OUTPUT_ALL_DATA, s_.data_mode());
 364  E :  }
 365    :  
 366  E :  TEST_F(BlockGraphSerializerTest, AddAttributes) {
 367  E :    ASSERT_EQ(0u, s_.attributes());
 368    :  
 369  E :    s_.add_attributes(1);
 370  E :    ASSERT_EQ(1u, s_.attributes());
 371    :  
 372  E :    s_.add_attributes(2 | 4);
 373  E :    ASSERT_EQ(1u | 2u | 4u, s_.attributes());
 374  E :  }
 375    :  
 376  E :  TEST_F(BlockGraphSerializerTest, ClearAttributes) {
 377  E :    ASSERT_EQ(0u, s_.attributes());
 378    :  
 379  E :    s_.add_attributes(1 | 2);
 380  E :    ASSERT_EQ(1u | 2u, s_.attributes());
 381    :  
 382  E :    s_.clear_attributes(2);
 383  E :    ASSERT_EQ(1u, s_.attributes());
 384  E :  }
 385    :  
 386  E :  TEST_F(BlockGraphSerializerTest, SetAttributes) {
 387  E :    ASSERT_EQ(0u, s_.attributes());
 388    :  
 389  E :    s_.set_attributes(1 | 2);
 390  E :    ASSERT_EQ(1u | 2u, s_.attributes());
 391    :  
 392  E :    s_.set_attributes(4 | 8);
 393  E :    ASSERT_EQ(4u | 8u, s_.attributes());
 394  E :  }
 395    :  
 396  E :  TEST_F(BlockGraphSerializerTest, HasAttributes) {
 397  E :    ASSERT_EQ(0u, s_.attributes());
 398    :  
 399  E :    s_.set_attributes(1 | 2);
 400  E :    ASSERT_EQ(1u | 2u, s_.attributes());
 401    :  
 402  E :    ASSERT_TRUE(s_.has_attributes(1));
 403  E :    ASSERT_TRUE(s_.has_attributes(2));
 404  E :    ASSERT_TRUE(s_.has_attributes(1 | 2));
 405  E :    ASSERT_FALSE(s_.has_attributes(1 | 2 | 4));
 406  E :  }
 407    :  
 408  E :  TEST_F(BlockGraphSerializerTest, HasAnyAttributes) {
 409  E :    ASSERT_EQ(0u, s_.attributes());
 410    :  
 411  E :    s_.set_attributes(1 | 2);
 412  E :    ASSERT_EQ(1u | 2u, s_.attributes());
 413    :  
 414  E :    ASSERT_TRUE(s_.has_any_attributes(1));
 415  E :    ASSERT_TRUE(s_.has_any_attributes(2));
 416  E :    ASSERT_TRUE(s_.has_any_attributes(1 | 2 | 4));
 417  E :    ASSERT_FALSE(s_.has_any_attributes(4 | 8));
 418  E :  }
 419    :  
 420  E :  TEST_F(BlockGraphSerializerTest, VariableLengthUint32Encoding) {
 421    :    const uint32 kTestValues[] = {
 422    :        // 5-bit values (< 32) that map to 1 byte.
 423    :        1, 27, 31,
 424    :        // 13-bit values (< 8,192) that map to 2 bytes.
 425    :        32, 1034, 8191,
 426    :        // 21-bit values (< 2,097,152) that map to 3 bytes.
 427    :        8192, 1023847, 2097151,
 428    :        // 29-bit values (< 536,870,912) that map to 4 bytes.
 429    :        2097152, 38274285, 536870911,
 430    :        // 32-bit values (< 4,294,967,296) that map to 5 bytes.
 431  E :        536870912, 1610612736, 4294967295 };
 432    :  
 433  E :    for (size_t i = 0; i < arraysize(kTestValues); ++i) {
 434  E :      InitOutArchive();
 435  E :      ASSERT_TRUE(s_.SaveUint32(kTestValues[i], oa_.get()));
 436  E :      ASSERT_EQ((i / 3) + 1, v_.size());
 437    :  
 438  E :      InitInArchive();
 439  E :      uint32 value = 0;
 440  E :      ASSERT_TRUE(s_.LoadUint32(&value, ia_.get()));
 441    :  
 442  E :      ASSERT_EQ(kTestValues[i], value);
 443  E :    }
 444  E :  }
 445    :  
 446  E :  TEST_F(BlockGraphSerializerTest, VariableLengthInt32Encoding) {
 447    :    const int32 kTestValues[] = {
 448    :        // 4-bit values (< 16) that map to 1 byte.
 449    :        1, 9, 15,
 450    :        // 12-bit values (< 4,096) that map to 2 bytes.
 451    :        16, 1034, 4095,
 452    :        // 20-bit values (< 1,048,576) that map to 3 bytes.
 453    :        4096, 815632, 1048575,
 454    :        // 28-bit values (< 268,435,456) that map to 4 bytes.
 455    :        1048576, 38274285, 268435455,
 456    :        // 31-bit values (< 2,147,483,648) that map to 5 bytes.
 457  E :        268435456, 805306368, 2147483647 };
 458    :  
 459  E :    for (size_t i = 0; i < arraysize(kTestValues); ++i) {
 460    :      // We try the value in a negative and positive format.
 461  E :      for (int32 j = -1; j <= 1; j += 2) {
 462  E :        int32 expected_value = kTestValues[i] * j;
 463    :  
 464  E :        InitOutArchive();
 465  E :        ASSERT_TRUE(s_.SaveInt32(expected_value, oa_.get()));
 466  E :        ASSERT_EQ((i / 3) + 1, v_.size());
 467    :  
 468  E :        InitInArchive();
 469  E :        int32 value = 0;
 470  E :        ASSERT_TRUE(s_.LoadInt32(&value, ia_.get()));
 471    :  
 472  E :        ASSERT_EQ(expected_value, value);
 473  E :      }
 474  E :    }
 475  E :  }
 476    :  
 477  E :  TEST_F(BlockGraphSerializerTest, FailsToLoadWrongVersion) {
 478    :    // Serialize an empty block-graph.
 479  E :    InitOutArchive();
 480  E :    ASSERT_TRUE(s_.Save(bg_, oa_.get()));
 481    :  
 482    :    // The first 4 bytes of the stream are the version. We change it so it is
 483    :    // invalid.
 484  E :    v_[0] += 1;
 485    :  
 486    :    // Deserialization should fail.
 487  E :    InitInArchive();
 488  E :    ASSERT_FALSE(s_.Load(&bg_, ia_.get()));
 489  E :  }
 490    :  
 491  E :  TEST_F(BlockGraphSerializerTest, RoundTripNoData) {
 492    :    ASSERT_NO_FATAL_FAILURE(TestRoundTrip(
 493    :        BlockGraphSerializer::OUTPUT_NO_DATA,
 494    :        BlockGraphSerializer::DEFAULT_ATTRIBUTES,
 495  E :        eInitBlockDataCallbacks1, 4));
 496  E :  }
 497    :  
 498  E :  TEST_F(BlockGraphSerializerTest, RoundTripNoDataCustomRepresentation) {
 499    :    ASSERT_NO_FATAL_FAILURE(TestRoundTrip(
 500    :        BlockGraphSerializer::OUTPUT_NO_DATA,
 501    :        BlockGraphSerializer::DEFAULT_ATTRIBUTES,
 502  E :        eInitBlockDataCallbacks2, 4));
 503  E :  }
 504    :  
 505  E :  TEST_F(BlockGraphSerializerTest, RoundTripOwnedData) {
 506    :    ASSERT_NO_FATAL_FAILURE(TestRoundTrip(
 507    :        BlockGraphSerializer::OUTPUT_OWNED_DATA,
 508    :        BlockGraphSerializer::DEFAULT_ATTRIBUTES,
 509  E :        eInitBlockDataCallbacks1, 2));
 510  E :  }
 511    :  
 512  E :  TEST_F(BlockGraphSerializerTest, RoundTripOwnedDataCustomRepresentation) {
 513    :    ASSERT_NO_FATAL_FAILURE(TestRoundTrip(
 514    :        BlockGraphSerializer::OUTPUT_OWNED_DATA,
 515    :        BlockGraphSerializer::DEFAULT_ATTRIBUTES,
 516  E :        eInitBlockDataCallbacks2, 2));
 517  E :  }
 518    :  
 519  E :  TEST_F(BlockGraphSerializerTest, RoundTripAllData) {
 520    :    ASSERT_NO_FATAL_FAILURE(TestRoundTrip(
 521    :        BlockGraphSerializer::OUTPUT_ALL_DATA,
 522    :        BlockGraphSerializer::DEFAULT_ATTRIBUTES,
 523  E :        eNoBlockDataCallbacks, 0));
 524  E :  }
 525    :  
 526    :  // TODO(chrisha): Do a heck of a lot more testing of protected member functions.
 527    :  
 528    :  }  // namespace block_graph

Coverage information generated Thu Jan 14 17:40:38 2016.