event_trace_controller_unittest.cc revision 3f50c38dc070f4bb515c1b64450dae14f316474e
1// Copyright (c) 2011 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 <initguid.h>  // NOLINT.
8
9#include "base/file_path.h"
10#include "base/file_util.h"
11#include "base/logging.h"
12#include "base/sys_info.h"
13#include "base/win/event_trace_controller.h"
14#include "base/win/event_trace_provider.h"
15#include "base/win/scoped_handle.h"
16#include "testing/gtest/include/gtest/gtest.h"
17
18namespace {
19
20using base::win::EtwTraceController;
21using base::win::EtwTraceProvider;
22using base::win::EtwTraceProperties;
23
24const wchar_t kTestSessionName[] = L"TestLogSession";
25
26// {0D236A42-CD18-4e3d-9975-DCEEA2106E05}
27DEFINE_GUID(kTestProvider,
28    0xd236a42, 0xcd18, 0x4e3d, 0x99, 0x75, 0xdc, 0xee, 0xa2, 0x10, 0x6e, 0x5);
29
30DEFINE_GUID(kGuidNull,
31    0x0000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0);
32
33const ULONG kTestProviderFlags = 0xCAFEBABE;
34
35class TestingProvider: public EtwTraceProvider {
36 public:
37  explicit TestingProvider(const GUID& provider_name)
38      : EtwTraceProvider(provider_name) {
39    callback_event_.Set(::CreateEvent(NULL, TRUE, FALSE, NULL));
40  }
41
42  void WaitForCallback() {
43    ::WaitForSingleObject(callback_event_.Get(), INFINITE);
44    ::ResetEvent(callback_event_.Get());
45  }
46
47 private:
48  virtual void OnEventsEnabled() {
49    ::SetEvent(callback_event_.Get());
50  }
51  virtual void PostEventsDisabled() {
52    ::SetEvent(callback_event_.Get());
53  }
54
55  base::win::ScopedHandle callback_event_;
56
57  DISALLOW_COPY_AND_ASSIGN(TestingProvider);
58};
59
60}  // namespace
61
62TEST(EtwTraceTest, Cleanup) {
63  // Clean up potential leftover sessions from previous unsuccessful runs.
64  EtwTraceProperties ignore;
65  EtwTraceController::Stop(kTestSessionName, &ignore);
66}
67
68TEST(EtwTracePropertiesTest, Initialization) {
69  EtwTraceProperties prop;
70
71  EVENT_TRACE_PROPERTIES* p = prop.get();
72  EXPECT_NE(0u, p->Wnode.BufferSize);
73  EXPECT_EQ(0u, p->Wnode.ProviderId);
74  EXPECT_EQ(0u, p->Wnode.HistoricalContext);
75
76  EXPECT_TRUE(kGuidNull == p->Wnode.Guid);
77  EXPECT_EQ(0, p->Wnode.ClientContext);
78  EXPECT_EQ(WNODE_FLAG_TRACED_GUID, p->Wnode.Flags);
79
80  EXPECT_EQ(0, p->BufferSize);
81  EXPECT_EQ(0, p->MinimumBuffers);
82  EXPECT_EQ(0, p->MaximumBuffers);
83  EXPECT_EQ(0, p->MaximumFileSize);
84  EXPECT_EQ(0, p->LogFileMode);
85  EXPECT_EQ(0, p->FlushTimer);
86  EXPECT_EQ(0, p->EnableFlags);
87  EXPECT_EQ(0, p->AgeLimit);
88
89  EXPECT_EQ(0, p->NumberOfBuffers);
90  EXPECT_EQ(0, p->FreeBuffers);
91  EXPECT_EQ(0, p->EventsLost);
92  EXPECT_EQ(0, p->BuffersWritten);
93  EXPECT_EQ(0, p->LogBuffersLost);
94  EXPECT_EQ(0, p->RealTimeBuffersLost);
95  EXPECT_EQ(0, p->LoggerThreadId);
96  EXPECT_NE(0u, p->LogFileNameOffset);
97  EXPECT_NE(0u, p->LoggerNameOffset);
98}
99
100TEST(EtwTracePropertiesTest, Strings) {
101  EtwTraceProperties prop;
102
103  ASSERT_STREQ(L"", prop.GetLoggerFileName());
104  ASSERT_STREQ(L"", prop.GetLoggerName());
105
106  std::wstring name(1023, L'A');
107  ASSERT_HRESULT_SUCCEEDED(prop.SetLoggerFileName(name.c_str()));
108  ASSERT_HRESULT_SUCCEEDED(prop.SetLoggerName(name.c_str()));
109  ASSERT_STREQ(name.c_str(), prop.GetLoggerFileName());
110  ASSERT_STREQ(name.c_str(), prop.GetLoggerName());
111
112  std::wstring name2(1024, L'A');
113  ASSERT_HRESULT_FAILED(prop.SetLoggerFileName(name2.c_str()));
114  ASSERT_HRESULT_FAILED(prop.SetLoggerName(name2.c_str()));
115}
116
117TEST(EtwTraceControllerTest, Initialize) {
118  EtwTraceController controller;
119
120  EXPECT_EQ(NULL, controller.session());
121  EXPECT_STREQ(L"", controller.session_name());
122}
123
124TEST(EtwTraceControllerTest, StartRealTimeSession) {
125  EtwTraceController controller;
126
127  HRESULT hr = controller.StartRealtimeSession(kTestSessionName, 100 * 1024);
128  if (hr == E_ACCESSDENIED) {
129    VLOG(1) << "You must be an administrator to run this test on Vista";
130    return;
131  }
132
133  EXPECT_TRUE(NULL != controller.session());
134  EXPECT_STREQ(kTestSessionName, controller.session_name());
135
136  EXPECT_HRESULT_SUCCEEDED(controller.Stop(NULL));
137  EXPECT_EQ(NULL, controller.session());
138  EXPECT_STREQ(L"", controller.session_name());
139}
140
141TEST(EtwTraceControllerTest, StartFileSession) {
142  FilePath temp;
143
144  ASSERT_HRESULT_SUCCEEDED(file_util::CreateTemporaryFile(&temp));
145
146  EtwTraceController controller;
147  HRESULT hr = controller.StartFileSession(kTestSessionName,
148                                           temp.value().c_str());
149  if (hr == E_ACCESSDENIED) {
150    VLOG(1) << "You must be an administrator to run this test on Vista";
151    return;
152  }
153
154  EXPECT_TRUE(NULL != controller.session());
155  EXPECT_STREQ(kTestSessionName, controller.session_name());
156
157  EXPECT_HRESULT_SUCCEEDED(controller.Stop(NULL));
158  EXPECT_EQ(NULL, controller.session());
159  EXPECT_STREQ(L"", controller.session_name());
160}
161
162TEST(EtwTraceControllerTest, EnableDisable) {
163  TestingProvider provider(kTestProvider);
164
165  EXPECT_EQ(ERROR_SUCCESS, provider.Register());
166  EXPECT_EQ(NULL, provider.session_handle());
167
168  EtwTraceController controller;
169  HRESULT hr = controller.StartRealtimeSession(kTestSessionName, 100 * 1024);
170  if (hr == E_ACCESSDENIED) {
171    VLOG(1) << "You must be an administrator to run this test on Vista";
172    return;
173  }
174
175  EXPECT_HRESULT_SUCCEEDED(controller.EnableProvider(kTestProvider,
176                           TRACE_LEVEL_VERBOSE, kTestProviderFlags));
177
178  provider.WaitForCallback();
179
180  EXPECT_EQ(TRACE_LEVEL_VERBOSE, provider.enable_level());
181  EXPECT_EQ(kTestProviderFlags, provider.enable_flags());
182
183  EXPECT_HRESULT_SUCCEEDED(controller.DisableProvider(kTestProvider));
184
185  provider.WaitForCallback();
186
187  EXPECT_EQ(0, provider.enable_level());
188  EXPECT_EQ(0, provider.enable_flags());
189
190  EXPECT_EQ(ERROR_SUCCESS, provider.Unregister());
191
192  // Enable the provider again, before registering.
193  EXPECT_HRESULT_SUCCEEDED(controller.EnableProvider(kTestProvider,
194                           TRACE_LEVEL_VERBOSE, kTestProviderFlags));
195
196  // Register the provider again, the settings above
197  // should take immediate effect.
198  EXPECT_EQ(ERROR_SUCCESS, provider.Register());
199
200  EXPECT_EQ(TRACE_LEVEL_VERBOSE, provider.enable_level());
201  EXPECT_EQ(kTestProviderFlags, provider.enable_flags());
202
203  EXPECT_HRESULT_SUCCEEDED(controller.Stop(NULL));
204
205  provider.WaitForCallback();
206
207  // Session should have wound down.
208  EXPECT_EQ(0, provider.enable_level());
209  EXPECT_EQ(0, provider.enable_flags());
210}
211