event_trace_controller_unittest.cc revision 868fa2fe829687343ffae624259930155e16dbd8
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.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
22namespace base {
23namespace win {
24
25namespace {
26
27DEFINE_GUID(kGuidNull,
28    0x0000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0);
29
30const ULONG kTestProviderFlags = 0xCAFEBABE;
31
32class 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
59TEST(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
91TEST(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
108namespace {
109
110class 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
137TEST_F(EtwTraceControllerTest, Initialize) {
138  EtwTraceController controller;
139
140  EXPECT_EQ(NULL, controller.session());
141  EXPECT_STREQ(L"", controller.session_name());
142}
143
144
145TEST_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
163TEST_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    file_util::Delete(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  file_util::Delete(temp, false);
185}
186
187TEST_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