Coverage for /Syzygy/genfilter/filter_compiler_unittest.cc

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

Line-by-line coverage:

   1    :  // Copyright 2013 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/genfilter/filter_compiler.h"
  16    :  
  17    :  #include "base/files/file_util.h"
  18    :  #include "gtest/gtest.h"
  19    :  #include "syzygy/common/unittest_util.h"
  20    :  #include "syzygy/core/unittest_util.h"
  21    :  #include "syzygy/pe/unittest_util.h"
  22    :  
  23    :  namespace genfilter {
  24    :  
  25    :  namespace {
  26    :  
  27    :  class TestFilterCompiler : public FilterCompiler {
  28    :   public:
  29    :    using FilterCompiler::Rule;
  30    :    using FilterCompiler::RuleMap;
  31    :    using FilterCompiler::RulePointers;
  32    :  
  33    :    using FilterCompiler::rule_map_;
  34    :    using FilterCompiler::rules_by_type_;
  35    :  
  36  E :    TestFilterCompiler() { }
  37    :  
  38    :    // Returns the |index|th rule.
  39  E :    const Rule& rule(size_t index) const {
  40  E :      RuleMap::const_iterator it = rule_map_.find(index);
  41  E :      return it->second;
  42  E :    }
  43    :  };
  44    :  
  45    :  class FilterCompilerTest : public testing::PELibUnitTest {
  46    :   public:
  47    :    typedef testing::PELibUnitTest Super;
  48    :  
  49  E :    virtual void SetUp() override {
  50  E :      Super::SetUp();
  51  E :      ASSERT_NO_FATAL_FAILURE(CreateTemporaryDir(&temp_dir_));
  52  E :      test_dll_ = testing::GetExeRelativePath(testing::kTestDllName);
  53  E :      test_dll_pdb_ = testing::GetOutputRelativePath(testing::kTestDllPdbName);
  54  E :      dummy_dll_ = testing::GetExeRelativePath(L"this-does-not-exist.dll");
  55  E :      dummy_pdb_ = testing::GetExeRelativePath(L"this-does-not-exist.pdb");
  56    :      mismatched_test_dll_pdb_ =
  57  E :          testing::GetSrcRelativePath(L"pe\\test_data\\test_dll.pdb");
  58  E :      filter_txt_ = temp_dir_.Append(L"filter.txt");
  59  E :    }
  60    :  
  61  E :    virtual void TearDown() override {
  62  E :      ASSERT_TRUE(base::DeleteFile(temp_dir_, true));
  63  E :      Super::TearDown();
  64  E :    }
  65    :  
  66  E :    void CreateFilterDescriptionFile(const base::StringPiece& line) {
  67  E :      base::ScopedFILE file(base::OpenFile(filter_txt_, "wb"));
  68  E :      ::fprintf(file.get(), "%.*s\n", line.length(), line.data());
  69  E :    }
  70    :  
  71  E :    void CreateFilterDescriptionFile() {
  72  E :      base::ScopedFILE file(base::OpenFile(filter_txt_, "wb"));
  73  E :      ::fprintf(file.get(), "# This is a comment.\n");
  74  E :      ::fprintf(file.get(), "\n");
  75  E :      ::fprintf(file.get(), "+function:DllMain  # Another comment.\n");
  76  E :      ::fprintf(file.get(), " + function : ThisFunctionDoesNotExist \n");
  77  E :      ::fprintf(file.get(), "-public_symbol:\\?function1.*\n");
  78  E :    }
  79    :  
  80    :    // A temporary folder for holding filter files, etc.
  81    :    base::FilePath temp_dir_;
  82    :  
  83    :    // A handful of paths.
  84    :    base::FilePath test_dll_;
  85    :    base::FilePath test_dll_pdb_;
  86    :    base::FilePath dummy_dll_;
  87    :    base::FilePath dummy_pdb_;
  88    :    base::FilePath mismatched_test_dll_pdb_;
  89    :    base::FilePath filter_txt_;
  90    :  };
  91    :  
  92    :  }  // namespace
  93    :  
  94  E :  TEST_F(FilterCompilerTest, Constructor) {
  95  E :    TestFilterCompiler fc;
  96  E :    EXPECT_TRUE(fc.image_path().empty());
  97  E :    EXPECT_TRUE(fc.pdb_path().empty());
  98  E :    EXPECT_TRUE(fc.rule_map_.empty());
  99  E :    for (size_t i = 0; i < arraysize(fc.rules_by_type_); ++i) {
 100  E :      EXPECT_TRUE(fc.rules_by_type_[i].empty());
 101  E :    }
 102  E :  }
 103    :  
 104  E :  TEST_F(FilterCompilerTest, InitFailsInvalidPePath) {
 105  E :    DisableLogging();
 106    :  
 107  E :    TestFilterCompiler fc1;
 108  E :    EXPECT_FALSE(fc1.Init(dummy_dll_));
 109    :  
 110  E :    TestFilterCompiler fc2;
 111  E :    EXPECT_FALSE(fc2.Init(dummy_dll_, base::FilePath()));
 112  E :  }
 113    :  
 114  E :  TEST_F(FilterCompilerTest, InitFailsInvalidPdbPath) {
 115  E :    DisableLogging();
 116    :  
 117  E :    TestFilterCompiler fc;
 118  E :    EXPECT_FALSE(fc.Init(test_dll_, dummy_pdb_));
 119  E :  }
 120    :  
 121  E :  TEST_F(FilterCompilerTest, InitFailsMismatchedPeAndPdb) {
 122  E :    DisableLogging();
 123    :  
 124  E :    TestFilterCompiler fc;
 125  E :    EXPECT_FALSE(fc.Init(test_dll_, mismatched_test_dll_pdb_));
 126  E :  }
 127    :  
 128  E :  TEST_F(FilterCompilerTest, InitSucceedsSpecifiedPdb) {
 129  E :    TestFilterCompiler fc;
 130  E :    EXPECT_TRUE(fc.Init(test_dll_, test_dll_pdb_));
 131  E :    EXPECT_EQ(test_dll_, fc.image_path());
 132  E :    EXPECT_EQ(test_dll_pdb_, fc.pdb_path());
 133  E :  }
 134    :  
 135  E :  TEST_F(FilterCompilerTest, InitSucceedsSearchForPdb) {
 136  E :    TestFilterCompiler fc1;
 137  E :    EXPECT_TRUE(fc1.Init(test_dll_));
 138  E :    EXPECT_EQ(test_dll_, fc1.image_path());
 139  E :    EXPECT_SAME_FILE(test_dll_pdb_, fc1.pdb_path());
 140    :  
 141  E :    TestFilterCompiler fc2;
 142  E :    EXPECT_TRUE(fc2.Init(test_dll_, base::FilePath()));
 143  E :    EXPECT_EQ(test_dll_, fc2.image_path());
 144  E :    EXPECT_SAME_FILE(test_dll_pdb_, fc2.pdb_path());
 145  E :  }
 146    :  
 147  E :  TEST_F(FilterCompilerTest, AddRule) {
 148  E :    DisableLogging();
 149    :  
 150  E :    TestFilterCompiler fc;
 151  E :    ASSERT_TRUE(fc.Init(test_dll_, test_dll_pdb_));
 152  E :    EXPECT_EQ(0u, fc.rule_map_.size());
 153  E :    EXPECT_EQ(0u, fc.rules_by_type_[FilterCompiler::kFunctionRule].size());
 154  E :    EXPECT_EQ(0u, fc.rules_by_type_[FilterCompiler::kPublicSymbolRule].size());
 155    :  
 156    :    EXPECT_FALSE(fc.AddRule(FilterCompiler::kAddToFilter,
 157    :                            FilterCompiler::kFunctionRule,
 158  E :                            "broken(regex[foo"));
 159    :  
 160    :    EXPECT_TRUE(fc.AddRule(FilterCompiler::kAddToFilter,
 161    :                           FilterCompiler::kFunctionRule,
 162  E :                           "foo"));
 163  E :    EXPECT_EQ(1u, fc.rule_map_.size());
 164  E :    EXPECT_EQ(1u, fc.rules_by_type_[FilterCompiler::kFunctionRule].size());
 165  E :    EXPECT_EQ(0u, fc.rules_by_type_[FilterCompiler::kPublicSymbolRule].size());
 166    :  
 167    :    EXPECT_TRUE(fc.AddRule(FilterCompiler::kSubtractFromFilter,
 168    :                           FilterCompiler::kPublicSymbolRule,
 169  E :                           "bar"));
 170  E :    EXPECT_EQ(2u, fc.rule_map_.size());
 171  E :    EXPECT_EQ(1u, fc.rules_by_type_[FilterCompiler::kFunctionRule].size());
 172  E :    EXPECT_EQ(1u, fc.rules_by_type_[FilterCompiler::kPublicSymbolRule].size());
 173  E :  }
 174    :  
 175  E :  TEST_F(FilterCompilerTest, ParseFilterDescriptionFileMissingFile) {
 176  E :    DisableLogging();
 177    :  
 178  E :    TestFilterCompiler fc;
 179  E :    ASSERT_TRUE(fc.Init(test_dll_, test_dll_pdb_));
 180    :  
 181  E :    EXPECT_FALSE(fc.ParseFilterDescriptionFile(filter_txt_));
 182  E :  }
 183    :  
 184  E :  TEST_F(FilterCompilerTest, ParseFilterDescriptionFileBadModificationType) {
 185  E :    DisableLogging();
 186    :  
 187  E :    ASSERT_NO_FATAL_FAILURE(CreateFilterDescriptionFile("?function:foo"));
 188    :  
 189  E :    TestFilterCompiler fc;
 190  E :    ASSERT_TRUE(fc.Init(test_dll_, test_dll_pdb_));
 191    :  
 192  E :    EXPECT_FALSE(fc.ParseFilterDescriptionFile(filter_txt_));
 193  E :  }
 194    :  
 195  E :  TEST_F(FilterCompilerTest, ParseFilterDescriptionFileBadRuleType) {
 196  E :    DisableLogging();
 197    :  
 198    :    ASSERT_NO_FATAL_FAILURE(CreateFilterDescriptionFile(
 199  E :        "+invalid_type:foo"));
 200    :  
 201  E :    TestFilterCompiler fc;
 202  E :    ASSERT_TRUE(fc.Init(test_dll_, test_dll_pdb_));
 203    :  
 204  E :    EXPECT_FALSE(fc.ParseFilterDescriptionFile(filter_txt_));
 205  E :  }
 206    :  
 207  E :  TEST_F(FilterCompilerTest, ParseFilterDescriptionFileBadRegex) {
 208  E :    DisableLogging();
 209    :  
 210    :    ASSERT_NO_FATAL_FAILURE(CreateFilterDescriptionFile(
 211  E :        "+function:broken(regex[ab"));
 212    :  
 213  E :    TestFilterCompiler fc;
 214  E :    ASSERT_TRUE(fc.Init(test_dll_, test_dll_pdb_));
 215    :  
 216  E :    EXPECT_FALSE(fc.ParseFilterDescriptionFile(filter_txt_));
 217  E :  }
 218    :  
 219  E :  TEST_F(FilterCompilerTest, ParseFilterDescriptionFileSucceeds) {
 220  E :    ASSERT_NO_FATAL_FAILURE(CreateFilterDescriptionFile());
 221    :  
 222  E :    TestFilterCompiler fc;
 223  E :    ASSERT_TRUE(fc.Init(test_dll_, test_dll_pdb_));
 224    :  
 225  E :    ASSERT_TRUE(fc.ParseFilterDescriptionFile(filter_txt_));
 226  E :    EXPECT_EQ(3u, fc.rule_map_.size());
 227  E :    EXPECT_EQ(FilterCompiler::kFunctionRule, fc.rule(0).rule_type);
 228  E :    EXPECT_EQ(FilterCompiler::kFunctionRule, fc.rule(1).rule_type);
 229  E :    EXPECT_EQ(FilterCompiler::kPublicSymbolRule, fc.rule(2).rule_type);
 230  E :    EXPECT_EQ(FilterCompiler::kAddToFilter, fc.rule(0).modification_type);
 231  E :    EXPECT_EQ(FilterCompiler::kAddToFilter, fc.rule(1).modification_type);
 232  E :    EXPECT_EQ(FilterCompiler::kSubtractFromFilter, fc.rule(2).modification_type);
 233  E :  }
 234    :  
 235  E :  TEST_F(FilterCompilerTest, Compile) {
 236  E :    ASSERT_NO_FATAL_FAILURE(CreateFilterDescriptionFile());
 237    :  
 238  E :    TestFilterCompiler fc;
 239  E :    ASSERT_TRUE(fc.Init(test_dll_, test_dll_pdb_));
 240  E :    ASSERT_TRUE(fc.ParseFilterDescriptionFile(filter_txt_));
 241  E :    ASSERT_EQ(3u, fc.rule_map_.size());  // Three rules should have been parsed.
 242    :  
 243  E :    pe::ImageFilter filter;
 244  E :    EXPECT_TRUE(fc.Compile(&filter));
 245    :  
 246    :    // The first and last rules should have matched actual symbol info.
 247  E :    EXPECT_EQ(1u, fc.rule(0).ranges.size());
 248  E :    EXPECT_EQ(0u, fc.rule(1).ranges.size());
 249  E :    EXPECT_EQ(1u, fc.rule(2).ranges.size());
 250    :  
 251    :    // The image filter should be non-empty.
 252  E :    EXPECT_LT(0u, filter.filter.size());
 253  E :  }
 254    :  
 255    :  }  // namespace genfilter

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