// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Unit tests for event trace controller.

#include <objbase.h>
#include <initguid.h>

#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/process/process_handle.h"
#include "base/strings/stringprintf.h"
#include "base/sys_info.h"
#include "base/win/event_trace_controller.h"
#include "base/win/event_trace_provider.h"
#include "base/win/scoped_handle.h"
#include "base/win/windows_version.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base {
namespace win {

namespace {

DEFINE_GUID(kGuidNull,
    0x0000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0);

const ULONG kTestProviderFlags = 0xCAFEBABE;

class TestingProvider: public EtwTraceProvider {
 public:
  explicit TestingProvider(const GUID& provider_name)
      : EtwTraceProvider(provider_name) {
    callback_event_.Set(::CreateEvent(NULL, TRUE, FALSE, NULL));
  }

  void WaitForCallback() {
    ::WaitForSingleObject(callback_event_.Get(), INFINITE);
    ::ResetEvent(callback_event_.Get());
  }

 private:
  void OnEventsEnabled() override { ::SetEvent(callback_event_.Get()); }
  void PostEventsDisabled() override { ::SetEvent(callback_event_.Get()); }

  ScopedHandle callback_event_;

  DISALLOW_COPY_AND_ASSIGN(TestingProvider);
};

}  // namespace

TEST(EtwTracePropertiesTest, Initialization) {
  EtwTraceProperties prop;

  EVENT_TRACE_PROPERTIES* p = prop.get();
  EXPECT_NE(0u, p->Wnode.BufferSize);
  EXPECT_EQ(0u, p->Wnode.ProviderId);
  EXPECT_EQ(0u, p->Wnode.HistoricalContext);

  EXPECT_TRUE(kGuidNull == p->Wnode.Guid);
  EXPECT_EQ(0u, p->Wnode.ClientContext);
  EXPECT_EQ(static_cast<ULONG>(WNODE_FLAG_TRACED_GUID), p->Wnode.Flags);

  EXPECT_EQ(0u, p->BufferSize);
  EXPECT_EQ(0u, p->MinimumBuffers);
  EXPECT_EQ(0u, p->MaximumBuffers);
  EXPECT_EQ(0u, p->MaximumFileSize);
  EXPECT_EQ(0u, p->LogFileMode);
  EXPECT_EQ(0u, p->FlushTimer);
  EXPECT_EQ(0u, p->EnableFlags);
  EXPECT_EQ(0, p->AgeLimit);

  EXPECT_EQ(0u, p->NumberOfBuffers);
  EXPECT_EQ(0u, p->FreeBuffers);
  EXPECT_EQ(0u, p->EventsLost);
  EXPECT_EQ(0u, p->BuffersWritten);
  EXPECT_EQ(0u, p->LogBuffersLost);
  EXPECT_EQ(0u, p->RealTimeBuffersLost);
  EXPECT_EQ(0u, p->LoggerThreadId);
  EXPECT_NE(0u, p->LogFileNameOffset);
  EXPECT_NE(0u, p->LoggerNameOffset);
}

TEST(EtwTracePropertiesTest, Strings) {
  EtwTraceProperties prop;

  ASSERT_STREQ(L"", prop.GetLoggerFileName());
  ASSERT_STREQ(L"", prop.GetLoggerName());

  std::wstring name(1023, L'A');
  ASSERT_HRESULT_SUCCEEDED(prop.SetLoggerFileName(name.c_str()));
  ASSERT_HRESULT_SUCCEEDED(prop.SetLoggerName(name.c_str()));
  ASSERT_STREQ(name.c_str(), prop.GetLoggerFileName());
  ASSERT_STREQ(name.c_str(), prop.GetLoggerName());

  std::wstring name2(1024, L'A');
  ASSERT_HRESULT_FAILED(prop.SetLoggerFileName(name2.c_str()));
  ASSERT_HRESULT_FAILED(prop.SetLoggerName(name2.c_str()));
}

namespace {

class EtwTraceControllerTest : public testing::Test {
 public:
  EtwTraceControllerTest()
      : session_name_(StringPrintf(L"TestSession-%d", GetCurrentProcId())) {
  }

  void SetUp() override {
    EtwTraceProperties ignore;
    EtwTraceController::Stop(session_name_.c_str(), &ignore);

    // Allocate a new provider name GUID for each test.
    ASSERT_HRESULT_SUCCEEDED(::CoCreateGuid(&test_provider_));
  }

