// Copyright 2018 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.

#include "media/audio/audio_thread_hang_monitor.h"

#include "base/bind.h"
#include "base/location.h"
#include "base/synchronization/waitable_event.h"
#include "base/task/post_task.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/task_environment.h"
#include "base/threading/thread.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/abseil-cpp/absl/types/optional.h"

using testing::ElementsAre;
using testing::Test;
using HangAction = media::AudioThreadHangMonitor::HangAction;

namespace media {

namespace {

constexpr int kStarted =
    static_cast<int>(AudioThreadHangMonitor::ThreadStatus::kStarted);
constexpr int kHung =
    static_cast<int>(AudioThreadHangMonitor::ThreadStatus::kHung);
constexpr int kRecovered =
    static_cast<int>(AudioThreadHangMonitor::ThreadStatus::kRecovered);

constexpr base::TimeDelta kShortHangDeadline = base::Seconds(5);
constexpr base::TimeDelta kLongHangDeadline = base::Minutes(30);

}  // namespace

class AudioThreadHangMonitorTest : public Test {
 public:
  AudioThreadHangMonitorTest()
      : task_env_(base::test::TaskEnvironment::TimeSource::MOCK_TIME),
        histograms_(),
        audio_thread_("Audio thread"),
        hang_monitor_({nullptr, base::OnTaskRunnerDeleter(nullptr)}) {
    CHECK(audio_thread_.Start());
    // We must inject the main thread task runner as the hang monitor task
    // runner since TaskEnvironment::FastForwardBy only works for the main
    // thread.
    hang_monitor_ = AudioThreadHangMonitor::Create(
        HangAction::kDoNothing, absl::nullopt, task_env_.GetMockTickClock(),
        audio_thread_.task_runner(), task_env_.GetMainThreadTaskRunner());
  }

  ~AudioThreadHangMonitorTest() override {
    hang_monitor_.reset();
    task_env_.RunUntilIdle();
  }

  void SetHangActionCallbacksForTesting() {
    hang_monitor_->SetHangActionCallbacksForTesting(
        base::BindRepeating(&AudioThreadHangMonitorTest::HangActionDump,
                            base::Unretained(this)),
        base::BindRepeating(&AudioThreadHangMonitorTest::HangActionTerminate,
                            base::Unretained(this)));
  }

  void RunUntilIdle() { task_env_.RunUntilIdle(); }

  void FlushAudioThread() {
    base::WaitableEvent ev;
    audio_thread_.task_runner()->PostTask(
        FROM_HERE,
        base::BindOnce(&base::WaitableEvent::Signal, base::Unretained(&ev)));
    ev.Wait();
  }

  void BlockAudioThreadUntilEvent() {
    // We keep |event_| as a member of the test fixture to make sure that the
    // audio thread terminates before |event_| is destructed.
    event_.Reset();
    audio_thread_.task_runner()->PostTask(
        FROM_HERE,
        base::BindOnce(&base::WaitableEvent::Wait, base::Unretained(&event_)));
  }

  MOCK_METHOD0(HangActionDump, void());
  MOCK_METHOD0(HangActionTerminate, void());

