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" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/files/file_util.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() { 4623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) for (EventQueue::const_iterator it(events_.begin()), end(events_.end()); 4723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) it != end; ++it) { 485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) delete[] reinterpret_cast<char*>(it->MofData); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events_.clear(); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void EnqueueEvent(EVENT_TRACE* event) { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events_.push_back(*event); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EVENT_TRACE& back = events_.back(); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (event->MofData != NULL && event->MofLength != 0) { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back.MofData = new char[event->MofLength]; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(back.MofData, event->MofData, event->MofLength); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void ProcessEvent(EVENT_TRACE* event) { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnqueueEvent(event); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::SetEvent(sank_event_.Get()); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static ScopedHandle sank_event_; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static EventQueue events_; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TestConsumer); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ScopedHandle TestConsumer::sank_event_; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EventQueue TestConsumer::events_; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class EtwTraceConsumerBaseTest: public testing::Test { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwTraceConsumerBaseTest() 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : session_name_(StringPrintf(L"TestSession-%d", 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Process::Current().pid())) { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cleanup any potentially dangling sessions. 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwTraceProperties ignore; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwTraceController::Stop(session_name_.c_str(), &ignore); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allocate a new GUID for each provider test. 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_HRESULT_SUCCEEDED(::CoCreateGuid(&test_provider_)); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void TearDown() { 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Cleanup any potentially dangling sessions. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwTraceProperties ignore; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwTraceController::Stop(session_name_.c_str(), &ignore); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GUID test_provider_; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::wstring session_name_; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(EtwTraceConsumerBaseTest, Initialize) { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestConsumer consumer_; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(EtwTraceConsumerBaseTest, OpenRealtimeSucceedsWhenNoSession) { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestConsumer consumer_; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_HRESULT_SUCCEEDED( 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) consumer_.OpenRealtimeSession(session_name_.c_str())); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(EtwTraceConsumerBaseTest, ConsumerImmediateFailureWhenNoSession) { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestConsumer consumer_; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_HRESULT_SUCCEEDED( 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) consumer_.OpenRealtimeSession(session_name_.c_str())); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_HRESULT_FAILED(consumer_.Consume()); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class EtwTraceConsumerRealtimeTest: public EtwTraceConsumerBaseTest { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwTraceConsumerBaseTest::SetUp(); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_HRESULT_SUCCEEDED( 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) consumer_.OpenRealtimeSession(session_name_.c_str())); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void TearDown() { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) consumer_.Close(); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwTraceConsumerBaseTest::TearDown(); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD ConsumerThread() { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::SetEvent(consumer_ready_.Get()); 14223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return consumer_.Consume(); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static DWORD WINAPI ConsumerThreadMainProc(void* arg) { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return reinterpret_cast<EtwTraceConsumerRealtimeTest*>(arg)-> 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConsumerThread(); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT StartConsumerThread() { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) consumer_ready_.Set(::CreateEvent(NULL, TRUE, FALSE, NULL)); 1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(consumer_ready_.IsValid()); 15323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) consumer_thread_.Set(::CreateThread(NULL, 0, ConsumerThreadMainProc, this, 15423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 0, NULL)); 15523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (consumer_thread_.Get() == NULL) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return HRESULT_FROM_WIN32(::GetLastError()); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci HANDLE events[] = { consumer_ready_.Get(), consumer_thread_.Get() }; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD result = ::WaitForMultipleObjects(arraysize(events), events, 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FALSE, INFINITE); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (result) { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WAIT_OBJECT_0: 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The event was set, the consumer_ is ready. 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return S_OK; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WAIT_OBJECT_0 + 1: { 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The thread finished. This may race with the event, so check 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // explicitly for the event here, before concluding there's trouble. 1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (::WaitForSingleObject(consumer_ready_.Get(), 0) == WAIT_OBJECT_0) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return S_OK; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD exit_code = 0; 1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (::GetExitCodeThread(consumer_thread_.Get(), &exit_code)) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return exit_code; 17323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return HRESULT_FROM_WIN32(::GetLastError()); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return E_UNEXPECTED; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Waits for consumer_ thread to exit, and returns its exit code. 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT JoinConsumerThread() { 1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (::WaitForSingleObject(consumer_thread_.Get(), INFINITE) != 1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci WAIT_OBJECT_0) { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return HRESULT_FROM_WIN32(::GetLastError()); 1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD exit_code = 0; 1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (::GetExitCodeThread(consumer_thread_.Get(), &exit_code)) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return exit_code; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return HRESULT_FROM_WIN32(::GetLastError()); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestConsumer consumer_; 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScopedHandle consumer_ready_; 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScopedHandle consumer_thread_; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(EtwTraceConsumerRealtimeTest, ConsumerReturnsWhenSessionClosed) { 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwTraceController controller; 20323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (controller.StartRealtimeSession(session_name_.c_str(), 100 * 1024) == 20423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) E_ACCESSDENIED) { 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "You must be an administrator to run this test on Vista"; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start the consumer_. 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_HRESULT_SUCCEEDED(StartConsumerThread()); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wait around for the consumer_ thread a bit. 2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ASSERT_EQ(WAIT_TIMEOUT, ::WaitForSingleObject(consumer_thread_.Get(), 50)); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_HRESULT_SUCCEEDED(controller.Stop(NULL)); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The consumer_ returns success on session stop. 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_HRESULT_SUCCEEDED(JoinConsumerThread()); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// {57E47923-A549-476f-86CA-503D57F59E62} 22323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)DEFINE_GUID( 22423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) kTestEventType, 22523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 0x57e47923, 0xa549, 0x476f, 0x86, 0xca, 0x50, 0x3d, 0x57, 0xf5, 0x9e, 0x62); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(EtwTraceConsumerRealtimeTest, ConsumeEvent) { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwTraceController controller; 23123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (controller.StartRealtimeSession(session_name_.c_str(), 100 * 1024) == 23223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) E_ACCESSDENIED) { 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "You must be an administrator to run this test on Vista"; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ASSERT_HRESULT_SUCCEEDED(controller.EnableProvider( 23823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) test_provider_, TRACE_LEVEL_VERBOSE, 0xFFFFFFFF)); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwTraceProvider provider(test_provider_); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ERROR_SUCCESS, provider.Register()); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start the consumer_. 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_HRESULT_SUCCEEDED(StartConsumerThread()); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, TestConsumer::events_.size()); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwMofEvent<1> event(kTestEventType, 1, TRACE_LEVEL_ERROR); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERROR_SUCCESS, provider.Log(&event.header)); 2491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(WAIT_OBJECT_0, 2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ::WaitForSingleObject(TestConsumer::sank_event_.Get(), INFINITE)); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_HRESULT_SUCCEEDED(controller.Stop(NULL)); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_HRESULT_SUCCEEDED(JoinConsumerThread()); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NE(0u, TestConsumer::events_.size()); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We run events through a file session to assert that 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the content comes through. 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class EtwTraceConsumerDataTest: public EtwTraceConsumerBaseTest { 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwTraceConsumerDataTest() { 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() { 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwTraceConsumerBaseTest::SetUp(); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwTraceProperties prop; 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwTraceController::Stop(session_name_.c_str(), &prop); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a temp dir for this test. 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct a temp file name in our dir. 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp_file_ = temp_dir_.path().Append(L"test.etl"); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void TearDown() { 2787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_TRUE(base::DeleteFile(temp_file_, false)); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwTraceConsumerBaseTest::TearDown(); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT LogEventToTempSession(PEVENT_TRACE_HEADER header) { 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwTraceController controller; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set up a file session. 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT hr = controller.StartFileSession(session_name_.c_str(), 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp_file_.value().c_str()); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FAILED(hr)) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return hr; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Enable our provider. 29323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) EXPECT_HRESULT_SUCCEEDED(controller.EnableProvider( 29423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) test_provider_, TRACE_LEVEL_VERBOSE, 0xFFFFFFFF)); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwTraceProvider provider(test_provider_); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Then register our provider, means we get a session handle immediately. 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERROR_SUCCESS, provider.Register()); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Trace the event, it goes to the temp file. 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ERROR_SUCCESS, provider.Log(header)); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_HRESULT_SUCCEEDED(controller.DisableProvider(test_provider_)); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_HRESULT_SUCCEEDED(provider.Unregister()); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_HRESULT_SUCCEEDED(controller.Flush(NULL)); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_HRESULT_SUCCEEDED(controller.Stop(NULL)); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return S_OK; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT ConsumeEventFromTempSession() { 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now consume the event(s). 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestConsumer consumer_; 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT hr = consumer_.OpenFileSession(temp_file_.value().c_str()); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SUCCEEDED(hr)) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hr = consumer_.Consume(); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) consumer_.Close(); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // And nab the result. 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events_.swap(TestConsumer::events_); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return hr; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT RoundTripEvent(PEVENT_TRACE_HEADER header, PEVENT_TRACE* trace) { 3227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::DeleteFile(temp_file_, false); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT hr = LogEventToTempSession(header); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SUCCEEDED(hr)) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hr = ConsumeEventFromTempSession(); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FAILED(hr)) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return hr; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should now have the event in the queue. 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (events_.empty()) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return E_FAIL; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *trace = &events_.back(); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return S_OK; 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventQueue events_; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedTempDir temp_dir_; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FilePath temp_file_; 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(EtwTraceConsumerDataTest, RoundTrip) { 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EtwMofEvent<1> event(kTestEventType, 1, TRACE_LEVEL_ERROR); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char kData[] = "This is but test data"; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event.fields[0].DataPtr = reinterpret_cast<ULONG64>(kData); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event.fields[0].Length = sizeof(kData); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PEVENT_TRACE trace = NULL; 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT hr = RoundTripEvent(&event.header, &trace); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (hr == E_ACCESSDENIED) { 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "You must be an administrator to run this test on Vista"; 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_HRESULT_SUCCEEDED(hr) << "RoundTripEvent failed"; 36123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ASSERT_TRUE(trace != NULL); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(sizeof(kData), trace->MofLength); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_STREQ(kData, reinterpret_cast<const char*>(trace->MofData)); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace win 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace base 368