Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(57)

Side by Side Diff: base/event_trace_consumer_unittest.cc

Issue 624713003: Keep only base/extractor.[cc|h]. (Closed) Base URL: https://chromium.googlesource.com/external/omaha.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/event_trace_consumer.h ('k') | base/event_trace_controller.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2010 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 // ========================================================================
15 //
16 // Unit tests for event trace consumer_ base class.
17 #include "omaha/base/event_trace_consumer.h"
18 #include <atlbase.h>
19 #include <atlsync.h>
20 #include <list>
21 #include "base/basictypes.h"
22 #include "omaha/base/app_util.h"
23 #include "omaha/base/event_trace_controller.h"
24 #include "omaha/base/event_trace_provider.h"
25 // TODO(omaha): Remove when http://b/2767208 is fixed.
26 #include "omaha/base/vistautil.h"
27 #include "omaha/testing/unit_test.h"
28
29 #include <initguid.h> // NOLINT - has to be last
30
31 namespace omaha {
32
33 namespace {
34
35 using omaha::EtwTraceConsumerBase;
36 using omaha::EtwTraceController;
37 using omaha::EtwTraceProperties;
38
39 typedef std::list<EVENT_TRACE> EventQueue;
40
41 class TestConsumer: public EtwTraceConsumerBase<TestConsumer> {
42 public:
43 TestConsumer() {
44 sank_event_.Create(NULL, TRUE, FALSE, NULL);
45
46 ClearQueue();
47 }
48
49 ~TestConsumer() {
50 ClearQueue();
51 sank_event_.Close();
52 }
53
54 void ClearQueue() {
55 EventQueue::const_iterator it(events_.begin()), end(events_.end());
56
57 for (; it != end; ++it) {
58 delete [] it->MofData;
59 }
60
61 events_.clear();
62 }
63
64 static void EnqueueEvent(EVENT_TRACE* event) {
65 events_.push_back(*event);
66 EVENT_TRACE& back = events_.back();
67
68 if (NULL != event->MofData && 0 != event->MofLength) {
69 back.MofData = new char[event->MofLength];
70 memcpy(back.MofData, event->MofData, event->MofLength);
71 }
72 }
73
74 static void ProcessEvent(EVENT_TRACE* event) {
75 EnqueueEvent(event);
76 sank_event_.Set();
77 }
78
79 static CEvent sank_event_;
80 static EventQueue events_;
81
82 private:
83 DISALLOW_COPY_AND_ASSIGN(TestConsumer);
84 };
85
86 CEvent TestConsumer::sank_event_;
87 EventQueue TestConsumer::events_;
88
89 const wchar_t* const kTestSessionName = L"TestLogSession";
90
91 void StopTestTraceSession() {
92 // Shut down any potentially dangling session.
93 EtwTraceProperties prop;
94 EtwTraceController::Stop(kTestSessionName, &prop);
95 }
96
97 class EtwTraceConsumerBaseTest: public testing::Test {
98 public:
99 virtual void SetUp() {
100 StopTestTraceSession();
101 }
102 };
103
104 } // namespace
105
106 TEST_F(EtwTraceConsumerBaseTest, Initialize) {
107 TestConsumer consumer_;
108 }
109
110 TEST_F(EtwTraceConsumerBaseTest, OpenRealtimeSucceedsWhenNoSession) {
111 TestConsumer consumer_;
112
113 EXPECT_HRESULT_SUCCEEDED(consumer_.OpenRealtimeSession(kTestSessionName));
114 }
115
116 TEST_F(EtwTraceConsumerBaseTest, ConsumerImmediateFailureWhenNoSession) {
117 TestConsumer consumer_;
118
119 EXPECT_HRESULT_SUCCEEDED(consumer_.OpenRealtimeSession(kTestSessionName));
120 EXPECT_HRESULT_FAILED(consumer_.Consume());
121 }
122
123 class EtwTraceConsumerRealtimeTest: public testing::Test {
124 public:
125 virtual void SetUp() {
126 StopTestTraceSession();
127
128 EXPECT_HRESULT_SUCCEEDED(consumer_.OpenRealtimeSession(kTestSessionName));
129 }
130
131 virtual void TearDown() {
132 consumer_.Close();
133 }
134
135 DWORD ConsumerThread() {
136 ::SetEvent(consumer_ready_);
137
138 HRESULT hr = consumer_.Consume();
139 return hr;
140 }
141
142 static DWORD WINAPI ConsumerThreadMainProc(void* arg) {
143 return reinterpret_cast<EtwTraceConsumerRealtimeTest*>(arg)->
144 ConsumerThread();
145 }
146
147 HRESULT StartConsumerThread() {
148 consumer_ready_.Attach(::CreateEvent(NULL, TRUE, FALSE, NULL));
149 EXPECT_TRUE(consumer_ready_ != NULL);
150 consumer_thread_.Attach(::CreateThread(NULL, 0, ConsumerThreadMainProc,
151 this, 0, NULL));
152 if (NULL == consumer_thread_)
153 return HRESULT_FROM_WIN32(::GetLastError());
154
155 HRESULT hr = S_OK;
156 HANDLE events[] = { consumer_ready_, consumer_thread_ };
157 DWORD result = ::WaitForMultipleObjects(arraysize(events), events,
158 FALSE, INFINITE);
159 switch (result) {
160 case WAIT_OBJECT_0:
161 // The event was set, the consumer_ is ready.
162 return S_OK;
163 case WAIT_OBJECT_0 + 1: {
164 // The thread finished. This may race with the event, so check
165 // explicitly for the event here, before concluding there's trouble.
166 if (WAIT_OBJECT_0 == ::WaitForSingleObject(consumer_ready_, 0))
167 return S_OK;
168 DWORD exit_code = 0;
169 if (::GetExitCodeThread(consumer_thread_, &exit_code))
170 return exit_code;
171 else
172 return HRESULT_FROM_WIN32(::GetLastError());
173 break;
174 }
175 default:
176 return E_UNEXPECTED;
177 break;
178 }
179
180 // NOTREACHED
181 }
182
183 // Waits for consumer_ thread to exit, and returns its exit code.
184 HRESULT JoinConsumerThread() {
185 if (WAIT_OBJECT_0 != ::WaitForSingleObject(consumer_thread_, INFINITE))
186 return HRESULT_FROM_WIN32(::GetLastError());
187
188 DWORD exit_code = 0;
189 if (::GetExitCodeThread(consumer_thread_, &exit_code))
190 return exit_code;
191
192 return HRESULT_FROM_WIN32(::GetLastError());
193 }
194
195 TestConsumer consumer_;
196 CHandle consumer_ready_;
197 CHandle consumer_thread_;
198 };
199
200 TEST_F(EtwTraceConsumerRealtimeTest, ConsumerReturnsWhenSessionClosed) {
201 if (!IsBuildSystem() && !vista_util::IsVistaOrLater()) {
202 std::wcout << _T("\tTest not run due to http://b/2767208.") << std::endl;
203 return;
204 }
205
206 EtwTraceController controller;
207
208 HRESULT hr = controller.StartRealtimeSession(kTestSessionName, 100 * 1024);
209 if (hr == E_ACCESSDENIED) {
210 SUCCEED() << "You must be an administrator to run this test on Vista";
211 return;
212 }
213
214 // Start the consumer_.
215 EXPECT_HRESULT_SUCCEEDED(StartConsumerThread());
216
217 // Wait around for the consumer_ thread a bit.
218 EXPECT_EQ(WAIT_TIMEOUT, ::WaitForSingleObject(consumer_thread_, 50));
219
220 EXPECT_HRESULT_SUCCEEDED(controller.Stop(NULL));
221
222 // The consumer_ returns success on session stop.
223 EXPECT_HRESULT_SUCCEEDED(JoinConsumerThread());
224 }
225
226 namespace {
227
228 // {036B8F65-8DF3-46e4-ABFC-6985C43D59BA}
229 DEFINE_GUID(kTestProvider,
230 0x36b8f65, 0x8df3, 0x46e4, 0xab, 0xfc, 0x69, 0x85, 0xc4, 0x3d, 0x59, 0xba);
231
232 // {57E47923-A549-476f-86CA-503D57F59E62}
233 DEFINE_GUID(kTestEventType,
234 0x57e47923, 0xa549, 0x476f, 0x86, 0xca, 0x50, 0x3d, 0x57, 0xf5, 0x9e, 0x62);
235
236 } // namespace
237
238 TEST_F(EtwTraceConsumerRealtimeTest, ConsumeEvent) {
239 if (!IsBuildSystem() && !vista_util::IsVistaOrLater()) {
240 std::wcout << _T("\tTest not run due to http://b/2767208.") << std::endl;
241 return;
242 }
243
244 EtwTraceController controller;
245 HRESULT hr = controller.StartRealtimeSession(kTestSessionName, 100 * 1024);
246 if (hr == E_ACCESSDENIED) {
247 SUCCEED() << "You must be an administrator to run this test on Vista";
248 return;
249 }
250
251 EXPECT_HRESULT_SUCCEEDED(controller.EnableProvider(kTestProvider,
252 TRACE_LEVEL_VERBOSE, 0xFFFFFFFF));
253
254 EtwTraceProvider provider(kTestProvider);
255 EXPECT_EQ(ERROR_SUCCESS, provider.Register());
256
257 // Start the consumer_.
258 EXPECT_HRESULT_SUCCEEDED(StartConsumerThread());
259
260 EXPECT_EQ(0, TestConsumer::events_.size());
261
262 EtwMofEvent<1> event(kTestEventType, 1, TRACE_LEVEL_ERROR);
263 EXPECT_EQ(ERROR_SUCCESS, provider.Log(&event.header));
264
265 EXPECT_EQ(WAIT_OBJECT_0, ::WaitForSingleObject(TestConsumer::sank_event_,
266 INFINITE));
267 EXPECT_HRESULT_SUCCEEDED(controller.Stop(NULL));
268 EXPECT_HRESULT_SUCCEEDED(JoinConsumerThread());
269 EXPECT_NE(0, TestConsumer::events_.size());
270 }
271
272 namespace {
273
274 // We run events through a file session to assert that
275 // the content comes through.
276 class EtwTraceConsumerDataTest: public testing::Test {
277 public:
278 EtwTraceConsumerDataTest() {
279 }
280
281 virtual void SetUp() {
282 StopTestTraceSession();
283
284 // Construct a temp file name.
285 CString temp_dir = omaha::app_util::GetTempDir();
286 EXPECT_TRUE(::GetTempFileName(temp_dir, _T("tmp"), 0,
287 CStrBuf(temp_file_, MAX_PATH)));
288 }
289
290 virtual void TearDown() {
291 EXPECT_TRUE(::DeleteFile(temp_file_));
292
293 // Shut down any potentially dangling session.
294 EtwTraceProperties prop;
295 EtwTraceController::Stop(kTestSessionName, &prop);
296 }
297
298 HRESULT LogEventToTempSession(PEVENT_TRACE_HEADER header) {
299 EtwTraceController controller;
300
301 // Set up a file session.
302 HRESULT hr = controller.StartFileSession(kTestSessionName, temp_file_);
303 if (FAILED(hr))
304 return hr;
305
306 // Enable our provider.
307 EXPECT_HRESULT_SUCCEEDED(controller.EnableProvider(kTestProvider,
308 TRACE_LEVEL_VERBOSE, 0xFFFFFFFF));
309
310 EtwTraceProvider provider(kTestProvider);
311 // Then register our provider, means we get a session handle immediately.
312 EXPECT_EQ(ERROR_SUCCESS, provider.Register());
313 // Trace the event, it goes to the temp file.
314 EXPECT_EQ(ERROR_SUCCESS, provider.Log(header));
315 EXPECT_HRESULT_SUCCEEDED(controller.DisableProvider(kTestProvider));
316 EXPECT_HRESULT_SUCCEEDED(provider.Unregister());
317 EXPECT_HRESULT_SUCCEEDED(controller.Flush(NULL));
318 EXPECT_HRESULT_SUCCEEDED(controller.Stop(NULL));
319
320 return S_OK;
321 }
322
323 HRESULT ConsumeEventFromTempSession() {
324 // Now consume the event(s).
325 TestConsumer consumer_;
326 HRESULT hr = consumer_.OpenFileSession(temp_file_);
327 if (SUCCEEDED(hr))
328 hr = consumer_.Consume();
329 consumer_.Close();
330 // And nab the result.
331 events_.swap(TestConsumer::events_);
332 return hr;
333 }
334
335 HRESULT RoundTripEvent(PEVENT_TRACE_HEADER header, PEVENT_TRACE* trace) {
336 ::DeleteFile(temp_file_);
337
338 HRESULT hr = LogEventToTempSession(header);
339 if (SUCCEEDED(hr))
340 hr = ConsumeEventFromTempSession();
341
342 if (FAILED(hr))
343 return hr;
344
345 // We should now have the event in the queue.
346 if (events_.empty())
347 return E_FAIL;
348
349 *trace = &events_.back();
350 return S_OK;
351 }
352
353 EventQueue events_;
354 CString temp_file_;
355 };
356
357 } // namespace
358
359
360 TEST_F(EtwTraceConsumerDataTest, RoundTrip) {
361 EtwMofEvent<1> event(kTestEventType, 1, TRACE_LEVEL_ERROR);
362
363 static const char kData[] = "This is but test data";
364 event.fields[0].DataPtr = reinterpret_cast<ULONG_PTR>(kData);
365 event.fields[0].Length = sizeof(kData);
366
367 PEVENT_TRACE trace = NULL;
368 HRESULT hr = RoundTripEvent(&event.header, &trace);
369 if (hr == E_ACCESSDENIED) {
370 SUCCEED() << "You must be an administrator to run this test on Vista";
371 return;
372 }
373 ASSERT_TRUE(NULL != trace);
374 EXPECT_EQ(sizeof(kData), trace->MofLength);
375 EXPECT_STREQ(kData, reinterpret_cast<const char*>(trace->MofData));
376 }
377
378 } // namespace omaha
379
OLDNEW
« no previous file with comments | « base/event_trace_consumer.h ('k') | base/event_trace_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698