Coverage for /Syzygy/relink/relink_app_unittest.cc

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

Line-by-line coverage:

   1    :  // Copyright 2012 Google Inc.
   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/relink/relink_app.h"
  16    :  
  17    :  #include "base/stringprintf.h"
  18    :  #include "gmock/gmock.h"
  19    :  #include "gtest/gtest.h"
  20    :  #include "syzygy/block_graph/unittest_util.h"
  21    :  #include "syzygy/common/unittest_util.h"
  22    :  #include "syzygy/core/unittest_util.h"
  23    :  #include "syzygy/pe/pe_utils.h"
  24    :  #include "syzygy/pe/unittest_util.h"
  25    :  
  26    :  namespace relink {
  27    :  
  28    :  using block_graph::BlockGraph;
  29    :  using common::Application;
  30    :  using core::RelativeAddress;
  31    :  using ::testing::ScopedLogLevelSaver;
  32    :  
  33    :  namespace {
  34    :  
  35    :  class TestRelinkApp : public RelinkApp {
  36    :   public:
  37    :    using RelinkApp::input_dll_path_;
  38    :    using RelinkApp::input_pdb_path_;
  39    :    using RelinkApp::output_dll_path_;
  40    :    using RelinkApp::output_pdb_path_;
  41    :    using RelinkApp::order_file_path_;
  42    :    using RelinkApp::seed_;
  43    :    using RelinkApp::padding_;
  44    :    using RelinkApp::no_augment_pdb_;
  45    :    using RelinkApp::compress_pdb_;
  46    :    using RelinkApp::no_strip_strings_;
  47    :    using RelinkApp::output_metadata_;
  48    :    using RelinkApp::overwrite_;
  49    :  };
  50    :  
  51    :  typedef common::Application<TestRelinkApp> TestApp;
  52    :  
  53    :  class RelinkAppTest : public testing::PELibUnitTest {
  54    :   public:
  55    :    typedef testing::PELibUnitTest Super;
  56    :  
  57    :    RelinkAppTest()
  58    :        : cmd_line_(FilePath(L"relink.exe")),
  59    :          test_impl_(test_app_.implementation()),
  60    :          seed_(1234567),
  61    :          padding_(32),
  62    :          no_augment_pdb_(false),
  63    :          compress_pdb_(false),
  64    :          no_strip_strings_(false),
  65    :          output_metadata_(false),
  66  E :          overwrite_(false) {
  67  E :    }
  68    :  
  69  E :    void SetUp() {
  70  E :      Super::SetUp();
  71    :  
  72    :      // Several of the tests generate progress and (deliberate) error messages
  73    :      // that would otherwise clutter the unittest output.
  74  E :      logging::SetMinLogLevel(logging::LOG_FATAL);
  75    :  
  76    :      // Setup the IO streams.
  77  E :      CreateTemporaryDir(&temp_dir_);
  78  E :      stdin_path_ = temp_dir_.Append(L"NUL");
  79  E :      stdout_path_ = temp_dir_.Append(L"stdout.txt");
  80  E :      stderr_path_ = temp_dir_.Append(L"stderr.txt");
  81  E :      InitStreams(stdin_path_, stdout_path_, stderr_path_);
  82    :  
  83    :      // Initialize the (potential) input and output path values.
  84  E :      abs_input_dll_path_ = testing::GetExeRelativePath(kDllName);
  85  E :      input_dll_path_ = testing::GetRelativePath(abs_input_dll_path_);
  86  E :      abs_input_pdb_path_ = testing::GetExeRelativePath(kDllPdbName);
  87  E :      input_pdb_path_ = testing::GetRelativePath(abs_input_pdb_path_);
  88  E :      output_dll_path_ = temp_dir_.Append(input_dll_path_.BaseName());
  89  E :      output_pdb_path_ = temp_dir_.Append(input_pdb_path_.BaseName());
  90  E :      order_file_path_ = temp_dir_.Append(L"order.json");
  91    :  
  92    :      // Point the application at the test's command-line and IO streams.
  93  E :      test_app_.set_command_line(&cmd_line_);
  94  E :      test_app_.set_in(in());
  95  E :      test_app_.set_out(out());
  96  E :      test_app_.set_err(err());
  97  E :    }
  98    :  
  99    :    // Stashes the current log-level before each test instance and restores it
 100    :    // after each test completes.
 101    :    ScopedLogLevelSaver log_level_saver;
 102    :  
 103    :    // @name The application under test.
 104    :    // @{
 105    :    TestApp test_app_;
 106    :    TestApp::Implementation& test_impl_;
 107    :    FilePath temp_dir_;
 108    :    FilePath stdin_path_;
 109    :    FilePath stdout_path_;
 110    :    FilePath stderr_path_;
 111    :    // @}
 112    :  
 113    :    // @name Command-line and parameters.
 114    :    // @{
 115    :    CommandLine cmd_line_;
 116    :    FilePath input_dll_path_;
 117    :    FilePath input_pdb_path_;
 118    :    FilePath output_dll_path_;
 119    :    FilePath output_pdb_path_;
 120    :    FilePath order_file_path_;
 121    :    uint32 seed_;
 122    :    size_t padding_;
 123    :    bool no_augment_pdb_;
 124    :    bool compress_pdb_;
 125    :    bool no_strip_strings_;
 126    :    bool output_metadata_;
 127    :    bool overwrite_;
 128    :    // @}
 129    :  
 130    :    // @name Expected final values of input parameters.
 131    :    // @{
 132    :    FilePath abs_input_dll_path_;
 133    :    FilePath abs_input_pdb_path_;
 134    :    // @}
 135    :  };
 136    :  
 137    :  }  // namespace
 138    :  
 139  E :  TEST_F(RelinkAppTest, GetHelp) {
 140  E :    cmd_line_.AppendSwitch("help");
 141  E :    ASSERT_FALSE(test_impl_.ParseCommandLine(&cmd_line_));
 142  E :  }
 143    :  
 144  E :  TEST_F(RelinkAppTest, EmptyCommandLineFails) {
 145  E :    ASSERT_FALSE(test_impl_.ParseCommandLine(&cmd_line_));
 146  E :  }
 147    :  
 148  E :  TEST_F(RelinkAppTest, ParseWithNeitherInputNorOrderFails) {
 149  E :    cmd_line_.AppendSwitchPath("output-dll", output_dll_path_);
 150    :  
 151  E :    ASSERT_FALSE(test_impl_.ParseCommandLine(&cmd_line_));
 152  E :  }
 153    :  
 154  E :  TEST_F(RelinkAppTest, ParseWithSeedAndOrderFails) {
 155  E :    cmd_line_.AppendSwitchPath("output-dll", output_dll_path_);
 156  E :    cmd_line_.AppendSwitchASCII("seed", base::StringPrintf("%d", seed_));
 157  E :    cmd_line_.AppendSwitchPath("order_file", order_file_path_);
 158    :  
 159  E :    ASSERT_FALSE(test_impl_.ParseCommandLine(&cmd_line_));
 160  E :  }
 161    :  
 162  E :  TEST_F(RelinkAppTest, ParseWithEmptySeedFails) {
 163  E :    cmd_line_.AppendSwitchPath("output-dll", output_dll_path_);
 164  E :    cmd_line_.AppendSwitch("seed");
 165    :  
 166  E :    ASSERT_FALSE(test_impl_.ParseCommandLine(&cmd_line_));
 167  E :  }
 168    :  
 169  E :  TEST_F(RelinkAppTest, ParseWithInvalidSeedFails) {
 170  E :    cmd_line_.AppendSwitchPath("output-dll", output_dll_path_);
 171  E :    cmd_line_.AppendSwitchASCII("seed", "hello");
 172    :  
 173  E :    ASSERT_FALSE(test_impl_.ParseCommandLine(&cmd_line_));
 174  E :  }
 175    :  
 176  E :  TEST_F(RelinkAppTest, ParseWithEmptyPaddingFails) {
 177  E :    cmd_line_.AppendSwitchPath("output-dll", output_dll_path_);
 178  E :    cmd_line_.AppendSwitch("padding");
 179    :  
 180  E :    ASSERT_FALSE(test_impl_.ParseCommandLine(&cmd_line_));
 181  E :  }
 182    :  
 183  E :  TEST_F(RelinkAppTest, ParseWithInvalidPaddingFails) {
 184  E :    cmd_line_.AppendSwitchPath("output-dll", output_dll_path_);
 185  E :    cmd_line_.AppendSwitchASCII("padding", "hello");
 186    :  
 187  E :    ASSERT_FALSE(test_impl_.ParseCommandLine(&cmd_line_));
 188  E :  }
 189    :  
 190  E :  TEST_F(RelinkAppTest, ParseMinimalCommandLineWithInputDll) {
 191  E :    cmd_line_.AppendSwitchPath("input-dll", input_dll_path_);
 192  E :    cmd_line_.AppendSwitchPath("output-dll", output_dll_path_);
 193    :  
 194  E :    EXPECT_TRUE(test_impl_.ParseCommandLine(&cmd_line_));
 195  E :    EXPECT_TRUE(test_impl_.SetUp());
 196  E :  }
 197    :  
 198  E :  TEST_F(RelinkAppTest, ParseMinimalCommandLineWithOrderFile) {
 199    :    // The order file doesn't actually exist, so setup should fail to infer the
 200    :    // input dll.
 201  E :    cmd_line_.AppendSwitchPath("order-file", order_file_path_);
 202  E :    cmd_line_.AppendSwitchPath("output-dll", output_dll_path_);
 203    :  
 204  E :    EXPECT_TRUE(test_impl_.ParseCommandLine(&cmd_line_));
 205  E :    EXPECT_FALSE(test_impl_.SetUp());
 206  E :  }
 207    :  
 208  E :  TEST_F(RelinkAppTest, ParseFullCommandLineWithOrderFile) {
 209    :    // Note that we specify the no-metadata flag, so we expect false below
 210    :    // for the output_metadata_ member. Also note that neither seed nor padding
 211    :    // are given, and should default to 0.
 212  E :    cmd_line_.AppendSwitchPath("output-dll", output_dll_path_);
 213  E :    cmd_line_.AppendSwitchPath("output-pdb", output_pdb_path_);
 214  E :    cmd_line_.AppendSwitchPath("order-file", order_file_path_);
 215  E :    cmd_line_.AppendSwitch("no-augment-pdb");
 216  E :    cmd_line_.AppendSwitch("compress-pdb");
 217  E :    cmd_line_.AppendSwitch("no-strip-strings");
 218  E :    cmd_line_.AppendSwitch("no-metadata");
 219  E :    cmd_line_.AppendSwitch("overwrite");
 220    :  
 221  E :    EXPECT_TRUE(test_impl_.ParseCommandLine(&cmd_line_));
 222  E :    EXPECT_TRUE(test_impl_.input_dll_path_.empty());
 223  E :    EXPECT_TRUE(test_impl_.input_pdb_path_.empty());
 224  E :    EXPECT_EQ(output_dll_path_, test_impl_.output_dll_path_);
 225  E :    EXPECT_EQ(output_pdb_path_, test_impl_.output_pdb_path_);
 226  E :    EXPECT_EQ(order_file_path_, test_impl_.order_file_path_);
 227  E :    EXPECT_EQ(0, test_impl_.seed_);
 228  E :    EXPECT_EQ(0, test_impl_.padding_);
 229  E :    EXPECT_TRUE(test_impl_.no_augment_pdb_);
 230  E :    EXPECT_TRUE(test_impl_.compress_pdb_);
 231  E :    EXPECT_TRUE(test_impl_.no_strip_strings_);
 232  E :    EXPECT_FALSE(test_impl_.output_metadata_);
 233  E :    EXPECT_TRUE(test_impl_.overwrite_);
 234    :  
 235    :    // The order file doesn't actually exist, so setup should fail to infer the
 236    :    // input dll.
 237  E :    EXPECT_FALSE(test_impl_.SetUp());
 238  E :  }
 239    :  
 240  E :  TEST_F(RelinkAppTest, ParseFullCommandLineWithInputSeedAndMetadata) {
 241    :    // Note that we omit the no-metadata flag, so we expect true below for the
 242    :    // output_metadata_ member.
 243  E :    cmd_line_.AppendSwitchPath("input-dll", input_dll_path_);
 244  E :    cmd_line_.AppendSwitchPath("input-pdb", input_pdb_path_);
 245  E :    cmd_line_.AppendSwitchPath("output-dll", output_dll_path_);
 246  E :    cmd_line_.AppendSwitchPath("output-pdb", output_pdb_path_);
 247  E :    cmd_line_.AppendSwitchASCII("seed", base::StringPrintf("%d", seed_));
 248  E :    cmd_line_.AppendSwitchASCII("padding", base::StringPrintf("%d", padding_));
 249  E :    cmd_line_.AppendSwitch("no-augment-pdb");
 250  E :    cmd_line_.AppendSwitch("compress-pdb");
 251  E :    cmd_line_.AppendSwitch("no-strip-strings");
 252  E :    cmd_line_.AppendSwitch("overwrite");
 253    :  
 254  E :    EXPECT_TRUE(test_impl_.ParseCommandLine(&cmd_line_));
 255  E :    EXPECT_EQ(abs_input_dll_path_, test_impl_.input_dll_path_);
 256  E :    EXPECT_EQ(abs_input_pdb_path_, test_impl_.input_pdb_path_);
 257  E :    EXPECT_EQ(output_dll_path_, test_impl_.output_dll_path_);
 258  E :    EXPECT_EQ(output_pdb_path_, test_impl_.output_pdb_path_);
 259  E :    EXPECT_TRUE(test_impl_.order_file_path_.empty());
 260  E :    EXPECT_EQ(seed_, test_impl_.seed_);
 261  E :    EXPECT_EQ(padding_, test_impl_.padding_);
 262  E :    EXPECT_TRUE(test_impl_.no_augment_pdb_);
 263  E :    EXPECT_TRUE(test_impl_.compress_pdb_);
 264  E :    EXPECT_TRUE(test_impl_.no_strip_strings_);
 265  E :    EXPECT_TRUE(test_impl_.output_metadata_);
 266  E :    EXPECT_TRUE(test_impl_.overwrite_);
 267    :  
 268    :    // SetUp() has nothing else to infer so it should succeed.
 269  E :    EXPECT_TRUE(test_impl_.SetUp());
 270  E :  }
 271    :  
 272  E :  TEST_F(RelinkAppTest, RandomRelink) {
 273  E :    cmd_line_.AppendSwitchPath("input-dll", input_dll_path_);
 274  E :    cmd_line_.AppendSwitchPath("input-pdb", input_pdb_path_);
 275  E :    cmd_line_.AppendSwitchPath("output-dll", output_dll_path_);
 276  E :    cmd_line_.AppendSwitchPath("output-pdb", output_pdb_path_);
 277  E :    cmd_line_.AppendSwitchASCII("seed", base::StringPrintf("%d", seed_));
 278  E :    cmd_line_.AppendSwitchASCII("padding", base::StringPrintf("%d", padding_));
 279  E :    cmd_line_.AppendSwitch("overwrite");
 280    :  
 281  E :    ASSERT_EQ(0, test_app_.Run());
 282  E :    ASSERT_NO_FATAL_FAILURE(CheckTestDll(output_dll_path_));
 283  E :  }
 284    :  
 285  E :  TEST_F(RelinkAppTest, RandomRelinkBasicBlocks) {
 286  E :    cmd_line_.AppendSwitchPath("input-dll", input_dll_path_);
 287  E :    cmd_line_.AppendSwitchPath("input-pdb", input_pdb_path_);
 288  E :    cmd_line_.AppendSwitchPath("output-dll", output_dll_path_);
 289  E :    cmd_line_.AppendSwitchPath("output-pdb", output_pdb_path_);
 290  E :    cmd_line_.AppendSwitchASCII("seed", base::StringPrintf("%d", seed_));
 291  E :    cmd_line_.AppendSwitchASCII("padding", base::StringPrintf("%d", padding_));
 292  E :    cmd_line_.AppendSwitch("overwrite");
 293  E :    cmd_line_.AppendSwitch("basic-blocks");
 294  E :    cmd_line_.AppendSwitch("exclude-bb-padding");
 295    :  
 296  E :    ASSERT_EQ(0, test_app_.Run());
 297  E :    ASSERT_NO_FATAL_FAILURE(CheckTestDll(output_dll_path_));
 298  E :  }
 299    :  
 300    :  }  // namespace pe

Coverage information generated Thu Sep 06 11:30:46 2012.