// Copyright (c) 2009 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 "chrome/browser/process_info_snapshot.h"

#include <sys/types.h>  // For |uid_t| (and |pid_t|).
#include <unistd.h>  // For |getpid()|, |getuid()|, etc.

#include <vector>

#include "base/command_line.h"
#include "base/eintr_wrapper.h"
#include "base/file_path.h"
#include "base/logging.h"
#include "base/process_util.h"

#include "testing/gtest/include/gtest/gtest.h"

typedef testing::Test ProcessInfoSnapshotMacTest;

TEST_F(ProcessInfoSnapshotMacTest, FindPidOneTest) {
  // Sample process with PID 1, which should exist and presumably belong to
  // root.
  std::vector<base::ProcessId> pid_list;
  pid_list.push_back(1);
  ProcessInfoSnapshot snapshot;
  ASSERT_TRUE(snapshot.Sample(pid_list));

  ProcessInfoSnapshot::ProcInfoEntry proc_info;
  ASSERT_TRUE(snapshot.GetProcInfo(1, &proc_info));
  EXPECT_EQ(1, static_cast<int64>(proc_info.pid));
  EXPECT_EQ(0, static_cast<int64>(proc_info.ppid));
  EXPECT_EQ(0, static_cast<int64>(proc_info.uid));
  EXPECT_EQ(0, static_cast<int64>(proc_info.euid));
  EXPECT_GE(proc_info.rss, 0u);
  EXPECT_GT(proc_info.vsize, 0u);

  // Try out the |Get...OfPID()|, but don't examine the results, since they
  // depend on how we map |ProcInfoEntry| to |...KBytes|.
  base::CommittedKBytes usage;
  EXPECT_TRUE(snapshot.GetCommittedKBytesOfPID(1, &usage));
  base::WorkingSetKBytes ws_usage;
  EXPECT_TRUE(snapshot.GetWorkingSetKBytesOfPID(1, &ws_usage));

  // Make sure it hasn't picked up some other PID (say, 2).
  EXPECT_FALSE(snapshot.GetProcInfo(2, &proc_info));

  // Make sure PID 2 still isn't there (in case I mess up my use of std::map).
  EXPECT_FALSE(snapshot.GetProcInfo(2, &proc_info));

  // Test |Reset()|.
  snapshot.Reset();
  EXPECT_FALSE(snapshot.GetProcInfo(1, &proc_info));
}

TEST_F(ProcessInfoSnapshotMacTest, FindPidSelfTest) {
  // Sample this process and its parent.
  base::ProcessId pid = static_cast<base::ProcessId>(getpid());
  base::ProcessId ppid = static_cast<base::ProcessId>(getppid());
  uid_t uid = getuid();
  uid_t euid = geteuid();
  EXPECT_NE(static_cast<int64>(ppid), 0);

  std::vector<base::ProcessId> pid_list;
  pid_list.push_back(pid);
  pid_list.push_back(ppid);
  ProcessInfoSnapshot snapshot;
  ASSERT_TRUE(snapshot.Sample(pid_list));

  // Find our process.
  ProcessInfoSnapshot::ProcInfoEntry proc_info;
  ASSERT_TRUE(snapshot.GetProcInfo(pid, &proc_info));
  EXPECT_EQ(pid, proc_info.pid);
  EXPECT_EQ(ppid, proc_info.ppid);
  EXPECT_EQ(uid, proc_info.uid);
  EXPECT_EQ(euid, proc_info.euid);
  EXPECT_GE(proc_info.rss, 100u);     // Sanity check: we're running, so we
                                      // should occupy at least 100 kilobytes.
  EXPECT_GE(proc_info.vsize, 1024u);  // Sanity check: our |vsize| is presumably
                                      // at least a megabyte.
  EXPECT_GE(proc_info.rshrd, 1024u);  // Shared memory should also > 1 MB.
  EXPECT_GE(proc_info.rprvt, 1024u);  // Same with private memory.

  // Find our parent.
  ASSERT_TRUE(snapshot.GetProcInfo(ppid, &proc_info));
  EXPECT_EQ(ppid, proc_info.pid);
  EXPECT_NE(static_cast<int64>(proc_info.ppid), 0);
  EXPECT_EQ(uid, proc_info.uid);    // This (and the following) should be true
  EXPECT_EQ(euid, proc_info.euid);  // under reasonable circumstances.
  // Can't say anything definite about its |rss|.
  EXPECT_GT(proc_info.vsize, 0u);   // Its |vsize| should be nonzero though.
}

// To verify that ProcessInfoSnapshot is getting the actual uid and effective
// uid, this test runs top. top should have a uid of the caller and effective
// uid of 0 (root).
TEST_F(ProcessInfoSnapshotMacTest, EffectiveVsRealUserIDTest) {
  // Create a pipe to be able to read top's output.
  int fds[2];
  PCHECK(pipe(fds) == 0);
  base::file_handle_mapping_vector fds_to_remap;
  fds_to_remap.push_back(std::make_pair(fds[1], 1));

  // Hook up top's stderr to the test process' stderr.
  fds_to_remap.push_back(std::make_pair(fileno(stderr), 2));

  std::vector<std::string> argv;
  argv.push_back("/usr/bin/top");
  argv.push_back("-l");
  argv.push_back("0");

  base::ProcessHandle process_handle;
  ASSERT_TRUE(base::LaunchApp(argv, fds_to_remap, false, &process_handle));
  PCHECK(HANDLE_EINTR(close(fds[1])) == 0);

  // Wait until there's some output form top. This is an easy way to tell that
  // the exec() call is done and top is actually running.
  char buf[1];
  PCHECK(HANDLE_EINTR(read(fds[0], buf, 1)) == 1);

  std::vector<base::ProcessId> pid_list;
  pid_list.push_back(process_handle);
  ProcessInfoSnapshot snapshot;
  ASSERT_TRUE(snapshot.Sample(pid_list));

  ProcessInfoSnapshot::ProcInfoEntry proc_info;
  ASSERT_TRUE(snapshot.GetProcInfo(process_handle, &proc_info));
  // Effective user ID should be 0 (root).
  EXPECT_EQ(proc_info.euid, 0u);
  // Real user ID should match the calling process's user id.
  EXPECT_EQ(proc_info.uid, geteuid());

  ASSERT_TRUE(base::KillProcess(process_handle, 0, true));
  PCHECK(HANDLE_EINTR(close(fds[0])) == 0);
}
