Coverage for /Syzygy/trace/parse/parse_engine_unittest.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
93.2%3283520.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/trace/parse/parse_engine.h"
  16    :  
  17    :  #include <windows.h>  // NOLINT
  18    :  #include <wmistr.h>  // NOLINT
  19    :  #include <evntrace.h>
  20    :  
  21    :  #include <set>
  22    :  #include <vector>
  23    :  
  24    :  #include "base/logging.h"
  25    :  #include "gmock/gmock.h"
  26    :  #include "gtest/gtest.h"
  27    :  #include "syzygy/trace/parse/parser.h"
  28    :  
  29    :  using trace::parser::Parser;
  30    :  using trace::parser::ParseEngine;
  31    :  using trace::parser::ParseEventHandlerImpl;
  32    :  using trace::parser::ModuleInformation;
  33    :  
  34    :  namespace {
  35    :  
  36    :  typedef std::multiset<FuncAddr> FunctionSet;
  37    :  typedef std::vector<TraceModuleData> ModuleSet;
  38    :  
  39    :  class ParseEngineUnitTest
  40    :      : public testing::Test,
  41    :        public ParseEngine,
  42    :        public ParseEventHandlerImpl {
  43    :   public:
  44    :    ParseEngineUnitTest()
  45    :        : ParseEngine("Test", true),
  46    :          basic_block_frequencies(0),
  47  E :          expected_data(NULL) {
  48  E :      set_event_handler(this);
  49  E :    }
  50    :  
  51  E :    ~ParseEngineUnitTest() {
  52  E :    }
  53    :  
  54    :  
  55  i :    bool IsRecognizedTraceFile(const FilePath& trace_file_path) OVERRIDE {
  56  i :      return true;
  57  i :    }
  58    :  
  59  i :    bool OpenTraceFile(const FilePath& trace_file_path) OVERRIDE {
  60  i :      return true;
  61  i :    }
  62    :  
  63  i :    virtual bool ConsumeAllEvents() {
  64  i :      return true;
  65  i :    }
  66    :  
  67  i :    virtual bool CloseAllTraceFiles() {
  68  i :      return true;
  69  i :    }
  70    :  
  71    :    // ParseEventHander methods.
  72    :  
  73    :    virtual void OnProcessStarted(base::Time time,
  74    :                                  DWORD process_id,
  75  i :                                  const TraceSystemInfo* data) {
  76  i :      ASSERT_EQ(process_id, kProcessId);
  77  i :    }
  78    :  
  79  i :    virtual void OnProcessEnded(base::Time time, DWORD process_id) {
  80  i :      ASSERT_EQ(process_id, kProcessId);
  81  i :    }
  82    :  
  83    :    virtual void OnFunctionEntry(base::Time time,
  84    :                                 DWORD process_id,
  85    :                                 DWORD thread_id,
  86  E :                                 const TraceEnterExitEventData* data) {
  87  E :      ASSERT_EQ(process_id, kProcessId);
  88  E :      ASSERT_EQ(thread_id, kThreadId);
  89  E :      ASSERT_TRUE(reinterpret_cast<const void*>(data) == expected_data);
  90  E :      EXPECT_TRUE(data->function != NULL);
  91  E :      function_entries.insert(data->function);
  92  E :    }
  93    :  
  94    :    virtual void OnFunctionExit(base::Time time,
  95    :                                DWORD process_id,
  96    :                                DWORD thread_id,
  97  E :                                const TraceEnterExitEventData* data) {
  98  E :      ASSERT_EQ(process_id, kProcessId);
  99  E :      ASSERT_EQ(thread_id, kThreadId);
 100  E :      ASSERT_TRUE(reinterpret_cast<const void*>(data) == expected_data);
 101  E :      EXPECT_TRUE(data->function != NULL);
 102  E :      function_exits.insert(data->function);
 103  E :    }
 104    :  
 105    :    virtual void OnBatchFunctionEntry(base::Time time,
 106    :                                      DWORD process_id,
 107    :                                      DWORD thread_id,
 108  E :                                      const TraceBatchEnterData* data) {
 109  E :      ASSERT_EQ(process_id, kProcessId);
 110  E :      ASSERT_EQ(thread_id, kThreadId);
 111  E :      ASSERT_TRUE(reinterpret_cast<const void*>(data) == expected_data);
 112  E :      for (size_t i = 0; i < data->num_calls; ++i) {
 113  E :        function_entries.insert(data->calls[i].function);
 114  E :      }
 115  E :    }
 116    :  
 117    :    virtual void OnProcessAttach(base::Time time,
 118    :                                 DWORD process_id,
 119    :                                 DWORD thread_id,
 120  E :                                 const TraceModuleData* data) {
 121  E :      ASSERT_EQ(process_id, kProcessId);
 122  E :      ASSERT_EQ(thread_id, kThreadId);
 123  E :      ASSERT_TRUE(reinterpret_cast<const void*>(data) == expected_data);
 124  E :      process_attaches.push_back(*data);
 125  E :    }
 126    :  
 127    :    virtual void OnProcessDetach(base::Time time,
 128    :                                 DWORD process_id,
 129    :                                 DWORD thread_id,
 130  E :                                 const TraceModuleData* data) {
 131  E :      ASSERT_EQ(process_id, kProcessId);
 132  E :      ASSERT_EQ(thread_id, kThreadId);
 133  E :      ASSERT_TRUE(reinterpret_cast<const void*>(data) == expected_data);
 134  E :      process_detaches.push_back(*data);
 135  E :    }
 136    :  
 137    :    virtual void OnThreadAttach(base::Time time,
 138    :                                DWORD process_id,
 139    :                                DWORD thread_id,
 140  E :                                const TraceModuleData* data) {
 141  E :      ASSERT_EQ(process_id, kProcessId);
 142  E :      ASSERT_EQ(thread_id, kThreadId);
 143  E :      ASSERT_TRUE(reinterpret_cast<const void*>(data) == expected_data);
 144  E :      thread_attaches.push_back(*data);
 145  E :    }
 146    :  
 147    :    // Issued for DLL_THREAD_DETACH on an instrumented module.
 148    :    virtual void OnThreadDetach(base::Time time,
 149    :                                DWORD process_id,
 150    :                                DWORD thread_id,
 151  E :                                const TraceModuleData* data) {
 152  E :      ASSERT_EQ(process_id, kProcessId);
 153  E :      ASSERT_EQ(thread_id, kThreadId);
 154  E :      ASSERT_TRUE(reinterpret_cast<const void*>(data) == expected_data);
 155  E :      thread_detaches.push_back(*data);
 156  E :    }
 157    :  
 158    :    virtual void OnBasicBlockFrequency(
 159    :        base::Time time,
 160    :        DWORD process_id,
 161    :        DWORD thread_id,
 162  E :        const TraceBasicBlockFrequencyData* data) {
 163  E :      ASSERT_EQ(process_id, kProcessId);
 164  E :      ASSERT_EQ(thread_id, kThreadId);
 165  E :      ASSERT_TRUE(reinterpret_cast<const void*>(data) == expected_data);
 166  E :      ++basic_block_frequencies;
 167  E :    }
 168    :  
 169    :    static const DWORD kProcessId;
 170    :    static const DWORD kThreadId;
 171    :    static const ModuleInformation kExeInfo;
 172    :    static const ModuleInformation kDllInfo;
 173    :    static const TraceModuleData kModuleData;
 174    :    static const TraceBasicBlockFrequencyData kBasicBlockFrequencyData;
 175    :    static const TraceBasicBlockFrequencyData kShortBasicBlockFrequencyData;
 176    :  
 177    :    FunctionSet function_entries;
 178    :    FunctionSet function_exits;
 179    :    ModuleSet process_attaches;
 180    :    ModuleSet process_detaches;
 181    :    ModuleSet thread_attaches;
 182    :    ModuleSet thread_detaches;
 183    :    size_t basic_block_frequencies;
 184    :  
 185    :    const void* expected_data;
 186    :  };
 187    :  
 188    :  const DWORD ParseEngineUnitTest::kProcessId = 0xAAAAAAAA;
 189    :  
 190    :  const DWORD ParseEngineUnitTest::kThreadId = 0xBBBBBBBB;
 191    :  
 192  E :  const ModuleInformation ParseEngineUnitTest::kExeInfo = {
 193  E :      0x11111111, 0x22222222, 0x33333333, 0x44444444, L"file_name.exe" };
 194    :  
 195  E :  const ModuleInformation ParseEngineUnitTest::kDllInfo = {
 196  E :      0x55555555, 0x66666666, 0x77777777, 0x88888888, L"file_name.dll" };
 197    :  
 198    :  const TraceModuleData ParseEngineUnitTest::kModuleData = {
 199    :      reinterpret_cast<ModuleAddr>(0x99999999),
 200    :      0x11111111,
 201    :      0x22222222,
 202    :      0x33333333,
 203    :      L"module",
 204    :      L"executable" };
 205    :  
 206    :  const TraceBasicBlockFrequencyData
 207    :  ParseEngineUnitTest::kBasicBlockFrequencyData = {
 208    :      reinterpret_cast<ModuleAddr>(0x11111111),
 209    :      0x22222222,
 210    :      0x33333333,
 211    :      0x44444444,
 212    :      1,
 213    :      1,
 214    :      0 };
 215    :  
 216    :  // This basic-block frequency struct does not contain enough data for its
 217    :  // implicitly encoded length.
 218    :  const TraceBasicBlockFrequencyData
 219    :  ParseEngineUnitTest::kShortBasicBlockFrequencyData = {
 220    :      reinterpret_cast<ModuleAddr>(0x11111111),
 221    :      0x22222222,
 222    :      0x33333333,
 223    :      0x44444444,
 224    :      4,
 225    :      10,
 226    :      0 };
 227    :  
 228    :  // A test function to show up in the trace events.
 229  i :  void TestFunc1() {
 230  i :    ::Sleep(100);
 231  i :  }
 232    :  
 233    :  // Another test function to show up in the trace events.
 234  i :  void TestFunc2() {
 235  i :    ::time(NULL);
 236  i :  }
 237    :  
 238  E :  TEST_F(ParseEngineUnitTest, ModuleInfo) {
 239  E :    const ModuleInformation* module_info = NULL;
 240    :  
 241    :    // Insert the module information.
 242  E :    ASSERT_TRUE(AddModuleInformation(kProcessId, kExeInfo));
 243  E :    ASSERT_TRUE(AddModuleInformation(kProcessId, kDllInfo));
 244  E :    ASSERT_EQ(1, processes_.size());
 245  E :    ASSERT_EQ(2, processes_[kProcessId].size());
 246    :  
 247    :    // Multiple identical insertions should be ok.
 248  E :    ASSERT_TRUE(AddModuleInformation(kProcessId, kDllInfo));
 249  E :    ASSERT_EQ(2, processes_[kProcessId].size());
 250    :  
 251    :    // Intersecting but not identical insertions should fail if disallowed.
 252  E :    ModuleInformation bad_dll_info(kDllInfo);
 253  E :    bad_dll_info.base_address += 100;
 254  E :    ASSERT_TRUE(fail_on_module_conflict_);
 255  E :    ASSERT_FALSE(AddModuleInformation(kProcessId, bad_dll_info));
 256  E :    ASSERT_EQ(2, processes_[kProcessId].size());
 257    :  
 258    :    // If conflicting module info is non-fatal, insertions should appear to
 259    :    // succeed but not actually happen.
 260  E :    fail_on_module_conflict_ = false;
 261  E :    ASSERT_TRUE(AddModuleInformation(kProcessId, bad_dll_info));
 262  E :    ASSERT_EQ(2, processes_[kProcessId].size());
 263  E :    fail_on_module_conflict_ = true;
 264    :  
 265    :    // Search for unknown process.
 266  E :    module_info = GetModuleInformation(kProcessId + 1, kExeInfo.base_address);
 267  E :    ASSERT_TRUE(module_info == NULL);
 268    :  
 269    :    // Search before exe start address
 270  E :    const int kBeforeOffset = -1;
 271    :    module_info = GetModuleInformation(kProcessId,
 272  E :                                       kExeInfo.base_address + kBeforeOffset);
 273  E :    ASSERT_TRUE(module_info == NULL);
 274    :  
 275    :    // Search after exe end address.
 276  E :    const size_t kAfterOffset = kExeInfo.module_size;
 277    :    module_info = GetModuleInformation(kProcessId,
 278  E :                                       kExeInfo.base_address + kAfterOffset);
 279  E :    ASSERT_TRUE(module_info == NULL);
 280    :  
 281    :    // Get exe module by start address.
 282  E :    const size_t kStartOffset = 0;
 283    :    module_info = GetModuleInformation(kProcessId,
 284  E :                                       kExeInfo.base_address + kStartOffset);
 285  E :    ASSERT_TRUE(module_info != NULL);
 286  E :    ASSERT_TRUE(*module_info == kExeInfo);
 287    :  
 288    :    // Get exe module by address somewhere in the middle.
 289  E :    const size_t kMiddleOffset = kExeInfo.module_size / 2;
 290    :    module_info = GetModuleInformation(kProcessId,
 291  E :                                       kExeInfo.base_address + kMiddleOffset);
 292  E :    ASSERT_TRUE(module_info != NULL);
 293  E :    ASSERT_TRUE(*module_info == kExeInfo);
 294    :  
 295    :    // Get exe module by address at the end.
 296  E :    const size_t kEndOffset = kExeInfo.module_size - 1;
 297    :    module_info = GetModuleInformation(kProcessId,
 298  E :                                       kExeInfo.base_address + kEndOffset);
 299  E :    ASSERT_TRUE(module_info != NULL);
 300  E :    ASSERT_TRUE(*module_info == kExeInfo);
 301    :  
 302    :    // We only remove modules from a given process if a conflicting module is
 303    :    // loaded after the module has been marked as dirty. This is because (1) we
 304    :    // don't guarantee temporal order of all events in a process, so you
 305    :    // might parse a function event after seeing the module get unloaded
 306    :    // if the buffers are flushed in that order; and (2) because process ids may
 307    :    // be reused (but not concurrently) so we do want to drop stale module info
 308    :    // when the process has been replaced.
 309    :  
 310    :    // Get dll module by address somewhere in the middle, then remove it and
 311    :    // see that it's STILL found by that address.
 312  E :    const size_t kDllOffset = kDllInfo.module_size / 2;
 313    :    module_info = GetModuleInformation(kProcessId,
 314  E :                                       kDllInfo.base_address + kDllOffset);
 315  E :    ASSERT_TRUE(module_info != NULL);
 316  E :    ASSERT_TRUE(*module_info == kDllInfo);
 317  E :    ASSERT_TRUE(RemoveModuleInformation(kProcessId, kDllInfo));
 318  E :    ASSERT_EQ(2, processes_[kProcessId].size());
 319    :    module_info = GetModuleInformation(kProcessId,
 320  E :                                       kDllInfo.base_address + kDllOffset);
 321  E :    ASSERT_TRUE(module_info != NULL);
 322  E :    ASSERT_TRUE(*module_info == kDllInfo);
 323    :  
 324    :    // Add conflicting module information and see that the old module is gone.
 325  E :    ModuleInformation new_dll_info = kDllInfo;
 326  E :    new_dll_info.base_address += 4;
 327  E :    ASSERT_TRUE(AddModuleInformation(kProcessId, new_dll_info));
 328  E :    ASSERT_EQ(2, processes_[kProcessId].size());
 329  E :    module_info = GetModuleInformation(kProcessId, kDllInfo.base_address);
 330  E :    ASSERT_TRUE(module_info == NULL);
 331  E :    module_info = GetModuleInformation(kProcessId, new_dll_info.base_address);
 332  E :    ASSERT_TRUE(module_info != NULL);
 333  E :    ASSERT_TRUE(*module_info == new_dll_info);
 334  E :  }
 335    :  
 336  E :  TEST_F(ParseEngineUnitTest, UnhandledEvent) {
 337  E :    EVENT_TRACE event_record = {};
 338  E :    ASSERT_FALSE(DispatchEvent(&event_record));
 339    :  
 340  E :    event_record.Header.ProcessId = kProcessId;
 341  E :    event_record.Header.ThreadId = kThreadId;
 342  E :    event_record.Header.Guid = kCallTraceEventClass;
 343  E :    event_record.Header.Class.Type = 0xFF;  // Invalid value.
 344  E :    ASSERT_TRUE(DispatchEvent(&event_record));
 345  E :    ASSERT_TRUE(error_occurred());
 346  E :  }
 347    :  
 348  E :  TEST_F(ParseEngineUnitTest, FunctionEntryEvents) {
 349  E :    TraceEnterEventData event_data = {};
 350  E :    event_data.function = &TestFunc1;
 351  E :    expected_data = &event_data;
 352    :  
 353  E :    EVENT_TRACE event_record = {};
 354  E :    event_record.Header.ProcessId = kProcessId;
 355  E :    event_record.Header.ThreadId = kThreadId;
 356  E :    event_record.Header.Guid = kCallTraceEventClass;
 357  E :    event_record.Header.Class.Type = TRACE_ENTER_EVENT;
 358  E :    event_record.MofData = &event_data;
 359  E :    event_record.MofLength = sizeof(event_data);
 360    :  
 361  E :    ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(DispatchEvent(&event_record)));
 362  E :    ASSERT_FALSE(error_occurred());
 363  E :    ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(DispatchEvent(&event_record)));
 364  E :    ASSERT_FALSE(error_occurred());
 365  E :    ASSERT_EQ(function_entries.size(), 2);
 366  E :    ASSERT_EQ(function_entries.count(&TestFunc1), 2);
 367    :  
 368    :    // Check for short event header.
 369  E :    event_record.MofLength = FIELD_OFFSET(TraceEnterEventData, function);
 370  E :    ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(DispatchEvent(&event_record)));
 371  E :    ASSERT_TRUE(error_occurred());
 372    :  
 373    :    // Check for short event tail.
 374  E :    set_error_occurred(false);
 375  E :    event_data.num_traces = 20;
 376  E :    event_record.MofLength = FIELD_OFFSET(TraceEnterEventData, traces);
 377  E :    ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(DispatchEvent(&event_record)));
 378  E :    ASSERT_TRUE(error_occurred());
 379  E :  }
 380    :  
 381  E :  TEST_F(ParseEngineUnitTest, FunctionExitEvents) {
 382  E :    TraceExitEventData event_data = {};
 383  E :    event_data.function = &TestFunc2;
 384  E :    expected_data = &event_data;
 385    :  
 386  E :    EVENT_TRACE event_record = {};
 387  E :    event_record.Header.ProcessId = kProcessId;
 388  E :    event_record.Header.ThreadId = kThreadId;
 389  E :    event_record.Header.Guid = kCallTraceEventClass;
 390  E :    event_record.Header.Class.Type = TRACE_EXIT_EVENT;
 391  E :    event_record.MofData = &event_data;
 392  E :    event_record.MofLength = sizeof(event_data);
 393    :  
 394  E :    ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(DispatchEvent(&event_record)));
 395  E :    ASSERT_FALSE(error_occurred());
 396  E :    ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(DispatchEvent(&event_record)));
 397  E :    ASSERT_FALSE(error_occurred());
 398  E :    ASSERT_EQ(function_exits.size(), 2);
 399  E :    ASSERT_EQ(function_exits.count(&TestFunc2), 2);
 400    :  
 401    :    // Check for short event header.
 402  E :    event_record.MofLength = FIELD_OFFSET(TraceEnterEventData, function);
 403  E :    ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(DispatchEvent(&event_record)));
 404  E :    ASSERT_TRUE(error_occurred());
 405    :  
 406    :    // Check for short event tail.
 407  E :    set_error_occurred(false);
 408  E :    event_data.num_traces = 20;
 409  E :    event_record.MofLength = FIELD_OFFSET(TraceExitEventData, traces);
 410  E :    ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(DispatchEvent(&event_record)));
 411  E :    ASSERT_TRUE(error_occurred());
 412  E :  }
 413    :  
 414  E :  TEST_F(ParseEngineUnitTest, BatchFunctionEntry) {
 415  E :    uint8 raw_data[sizeof(TraceBatchEnterData) + 4 * sizeof(FuncCall)] = {};
 416    :    TraceBatchEnterData& event_data =
 417  E :       *reinterpret_cast<TraceBatchEnterData*>(&raw_data);
 418  E :    event_data.thread_id = kThreadId;
 419  E :    event_data.num_calls = 5;
 420  E :    event_data.calls[0].function = &TestFunc1;
 421  E :    event_data.calls[1].function = &TestFunc2;
 422  E :    event_data.calls[2].function = &TestFunc1;
 423  E :    event_data.calls[3].function = &TestFunc2;
 424  E :    event_data.calls[4].function = NULL;
 425  E :    expected_data = &raw_data;
 426    :  
 427  E :    EVENT_TRACE event_record = {};
 428  E :    event_record.Header.ProcessId = kProcessId;
 429  E :    event_record.Header.ThreadId = kThreadId;
 430  E :    event_record.Header.Guid = kCallTraceEventClass;
 431  E :    event_record.Header.Class.Type = TRACE_BATCH_ENTER;
 432  E :    event_record.MofData = &raw_data;
 433  E :    event_record.MofLength = sizeof(raw_data);
 434    :  
 435  E :    ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(DispatchEvent(&event_record)));
 436  E :    ASSERT_FALSE(error_occurred());
 437  E :    ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(DispatchEvent(&event_record)));
 438  E :    ASSERT_FALSE(error_occurred());
 439  E :    ASSERT_EQ(function_entries.size(), 8);
 440  E :    ASSERT_EQ(function_entries.count(&TestFunc1), 4);
 441  E :    ASSERT_EQ(function_entries.count(&TestFunc2), 4);
 442    :  
 443    :    // Check for short event header.
 444  E :    event_record.MofLength = FIELD_OFFSET(TraceBatchEnterData, num_calls);
 445  E :    ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(DispatchEvent(&event_record)));
 446  E :    ASSERT_TRUE(error_occurred());
 447    :  
 448    :    // Check for short event tail (remove the empty record + one byte).
 449  E :    set_error_occurred(false);
 450  E :    event_record.MofLength = sizeof(raw_data) - sizeof(FuncCall) - 1;
 451  E :    ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(DispatchEvent(&event_record)));
 452  E :    ASSERT_TRUE(error_occurred());
 453  E :  }
 454    :  
 455  E :  TEST_F(ParseEngineUnitTest, ProcessAttachIncomplete) {
 456  E :    TraceModuleData incomplete(kModuleData);
 457  E :    incomplete.module_base_addr = NULL;
 458    :  
 459  E :    EVENT_TRACE event_record = {};
 460  E :    event_record.Header.ProcessId = kProcessId;
 461  E :    event_record.Header.ThreadId = kThreadId;
 462  E :    event_record.Header.Guid = kCallTraceEventClass;
 463  E :    event_record.Header.Class.Type = TRACE_PROCESS_ATTACH_EVENT;
 464  E :    event_record.MofData = const_cast<TraceModuleData*>(&incomplete);
 465  E :    event_record.MofLength = sizeof(incomplete);
 466  E :    expected_data = &kModuleData;
 467    :  
 468    :    // No error should be reported for NULL module addr, instead the record
 469    :    // should be ignored.
 470  E :    ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(DispatchEvent(&event_record)));
 471  E :    ASSERT_FALSE(error_occurred());
 472  E :    ASSERT_EQ(process_attaches.size(), 0);
 473  E :  }
 474    :  
 475  E :  TEST_F(ParseEngineUnitTest, ProcessAttach) {
 476  E :    EVENT_TRACE event_record = {};
 477  E :    event_record.Header.ProcessId = kProcessId;
 478  E :    event_record.Header.ThreadId = kThreadId;
 479  E :    event_record.Header.Guid = kCallTraceEventClass;
 480  E :    event_record.Header.Class.Type = TRACE_PROCESS_ATTACH_EVENT;
 481  E :    event_record.MofData = const_cast<TraceModuleData*>(&kModuleData);
 482  E :    event_record.MofLength = sizeof(kModuleData);
 483  E :    expected_data = &kModuleData;
 484    :  
 485  E :    ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(DispatchEvent(&event_record)));
 486  E :    ASSERT_FALSE(error_occurred());
 487  E :    ASSERT_EQ(process_attaches.size(), 1);
 488    :  
 489    :    // Check for short module event.
 490  E :    event_record.MofLength -= 1;
 491  E :    ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(DispatchEvent(&event_record)));
 492  E :    ASSERT_TRUE(error_occurred());
 493  E :  }
 494    :  
 495  E :  TEST_F(ParseEngineUnitTest, ProcessDetach) {
 496  E :    EVENT_TRACE event_record = {};
 497  E :    event_record.Header.ProcessId = kProcessId;
 498  E :    event_record.Header.ThreadId = kThreadId;
 499  E :    event_record.Header.Guid = kCallTraceEventClass;
 500  E :    event_record.Header.Class.Type = TRACE_PROCESS_DETACH_EVENT;
 501  E :    event_record.MofData = const_cast<TraceModuleData*>(&kModuleData);
 502  E :    event_record.MofLength = sizeof(kModuleData);
 503  E :    expected_data = &kModuleData;
 504    :  
 505  E :    ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(DispatchEvent(&event_record)));
 506  E :    ASSERT_FALSE(error_occurred());
 507  E :    ASSERT_EQ(process_detaches.size(), 1);
 508    :  
 509    :    // Check for short module event.
 510  E :    event_record.MofLength -= 1;
 511  E :    ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(DispatchEvent(&event_record)));
 512  E :    ASSERT_TRUE(error_occurred());
 513  E :  }
 514    :  
 515  E :  TEST_F(ParseEngineUnitTest, ThreadAttach) {
 516  E :    EVENT_TRACE event_record = {};
 517  E :    event_record.Header.ProcessId = kProcessId;
 518  E :    event_record.Header.ThreadId = kThreadId;
 519  E :    event_record.Header.Guid = kCallTraceEventClass;
 520  E :    event_record.Header.Class.Type = TRACE_THREAD_ATTACH_EVENT;
 521  E :    event_record.MofData = const_cast<TraceModuleData*>(&kModuleData);
 522  E :    event_record.MofLength = sizeof(kModuleData);
 523  E :    expected_data = &kModuleData;
 524    :  
 525  E :    ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(DispatchEvent(&event_record)));
 526  E :    ASSERT_FALSE(error_occurred());
 527  E :    ASSERT_EQ(thread_attaches.size(), 1);
 528    :  
 529    :    // Check for short module event.
 530  E :    event_record.MofLength -= 1;
 531  E :    ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(DispatchEvent(&event_record)));
 532  E :    ASSERT_TRUE(error_occurred());
 533  E :  }
 534    :  
 535  E :  TEST_F(ParseEngineUnitTest, ThreadDetach) {
 536  E :    EVENT_TRACE event_record = {};
 537  E :    event_record.Header.ProcessId = kProcessId;
 538  E :    event_record.Header.ThreadId = kThreadId;
 539  E :    event_record.Header.Guid = kCallTraceEventClass;
 540  E :    event_record.Header.Class.Type = TRACE_THREAD_DETACH_EVENT;
 541  E :    event_record.MofData = const_cast<TraceModuleData*>(&kModuleData);
 542  E :    event_record.MofLength = sizeof(kModuleData);
 543  E :    expected_data = &kModuleData;
 544    :  
 545  E :    ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(DispatchEvent(&event_record)));
 546  E :    ASSERT_FALSE(error_occurred());
 547  E :    ASSERT_EQ(thread_detaches.size(), 1);
 548    :  
 549    :    // Check for short module event.
 550  E :    event_record.MofLength -= 1;
 551  E :    ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(DispatchEvent(&event_record)));
 552  E :    ASSERT_TRUE(error_occurred());
 553  E :  }
 554    :  
 555  E :  TEST_F(ParseEngineUnitTest, BasicBlockFrequencyTooSmallForHeader) {
 556  E :    EVENT_TRACE event_record = {};
 557  E :    event_record.Header.ProcessId = kProcessId;
 558  E :    event_record.Header.ThreadId = kThreadId;
 559  E :    event_record.Header.Guid = kCallTraceEventClass;
 560  E :    event_record.Header.Class.Type = TRACE_BASIC_BLOCK_FREQUENCY;
 561    :    event_record.MofData = const_cast<TraceBasicBlockFrequencyData*>(
 562  E :        &kBasicBlockFrequencyData);
 563  E :    event_record.MofLength = sizeof(kBasicBlockFrequencyData) - 1;
 564    :  
 565  E :    ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(DispatchEvent(&event_record)));
 566  E :    ASSERT_TRUE(error_occurred());
 567  E :    ASSERT_EQ(basic_block_frequencies, 0);
 568  E :  }
 569    :  
 570  E :  TEST_F(ParseEngineUnitTest, BasicBlockFrequencyTooSmallForContents) {
 571  E :    EVENT_TRACE event_record = {};
 572  E :    event_record.Header.ProcessId = kProcessId;
 573  E :    event_record.Header.ThreadId = kThreadId;
 574  E :    event_record.Header.Guid = kCallTraceEventClass;
 575  E :    event_record.Header.Class.Type = TRACE_BASIC_BLOCK_FREQUENCY;
 576    :    event_record.MofData = const_cast<TraceBasicBlockFrequencyData*>(
 577  E :        &kShortBasicBlockFrequencyData);
 578  E :    event_record.MofLength = sizeof(kShortBasicBlockFrequencyData);
 579    :  
 580  E :    ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(DispatchEvent(&event_record)));
 581  E :    ASSERT_TRUE(error_occurred());
 582  E :    ASSERT_EQ(basic_block_frequencies, 0);
 583  E :  }
 584    :  
 585  E :  TEST_F(ParseEngineUnitTest, BasicBlockFrequency) {
 586  E :    EVENT_TRACE event_record = {};
 587  E :    event_record.Header.ProcessId = kProcessId;
 588  E :    event_record.Header.ThreadId = kThreadId;
 589  E :    event_record.Header.Guid = kCallTraceEventClass;
 590  E :    event_record.Header.Class.Type = TRACE_BASIC_BLOCK_FREQUENCY;
 591    :    event_record.MofData = const_cast<TraceBasicBlockFrequencyData*>(
 592  E :        &kBasicBlockFrequencyData);
 593  E :    event_record.MofLength = sizeof(kBasicBlockFrequencyData);
 594  E :    expected_data = &kBasicBlockFrequencyData;
 595    :  
 596  E :    ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(DispatchEvent(&event_record)));
 597  E :    ASSERT_FALSE(error_occurred());
 598  E :    ASSERT_EQ(basic_block_frequencies, 1);
 599  E :  }
 600    :  
 601    :  }  // namespace

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