Coverage for /Syzygy/optimize/transforms/unreachable_block_transform_unittest.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
100.0%59590.C++test

Line-by-line coverage:

   1    :  // Copyright 2014 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/optimize/transforms/unreachable_block_transform.h"
  16    :  
  17    :  #include "base/files/scoped_temp_dir.h"
  18    :  #include "gmock/gmock.h"
  19    :  #include "gtest/gtest.h"
  20    :  #include "syzygy/block_graph/block_graph.h"
  21    :  #include "syzygy/optimize/application_profile.h"
  22    :  #include "syzygy/pe/pe_transform_policy.h"
  23    :  
  24    :  namespace optimize {
  25    :  namespace transforms {
  26    :  
  27    :  namespace {
  28    :  
  29    :  using block_graph::BlockGraph;
  30    :  using pe::ImageLayout;
  31    :  
  32    :  // Dummy code body.
  33    :  const uint8 kCodeBody1[] = { 0x74, 0x02, 0x33, 0xC0, 0xC3 };
  34    :  const uint8 kCodeBody2[] = { 0x0B, 0xC0, 0x75, 0xFC, 0xC3 };
  35    :  
  36    :  class UnreachableBlockTransformTest : public testing::Test {
  37    :   public:
  38  E :    UnreachableBlockTransformTest()
  39    :        : code1_(NULL), code2_(NULL), image_(&block_graph_) {
  40  E :    }
  41    :  
  42  E :    virtual void SetUp() {
  43    :      code1_ = block_graph_.AddBlock(BlockGraph::CODE_BLOCK,
  44    :                                     sizeof(kCodeBody1),
  45  E :                                     "code1");
  46  E :      DCHECK_NE(reinterpret_cast<BlockGraph::Block*>(NULL), code1_);
  47  E :      code1_->SetData(kCodeBody1, code1_->size());
  48    :  
  49    :      code2_ = block_graph_.AddBlock(BlockGraph::CODE_BLOCK,
  50    :                                     sizeof(kCodeBody2),
  51  E :                                     "code2");
  52  E :      DCHECK_NE(reinterpret_cast<BlockGraph::Block*>(NULL), code2_);
  53  E :      code2_->SetData(kCodeBody2, code2_->size());
  54    :  
  55    :      code3_ = block_graph_.AddBlock(BlockGraph::CODE_BLOCK,
  56    :                                     sizeof(kCodeBody2),
  57  E :                                     "code3");
  58  E :      DCHECK_NE(reinterpret_cast<BlockGraph::Block*>(NULL), code3_);
  59  E :      code3_->SetData(kCodeBody2, code2_->size());
  60    :  
  61    :  
  62    :      // Add a reference so that code1 is calling code2.
  63    :      code1_->SetReference(1, BlockGraph::Reference(BlockGraph::RELATIVE_REF,
  64    :                                  BlockGraph::Reference::kMaximumSize,
  65  E :                                  code2_, 0, 0));
  66    :  
  67    :      // Keep track of the original blocks id.
  68  E :      code1_id_ = code1_->id();
  69  E :      code2_id_ = code2_->id();
  70  E :      code3_id_ = code3_->id();
  71  E :    }
  72    :  
  73    :   protected:
  74    :    pe::PETransformPolicy policy_;
  75    :    BlockGraph block_graph_;
  76    :    BlockGraph::Block* code1_;
  77    :    BlockGraph::Block* code2_;
  78    :    BlockGraph::Block* code3_;
  79    :    BlockGraph::BlockId code1_id_;
  80    :    BlockGraph::BlockId code2_id_;
  81    :    BlockGraph::BlockId code3_id_;
  82    :    UnreachableBlockTransform tx_;
  83    :    ImageLayout image_;
  84    :  };
  85    :  
  86    :  }  // namespace
  87    :  
  88  E :  TEST_F(UnreachableBlockTransformTest, UnusedBlockFromCode1) {
  89  E :    DCHECK_NE(reinterpret_cast<BlockGraph::Block*>(NULL), code1_);
  90  E :    DCHECK_NE(reinterpret_cast<BlockGraph::Block*>(NULL), code2_);
  91  E :    DCHECK_NE(reinterpret_cast<BlockGraph::Block*>(NULL), code3_);
  92    :  
  93    :    // Apply the unreachable transform.
  94  E :    EXPECT_TRUE(tx_.TransformBlockGraph(&policy_, &block_graph_, code1_));
  95    :  
  96    :    // Validates that code1_ and code2_ are still present and code3_ has been
  97    :    // removed by the transform.
  98  E :    EXPECT_EQ(code1_, block_graph_.GetBlockById(code1_id_));
  99  E :    EXPECT_EQ(code2_, block_graph_.GetBlockById(code2_id_));
 100  E :    EXPECT_EQ(NULL, block_graph_.GetBlockById(code3_id_));
 101  E :  }
 102    :  
 103  E :  TEST_F(UnreachableBlockTransformTest, UnusedBlockFromCode3) {
 104  E :    DCHECK_NE(reinterpret_cast<BlockGraph::Block*>(NULL), code1_);
 105  E :    DCHECK_NE(reinterpret_cast<BlockGraph::Block*>(NULL), code2_);
 106  E :    DCHECK_NE(reinterpret_cast<BlockGraph::Block*>(NULL), code3_);
 107    :  
 108    :    // Apply the unreachable transform.
 109  E :    EXPECT_TRUE(tx_.TransformBlockGraph(&policy_, &block_graph_, code3_));
 110    :  
 111    :    // Validates that code3_ is still present and other blocks have been
 112    :    // removed by the transform.
 113  E :    EXPECT_EQ(NULL, block_graph_.GetBlockById(code1_id_));
 114  E :    EXPECT_EQ(NULL, block_graph_.GetBlockById(code2_id_));
 115  E :    EXPECT_EQ(code3_, block_graph_.GetBlockById(code3_id_));
 116  E :  }
 117    :  
 118  E :  TEST_F(UnreachableBlockTransformTest, UsedPEParsedBlock) {
 119  E :    DCHECK_NE(reinterpret_cast<BlockGraph::Block*>(NULL), code1_);
 120  E :    DCHECK_NE(reinterpret_cast<BlockGraph::Block*>(NULL), code2_);
 121  E :    DCHECK_NE(reinterpret_cast<BlockGraph::Block*>(NULL), code3_);
 122    :  
 123    :    // Set code3_ as a root.
 124  E :    code3_->set_attribute(BlockGraph::PE_PARSED);
 125    :  
 126    :    // Apply the unreachable transform.
 127  E :    EXPECT_TRUE(tx_.TransformBlockGraph(&policy_, &block_graph_, code1_));
 128    :  
 129    :    // Validates that all blocks are still present.
 130  E :    EXPECT_EQ(code1_, block_graph_.GetBlockById(code1_id_));
 131  E :    EXPECT_EQ(code2_, block_graph_.GetBlockById(code2_id_));
 132  E :    EXPECT_EQ(code3_, block_graph_.GetBlockById(code3_id_));
 133  E :  }
 134    :  
 135  E :  TEST_F(UnreachableBlockTransformTest, UnreachableGraphProduced) {
 136  E :    DCHECK_NE(reinterpret_cast<BlockGraph::Block*>(NULL), code1_);
 137  E :    DCHECK_NE(reinterpret_cast<BlockGraph::Block*>(NULL), code2_);
 138  E :    DCHECK_NE(reinterpret_cast<BlockGraph::Block*>(NULL), code3_);
 139    :  
 140    :    // Set the target path to dump the unreachable graph.
 141  E :    base::ScopedTempDir temp_dir;
 142  E :    EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
 143  E :    base::FilePath temp_path = temp_dir.path().Append(L"deadcode.cachegrind");
 144  E :    tx_.set_unreachable_graph_path(temp_path);
 145    :  
 146    :    // Apply the unreachable transform.
 147  E :    EXPECT_TRUE(tx_.TransformBlockGraph(&policy_, &block_graph_, code1_));
 148    :  
 149    :    // Read the contents of the produced file.
 150  E :    std::string contents;
 151  E :    base::ReadFileToString(temp_path, &contents);
 152    :  
 153    :    // Validate the output.
 154  E :    const char expected[] = "events: Size Count\nob=\nfn=code3\n3 5 1\n\n";
 155  E :    EXPECT_STREQ(expected, contents.c_str());
 156  E :  }
 157    :  
 158    :  
 159    :  }  // namespace transforms
 160    :  }  // namespace optimize

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