Coverage for /Syzygy/block_graph/block_graph_serializer_unittest.cc

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

Coverage information generated Wed Dec 11 11:34:16 2013.