Coverage for /Syzygy/reorder/reorder_app_unittest.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
100.0%1901900.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/reorder/reorder_app.h"
  16    :  
  17    :  #include <string>
  18    :  
  19    :  #include "base/strings/stringprintf.h"
  20    :  #include "gmock/gmock.h"
  21    :  #include "gtest/gtest.h"
  22    :  #include "syzygy/block_graph/basic_block_decomposer.h"
  23    :  #include "syzygy/block_graph/typed_block.h"
  24    :  #include "syzygy/block_graph/unittest_util.h"
  25    :  #include "syzygy/common/unittest_util.h"
  26    :  #include "syzygy/core/unittest_util.h"
  27    :  #include "syzygy/pe/decomposer.h"
  28    :  #include "syzygy/pe/pe_utils.h"
  29    :  #include "syzygy/pe/unittest_util.h"
  30    :  #include "syzygy/reorder/reorderer.h"
  31    :  
  32    :  namespace reorder {
  33    :  
  34    :  using block_graph::BlockGraph;
  35    :  using application::Application;
  36    :  using core::RelativeAddress;
  37    :  using ::testing::ScopedLogLevelSaver;
  38    :  
  39    :  namespace {
  40    :  
  41    :  class TestReorderApp : public ReorderApp {
  42    :   public:
  43    :    using ReorderApp::kInvalidMode;
  44    :    using ReorderApp::kLinearOrderMode;
  45    :    using ReorderApp::kRandomOrderMode;
  46    :    using ReorderApp::kDeadCodeFinderMode;
  47    :    using ReorderApp::mode_;
  48    :    using ReorderApp::instrumented_image_path_;
  49    :    using ReorderApp::input_image_path_;
  50    :    using ReorderApp::output_file_path_;
  51    :    using ReorderApp::bb_entry_count_file_path_;
  52    :    using ReorderApp::trace_file_paths_;
  53    :    using ReorderApp::seed_;
  54    :    using ReorderApp::pretty_print_;
  55    :    using ReorderApp::flags_;
  56    :    using ReorderApp::kInstrumentedImage;
  57    :    using ReorderApp::kOutputFile;
  58    :    using ReorderApp::kInputImage;
  59    :    using ReorderApp::kBasicBlockEntryCounts;
  60    :    using ReorderApp::kSeed;
  61    :    using ReorderApp::kListDeadCode;
  62    :    using ReorderApp::kPrettyPrint;
  63    :    using ReorderApp::kReordererFlags;
  64    :    using ReorderApp::kInstrumentedDll;
  65    :    using ReorderApp::kInputDll;
  66    :  };
  67    :  
  68    :  typedef application::Application<TestReorderApp> TestApp;
  69    :  
  70    :  class ReorderAppTest : public testing::PELibUnitTest {
  71    :   public:
  72    :    typedef testing::PELibUnitTest Super;
  73    :  
  74    :    ReorderAppTest()
  75    :        : cmd_line_(base::FilePath(L"reorder.exe")),
  76    :          test_impl_(test_app_.implementation()),
  77    :          seed_(1234567),
  78  E :          pretty_print_(false) {
  79  E :    }
  80    :  
  81  E :    void SetUp() {
  82  E :      Super::SetUp();
  83    :  
  84    :      // Several of the tests generate progress and (deliberate) error messages
  85    :      // that would otherwise clutter the unit-test output.
  86  E :      logging::SetMinLogLevel(logging::LOG_FATAL);
  87    :  
  88    :      // Setup the IO streams.
  89  E :      CreateTemporaryDir(&temp_dir_);
  90  E :      stdin_path_ = temp_dir_.Append(L"NUL");
  91  E :      stdout_path_ = temp_dir_.Append(L"stdout.txt");
  92  E :      stderr_path_ = temp_dir_.Append(L"stderr.txt");
  93  E :      InitStreams(stdin_path_, stdout_path_, stderr_path_);
  94    :  
  95    :      // Initialize the (potential) input and output path values.
  96    :      abs_input_image_path_ = testing::GetExeTestDataRelativePath(
  97  E :          testing::kTestDllName);
  98  E :      input_image_path_ = testing::GetRelativePath(abs_input_image_path_);
  99    :  
 100    :      abs_instrumented_image_path_ = testing::GetExeTestDataRelativePath(
 101  E :          testing::kCallTraceInstrumentedTestDllName);
 102    :      instrumented_image_path_ = testing::GetRelativePath(
 103  E :          abs_instrumented_image_path_);
 104    :  
 105  E :      abs_output_file_path_ = testing::GetExeTestDataRelativePath(L"order.json");
 106  E :      output_file_path_ = testing::GetRelativePath(abs_output_file_path_);
 107    :  
 108    :      abs_bb_entry_count_file_path_ = testing::GetExeTestDataRelativePath(
 109  E :          L"basic_block_entry_traces\\entry_counts.json");
 110    :      bb_entry_count_file_path_ = testing::GetRelativePath(
 111  E :          abs_bb_entry_count_file_path_);
 112    :  
 113    :      abs_trace_file_path_ = testing::GetExeTestDataRelativePath(
 114  E :          testing::kCallTraceTraceFiles[0]);
 115  E :      trace_file_path_ = testing::GetRelativePath(abs_trace_file_path_);
 116    :  
 117    :      // Point the application at the test's command-line and IO streams.
 118  E :      test_app_.set_command_line(&cmd_line_);
 119  E :      test_app_.set_in(in());
 120  E :      test_app_.set_out(out());
 121  E :      test_app_.set_err(err());
 122  E :    }
 123    :  
 124    :   protected:
 125    :    // Stashes the current log-level before each test instance and restores it
 126    :    // after each test completes.
 127    :    ScopedLogLevelSaver log_level_saver;
 128    :  
 129    :    // @name The application under test.
 130    :    // @{
 131    :    TestApp test_app_;
 132    :    TestApp::Implementation& test_impl_;
 133    :    base::FilePath temp_dir_;
 134    :    base::FilePath stdin_path_;
 135    :    base::FilePath stdout_path_;
 136    :    base::FilePath stderr_path_;
 137    :    // @}
 138    :  
 139    :    // @name Command-line and parameters.
 140    :    // @{
 141    :    base::CommandLine cmd_line_;
 142    :    base::FilePath instrumented_image_path_;
 143    :    base::FilePath input_image_path_;
 144    :    base::FilePath output_file_path_;
 145    :    base::FilePath bb_entry_count_file_path_;
 146    :    base::FilePath trace_file_path_;
 147    :    uint32 seed_;
 148    :    bool pretty_print_;
 149    :    // @}
 150    :  
 151    :    // @name Expected final values of input parameters.
 152    :    // @{
 153    :    base::FilePath abs_input_image_path_;
 154    :    base::FilePath abs_instrumented_image_path_;
 155    :    base::FilePath abs_output_file_path_;
 156    :    base::FilePath abs_bb_entry_count_file_path_;
 157    :    base::FilePath abs_trace_file_path_;
 158    :    // @}
 159    :  };
 160    :  
 161    :  }  // namespace
 162    :  
 163  E :  TEST_F(ReorderAppTest, GetHelp) {
 164  E :    cmd_line_.AppendSwitch("help");
 165  E :    ASSERT_FALSE(test_impl_.ParseCommandLine(&cmd_line_));
 166  E :  }
 167    :  
 168  E :  TEST_F(ReorderAppTest, EmptyCommandLineFails) {
 169  E :    ASSERT_FALSE(test_impl_.ParseCommandLine(&cmd_line_));
 170  E :  }
 171    :  
 172  E :  TEST_F(ReorderAppTest, ParseWithNeitherInstrumentedNorOrderFails) {
 173  E :    cmd_line_.AppendSwitchPath("input-image", input_image_path_);
 174    :  
 175  E :    ASSERT_FALSE(test_impl_.ParseCommandLine(&cmd_line_));
 176  E :  }
 177    :  
 178  E :  TEST_F(ReorderAppTest, ParseWithSeedAndListDeadCodeFails) {
 179    :    cmd_line_.AppendSwitchPath(
 180  E :        TestReorderApp::kInstrumentedImage, instrumented_image_path_);
 181  E :    cmd_line_.AppendSwitchPath(TestReorderApp::kOutputFile, output_file_path_);
 182  E :    cmd_line_.AppendSwitchPath(TestReorderApp::kInputImage, input_image_path_);
 183    :    cmd_line_.AppendSwitchASCII(
 184  E :        TestReorderApp::kSeed, base::StringPrintf("%d", seed_));
 185  E :    cmd_line_.AppendSwitch(TestReorderApp::kListDeadCode);
 186    :  
 187  E :    ASSERT_FALSE(test_impl_.ParseCommandLine(&cmd_line_));
 188  E :  }
 189    :  
 190  E :  TEST_F(ReorderAppTest, ParseWithEmptySeedFails) {
 191    :    cmd_line_.AppendSwitchPath(
 192  E :        TestReorderApp::kInstrumentedImage, instrumented_image_path_);
 193  E :    cmd_line_.AppendSwitchPath(TestReorderApp::kOutputFile, output_file_path_);
 194  E :    cmd_line_.AppendSwitch(TestReorderApp::kSeed);
 195    :  
 196  E :    ASSERT_FALSE(test_impl_.ParseCommandLine(&cmd_line_));
 197  E :  }
 198    :  
 199  E :  TEST_F(ReorderAppTest, ParseWithInvalidSeedFails) {
 200    :    cmd_line_.AppendSwitchPath(
 201  E :        TestReorderApp::kInstrumentedImage, instrumented_image_path_);
 202  E :    cmd_line_.AppendSwitchPath(TestReorderApp::kOutputFile, output_file_path_);
 203  E :    cmd_line_.AppendSwitchASCII(TestReorderApp::kSeed, "hello");
 204    :  
 205  E :    ASSERT_FALSE(test_impl_.ParseCommandLine(&cmd_line_));
 206  E :  }
 207    :  
 208  E :  TEST_F(ReorderAppTest, ParseWithInvalidFlagsFails) {
 209    :    cmd_line_.AppendSwitchPath(
 210  E :        TestReorderApp::kInstrumentedImage, instrumented_image_path_);
 211  E :    cmd_line_.AppendSwitchPath(TestReorderApp::kOutputFile, output_file_path_);
 212    :    cmd_line_.AppendSwitchASCII(
 213  E :        TestReorderApp::kReordererFlags, "no-data,no-code,hello");
 214    :  
 215  E :    ASSERT_FALSE(test_impl_.ParseCommandLine(&cmd_line_));
 216  E :  }
 217    :  
 218  E :  TEST_F(ReorderAppTest, ParseLinearOrderWithNoTraceFiles) {
 219    :    cmd_line_.AppendSwitchPath(
 220  E :        TestReorderApp::kInstrumentedImage, instrumented_image_path_);
 221  E :    cmd_line_.AppendSwitchPath(TestReorderApp::kOutputFile, output_file_path_);
 222  E :    ASSERT_TRUE(test_impl_.ParseCommandLine(&cmd_line_));
 223  E :  }
 224    :  
 225  E :  TEST_F(ReorderAppTest, ParseMinimalLinearOrderCommandLine) {
 226    :    cmd_line_.AppendSwitchPath(
 227  E :        TestReorderApp::kInstrumentedImage, instrumented_image_path_);
 228  E :    cmd_line_.AppendSwitchPath(TestReorderApp::kOutputFile, output_file_path_);
 229  E :    cmd_line_.AppendArgPath(trace_file_path_);
 230    :  
 231  E :    ASSERT_TRUE(test_impl_.ParseCommandLine(&cmd_line_));
 232    :  
 233  E :    EXPECT_EQ(TestReorderApp::kLinearOrderMode, test_impl_.mode_);
 234  E :    EXPECT_TRUE(test_impl_.input_image_path_.empty());
 235  E :    EXPECT_EQ(abs_instrumented_image_path_, test_impl_.instrumented_image_path_);
 236  E :    EXPECT_EQ(abs_output_file_path_, test_impl_.output_file_path_);
 237  E :    EXPECT_EQ(abs_trace_file_path_, test_impl_.trace_file_paths_.front());
 238  E :    EXPECT_EQ(0U, test_impl_.seed_);
 239  E :    EXPECT_FALSE(test_impl_.pretty_print_);
 240    :    EXPECT_EQ(Reorderer::kFlagReorderCode | Reorderer::kFlagReorderData,
 241  E :              test_impl_.flags_);
 242    :  
 243  E :    EXPECT_TRUE(test_impl_.SetUp());
 244  E :  }
 245    :  
 246  E :  TEST_F(ReorderAppTest, ParseFullLinearOrderCommandLine) {
 247    :    cmd_line_.AppendSwitchPath(
 248  E :        TestReorderApp::kInstrumentedImage, instrumented_image_path_);
 249  E :    cmd_line_.AppendSwitchPath(TestReorderApp::kOutputFile, output_file_path_);
 250  E :    cmd_line_.AppendSwitchPath(TestReorderApp::kInputImage, input_image_path_);
 251    :    cmd_line_.AppendSwitchPath(
 252  E :        TestReorderApp::kBasicBlockEntryCounts, bb_entry_count_file_path_);
 253    :    cmd_line_.AppendSwitchASCII(
 254  E :        TestReorderApp::kReordererFlags, "no-data,no-code");
 255  E :    cmd_line_.AppendSwitch(TestReorderApp::kPrettyPrint);
 256  E :    cmd_line_.AppendArgPath(trace_file_path_);
 257    :  
 258  E :    ASSERT_TRUE(test_impl_.ParseCommandLine(&cmd_line_));
 259    :  
 260  E :    EXPECT_EQ(TestReorderApp::kLinearOrderMode, test_impl_.mode_);
 261  E :    EXPECT_EQ(abs_input_image_path_, test_impl_.input_image_path_);
 262  E :    EXPECT_EQ(abs_instrumented_image_path_, test_impl_.instrumented_image_path_);
 263  E :    EXPECT_EQ(abs_output_file_path_, test_impl_.output_file_path_);
 264    :    EXPECT_EQ(abs_bb_entry_count_file_path_,
 265  E :              test_impl_.bb_entry_count_file_path_);
 266  E :    EXPECT_EQ(abs_trace_file_path_, test_impl_.trace_file_paths_.front());
 267  E :    EXPECT_EQ(0U, test_impl_.seed_);
 268  E :    EXPECT_TRUE(test_impl_.pretty_print_);
 269  E :    EXPECT_EQ(0, test_impl_.flags_ & Reorderer::kFlagReorderCode);
 270  E :    EXPECT_EQ(0, test_impl_.flags_ & Reorderer::kFlagReorderData);
 271    :  
 272  E :    EXPECT_TRUE(test_impl_.SetUp());
 273  E :  }
 274    :  
 275  E :  TEST_F(ReorderAppTest, ParseMinimalDeprecatedLinearOrderCommandLine) {
 276    :    cmd_line_.AppendSwitchPath(
 277  E :        TestReorderApp::kInstrumentedDll, instrumented_image_path_);
 278  E :    cmd_line_.AppendSwitchPath(TestReorderApp::kOutputFile, output_file_path_);
 279  E :    cmd_line_.AppendArgPath(trace_file_path_);
 280    :  
 281  E :    ASSERT_TRUE(test_impl_.ParseCommandLine(&cmd_line_));
 282    :  
 283  E :    EXPECT_EQ(TestReorderApp::kLinearOrderMode, test_impl_.mode_);
 284  E :    EXPECT_TRUE(test_impl_.input_image_path_.empty());
 285  E :    EXPECT_EQ(abs_instrumented_image_path_, test_impl_.instrumented_image_path_);
 286  E :    EXPECT_EQ(abs_output_file_path_, test_impl_.output_file_path_);
 287  E :    EXPECT_EQ(abs_trace_file_path_, test_impl_.trace_file_paths_.front());
 288  E :    EXPECT_EQ(0U, test_impl_.seed_);
 289  E :    EXPECT_FALSE(test_impl_.pretty_print_);
 290    :  
 291  E :    EXPECT_TRUE(test_impl_.SetUp());
 292  E :  }
 293    :  
 294  E :  TEST_F(ReorderAppTest, ParseFullDeprecatedLinearOrderCommandLine) {
 295    :    cmd_line_.AppendSwitchPath(
 296  E :        TestReorderApp::kInstrumentedDll, instrumented_image_path_);
 297  E :    cmd_line_.AppendSwitchPath(TestReorderApp::kOutputFile, output_file_path_);
 298  E :    cmd_line_.AppendSwitchPath(TestReorderApp::kInputDll, input_image_path_);
 299  E :    cmd_line_.AppendSwitch(TestReorderApp::kPrettyPrint);
 300  E :    cmd_line_.AppendArgPath(trace_file_path_);
 301    :  
 302  E :    ASSERT_TRUE(test_impl_.ParseCommandLine(&cmd_line_));
 303    :  
 304  E :    EXPECT_EQ(TestReorderApp::kLinearOrderMode, test_impl_.mode_);
 305  E :    EXPECT_EQ(abs_input_image_path_, test_impl_.input_image_path_);
 306  E :    EXPECT_EQ(abs_instrumented_image_path_, test_impl_.instrumented_image_path_);
 307  E :    EXPECT_EQ(abs_output_file_path_, test_impl_.output_file_path_);
 308  E :    EXPECT_EQ(0U, test_impl_.seed_);
 309  E :    EXPECT_TRUE(test_impl_.pretty_print_);
 310    :  
 311  E :    EXPECT_TRUE(test_impl_.SetUp());
 312  E :  }
 313    :  
 314  E :  TEST_F(ReorderAppTest, ParseRandomOrderCommandLine) {
 315    :    cmd_line_.AppendSwitchPath(
 316  E :        TestReorderApp::kInstrumentedDll, instrumented_image_path_);
 317  E :    cmd_line_.AppendSwitchPath(TestReorderApp::kOutputFile, output_file_path_);
 318    :    cmd_line_.AppendSwitchASCII(
 319  E :        TestReorderApp::kSeed, base::StringPrintf("%d", seed_));
 320    :  
 321  E :    ASSERT_TRUE(test_impl_.ParseCommandLine(&cmd_line_));
 322    :  
 323  E :    EXPECT_EQ(TestReorderApp::kRandomOrderMode, test_impl_.mode_);
 324  E :    EXPECT_TRUE(test_impl_.input_image_path_.empty());
 325  E :    EXPECT_EQ(abs_instrumented_image_path_, test_impl_.instrumented_image_path_);
 326  E :    EXPECT_EQ(abs_output_file_path_, test_impl_.output_file_path_);
 327  E :    EXPECT_EQ(seed_, test_impl_.seed_);
 328  E :    EXPECT_TRUE(test_impl_.trace_file_paths_.empty());
 329  E :    EXPECT_FALSE(test_impl_.pretty_print_);
 330    :  
 331  E :    EXPECT_TRUE(test_impl_.SetUp());
 332  E :  }
 333    :  
 334  E :  TEST_F(ReorderAppTest, ParseRandomOrderWithTraceFilesFails) {
 335    :    cmd_line_.AppendSwitchPath(
 336  E :        TestReorderApp::kInstrumentedImage, instrumented_image_path_);
 337  E :    cmd_line_.AppendSwitchPath(TestReorderApp::kOutputFile, output_file_path_);
 338    :    cmd_line_.AppendSwitchASCII(
 339  E :        TestReorderApp::kSeed, base::StringPrintf("%d", seed_));
 340  E :    cmd_line_.AppendArgPath(trace_file_path_);
 341    :  
 342  E :    ASSERT_FALSE(test_impl_.ParseCommandLine(&cmd_line_));
 343  E :  }
 344    :  
 345  E :  TEST_F(ReorderAppTest, ParseDeadCodeFinderCommandLine) {
 346    :    cmd_line_.AppendSwitchPath(
 347  E :        TestReorderApp::kInstrumentedDll, instrumented_image_path_);
 348  E :    cmd_line_.AppendSwitchPath(TestReorderApp::kOutputFile, output_file_path_);
 349  E :    cmd_line_.AppendSwitch(TestReorderApp::kListDeadCode);
 350  E :    cmd_line_.AppendSwitch(TestReorderApp::kPrettyPrint);
 351  E :    cmd_line_.AppendArgPath(trace_file_path_);
 352    :  
 353  E :    ASSERT_TRUE(test_impl_.ParseCommandLine(&cmd_line_));
 354    :  
 355  E :    EXPECT_EQ(TestReorderApp::kDeadCodeFinderMode, test_impl_.mode_);
 356  E :    EXPECT_TRUE(test_impl_.input_image_path_.empty());
 357  E :    EXPECT_EQ(abs_instrumented_image_path_, test_impl_.instrumented_image_path_);
 358  E :    EXPECT_EQ(abs_output_file_path_, test_impl_.output_file_path_);
 359  E :    EXPECT_EQ(abs_trace_file_path_, test_impl_.trace_file_paths_.front());
 360  E :    EXPECT_EQ(0U, test_impl_.seed_);
 361  E :    EXPECT_TRUE(test_impl_.pretty_print_);
 362    :  
 363  E :    EXPECT_TRUE(test_impl_.SetUp());
 364  E :  }
 365    :  
 366  E :  TEST_F(ReorderAppTest, LinearOrderEndToEnd) {
 367    :    cmd_line_.AppendSwitchPath(
 368  E :        TestReorderApp::kInstrumentedImage, instrumented_image_path_);
 369  E :    cmd_line_.AppendSwitchPath(TestReorderApp::kOutputFile, output_file_path_);
 370  E :    cmd_line_.AppendSwitchPath(TestReorderApp::kInputImage, input_image_path_);
 371    :    cmd_line_.AppendSwitchPath(
 372  E :        TestReorderApp::kBasicBlockEntryCounts, bb_entry_count_file_path_);
 373  E :    cmd_line_.AppendSwitch(TestReorderApp::kPrettyPrint);
 374  E :    cmd_line_.AppendArgPath(trace_file_path_);
 375    :  
 376  E :    ASSERT_EQ(0, test_app_.Run());
 377  E :  }
 378    :  
 379  E :  TEST_F(ReorderAppTest, LinearOrderWithBasicBlockTrace) {
 380    :    cmd_line_.AppendSwitchPath(
 381  E :        TestReorderApp::kInstrumentedImage, instrumented_image_path_);
 382  E :    cmd_line_.AppendSwitchPath(TestReorderApp::kOutputFile, output_file_path_);
 383  E :    cmd_line_.AppendSwitchPath(TestReorderApp::kInputImage, input_image_path_);
 384    :    cmd_line_.AppendSwitchPath(
 385  E :        TestReorderApp::kBasicBlockEntryCounts, bb_entry_count_file_path_);
 386  E :    cmd_line_.AppendSwitch(TestReorderApp::kPrettyPrint);
 387  E :    cmd_line_.AppendArgPath(trace_file_path_);
 388    :  
 389    :    // Adding a Basic Block traces should be valid, and ignored.
 390    :    base::FilePath abs_bbtrace_file_path =
 391  E :        testing::GetExeTestDataRelativePath(testing::kBBEntryTraceFiles[0]);
 392    :    base::FilePath bbtrace_file_path =
 393  E :      testing::GetRelativePath(abs_bbtrace_file_path);
 394  E :    cmd_line_.AppendArgPath(abs_bbtrace_file_path);
 395    :  
 396  E :    ASSERT_EQ(0, test_app_.Run());
 397  E :  }
 398    :  
 399    :  }  // namespace reorder

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