  base::WaitableEvent event_;
  base::test::TaskEnvironment task_env_;
  base::HistogramTester histograms_;
  base::Thread audio_thread_;
  AudioThreadHangMonitor::Ptr hang_monitor_;
};

TEST_F(AudioThreadHangMonitorTest, LogsThreadStarted) {
  RunUntilIdle();

  EXPECT_THAT(histograms_.GetAllSamples("Media.AudioThreadStatus"),
              ElementsAre(base::Bucket(kStarted, 1)));
}

TEST_F(AudioThreadHangMonitorTest, DoesNotLogThreadHungWhenOk) {
  RunUntilIdle();

  for (int i = 0; i < 10; ++i) {
    // Flush the audio thread, then advance the clock. The audio thread should
    // register as "alive" every time.
    FlushAudioThread();
    task_env_.FastForwardBy(base::Minutes(1));
  }

  EXPECT_THAT(histograms_.GetAllSamples("Media.AudioThreadStatus"),
              ElementsAre(base::Bucket(kStarted, 1)));
}

TEST_F(AudioThreadHangMonitorTest, LogsHungWhenAudioThreadIsBlocked) {
  RunUntilIdle();

  BlockAudioThreadUntilEvent();
  task_env_.FastForwardBy(base::Minutes(10));
  event_.Signal();

  EXPECT_THAT(histograms_.GetAllSamples("Media.AudioThreadStatus"),
              ElementsAre(base::Bucket(kStarted, 1), base::Bucket(kHung, 1)));
}

TEST_F(AudioThreadHangMonitorTest, DoesNotLogThreadHungWithShortDeadline) {
  hang_monitor_ = AudioThreadHangMonitor::Create(
      HangAction::kDoNothing, kShortHangDeadline, task_env_.GetMockTickClock(),
      audio_thread_.task_runner(), task_env_.GetMainThreadTaskRunner());
  RunUntilIdle();

  BlockAudioThreadUntilEvent();
  task_env_.FastForwardBy(kShortHangDeadline / 2);
  event_.Signal();

  // Two started events, one for the originally created hang monitor and one for
  // the new created here.
  EXPECT_THAT(histograms_.GetAllSamples("Media.AudioThreadStatus"),
              ElementsAre(base::Bucket(kStarted, 2)));
}

TEST_F(AudioThreadHangMonitorTest, LogsThreadHungWithShortDeadline) {
  hang_monitor_ = AudioThreadHangMonitor::Create(
      HangAction::kDoNothing, kShortHangDeadline, task_env_.GetMockTickClock(),
      audio_thread_.task_runner(), task_env_.GetMainThreadTaskRunner());
  RunUntilIdle();

  BlockAudioThreadUntilEvent();
  task_env_.FastForwardBy(kShortHangDeadline * 2);
  event_.Signal();

  // Two started events, one for the originally created hang monitor and one for
  // the new created here.
  EXPECT_THAT(histograms_.GetAllSamples("Media.AudioThreadStatus"),
              ElementsAre(base::Bucket(kStarted, 2), base::Bucket(kHung, 1)));
}

TEST_F(AudioThreadHangMonitorTest, DoesNotLogThreadHungWithLongDeadline) {
  hang_monitor_ = AudioThreadHangMonitor::Create(
      HangAction::kDoNothing, kLongHangDeadline, task_env_.GetMockTickClock(),
      audio_thread_.task_runner(), task_env_.GetMainThreadTaskRunner());
  RunUntilIdle();

  BlockAudioThreadUntilEvent();
  task_env_.FastForwardBy(kLongHangDeadline / 2);
  event_.Signal();

  // Two started events, one for the originally created hang monitor and one for
  // the new created here.
  EXPECT_THAT(histograms_.GetAllSamples("Media.AudioThreadStatus"),
              ElementsAre(base::Bucket(kStarted, 2)));
}

TEST_F(AudioThreadHangMonitorTest, LogsThreadHungWithLongDeadline) {
  hang_monitor_ = AudioThreadHangMonitor::Create(
      HangAction::kDoNothing, kLongHangDeadline, task_env_.GetMockTickClock(),
      audio_thread_.task_runner(), task_env_.GetMainThreadTaskRunner());
  RunUntilIdle();

  BlockAudioThreadUntilEvent();
  task_env_.FastForwardBy(kLongHangDeadline * 2);
  event_.Signal();

  // Two started events, one for the originally created hang monitor and one for
  // the new created here.
  EXPECT_THAT(histograms_.GetAllSamples("Media.AudioThreadStatus"),
              ElementsAre(base::Bucket(kStarted, 2), base::Bucket(kHung, 1)));
}

// Zero deadline means that the default deadline should be used.
TEST_F(AudioThreadHangMonitorTest, ZeroDeadlineMeansDefaultDeadline) {
  hang_monitor_ = AudioThreadHangMonitor::Create(
      HangAction::kDoNothing, base::TimeDelta(), task_env_.GetMockTickClock(),
      audio_thread_.task_runner(), task_env_.GetMainThreadTaskRunner());
  RunUntilIdle();

  for (int i = 0; i < 10; ++i) {
    // Flush the audio thread, then advance the clock. The audio thread should
    // register as "alive" every time.
    FlushAudioThread();
    task_env_.FastForwardBy(base::Minutes(1));
  }

  EXPECT_THAT(histograms_.GetAllSamples("Media.AudioThreadStatus"),
              ElementsAre(base::Bucket(kStarted, 2)));

  BlockAudioThreadUntilEvent();
  task_env_.FastForwardBy(base::Minutes(10));
  event_.Signal();

  EXPECT_THAT(histograms_.GetAllSamples("Media.AudioThreadStatus"),
              ElementsAre(base::Bucket(kStarted, 2), base::Bucket(kHung, 1)));
}

TEST_F(AudioThreadHangMonitorTest,
       LogsRecoveredWhenAudioThreadIsBlockedThenRecovers) {
  RunUntilIdle();

  BlockAudioThreadUntilEvent();
  task_env_.FastForwardBy(base::Minutes(10));
  event_.Signal();

  for (int i = 0; i < 10; ++i) {
    // Flush the audio thread, then advance the clock. The audio thread should
    // register as "alive" every time.
    FlushAudioThread();
    task_env_.FastForwardBy(base::Minutes(1));
  }

  EXPECT_THAT(histograms_.GetAllSamples("Media.AudioThreadStatus"),
              ElementsAre(base::Bucket(kStarted, 1), base::Bucket(kHung, 1),
                          base::Bucket(kRecovered, 1)));
}

TEST_F(AudioThreadHangMonitorTest, NoHangActionWhenOk) {
  SetHangActionCallbacksForTesting();
  RunUntilIdle();

  for (int i = 0; i < 10; ++i) {
    // Flush the audio thread, then advance the clock. The audio thread should
    // register as "alive" every time.
    FlushAudioThread();
    task_env_.FastForwardBy(base::Minutes(1));
  }

  EXPECT_THAT(histograms_.GetAllSamples("Media.AudioThreadStatus"),
              ElementsAre(base::Bucket(kStarted, 1)));
}

TEST_F(AudioThreadHangMonitorTest, DumpsWhenAudioThreadIsBlocked) {
  hang_monitor_ = AudioThreadHangMonitor::Create(
      HangAction::kDump, absl::nullopt, task_env_.GetMockTickClock(),
      audio_thread_.task_runner(), task_env_.GetMainThreadTaskRunner());
  SetHangActionCallbacksForTesting();
  RunUntilIdle();

  EXPECT_CALL(*this, HangActionDump).Times(1);

  BlockAudioThreadUntilEvent();
  task_env_.FastForwardBy(base::Minutes(10));
  event_.Signal();

  EXPECT_THAT(histograms_.GetAllSamples("Media.AudioThreadStatus"),
              ElementsAre(base::Bucket(kStarted, 2), base::Bucket(kHung, 1)));
}

TEST_F(AudioThreadHangMonitorTest, TerminatesProcessWhenAudioThreadIsBlocked) {
  hang_monitor_ = AudioThreadHangMonitor::Create(
      HangAction::kTerminateCurrentProcess, absl::nullopt,
      task_env_.GetMockTickClock(), audio_thread_.task_runner(),
      task_env_.GetMainThreadTaskRunner());
  SetHangActionCallbacksForTesting();
  RunUntilIdle();

  EXPECT_CALL(*this, HangActionTerminate).Times(1);

  BlockAudioThreadUntilEvent();
  task_env_.FastForwardBy(base::Minutes(10));
  event_.Signal();

  EXPECT_THAT(histograms_.GetAllSamples("Media.AudioThreadStatus"),
              ElementsAre(base::Bucket(kStarted, 2), base::Bucket(kHung, 1)));
}

TEST_F(AudioThreadHangMonitorTest,
       DumpsAndTerminatesProcessWhenAudioThreadIsBlocked) {
  hang_monitor_ = AudioThreadHangMonitor::Create(
      HangAction::kDumpAndTerminateCurrentProcess, absl::nullopt,
      task_env_.GetMockTickClock(), audio_thread_.task_runner(),
      task_env_.GetMainThreadTaskRunner());
  SetHangActionCallbacksForTesting();
  RunUntilIdle();

  EXPECT_CALL(*this, HangActionDump).Times(1);
  EXPECT_CALL(*this, HangActionTerminate).Times(1);

  BlockAudioThreadUntilEvent();
  task_env_.FastForwardBy(base::Minutes(10));
  event_.Signal();

  EXPECT_THAT(histograms_.GetAllSamples("Media.AudioThreadStatus"),
              ElementsAre(base::Bucket(kStarted, 2), base::Bucket(kHung, 1)));
}

}  // namespace media
