#include "gpu/ipc/service/gpu_watchdog_thread.h"
#include <memory>
#include <string>
#include "base/test/task_environment.h"
#include "base/power_monitor/power_monitor.h"
#include "base/power_monitor/power_monitor_source.h"
#include "base/system/sys_info.h"
#include "base/task/current_thread.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/power_monitor_test.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#if BUILDFLAG(IS_MAC)
#include "base/mac/mac_util.h"
#endif
namespace gpu {
namespace {
constexpr auto kGpuWatchdogTimeoutForTesting = …;
constexpr auto kExtraGPUJobTimeForTesting = …;
[[maybe_unused]] constexpr auto kGpuWatchdogTimeoutForTestingSlow = …;
[[maybe_unused]] constexpr auto kExtraGPUJobTimeForTestingSlow = …;
[[maybe_unused]] constexpr auto kGpuWatchdogTimeoutForTestingSlowest = …;
[[maybe_unused]] constexpr auto kExtraGPUJobTimeForTestingSlowest = …;
void SimpleTask(base::TimeDelta duration, base::TimeDelta extra_time) { … }
}
class GpuWatchdogTest : public testing::Test { … };
class GpuWatchdogPowerTest : public GpuWatchdogTest { … };
void GpuWatchdogTest::SetUp() { … }
void GpuWatchdogPowerTest::SetUp() { … }
void GpuWatchdogPowerTest::TearDown() { … }
void GpuWatchdogTest::LongTaskWithReportProgress(base::TimeDelta duration,
base::TimeDelta report_delta) { … }
#if BUILDFLAG(IS_ANDROID)
void GpuWatchdogTest::LongTaskFromBackgroundToForeground(
base::TimeDelta duration,
base::TimeDelta extra_time,
base::TimeDelta time_to_switch_to_foreground) {
watchdog_thread_->OnBackgrounded();
SimpleTask(time_to_switch_to_foreground, base::TimeDelta());
watchdog_thread_->OnForegrounded();
SimpleTask(duration, extra_time);
}
#endif
void GpuWatchdogPowerTest::LongTaskOnResume(
base::TimeDelta duration,
base::TimeDelta extra_time,
base::TimeDelta time_to_power_resume) { … }
TEST_F(GpuWatchdogTest, GpuInitializationComplete) { … }
TEST_F(GpuWatchdogTest, GpuInitializationHang) { … }
TEST_F(GpuWatchdogTest, GpuInitializationAndRunningTasks) { … }
TEST_F(GpuWatchdogTest, GpuRunningATaskHang) { … }
#if BUILDFLAG(IS_ANDROID)
TEST_F(GpuWatchdogTest, ChromeInBackground) {
watchdog_thread_->OnBackgrounded();
auto normal_long_task_time = timeout_ * 6;
SimpleTask(normal_long_task_time, base::TimeDelta());
watchdog_thread_->OnInitComplete();
task_environment_.GetMainThreadTaskRunner()->PostTask(
FROM_HERE, base::BindOnce(&SimpleTask, normal_long_task_time,
base::TimeDelta()));
task_environment_.GetMainThreadTaskRunner()->PostTask(FROM_HERE,
run_loop.QuitClosure());
run_loop.Run();
bool result = watchdog_thread_->IsGpuHangDetectedForTesting();
EXPECT_FALSE(result);
}
TEST_F(GpuWatchdogTest, GpuSwitchingToForegroundHang) {
watchdog_thread_->OnInitComplete();
auto allowed_time = timeout_ * (kRestartFactor + 1);
task_environment_.GetMainThreadTaskRunner()->PostTask(
FROM_HERE,
base::BindOnce(&GpuWatchdogTest::LongTaskFromBackgroundToForeground,
base::Unretained(this), allowed_time,
extra_gpu_job_time_,
timeout_ / 4));
task_environment_.GetMainThreadTaskRunner()->PostTask(FROM_HERE,
run_loop.QuitClosure());
run_loop.Run();
bool result = watchdog_thread_->IsGpuHangDetectedForTesting();
EXPECT_TRUE(result);
}
#endif
TEST_F(GpuWatchdogTest, GpuInitializationPause) { … }
TEST_F(GpuWatchdogPowerTest, GpuOnSuspend) { … }
TEST_F(GpuWatchdogPowerTest, GpuOnResumeHang) { … }
}