Coverage for /Syzygy/sampler/sampling_profiler_unittest.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
95.0%38400.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/sampler/sampling_profiler.h"
  16    :  
  17    :  #include "base/logging.h"
  18    :  #include "base/win/pe_image.h"
  19    :  #include "base/win/scoped_handle.h"
  20    :  #include "base/win/windows_version.h"
  21    :  #include "gtest/gtest.h"
  22    :  
  23    :  // The address of our image base.
  24    :  extern "C" IMAGE_DOS_HEADER __ImageBase;
  25    :  
  26    :  namespace sampler {
  27    :  
  28    :  namespace {
  29    :  
  30    :  class SamplingProfilerTest : public testing::Test {
  31    :   public:
  32  E :    SamplingProfilerTest() : code_start(NULL), code_size(0) {
  33  E :    }
  34    :  
  35  E :    virtual void SetUp() {
  36    :      process.Set(::OpenProcess(PROCESS_QUERY_INFORMATION,
  37    :                                FALSE,
  38  E :                                ::GetCurrentProcessId()));
  39  E :      ASSERT_TRUE(process.IsValid());
  40    :  
  41  E :      base::win::PEImage image(&__ImageBase);
  42    :  
  43    :      // Get the address of the .text section, which is the first section output
  44    :      // by the VS tools.
  45  E :      ASSERT_TRUE(image.GetNumSections() > 0);
  46  E :      const IMAGE_SECTION_HEADER* text_section = image.GetSectionHeader(0);
  47  E :      ASSERT_EQ(0, strncmp(".text",
  48    :                           reinterpret_cast<const char*>(text_section->Name),
  49    :                           arraysize(text_section->Name)));
  50  E :      ASSERT_NE(0U, text_section->Characteristics & IMAGE_SCN_MEM_EXECUTE);
  51    :  
  52    :      code_start = reinterpret_cast<uint8*>(&__ImageBase) +
  53  E :          text_section->VirtualAddress;
  54  E :      code_size = text_section->Misc.VirtualSize;
  55  E :    }
  56    :  
  57    :   protected:
  58    :    base::win::ScopedHandle process;
  59    :    void* code_start;
  60    :    size_t code_size;
  61    :  };
  62    :  
  63    :  }  // namespace
  64    :  
  65  E :  TEST_F(SamplingProfilerTest, Initialize) {
  66  E :    SamplingProfiler profiler;
  67    :  
  68  E :    ASSERT_TRUE(profiler.Initialize(process.Get(), code_start, code_size, 8));
  69  E :  }
  70    :  
  71  E :  TEST_F(SamplingProfilerTest, Sample) {
  72  E :    if (base::win::GetVersion() >= base::win::VERSION_WIN8) {
  73  i :      LOG(INFO) << "Not running test on Windows 8 or higher.";
  74  i :      return;
  75    :    }
  76  E :    SamplingProfiler profiler;
  77    :  
  78    :    // Initialize with a huge bucket size, aiming for a single bucket.
  79    :    ASSERT_TRUE(
  80  E :        profiler.Initialize(process.Get(), code_start, code_size, 31));
  81    :  
  82  E :    ASSERT_EQ(1, profiler.buckets().size());
  83  E :    ASSERT_EQ(0, profiler.buckets()[0]);
  84    :  
  85    :    // We use a roomy timeout to make sure this test is not flaky.
  86    :    // On the buildbots, there may not be a whole lot of CPU time
  87    :    // allotted to our process in this wall-clock time duration,
  88    :    // and samples will only accrue while this thread is busy on
  89    :    // a CPU core.
  90  E :    base::TimeDelta spin_time = base::TimeDelta::FromSeconds(10);
  91    :  
  92  E :    base::TimeDelta save_sampling_interval;
  93  E :    ASSERT_TRUE(SamplingProfiler::GetSamplingInterval(&save_sampling_interval));
  94    :  
  95    :    // Sample every 0.5 millisecs.
  96    :    ASSERT_TRUE(SamplingProfiler::SetSamplingInterval(
  97  E :        base::TimeDelta::FromMicroseconds(500)));
  98    :  
  99    :    ASSERT_TRUE(SamplingProfiler::SetSamplingInterval(
 100  E :        base::TimeDelta::FromMicroseconds(500)));
 101    :  
 102    :    // Start the profiler.
 103  E :    ASSERT_TRUE(profiler.Start());
 104    :  
 105    :    // Get a volatile pointer to our bucket to make sure that the compiler
 106    :    // doesn't optimize out the test in the loop that follows.
 107  E :    volatile const ULONG* bucket_ptr = &profiler.buckets()[0];
 108    :  
 109    :    // Spin for spin_time wall-clock seconds, or until we get some samples.
 110    :    // Note that sleeping isn't going to do us any good, the samples only
 111    :    // accrue while we're executing code.
 112  E :    base::Time start = base::Time::Now();
 113  E :    base::TimeDelta elapsed;
 114    :    do {
 115  E :      elapsed = base::Time::Now() - start;
 116  E :    } while ((elapsed < spin_time) && *bucket_ptr == 0);
 117    :  
 118    :    // Stop the profiler.
 119  E :    ASSERT_TRUE(profiler.Stop());
 120    :  
 121    :    // Restore the sampling interval we found.
 122  E :    ASSERT_TRUE(SamplingProfiler::SetSamplingInterval(save_sampling_interval));
 123    :  
 124    :    // Check that we got some samples.
 125  E :    ASSERT_NE(0U, profiler.buckets()[0]);
 126  E :  }
 127    :  
 128    :  }  // namespace sampler

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