Coverage for /Syzygy/block_graph/block_graph_serializer_unittest.cc

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

Coverage information generated Thu Jul 04 09:34:53 2013.