  void TearDown() override {
    EtwTraceProperties prop;
    EtwTraceController::Stop(session_name_.c_str(), &prop);
  }

 protected:
  GUID test_provider_;
  std::wstring session_name_;
};

}  // namespace

TEST_F(EtwTraceControllerTest, Initialize) {
  EtwTraceController controller;

  EXPECT_EQ(0u, controller.session());
  EXPECT_STREQ(L"", controller.session_name());
}


TEST_F(EtwTraceControllerTest, StartRealTimeSession) {
  EtwTraceController controller;

  HRESULT hr = controller.StartRealtimeSession(session_name_.c_str(),
                                               100 * 1024);
  if (hr == E_ACCESSDENIED) {
    VLOG(1) << "You must be an administrator to run this test on Vista";
    return;
  }

  EXPECT_NE(0u, controller.session());
  EXPECT_STREQ(session_name_.c_str(), controller.session_name());

  EXPECT_HRESULT_SUCCEEDED(controller.Stop(NULL));
  EXPECT_EQ(0u, controller.session());
  EXPECT_STREQ(L"", controller.session_name());
}

TEST_F(EtwTraceControllerTest, StartFileSession) {
  ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  FilePath temp;
  ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir.GetPath(), &temp));

  EtwTraceController controller;
  HRESULT hr = controller.StartFileSession(session_name_.c_str(),
                                           temp.value().c_str());
  if (hr == E_ACCESSDENIED) {
    VLOG(1) << "You must be an administrator to run this test on Vista";
    base::DeleteFile(temp, false);
    return;
  }

  EXPECT_NE(0u, controller.session());
  EXPECT_STREQ(session_name_.c_str(), controller.session_name());

  EXPECT_HRESULT_SUCCEEDED(controller.Stop(NULL));
  EXPECT_EQ(0u, controller.session());
  EXPECT_STREQ(L"", controller.session_name());
  base::DeleteFile(temp, false);
}

// This test is flaky for unclear reasons. See bugs 525297 and 534184
TEST_F(EtwTraceControllerTest, DISABLED_EnableDisable) {
  TestingProvider provider(test_provider_);

  EXPECT_EQ(static_cast<DWORD>(ERROR_SUCCESS), provider.Register());
  EXPECT_EQ(0u, provider.session_handle());

  EtwTraceController controller;
  HRESULT hr = controller.StartRealtimeSession(session_name_.c_str(),
                                               100 * 1024);
  if (hr == E_ACCESSDENIED) {
    VLOG(1) << "You must be an administrator to run this test on Vista";
    return;
  }

  EXPECT_HRESULT_SUCCEEDED(controller.EnableProvider(test_provider_,
                           TRACE_LEVEL_VERBOSE, kTestProviderFlags));

  provider.WaitForCallback();

  EXPECT_EQ(TRACE_LEVEL_VERBOSE, provider.enable_level());
  EXPECT_EQ(kTestProviderFlags, provider.enable_flags());

  EXPECT_HRESULT_SUCCEEDED(controller.DisableProvider(test_provider_));

  provider.WaitForCallback();

  EXPECT_EQ(0, provider.enable_level());
  EXPECT_EQ(0u, provider.enable_flags());

  EXPECT_EQ(static_cast<DWORD>(ERROR_SUCCESS), provider.Unregister());

  // Enable the provider again, before registering.
  EXPECT_HRESULT_SUCCEEDED(controller.EnableProvider(test_provider_,
                           TRACE_LEVEL_VERBOSE, kTestProviderFlags));

  // Register the provider again, the settings above
  // should take immediate effect.
  EXPECT_EQ(static_cast<DWORD>(ERROR_SUCCESS), provider.Register());

  EXPECT_EQ(TRACE_LEVEL_VERBOSE, provider.enable_level());
  EXPECT_EQ(kTestProviderFlags, provider.enable_flags());

  // Consume the callback event of the previous controller.EnableProvider().
  provider.WaitForCallback();

  EXPECT_HRESULT_SUCCEEDED(controller.Stop(NULL));

  // Windows 7 does not call the callback when Stop() is called so we
  // can't wait, and enable_level and enable_flags are not zeroed.
  if (base::win::GetVersion() >= VERSION_WIN8) {
    provider.WaitForCallback();

    // Session should have wound down.
    EXPECT_EQ(0, provider.enable_level());
    EXPECT_EQ(0u, provider.enable_flags());
  }
}

}  // namespace win
}  // namespace base
