15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Unit tests for event trace consumer base class. 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/event_trace_consumer.h" 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <list> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <objbase.h> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/scoped_temp_dir.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 1758e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#include "base/process/process.h" 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/event_trace_controller.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/event_trace_provider.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/scoped_handle.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <initguid.h> // NOLINT - has to be last 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace base { 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace win { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef std::list<EVENT_TRACE> EventQueue; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestConsumer: public EtwTraceConsumerBase<TestConsumer> { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestConsumer() { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sank_event_.Set(::CreateEvent(NULL, TRUE, FALSE, NULL)); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearQueue(); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~TestConsumer() { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearQueue(); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sank_event_.Close(); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ClearQueue() { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventQueue::const_iterator it(events_.begin()), end(events_.end()); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (; it != end; ++it) { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete [] it->MofData; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events_.clear(); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void EnqueueEvent(EVENT_TRACE* event) { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events_.push_back(*event); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EVENT_TRACE& back = events_.back(); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (NULL != event->MofData && 0 != event->MofLength) { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back.MofData = new char[event->MofLength]; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(back.MofData, event->MofData, event->MofLength); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void ProcessEvent(EVENT_TRACE* event) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnqueueEvent(event); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::SetEvent(sank_event_.Get()); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static ScopedHandle sank_event_; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static EventQueue events_; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TestConsumer); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ScopedHandle TestConsumer::sank_event_; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EventQueue TestConsumer::events_; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class EtwTraceConsumerBaseTest: public testing::Test { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwTraceConsumerBaseTest() 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : session_name_(StringPrintf(L"TestSession-%d", 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Process::Current().pid())) { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cleanup any potentially dangling sessions. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwTraceProperties ignore; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwTraceController::Stop(session_name_.c_str(), &ignore); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allocate a new GUID for each provider test. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_HRESULT_SUCCEEDED(::CoCreateGuid(&test_provider_)); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void TearDown() { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cleanup any potentially danging sessions. 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwTraceProperties ignore; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwTraceController::Stop(session_name_.c_str(), &ignore); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GUID test_provider_; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::wstring session_name_; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(EtwTraceConsumerBaseTest, Initialize) { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestConsumer consumer_; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(EtwTraceConsumerBaseTest, OpenRealtimeSucceedsWhenNoSession) { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestConsumer consumer_; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_HRESULT_SUCCEEDED( 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) consumer_.OpenRealtimeSession(session_name_.c_str())); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(EtwTraceConsumerBaseTest, ConsumerImmediateFailureWhenNoSession) { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestConsumer consumer_; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_HRESULT_SUCCEEDED( 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) consumer_.OpenRealtimeSession(session_name_.c_str())); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_HRESULT_FAILED(consumer_.Consume()); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class EtwTraceConsumerRealtimeTest: public EtwTraceConsumerBaseTest { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwTraceConsumerBaseTest::SetUp(); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_HRESULT_SUCCEEDED( 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) consumer_.OpenRealtimeSession(session_name_.c_str())); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void TearDown() { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) consumer_.Close(); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwTraceConsumerBaseTest::TearDown(); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD ConsumerThread() { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::SetEvent(consumer_ready_.Get()); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT hr = consumer_.Consume(); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return hr; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static DWORD WINAPI ConsumerThreadMainProc(void* arg) { 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return reinterpret_cast<EtwTraceConsumerRealtimeTest*>(arg)-> 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConsumerThread(); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT StartConsumerThread() { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) consumer_ready_.Set(::CreateEvent(NULL, TRUE, FALSE, NULL)); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(consumer_ready_ != NULL); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) consumer_thread_.Set(::CreateThread(NULL, 0, ConsumerThreadMainProc, 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, 0, NULL)); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (NULL == consumer_thread_.Get()) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return HRESULT_FROM_WIN32(::GetLastError()); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT hr = S_OK; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE events[] = { consumer_ready_, consumer_thread_ }; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD result = ::WaitForMultipleObjects(arraysize(events), events, 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FALSE, INFINITE); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (result) { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WAIT_OBJECT_0: 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The event was set, the consumer_ is ready. 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return S_OK; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WAIT_OBJECT_0 + 1: { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The thread finished. This may race with the event, so check 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // explicitly for the event here, before concluding there's trouble. 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (WAIT_OBJECT_0 == ::WaitForSingleObject(consumer_ready_, 0)) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return S_OK; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD exit_code = 0; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (::GetExitCodeThread(consumer_thread_, &exit_code)) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return exit_code; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return HRESULT_FROM_WIN32(::GetLastError()); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return E_UNEXPECTED; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return hr; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Waits for consumer_ thread to exit, and returns its exit code. 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT JoinConsumerThread() { 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (WAIT_OBJECT_0 != ::WaitForSingleObject(consumer_thread_, INFINITE)) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return HRESULT_FROM_WIN32(::GetLastError()); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD exit_code = 0; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (::GetExitCodeThread(consumer_thread_, &exit_code)) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return exit_code; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return HRESULT_FROM_WIN32(::GetLastError()); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestConsumer consumer_; 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScopedHandle consumer_ready_; 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScopedHandle consumer_thread_; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(EtwTraceConsumerRealtimeTest, ConsumerReturnsWhenSessionClosed) { 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwTraceController controller; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT hr = controller.StartRealtimeSession(session_name_.c_str(), 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 100 * 1024); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (hr == E_ACCESSDENIED) { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "You must be an administrator to run this test on Vista"; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start the consumer_. 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_HRESULT_SUCCEEDED(StartConsumerThread()); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wait around for the consumer_ thread a bit. 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WAIT_TIMEOUT, ::WaitForSingleObject(consumer_thread_, 50)); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_HRESULT_SUCCEEDED(controller.Stop(NULL)); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The consumer_ returns success on session stop. 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_HRESULT_SUCCEEDED(JoinConsumerThread()); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// {57E47923-A549-476f-86CA-503D57F59E62} 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DEFINE_GUID(kTestEventType, 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0x57e47923, 0xa549, 0x476f, 0x86, 0xca, 0x50, 0x3d, 0x57, 0xf5, 0x9e, 0x62); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(EtwTraceConsumerRealtimeTest, ConsumeEvent) { 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwTraceController controller; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT hr = controller.StartRealtimeSession(session_name_.c_str(), 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 100 * 1024); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (hr == E_ACCESSDENIED) { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "You must be an administrator to run this test on Vista"; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_HRESULT_SUCCEEDED(controller.EnableProvider(test_provider_, 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_LEVEL_VERBOSE, 0xFFFFFFFF)); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwTraceProvider provider(test_provider_); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ERROR_SUCCESS, provider.Register()); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start the consumer_. 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_HRESULT_SUCCEEDED(StartConsumerThread()); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, TestConsumer::events_.size()); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwMofEvent<1> event(kTestEventType, 1, TRACE_LEVEL_ERROR); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERROR_SUCCESS, provider.Log(&event.header)); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(WAIT_OBJECT_0, ::WaitForSingleObject(TestConsumer::sank_event_, 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INFINITE)); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_HRESULT_SUCCEEDED(controller.Stop(NULL)); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_HRESULT_SUCCEEDED(JoinConsumerThread()); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NE(0u, TestConsumer::events_.size()); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We run events through a file session to assert that 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the content comes through. 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class EtwTraceConsumerDataTest: public EtwTraceConsumerBaseTest { 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwTraceConsumerDataTest() { 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() { 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwTraceConsumerBaseTest::SetUp(); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwTraceProperties prop; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwTraceController::Stop(session_name_.c_str(), &prop); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a temp dir for this test. 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct a temp file name in our dir. 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp_file_ = temp_dir_.path().Append(L"test.etl"); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void TearDown() { 2947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_TRUE(base::DeleteFile(temp_file_, false)); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwTraceConsumerBaseTest::TearDown(); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT LogEventToTempSession(PEVENT_TRACE_HEADER header) { 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwTraceController controller; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set up a file session. 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT hr = controller.StartFileSession(session_name_.c_str(), 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp_file_.value().c_str()); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FAILED(hr)) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return hr; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Enable our provider. 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_HRESULT_SUCCEEDED(controller.EnableProvider(test_provider_, 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_LEVEL_VERBOSE, 0xFFFFFFFF)); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwTraceProvider provider(test_provider_); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Then register our provider, means we get a session handle immediately. 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERROR_SUCCESS, provider.Register()); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Trace the event, it goes to the temp file. 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERROR_SUCCESS, provider.Log(header)); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_HRESULT_SUCCEEDED(controller.DisableProvider(test_provider_)); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_HRESULT_SUCCEEDED(provider.Unregister()); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_HRESULT_SUCCEEDED(controller.Flush(NULL)); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_HRESULT_SUCCEEDED(controller.Stop(NULL)); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return S_OK; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT ConsumeEventFromTempSession() { 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now consume the event(s). 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestConsumer consumer_; 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT hr = consumer_.OpenFileSession(temp_file_.value().c_str()); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SUCCEEDED(hr)) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hr = consumer_.Consume(); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) consumer_.Close(); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // And nab the result. 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events_.swap(TestConsumer::events_); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return hr; 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT RoundTripEvent(PEVENT_TRACE_HEADER header, PEVENT_TRACE* trace) { 3387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::DeleteFile(temp_file_, false); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT hr = LogEventToTempSession(header); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SUCCEEDED(hr)) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hr = ConsumeEventFromTempSession(); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FAILED(hr)) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return hr; 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should now have the event in the queue. 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (events_.empty()) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return E_FAIL; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *trace = &events_.back(); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return S_OK; 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventQueue events_; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedTempDir temp_dir_; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FilePath temp_file_; 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(EtwTraceConsumerDataTest, RoundTrip) { 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwMofEvent<1> event(kTestEventType, 1, TRACE_LEVEL_ERROR); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char kData[] = "This is but test data"; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event.fields[0].DataPtr = reinterpret_cast<ULONG64>(kData); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event.fields[0].Length = sizeof(kData); 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PEVENT_TRACE trace = NULL; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT hr = RoundTripEvent(&event.header, &trace); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (hr == E_ACCESSDENIED) { 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "You must be an administrator to run this test on Vista"; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_HRESULT_SUCCEEDED(hr) << "RoundTripEvent failed"; 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(NULL != trace); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(sizeof(kData), trace->MofLength); 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_STREQ(kData, reinterpret_cast<const char*>(trace->MofData)); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace win 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace base 384