Home | History | Annotate | Download | only in win
      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