Coverage for /Syzygy/trace/common/unittest_util.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
100.0%73730.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/trace/common/unittest_util.h"
  16    :  
  17    :  #include <memory>
  18    :  
  19    :  #include "base/command_line.h"
  20    :  #include "base/environment.h"
  21    :  #include "base/process/kill.h"
  22    :  #include "base/process/launch.h"
  23    :  #include "base/strings/stringprintf.h"
  24    :  #include "base/strings/utf_string_conversions.h"
  25    :  #include "base/win/scoped_handle.h"
  26    :  #include "syzygy/common/align.h"
  27    :  #include "syzygy/common/buffer_writer.h"
  28    :  #include "syzygy/core/unittest_util.h"
  29    :  #include "syzygy/trace/protocol/call_trace_defs.h"
  30    :  
  31    :  namespace testing {
  32    :  
  33    :  CallTraceService::CallTraceService()
  34  E :      : instance_id_(base::StringPrintf("%d", ::GetCurrentProcessId())),
  35  E :        service_process_(base::kNullProcessHandle) {
  36  E :  }
  37    :  
  38  E :  CallTraceService::~CallTraceService() {
  39  E :    Stop();
  40  E :  }
  41    :  
  42  E :  void CallTraceService::Start(const base::FilePath& trace_dir) {
  43  E :    ASSERT_TRUE(!service_process_.IsValid());
  44    :  
  45  E :    base::CommandLine service_cmd(
  46    :        testing::GetExeRelativePath(L"call_trace_service.exe"));
  47  E :    service_cmd.AppendArg("start");
  48  E :    service_cmd.AppendSwitch("--verbose");
  49  E :    service_cmd.AppendSwitchPath("--trace-dir", trace_dir);
  50  E :    service_cmd.AppendSwitchASCII("--instance-id", instance_id_);
  51    :  
  52  E :    base::LaunchOptions options;
  53  E :    options.start_hidden = true;
  54    :  
  55  E :    std::wstring event_name;
  56  E :    ::GetSyzygyCallTraceRpcEventName(base::UTF8ToUTF16(instance_id_),
  57    :                                     &event_name);
  58  E :    base::win::ScopedHandle event(
  59    :        ::CreateEvent(NULL, TRUE, FALSE, event_name.c_str()));
  60  E :    ASSERT_TRUE(event.IsValid());
  61    :  
  62  E :    service_process_ = base::LaunchProcess(service_cmd, options);
  63  E :    ASSERT_TRUE(service_process_.IsValid());
  64    :  
  65    :    // We wait on both the "ready" handle and the process, as if the process
  66    :    // fails for any reason, it'll exit and its handle will become signaled.
  67  E :    HANDLE handles[] = {event.Get(), service_process_.Handle()};
  68  E :    ASSERT_EQ(WAIT_OBJECT_0, ::WaitForMultipleObjects(arraysize(handles),
  69    :                                                      handles,
  70    :                                                      FALSE,
  71  E :                                                      INFINITE));
  72  E :  }
  73    :  
  74  E :  void CallTraceService::Stop() {
  75  E :    if (!service_process_.IsValid())
  76  E :      return;
  77    :  
  78  E :    base::CommandLine service_cmd(
  79    :        testing::GetExeRelativePath(L"call_trace_service.exe"));
  80  E :    service_cmd.AppendArg("stop");
  81  E :    service_cmd.AppendSwitchASCII("--instance-id", instance_id_);
  82    :  
  83  E :    base::LaunchOptions options;
  84  E :    options.start_hidden = true;
  85  E :    options.wait = true;
  86  E :    base::Process stop_process = base::LaunchProcess(service_cmd, options);
  87  E :    ASSERT_TRUE(stop_process.IsValid());
  88    :  
  89  E :    int exit_code = 0;
  90  E :    ASSERT_TRUE(service_process_.WaitForExit(&exit_code));
  91  E :    service_process_.Close();
  92  E :  }
  93    :  
  94  E :  void CallTraceService::SetEnvironment() {
  95    :    // The instance id needs to be in the environment to be picked up by the
  96    :    // client library.
  97  E :    std::unique_ptr<base::Environment> env(base::Environment::Create());
  98  E :    ASSERT_FALSE(env.get() == NULL);
  99    :  
 100    :    // Get the existing value.
 101  E :    std::string env_var;
 102  E :    env->GetVar(::kSyzygyRpcInstanceIdEnvVar, &env_var);
 103    :  
 104    :    // Prefix the existing environment variable with the instance ID we've
 105    :    // chosen. This allows previously intended behaviour to persist.
 106  E :    env_var.insert(0, ";");
 107  E :    env_var.insert(0, instance_id_);
 108    :  
 109  E :    ASSERT_TRUE(env->SetVar(::kSyzygyRpcInstanceIdEnvVar, env_var));
 110  E :  }
 111    :  
 112    :  void WriteRecord(uint64_t timestamp,
 113    :                   uint16_t record_type,
 114    :                   const void* data,
 115    :                   size_t length,
 116  E :                   trace::service::TraceFileWriter* writer) {
 117  E :    ASSERT_TRUE(data != NULL);
 118  E :    ASSERT_TRUE(writer != NULL);
 119    :  
 120  E :    std::vector<uint8_t> buffer;
 121  E :    ::common::VectorBufferWriter buffer_writer(&buffer);
 122    :  
 123  E :    RecordPrefix record = {};
 124  E :    record.timestamp = timestamp;
 125  E :    record.type = TraceFileSegmentHeader::kTypeId;
 126  E :    record.size = sizeof(TraceFileSegmentHeader);
 127  E :    record.version.hi = TRACE_VERSION_HI;
 128  E :    record.version.lo = TRACE_VERSION_LO;
 129  E :    ASSERT_TRUE(buffer_writer.Write(record));
 130    :  
 131  E :    TraceFileSegmentHeader header = {};
 132  E :    header.segment_length = sizeof(RecordPrefix) + length;
 133  E :    header.thread_id = ::GetCurrentThreadId();
 134  E :    ASSERT_TRUE(buffer_writer.Write(header));
 135    :  
 136  E :    record.type = record_type;
 137  E :    record.size = length;
 138  E :    ASSERT_TRUE(buffer_writer.Write(record));
 139    :  
 140  E :    ASSERT_TRUE(buffer_writer.Write(
 141  E :        length, reinterpret_cast<const void*>(data)));
 142    :  
 143  E :    buffer.resize(::common::AlignUp(buffer.size(), writer->block_size()));
 144  E :    ASSERT_TRUE(writer->WriteRecord(buffer.data(), buffer.size()));
 145  E :  }
 146    :  
 147    :  }  // namespace testing

Coverage information generated Fri Jul 29 11:00:21 2016.