| Index: user_collector_test.cc
|
| diff --git a/user_collector_test.cc b/user_collector_test.cc
|
| index 71cce62f4903a7a38cbd2d67e665887068389f7f..335821c748fed26956741f1edb591aca9a977e86 100644
|
| --- a/user_collector_test.cc
|
| +++ b/user_collector_test.cc
|
| @@ -2,12 +2,13 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| -#include <gflags/gflags.h>
|
| -#include <gtest/gtest.h>
|
| +#include <unistd.h>
|
|
|
| #include "base/file_util.h"
|
| #include "crash-reporter/system_logging_mock.h"
|
| #include "crash-reporter/user_collector.h"
|
| +#include "gflags/gflags.h"
|
| +#include "gtest/gtest.h"
|
|
|
| int s_crashes = 0;
|
| bool s_metrics = false;
|
| @@ -28,13 +29,18 @@ class UserCollectorTest : public ::testing::Test {
|
| collector_.Initialize(CountCrash,
|
| kFilePath,
|
| IsMetrics,
|
| - &logging_);
|
| + &logging_,
|
| + false);
|
| mkdir("test", 0777);
|
| collector_.set_core_pattern_file("test/core_pattern");
|
| + pid_ = getpid();
|
| }
|
| protected:
|
| + void TestEnableOK(bool generate_diagnostics);
|
| +
|
| SystemLoggingMock logging_;
|
| UserCollector collector_;
|
| + pid_t pid_;
|
| };
|
|
|
| TEST_F(UserCollectorTest, EnableOK) {
|
| @@ -42,8 +48,7 @@ TEST_F(UserCollectorTest, EnableOK) {
|
| ASSERT_TRUE(collector_.Enable());
|
| ASSERT_TRUE(file_util::ReadFileToString(FilePath("test/core_pattern"),
|
| &contents));
|
| - ASSERT_STREQ(contents.c_str(),
|
| - "|/my/path --signal=%s --pid=%p --exec=%e");
|
| + ASSERT_EQ("|/my/path --signal=%s --pid=%p", contents);
|
| ASSERT_EQ(s_crashes, 0);
|
| ASSERT_NE(logging_.log().find("Enabling crash handling"), std::string::npos);
|
| }
|
| @@ -62,7 +67,7 @@ TEST_F(UserCollectorTest, DisableOK) {
|
| ASSERT_TRUE(collector_.Disable());
|
| ASSERT_TRUE(file_util::ReadFileToString(FilePath("test/core_pattern"),
|
| &contents));
|
| - ASSERT_STREQ(contents.c_str(), "core");
|
| + ASSERT_EQ("core", contents);
|
| ASSERT_EQ(s_crashes, 0);
|
| ASSERT_NE(logging_.log().find("Disabling crash handling"),
|
| std::string::npos);
|
| @@ -77,7 +82,6 @@ TEST_F(UserCollectorTest, DisableNoFileAccess) {
|
| std::string::npos);
|
| }
|
|
|
| -
|
| TEST_F(UserCollectorTest, HandleCrashWithoutMetrics) {
|
| s_metrics = false;
|
| collector_.HandleCrash(10, 20, "foobar");
|
| @@ -96,6 +100,215 @@ TEST_F(UserCollectorTest, HandleCrashWithMetrics) {
|
| ASSERT_EQ(s_crashes, 1);
|
| }
|
|
|
| +TEST_F(UserCollectorTest, GetProcessPath) {
|
| + FilePath path = collector_.GetProcessPath(100);
|
| + ASSERT_EQ("/proc/100", path.value());
|
| +}
|
| +
|
| +TEST_F(UserCollectorTest, GetSymlinkTarget) {
|
| + FilePath result;
|
| + ASSERT_FALSE(collector_.GetSymlinkTarget(FilePath("/does_not_exist"),
|
| + &result));
|
| +
|
| + std::string long_link;
|
| + for (int i = 0; i < 50; ++i)
|
| + long_link += "0123456789";
|
| + long_link += "/gold";
|
| +
|
| + for (size_t len = 1; len <= long_link.size(); ++len) {
|
| + std::string this_link;
|
| + static const char kLink[] = "test/this_link";
|
| + this_link.assign(long_link.c_str(), len);
|
| + ASSERT_EQ(len, this_link.size());
|
| + unlink(kLink);
|
| + ASSERT_EQ(0, symlink(this_link.c_str(), kLink));
|
| + ASSERT_TRUE(collector_.GetSymlinkTarget(FilePath(kLink), &result));
|
| + ASSERT_EQ(this_link, result.value());
|
| + }
|
| +}
|
| +
|
| +TEST_F(UserCollectorTest, GetIdFromStatus) {
|
| + int id = 1;
|
| + EXPECT_FALSE(collector_.GetIdFromStatus(UserCollector::kUserId,
|
| + UserCollector::kIdEffective,
|
| + "nothing here",
|
| + &id));
|
| + EXPECT_EQ(id, 1);
|
| +
|
| + // Not enough parameters.
|
| + EXPECT_FALSE(collector_.GetIdFromStatus(UserCollector::kUserId,
|
| + UserCollector::kIdReal,
|
| + "line 1\nUid:\t1\n", &id));
|
| +
|
| + const char valid_contents[] = "\nUid:\t1\t2\t3\t4\nGid:\t5\t6\t7\t8\n";
|
| + EXPECT_TRUE(collector_.GetIdFromStatus(UserCollector::kUserId,
|
| + UserCollector::kIdReal,
|
| + valid_contents,
|
| + &id));
|
| + EXPECT_EQ(1, id);
|
| +
|
| + EXPECT_TRUE(collector_.GetIdFromStatus(UserCollector::kUserId,
|
| + UserCollector::kIdEffective,
|
| + valid_contents,
|
| + &id));
|
| + EXPECT_EQ(2, id);
|
| +
|
| + EXPECT_TRUE(collector_.GetIdFromStatus(UserCollector::kUserId,
|
| + UserCollector::kIdFileSystem,
|
| + valid_contents,
|
| + &id));
|
| + EXPECT_EQ(4, id);
|
| +
|
| + EXPECT_TRUE(collector_.GetIdFromStatus(UserCollector::kGroupId,
|
| + UserCollector::kIdEffective,
|
| + valid_contents,
|
| + &id));
|
| + EXPECT_EQ(6, id);
|
| +
|
| + EXPECT_TRUE(collector_.GetIdFromStatus(UserCollector::kGroupId,
|
| + UserCollector::kIdSet,
|
| + valid_contents,
|
| + &id));
|
| + EXPECT_EQ(7, id);
|
| +
|
| + EXPECT_FALSE(collector_.GetIdFromStatus(UserCollector::kGroupId,
|
| + UserCollector::IdKind(5),
|
| + valid_contents,
|
| + &id));
|
| + EXPECT_FALSE(collector_.GetIdFromStatus(UserCollector::kGroupId,
|
| + UserCollector::IdKind(-1),
|
| + valid_contents,
|
| + &id));
|
| +
|
| + // Fail if junk after number
|
| + EXPECT_FALSE(collector_.GetIdFromStatus(UserCollector::kUserId,
|
| + UserCollector::kIdReal,
|
| + "Uid:\t1f\t2\t3\t4\n",
|
| + &id));
|
| + EXPECT_TRUE(collector_.GetIdFromStatus(UserCollector::kUserId,
|
| + UserCollector::kIdReal,
|
| + "Uid:\t1\t2\t3\t4\n",
|
| + &id));
|
| + EXPECT_EQ(1, id);
|
| +
|
| + // Fail if more than 4 numbers.
|
| + EXPECT_FALSE(collector_.GetIdFromStatus(UserCollector::kUserId,
|
| + UserCollector::kIdReal,
|
| + "Uid:\t1\t2\t3\t4\t5\n",
|
| + &id));
|
| +}
|
| +
|
| +TEST_F(UserCollectorTest, GetUserInfoFromName) {
|
| + gid_t gid = 100;
|
| + uid_t uid = 100;
|
| + EXPECT_TRUE(collector_.GetUserInfoFromName("root", &uid, &gid));
|
| + EXPECT_EQ(0, uid);
|
| + EXPECT_EQ(0, gid);
|
| +}
|
| +
|
| +TEST_F(UserCollectorTest, GetCrashDirectoryInfo) {
|
| + FilePath path;
|
| + const int kRootUid = 0;
|
| + const int kRootGid = 0;
|
| + const int kNtpUid = 5;
|
| + const int kChronosUid = 1000;
|
| + const int kChronosGid = 1001;
|
| + const mode_t kExpectedSystemMode = 01755;
|
| + const mode_t kExpectedUserMode = 0755;
|
| +
|
| + mode_t directory_mode;
|
| + uid_t directory_owner;
|
| + gid_t directory_group;
|
| +
|
| + path = collector_.GetCrashDirectoryInfo(kRootUid,
|
| + kChronosUid,
|
| + kChronosGid,
|
| + &directory_mode,
|
| + &directory_owner,
|
| + &directory_group);
|
| + EXPECT_EQ("/var/spool/crash", path.value());
|
| + EXPECT_EQ(kExpectedSystemMode, directory_mode);
|
| + EXPECT_EQ(kRootUid, directory_owner);
|
| + EXPECT_EQ(kRootGid, directory_group);
|
| +
|
| + path = collector_.GetCrashDirectoryInfo(kNtpUid,
|
| + kChronosUid,
|
| + kChronosGid,
|
| + &directory_mode,
|
| + &directory_owner,
|
| + &directory_group);
|
| + EXPECT_EQ("/var/spool/crash", path.value());
|
| + EXPECT_EQ(kExpectedSystemMode, directory_mode);
|
| + EXPECT_EQ(kRootUid, directory_owner);
|
| + EXPECT_EQ(kRootGid, directory_group);
|
| +
|
| + path = collector_.GetCrashDirectoryInfo(kChronosUid,
|
| + kChronosUid,
|
| + kChronosGid,
|
| + &directory_mode,
|
| + &directory_owner,
|
| + &directory_group);
|
| + EXPECT_EQ("/home/chronos/user/crash", path.value());
|
| + EXPECT_EQ(kExpectedUserMode, directory_mode);
|
| + EXPECT_EQ(kChronosUid, directory_owner);
|
| + EXPECT_EQ(kChronosGid, directory_group);
|
| +}
|
| +
|
| +TEST_F(UserCollectorTest, CopyOffProcFilesBadPath) {
|
| + // Try a path that is not writable.
|
| + ASSERT_FALSE(collector_.CopyOffProcFiles(pid_, FilePath("/bad/path")));
|
| + ASSERT_NE(logging_.log().find(
|
| + "Could not create /bad/path"),
|
| + std::string::npos);
|
| +}
|
| +
|
| +TEST_F(UserCollectorTest, CopyOffProcFilesBadPid) {
|
| + FilePath container_path("test/container");
|
| + ASSERT_FALSE(collector_.CopyOffProcFiles(0, container_path));
|
| + ASSERT_NE(logging_.log().find(
|
| + "Path /proc/0 does not exist"),
|
| + std::string::npos);
|
| +}
|
| +
|
| +TEST_F(UserCollectorTest, CopyOffProcFilesOK) {
|
| + FilePath container_path("test/container");
|
| + ASSERT_TRUE(collector_.CopyOffProcFiles(pid_, container_path));
|
| + ASSERT_EQ(logging_.log().find(
|
| + "Could not copy"), std::string::npos);
|
| + static struct {
|
| + const char *name;
|
| + bool exists;
|
| + } expectations[] = {
|
| + { "auxv", true },
|
| + { "cmdline", true },
|
| + { "environ", true },
|
| + { "maps", true },
|
| + { "mem", false },
|
| + { "mounts", false },
|
| + { "sched", false },
|
| + { "status", true }
|
| + };
|
| + for (unsigned i = 0; i < sizeof(expectations)/sizeof(expectations[0]); ++i) {
|
| + EXPECT_EQ(expectations[i].exists,
|
| + file_util::PathExists(
|
| + container_path.Append(expectations[i].name)));
|
| + }
|
| +}
|
| +
|
| +TEST_F(UserCollectorTest, FormatDumpBasename) {
|
| + struct tm tm = {0};
|
| + tm.tm_sec = 15;
|
| + tm.tm_min = 50;
|
| + tm.tm_hour = 13;
|
| + tm.tm_mday = 23;
|
| + tm.tm_mon = 4;
|
| + tm.tm_year = 110;
|
| + tm.tm_isdst = -1;
|
| + std::string basename =
|
| + collector_.FormatDumpBasename("foo", mktime(&tm), 100);
|
| + ASSERT_EQ("foo.20100523.135015.100", basename);
|
| +}
|
| +
|
| int main(int argc, char **argv) {
|
| ::testing::InitGoogleTest(&argc, argv);
|
| return RUN_ALL_TESTS();
|
|
|