// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/process/process.h"

#include <memory>
#include <string>
#include <utility>

#include "base/at_exit.h"
#include "base/debug/invalid_access_win.h"
#include "base/process/kill.h"
#include "base/test/multiprocess_test.h"
#include "base/test/test_timeouts.h"
#include "base/threading/platform_thread.h"
#include "base/threading/thread_local.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/multiprocess_func_list.h"

#if BUILDFLAG(IS_CHROMEOS)
#include <unistd.h>

#include <vector>

#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "base/time/time.h"
#endif  // BUILDFLAG(IS_CHROMEOS)

#if BUILDFLAG(IS_WIN)
#include "base/win/base_win_buildflags.h"

#include <windows.h>
#endif

namespace {

#if BUILDFLAG(IS_WIN)
constexpr int kExpectedStillRunningExitCode = 0x102;
#else
constexpr int kExpectedStillRunningExitCode = 0;
#endif

constexpr int kDummyExitCode = 42;

#if BUILDFLAG(IS_APPLE)
// Fake port provider that returns the calling process's
// task port, ignoring its argument.
class FakePortProvider : public base::PortProvider {
  mach_port_t TaskForPid(base::ProcessHandle process) const override {
    return mach_task_self();
  }
};
#endif

#if BUILDFLAG(IS_CHROMEOS)
const char kForeground[] = "/chrome_renderers/foreground";
const char kCgroupRoot[] = "/sys/fs/cgroup/cpu";
const char kFullRendererCgroupRoot[] = "/sys/fs/cgroup/cpu/chrome_renderers";
const char kProcPath[] = "/proc/%d/cgroup";

std::string GetProcessCpuCgroup(const base::Process& process) {
  std::string proc;
  if (!base::ReadFileToString(
          base::FilePath(base::StringPrintf(kProcPath, process.Pid())),
          &proc)) {
    return std::string();
  }

  std::vector<base::StringPiece> lines = SplitStringPiece(
      proc, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
  for (const auto& line : lines) {
    std::vector<base::StringPiece> fields = SplitStringPiece(
        line, ":", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
    if (fields.size() != 3U) {
      continue;
    }

    if (fields[1] == "cpu") {
      return static_cast<std::string>(fields[2]);
    }
  }

  return std::string();
}

bool AddProcessToCpuCgroup(const base::Process& process,
                           const std::string& cgroup) {
  base::FilePath path(cgroup);
  path = path.Append("cgroup.procs");
  return base::WriteFile(path, base::NumberToString(process.Pid()));
}
#endif  // BUILDFLAG(IS_CHROMEOS)

}  // namespace

namespace base {

class ProcessTest : public MultiProcessTest {
};

TEST_F(ProcessTest, Create) {
  Process process(SpawnChild("SimpleChildProcess"));
  ASSERT_TRUE(process.IsValid());
  ASSERT_FALSE(process.is_current());
  EXPECT_NE(process.Pid(), kNullProcessId);
  process.Close();
  ASSERT_FALSE(process.IsValid());
}

TEST_F(ProcessTest, CreateCurrent) {
  Process process = Process::Current();
  ASSERT_TRUE(process.IsValid());
  ASSERT_TRUE(process.is_current());
  EXPECT_NE(process.Pid(), kNullProcessId);
  process.Close();
  ASSERT_FALSE(process.IsValid());
}

TEST_F(ProcessTest, Move) {
  Process process1(SpawnChild("SimpleChildProcess"));
  EXPECT_TRUE(process1.IsValid());

  Process process2;
  EXPECT_FALSE(process2.IsValid());

  process2 = std::move(process1);
  EXPECT_TRUE(process2.IsValid());
  EXPECT_FALSE(process1.IsValid());
  EXPECT_FALSE(process2.is_current());

  Process process3 = Process::Current();
  process2 = std::move(process3);
  EXPECT_TRUE(process2.is_current());
  EXPECT_TRUE(process2.IsValid());
  EXPECT_FALSE(process3.IsValid());
}

TEST_F(ProcessTest, Duplicate) {
  Process process1(SpawnChild("SimpleChildProcess"));
  ASSERT_TRUE(process1.IsValid());

  Process process2 = process1.Duplicate();
  ASSERT_TRUE(process1.IsValid());
  ASSERT_TRUE(process2.IsValid());
  EXPECT_EQ(process1.Pid(), process2.Pid());
  EXPECT_FALSE(process1.is_current());
  EXPECT_FALSE(process2.is_current());

  process1.Close();
  ASSERT_TRUE(process2.IsValid());
}

TEST_F(ProcessTest, DuplicateCurrent) {
  Process process1 = Process::Current();
  ASSERT_TRUE(process1.IsValid());

  Process process2 = process1.Duplicate();
  ASSERT_TRUE(process1.IsValid());
  ASSERT_TRUE(process2.IsValid());
  EXPECT_EQ(process1.Pid(), process2.Pid());
  EXPECT_TRUE(process1.is_current());
  EXPECT_TRUE(process2.is_current());

  process1.Close();
  ASSERT_TRUE(process2.IsValid());
}

MULTIPROCESS_TEST_MAIN(SleepyChildProcess) {
  PlatformThread::Sleep(TestTimeouts::action_max_timeout());
  return 0;
}

// TODO(https://crbug.com/726484): Enable these tests on Fuchsia when
// CreationTime() is implemented.
TEST_F(ProcessTest, CreationTimeCurrentProcess) {
  // The current process creation time should be less than or equal to the
  // current time.
  EXPECT_FALSE(Process::Current().CreationTime().is_null());
  EXPECT_LE(Process::Current().CreationTime(), Time::Now());
}

#if !BUILDFLAG(IS_ANDROID)  // Cannot read other processes' creation time on
                            // Android.
TEST_F(ProcessTest, CreationTimeOtherProcess) {
  // The creation time of a process should be between a time recorded before it
  // was spawned and a time recorded after it was spawned. However, since the
  // base::Time and process creation clocks don't match, tolerate some error.
  constexpr base::TimeDelta kTolerance =
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
      // On Linux, process creation time is relative to boot time which has a
      // 1-second resolution. Tolerate 1 second for the imprecise boot time and
      // 100 ms for the imprecise clock.
      Milliseconds(1100);
#elif BUILDFLAG(IS_WIN)
      // On Windows, process creation time is based on the system clock while
      // Time::Now() is a combination of system clock and
      // QueryPerformanceCounter(). Tolerate 100 ms for the clock mismatch.
      Milliseconds(100);
#elif BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_FUCHSIA)
      // On Mac and Fuchsia, process creation time should be very precise.
      Milliseconds(0);
#else
#error Unsupported platform
#endif
  const Time before_creation = Time::Now();
  Process process(SpawnChild("SleepyChildProcess"));
  const Time after_creation = Time::Now();
  const Time creation = process.CreationTime();
  EXPECT_LE(before_creation - kTolerance, creation);
  EXPECT_LE(creation, after_creation + kTolerance);
  EXPECT_TRUE(process.Terminate(kDummyExitCode, true));
}
#endif  // !BUILDFLAG(IS_ANDROID)

TEST_F(ProcessTest, Terminate) {
  Process process(SpawnChild("SleepyChildProcess"));
  ASSERT_TRUE(process.IsValid());

  int exit_code = kDummyExitCode;
  EXPECT_EQ(TERMINATION_STATUS_STILL_RUNNING,
            GetTerminationStatus(process.Handle(), &exit_code));
  EXPECT_EQ(kExpectedStillRunningExitCode, exit_code);

  exit_code = kDummyExitCode;
  int kExpectedExitCode = 250;
  process.Terminate(kExpectedExitCode, false);
  process.WaitForExitWithTimeout(TestTimeouts::action_max_timeout(),
                                 &exit_code);

  EXPECT_NE(TERMINATION_STATUS_STILL_RUNNING,
            GetTerminationStatus(process.Handle(), &exit_code));
#if BUILDFLAG(IS_WIN)
  // Only Windows propagates the |exit_code| set in Terminate().
  EXPECT_EQ(kExpectedExitCode, exit_code);
#endif
}

void AtExitHandler(void*) {
  // At-exit handler should not be called at
  // Process::TerminateCurrentProcessImmediately.
  DCHECK(false);
}

class ThreadLocalObject {
 public:
  ~ThreadLocalObject() {
    // Thread-local storage should not be destructed at
    // Process::TerminateCurrentProcessImmediately.
    DCHECK(false);
  }
};

MULTIPROCESS_TEST_MAIN(TerminateCurrentProcessImmediatelyWithCode0) {
  base::ThreadLocalOwnedPointer<ThreadLocalObject> object;
  object.Set(std::make_unique<ThreadLocalObject>());
  base::AtExitManager::RegisterCallback(&AtExitHandler, nullptr);
  Process::TerminateCurrentProcessImmediately(0);
}

TEST_F(ProcessTest, TerminateCurrentProcessImmediatelyWithZeroExitCode) {
  Process process(SpawnChild("TerminateCurrentProcessImmediatelyWithCode0"));
  ASSERT_TRUE(process.IsValid());
  int exit_code = 42;
  ASSERT_TRUE(process.WaitForExitWithTimeout(TestTimeouts::action_max_timeout(),
                                             &exit_code));
  EXPECT_EQ(0, exit_code);
}

MULTIPROCESS_TEST_MAIN(TerminateCurrentProcessImmediatelyWithCode250) {
  Process::TerminateCurrentProcessImmediately(250);
}

TEST_F(ProcessTest, TerminateCurrentProcessImmediatelyWithNonZeroExitCode) {
  Process process(SpawnChild("TerminateCurrentProcessImmediatelyWithCode250"));
  ASSERT_TRUE(process.IsValid());
  int exit_code = 42;
  ASSERT_TRUE(process.WaitForExitWithTimeout(TestTimeouts::action_max_timeout(),
                                             &exit_code));
  EXPECT_EQ(250, exit_code);
}

MULTIPROCESS_TEST_MAIN(FastSleepyChildProcess) {
  PlatformThread::Sleep(TestTimeouts::tiny_timeout() * 10);
  return 0;
}

TEST_F(ProcessTest, WaitForExit) {
  Process process(SpawnChild("FastSleepyChildProcess"));
  ASSERT_TRUE(process.IsValid());

  int exit_code = kDummyExitCode;
  EXPECT_TRUE(process.WaitForExit(&exit_code));
  EXPECT_EQ(0, exit_code);
}

TEST_F(ProcessTest, WaitForExitWithTimeout) {
  Process process(SpawnChild("SleepyChildProcess"));
  ASSERT_TRUE(process.IsValid());

  int exit_code = kDummyExitCode;
  TimeDelta timeout = TestTimeouts::tiny_timeout();
  EXPECT_FALSE(process.WaitForExitWithTimeout(timeout, &exit_code));
  EXPECT_EQ(kDummyExitCode, exit_code);

  process.Terminate(kDummyExitCode, false);
}

#if BUILDFLAG(IS_WIN)
TEST_F(ProcessTest, WaitForExitOrEventWithProcessExit) {
  Process process(SpawnChild("FastSleepyChildProcess"));
  ASSERT_TRUE(process.IsValid());

  base::win::ScopedHandle stop_watching_handle(
      CreateEvent(nullptr, TRUE, FALSE, nullptr));

  int exit_code = kDummyExitCode;
  EXPECT_EQ(process.WaitForExitOrEvent(stop_watching_handle, &exit_code),
            base::Process::WaitExitStatus::PROCESS_EXITED);
  EXPECT_EQ(0, exit_code);
}

TEST_F(ProcessTest, WaitForExitOrEventWithEventSet) {
  Process process(SpawnChild("SleepyChildProcess"));
  ASSERT_TRUE(process.IsValid());

  base::win::ScopedHandle stop_watching_handle(
      CreateEvent(nullptr, TRUE, TRUE, nullptr));

  int exit_code = kDummyExitCode;
  EXPECT_EQ(process.WaitForExitOrEvent(stop_watching_handle, &exit_code),
            base::Process::WaitExitStatus::STOP_EVENT_SIGNALED);
  EXPECT_EQ(kDummyExitCode, exit_code);

  process.Terminate(kDummyExitCode, false);
}
#endif  // BUILDFLAG(IS_WIN)

// Ensure that the priority of a process is restored correctly after
// backgrounding and restoring.
// Note: a platform may not be willing or able to lower the priority of
// a process. The calls to SetProcessBackground should be noops then.
TEST_F(ProcessTest, SetProcessBackgrounded) {
  if (!Process::CanBackgroundProcesses())
    return;
  Process process(SpawnChild("SimpleChildProcess"));
  int old_priority = process.GetPriority();
#if BUILDFLAG(IS_APPLE)
  // On the Mac, backgrounding a process requires a port to that process.
  // In the browser it's available through the MachBroker class, which is not
  // part of base. Additionally, there is an indefinite amount of time between
  // spawning a process and receiving its port. Because this test just checks
  // the ability to background/foreground a process, we can use the current
  // process's port instead.
  FakePortProvider provider;
  EXPECT_TRUE(process.SetProcessBackgrounded(&provider, true));
  EXPECT_TRUE(process.IsProcessBackgrounded(&provider));
  EXPECT_TRUE(process.SetProcessBackgrounded(&provider, false));
  EXPECT_FALSE(process.IsProcessBackgrounded(&provider));

#else
  EXPECT_TRUE(process.SetProcessBackgrounded(true));
  EXPECT_TRUE(process.IsProcessBackgrounded());
  EXPECT_TRUE(process.SetProcessBackgrounded(false));
  EXPECT_FALSE(process.IsProcessBackgrounded());
#endif
  int new_priority = process.GetPriority();
  EXPECT_EQ(old_priority, new_priority);
}

// Consumers can use WaitForExitWithTimeout(base::TimeDelta(), nullptr) to check
// whether the process is still running. This may not be safe because of the
// potential reusing of the process id. So we won't export Process::IsRunning()
// on all platforms. But for the controllable scenario in the test cases, the
// behavior should be guaranteed.
TEST_F(ProcessTest, CurrentProcessIsRunning) {
  EXPECT_FALSE(Process::Current().WaitForExitWithTimeout(
      base::TimeDelta(), nullptr));
}

#if BUILDFLAG(IS_APPLE)
// On Mac OSX, we can detect whether a non-child process is running.
TEST_F(ProcessTest, PredefinedProcessIsRunning) {
  // Process 1 is the /sbin/launchd, it should be always running.
  EXPECT_FALSE(Process::Open(1).WaitForExitWithTimeout(
      base::TimeDelta(), nullptr));
}
#endif

// Test is disabled on Windows AMR64 because
// TerminateWithHeapCorruption() isn't expected to work there.
// See: https://crbug.com/1054423
#if BUILDFLAG(IS_WIN)
#if defined(ARCH_CPU_ARM64)
#define MAYBE_HeapCorruption DISABLED_HeapCorruption
#else
#define MAYBE_HeapCorruption HeapCorruption
#endif
TEST_F(ProcessTest, MAYBE_HeapCorruption) {
  EXPECT_EXIT(base::debug::win::TerminateWithHeapCorruption(),
              ::testing::ExitedWithCode(STATUS_HEAP_CORRUPTION), "");
}

#if BUILDFLAG(WIN_ENABLE_CFG_GUARDS)
#define MAYBE_ControlFlowViolation ControlFlowViolation
#else
#define MAYBE_ControlFlowViolation DISABLED_ControlFlowViolation
#endif
TEST_F(ProcessTest, MAYBE_ControlFlowViolation) {
  // CFG causes ntdll!RtlFailFast2 to be called resulting in uncatchable
  // 0xC0000409 (STATUS_STACK_BUFFER_OVERRUN) exception.
  EXPECT_EXIT(base::debug::win::TerminateWithControlFlowViolation(),
              ::testing::ExitedWithCode(STATUS_STACK_BUFFER_OVERRUN), "");
}

#endif  // BUILDFLAG(IS_WIN)

TEST_F(ProcessTest, ChildProcessIsRunning) {
  Process process(SpawnChild("SleepyChildProcess"));
  EXPECT_FALSE(process.WaitForExitWithTimeout(
      base::TimeDelta(), nullptr));
  process.Terminate(0, true);
  EXPECT_TRUE(process.WaitForExitWithTimeout(
      base::TimeDelta(), nullptr));
}

#if BUILDFLAG(IS_CHROMEOS)

// Tests that the function IsProcessBackgroundedCGroup() can parse the contents
// of the /proc/<pid>/cgroup file successfully.
TEST_F(ProcessTest, TestIsProcessBackgroundedCGroup) {
  const char kNotBackgrounded[] = "5:cpuacct,cpu,cpuset:/daemons\n";
  const char kBackgrounded[] =
      "2:freezer:/chrome_renderers/to_be_frozen\n"
      "1:cpu:/chrome_renderers/background\n";

  EXPECT_FALSE(IsProcessBackgroundedCGroup(kNotBackgrounded));
  EXPECT_TRUE(IsProcessBackgroundedCGroup(kBackgrounded));
}

TEST_F(ProcessTest, InitializePriorityEmptyProcess) {
  // TODO(b/172213843): base::Process is used by base::TestSuite::Initialize
  // before we can use ScopedFeatureList here. Update the test to allow the
  // use of ScopedFeatureList before base::TestSuite::Initialize runs.
  if (!Process::OneGroupPerRendererEnabledForTesting())
    return;

  Process process;
  process.InitializePriority();
  const std::string unique_token = process.unique_token();
  ASSERT_TRUE(unique_token.empty());
}

TEST_F(ProcessTest, SetProcessBackgroundedOneCgroupPerRender) {
  if (!Process::OneGroupPerRendererEnabledForTesting())
    return;

  base::test::TaskEnvironment task_env;

  Process process(SpawnChild("SimpleChildProcess"));
  process.InitializePriority();
  const std::string unique_token = process.unique_token();
  ASSERT_FALSE(unique_token.empty());

  EXPECT_TRUE(process.SetProcessBackgrounded(false));
  EXPECT_FALSE(process.IsProcessBackgrounded());
  std::string cgroup = GetProcessCpuCgroup(process);
  EXPECT_FALSE(cgroup.empty());
  EXPECT_NE(cgroup.find(unique_token), std::string::npos);

  EXPECT_TRUE(process.SetProcessBackgrounded(true));
  EXPECT_TRUE(process.IsProcessBackgrounded());

  EXPECT_TRUE(process.Terminate(0, false));
  // Terminate should post a task, wait for it to run
  task_env.RunUntilIdle();

  cgroup = std::string(kCgroupRoot) + cgroup;
  EXPECT_FALSE(base::DirectoryExists(FilePath(cgroup)));
}

TEST_F(ProcessTest, CleanUpBusyProcess) {
  if (!Process::OneGroupPerRendererEnabledForTesting())
    return;

  base::test::TaskEnvironment task_env;

  Process process(SpawnChild("SimpleChildProcess"));
  process.InitializePriority();
  const std::string unique_token = process.unique_token();
  ASSERT_FALSE(unique_token.empty());

  EXPECT_TRUE(process.SetProcessBackgrounded(false));
  EXPECT_FALSE(process.IsProcessBackgrounded());
  std::string cgroup = GetProcessCpuCgroup(process);
  EXPECT_FALSE(cgroup.empty());
  EXPECT_NE(cgroup.find(unique_token), std::string::npos);

  // Add another process to the cgroup to ensure it stays busy.
  cgroup = std::string(kCgroupRoot) + cgroup;
  Process process2(SpawnChild("SimpleChildProcess"));
  EXPECT_TRUE(AddProcessToCpuCgroup(process2, cgroup));

  // Terminate the first process that should tirgger a cleanup of the cgroup
  EXPECT_TRUE(process.Terminate(0, false));
  // Wait until the background task runs once. This should fail and requeue
  // another task to retry.
  task_env.RunUntilIdle();
  EXPECT_TRUE(base::DirectoryExists(FilePath(cgroup)));

  // Move the second process to free the cgroup
  std::string foreground_path =
      std::string(kCgroupRoot) + std::string(kForeground);
  EXPECT_TRUE(AddProcessToCpuCgroup(process2, foreground_path));

  // Wait for the retry.
  PlatformThread::Sleep(base::Milliseconds(1100));
  task_env.RunUntilIdle();
  // The cgroup should be deleted now.
  EXPECT_FALSE(base::DirectoryExists(FilePath(cgroup)));

  process2.Terminate(0, false);
}

TEST_F(ProcessTest, SetProcessBackgroundedEmptyToken) {
  if (!Process::OneGroupPerRendererEnabledForTesting())
    return;

  Process process(SpawnChild("SimpleChildProcess"));
  const std::string unique_token = process.unique_token();
  ASSERT_TRUE(unique_token.empty());

  // Moving to the foreground should use the default foregorund path
  EXPECT_TRUE(process.SetProcessBackgrounded(false));
  EXPECT_FALSE(process.IsProcessBackgrounded());
  std::string cgroup = GetProcessCpuCgroup(process);
  EXPECT_FALSE(cgroup.empty());
  EXPECT_EQ(cgroup, kForeground);
}

TEST_F(ProcessTest, CleansUpStaleGroups) {
  if (!Process::OneGroupPerRendererEnabledForTesting())
    return;

  base::test::TaskEnvironment task_env;

  // Create a process that will not be cleaned up
  Process process(SpawnChild("SimpleChildProcess"));
  process.InitializePriority();
  const std::string unique_token = process.unique_token();
  ASSERT_FALSE(unique_token.empty());

  EXPECT_TRUE(process.SetProcessBackgrounded(true));
  EXPECT_TRUE(process.IsProcessBackgrounded());

  // Create a stale cgroup
  std::string root = kFullRendererCgroupRoot;
  std::string cgroup = root + "/" + unique_token;
  std::vector<std::string> tokens = base::SplitString(
      cgroup, "-", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
  tokens[1] = "fake";
  std::string fake_cgroup = base::JoinString(tokens, "-");
  EXPECT_TRUE(base::CreateDirectory(FilePath(fake_cgroup)));

  // Clean up stale groups
  Process::CleanUpStaleProcessStates();

  // validate the fake group is deleted
  EXPECT_FALSE(base::DirectoryExists(FilePath(fake_cgroup)));

  // validate the active process cgroup is not deleted
  EXPECT_TRUE(base::DirectoryExists(FilePath(cgroup)));

  // validate foreground and background are not deleted
  EXPECT_TRUE(base::DirectoryExists(FilePath(root + "/foreground")));
  EXPECT_TRUE(base::DirectoryExists(FilePath(root + "/background")));

  // clean up the process
  EXPECT_TRUE(process.Terminate(0, false));
  // Terminate should post a task, wait for it to run
  task_env.RunUntilIdle();
  EXPECT_FALSE(base::DirectoryExists(FilePath(cgroup)));
}

TEST_F(ProcessTest, OneCgroupDoesNotCleanUpGroupsWithWrongPrefix) {
  if (!Process::OneGroupPerRendererEnabledForTesting())
    return;

  base::test::TaskEnvironment task_env;

  // Create a process that will not be cleaned up
  Process process(SpawnChild("SimpleChildProcess"));
  process.InitializePriority();
  const std::string unique_token = process.unique_token();
  ASSERT_FALSE(unique_token.empty());

  EXPECT_TRUE(process.SetProcessBackgrounded(false));
  EXPECT_FALSE(process.IsProcessBackgrounded());
  std::string cgroup = GetProcessCpuCgroup(process);
  EXPECT_FALSE(cgroup.empty());
  EXPECT_NE(cgroup.find(unique_token), std::string::npos);

  // Create a stale cgroup
  FilePath cgroup_path = FilePath(std::string(kCgroupRoot) + cgroup);
  FilePath fake_cgroup = FilePath(kFullRendererCgroupRoot).AppendASCII("fake");
  EXPECT_TRUE(base::CreateDirectory(fake_cgroup));

  // Clean up stale groups
  Process::CleanUpStaleProcessStates();

  // validate the fake group is deleted
  EXPECT_TRUE(base::DirectoryExists(fake_cgroup));
  EXPECT_TRUE(base::DirectoryExists(cgroup_path));

  // clean up the process
  EXPECT_TRUE(process.SetProcessBackgrounded(true));
  EXPECT_TRUE(process.IsProcessBackgrounded());
  EXPECT_TRUE(process.Terminate(0, false));
  task_env.RunUntilIdle();
  EXPECT_FALSE(base::DirectoryExists(cgroup_path));
  base::DeleteFile(fake_cgroup);
}
#endif  // BUILDFLAG(IS_CHROMEOS)

}  // namespace base
