1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 // 5 // Unit tests for event trace controller. 6 7 #include <objbase.h> 8 #include <initguid.h> 9 10 #include "base/file_util.h" 11 #include "base/files/file_path.h" 12 #include "base/files/scoped_temp_dir.h" 13 #include "base/logging.h" 14 #include "base/process/process.h" 15 #include "base/strings/stringprintf.h" 16 #include "base/sys_info.h" 17 #include "base/win/event_trace_controller.h" 18 #include "base/win/event_trace_provider.h" 19 #include "base/win/scoped_handle.h" 20 #include "testing/gtest/include/gtest/gtest.h" 21 22 namespace base { 23 namespace win { 24 25 namespace { 26 27 DEFINE_GUID(kGuidNull, 28 0x0000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0); 29 30 const ULONG kTestProviderFlags = 0xCAFEBABE; 31 32 class TestingProvider: public EtwTraceProvider { 33 public: 34 explicit TestingProvider(const GUID& provider_name) 35 : EtwTraceProvider(provider_name) { 36 callback_event_.Set(::CreateEvent(NULL, TRUE, FALSE, NULL)); 37 } 38 39 void WaitForCallback() { 40 ::WaitForSingleObject(callback_event_.Get(), INFINITE); 41 ::ResetEvent(callback_event_.Get()); 42 } 43 44 private: 45 virtual void OnEventsEnabled() { 46 ::SetEvent(callback_event_.Get()); 47 } 48 virtual void PostEventsDisabled() { 49 ::SetEvent(callback_event_.Get()); 50 } 51 52 ScopedHandle callback_event_; 53 54 DISALLOW_COPY_AND_ASSIGN(TestingProvider); 55 }; 56 57 } // namespace 58 59 TEST(EtwTracePropertiesTest, Initialization) { 60 EtwTraceProperties prop; 61 62 EVENT_TRACE_PROPERTIES* p = prop.get(); 63 EXPECT_NE(0u, p->Wnode.BufferSize); 64 EXPECT_EQ(0u, p->Wnode.ProviderId); 65 EXPECT_EQ(0u, p->Wnode.HistoricalContext); 66 67 EXPECT_TRUE(kGuidNull == p->Wnode.Guid); 68 EXPECT_EQ(0, p->Wnode.ClientContext); 69 EXPECT_EQ(WNODE_FLAG_TRACED_GUID, p->Wnode.Flags); 70 71 EXPECT_EQ(0, p->BufferSize); 72 EXPECT_EQ(0, p->MinimumBuffers); 73 EXPECT_EQ(0, p->MaximumBuffers); 74 EXPECT_EQ(0, p->MaximumFileSize); 75 EXPECT_EQ(0, p->LogFileMode); 76 EXPECT_EQ(0, p->FlushTimer); 77 EXPECT_EQ(0, p->EnableFlags); 78 EXPECT_EQ(0, p->AgeLimit); 79 80 EXPECT_EQ(0, p->NumberOfBuffers); 81 EXPECT_EQ(0, p->FreeBuffers); 82 EXPECT_EQ(0, p->EventsLost); 83 EXPECT_EQ(0, p->BuffersWritten); 84 EXPECT_EQ(0, p->LogBuffersLost); 85 EXPECT_EQ(0, p->RealTimeBuffersLost); 86 EXPECT_EQ(0, p->LoggerThreadId); 87 EXPECT_NE(0u, p->LogFileNameOffset); 88 EXPECT_NE(0u, p->LoggerNameOffset); 89 } 90 91 TEST(EtwTracePropertiesTest, Strings) { 92 EtwTraceProperties prop; 93 94 ASSERT_STREQ(L"", prop.GetLoggerFileName()); 95 ASSERT_STREQ(L"", prop.GetLoggerName()); 96 97 std::wstring name(1023, L'A'); 98 ASSERT_HRESULT_SUCCEEDED(prop.SetLoggerFileName(name.c_str())); 99 ASSERT_HRESULT_SUCCEEDED(prop.SetLoggerName(name.c_str())); 100 ASSERT_STREQ(name.c_str(), prop.GetLoggerFileName()); 101 ASSERT_STREQ(name.c_str(), prop.GetLoggerName()); 102 103 std::wstring name2(1024, L'A'); 104 ASSERT_HRESULT_FAILED(prop.SetLoggerFileName(name2.c_str())); 105 ASSERT_HRESULT_FAILED(prop.SetLoggerName(name2.c_str())); 106 } 107 108 namespace { 109 110 class EtwTraceControllerTest : public testing::Test { 111 public: 112 EtwTraceControllerTest() 113 : session_name_( 114 StringPrintf(L"TestSession-%d", Process::Current().pid())) { 115 } 116 117 virtual void SetUp() { 118 EtwTraceProperties ignore; 119 EtwTraceController::Stop(session_name_.c_str(), &ignore); 120 121 // Allocate a new provider name GUID for each test. 122 ASSERT_HRESULT_SUCCEEDED(::CoCreateGuid(&test_provider_)); 123 } 124 125 virtual void TearDown() { 126 EtwTraceProperties prop; 127 EtwTraceController::Stop(session_name_.c_str(), &prop); 128 } 129 130 protected: 131 GUID test_provider_; 132 std::wstring session_name_; 133 }; 134 135 } // namespace 136 137 TEST_F(EtwTraceControllerTest, Initialize) { 138 EtwTraceController controller; 139 140 EXPECT_EQ(NULL, controller.session()); 141 EXPECT_STREQ(L"", controller.session_name()); 142 } 143 144 145 TEST_F(EtwTraceControllerTest, StartRealTimeSession) { 146 EtwTraceController controller; 147 148 HRESULT hr = controller.StartRealtimeSession(session_name_.c_str(), 149 100 * 1024); 150 if (hr == E_ACCESSDENIED) { 151 VLOG(1) << "You must be an administrator to run this test on Vista"; 152 return; 153 } 154 155 EXPECT_TRUE(NULL != controller.session()); 156 EXPECT_STREQ(session_name_.c_str(), controller.session_name()); 157 158 EXPECT_HRESULT_SUCCEEDED(controller.Stop(NULL)); 159 EXPECT_EQ(NULL, controller.session()); 160 EXPECT_STREQ(L"", controller.session_name()); 161 } 162 163 TEST_F(EtwTraceControllerTest, StartFileSession) { 164 ScopedTempDir temp_dir; 165 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 166 FilePath temp; 167 ASSERT_TRUE(file_util::CreateTemporaryFileInDir(temp_dir.path(), &temp)); 168 169 EtwTraceController controller; 170 HRESULT hr = controller.StartFileSession(session_name_.c_str(), 171 temp.value().c_str()); 172 if (hr == E_ACCESSDENIED) { 173 VLOG(1) << "You must be an administrator to run this test on Vista"; 174 base::DeleteFile(temp, false); 175 return; 176 } 177 178 EXPECT_TRUE(NULL != controller.session()); 179 EXPECT_STREQ(session_name_.c_str(), controller.session_name()); 180 181 EXPECT_HRESULT_SUCCEEDED(controller.Stop(NULL)); 182 EXPECT_EQ(NULL, controller.session()); 183 EXPECT_STREQ(L"", controller.session_name()); 184 base::DeleteFile(temp, false); 185 } 186 187 TEST_F(EtwTraceControllerTest, EnableDisable) { 188 TestingProvider provider(test_provider_); 189 190 EXPECT_EQ(ERROR_SUCCESS, provider.Register()); 191 EXPECT_EQ(NULL, provider.session_handle()); 192 193 EtwTraceController controller; 194 HRESULT hr = controller.StartRealtimeSession(session_name_.c_str(), 195 100 * 1024); 196 if (hr == E_ACCESSDENIED) { 197 VLOG(1) << "You must be an administrator to run this test on Vista"; 198 return; 199 } 200 201 EXPECT_HRESULT_SUCCEEDED(controller.EnableProvider(test_provider_, 202 TRACE_LEVEL_VERBOSE, kTestProviderFlags)); 203 204 provider.WaitForCallback(); 205 206 EXPECT_EQ(TRACE_LEVEL_VERBOSE, provider.enable_level()); 207 EXPECT_EQ(kTestProviderFlags, provider.enable_flags()); 208 209 EXPECT_HRESULT_SUCCEEDED(controller.DisableProvider(test_provider_)); 210 211 provider.WaitForCallback(); 212 213 EXPECT_EQ(0, provider.enable_level()); 214 EXPECT_EQ(0, provider.enable_flags()); 215 216 EXPECT_EQ(ERROR_SUCCESS, provider.Unregister()); 217 218 // Enable the provider again, before registering. 219 EXPECT_HRESULT_SUCCEEDED(controller.EnableProvider(test_provider_, 220 TRACE_LEVEL_VERBOSE, kTestProviderFlags)); 221 222 // Register the provider again, the settings above 223 // should take immediate effect. 224 EXPECT_EQ(ERROR_SUCCESS, provider.Register()); 225 226 EXPECT_EQ(TRACE_LEVEL_VERBOSE, provider.enable_level()); 227 EXPECT_EQ(kTestProviderFlags, provider.enable_flags()); 228 229 EXPECT_HRESULT_SUCCEEDED(controller.Stop(NULL)); 230 231 provider.WaitForCallback(); 232 233 // Session should have wound down. 234 EXPECT_EQ(0, provider.enable_level()); 235 EXPECT_EQ(0, provider.enable_flags()); 236 } 237 238 } // namespace win 239 } // namespace base 240