Steve Fung | 6c34c25 | 2015-08-20 00:27:30 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2012 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
Chris Sosa | e4a8603 | 2010-06-16 17:08:34 -0700 | [diff] [blame] | 16 | |
Steve Fung | 129bea5 | 2015-07-23 13:11:15 -0700 | [diff] [blame] | 17 | #include "user_collector.h" |
Ben Chan | 7e77690 | 2014-06-18 13:19:51 -0700 | [diff] [blame] | 18 | |
Ben Chan | 6e709a1 | 2012-02-29 12:10:44 -0800 | [diff] [blame] | 19 | #include <elf.h> |
Steve Fung | 8bafb3d | 2015-08-07 13:22:46 -0700 | [diff] [blame] | 20 | #include <sys/cdefs.h> // For __WORDSIZE |
Ken Mixter | 777484c | 2010-07-23 16:22:44 -0700 | [diff] [blame] | 21 | #include <unistd.h> |
Chris Sosa | e4a8603 | 2010-06-16 17:08:34 -0700 | [diff] [blame] | 22 | |
Ben Chan | ab6cc90 | 2014-09-05 08:21:06 -0700 | [diff] [blame] | 23 | #include <base/files/file_util.h> |
Ben Chan | 7e77690 | 2014-06-18 13:19:51 -0700 | [diff] [blame] | 24 | #include <base/files/scoped_temp_dir.h> |
| 25 | #include <base/strings/string_split.h> |
Alex Vakulenko | 74dc624 | 2015-10-13 09:23:34 -0700 | [diff] [blame] | 26 | #include <brillo/syslog_logging.h> |
Steve Fung | 6e13952 | 2015-02-05 14:54:16 -0800 | [diff] [blame] | 27 | #include <gmock/gmock.h> |
Ben Chan | 7e77690 | 2014-06-18 13:19:51 -0700 | [diff] [blame] | 28 | #include <gtest/gtest.h> |
Chris Sosa | e4a8603 | 2010-06-16 17:08:34 -0700 | [diff] [blame] | 29 | |
Simon Que | 9f90aca | 2013-02-19 17:19:52 -0800 | [diff] [blame] | 30 | using base::FilePath; |
Alex Vakulenko | 74dc624 | 2015-10-13 09:23:34 -0700 | [diff] [blame] | 31 | using brillo::FindLog; |
Ken Mixter | a324932 | 2011-03-03 08:47:38 -0800 | [diff] [blame] | 32 | |
Daniel Erat | d257ea1 | 2015-01-28 10:23:28 -0700 | [diff] [blame] | 33 | namespace { |
| 34 | |
| 35 | int s_crashes = 0; |
| 36 | bool s_metrics = false; |
| 37 | |
| 38 | const char kFilePath[] = "/my/path"; |
| 39 | |
Chris Sosa | e4a8603 | 2010-06-16 17:08:34 -0700 | [diff] [blame] | 40 | void CountCrash() { |
| 41 | ++s_crashes; |
| 42 | } |
| 43 | |
| 44 | bool IsMetrics() { |
| 45 | return s_metrics; |
| 46 | } |
| 47 | |
Daniel Erat | d257ea1 | 2015-01-28 10:23:28 -0700 | [diff] [blame] | 48 | } // namespace |
| 49 | |
Steve Fung | 6e13952 | 2015-02-05 14:54:16 -0800 | [diff] [blame] | 50 | class UserCollectorMock : public UserCollector { |
| 51 | public: |
| 52 | MOCK_METHOD0(SetUpDBus, void()); |
| 53 | }; |
| 54 | |
Chris Sosa | e4a8603 | 2010-06-16 17:08:34 -0700 | [diff] [blame] | 55 | class UserCollectorTest : public ::testing::Test { |
| 56 | void SetUp() { |
| 57 | s_crashes = 0; |
Steve Fung | 6e13952 | 2015-02-05 14:54:16 -0800 | [diff] [blame] | 58 | |
| 59 | EXPECT_CALL(collector_, SetUpDBus()).WillRepeatedly(testing::Return()); |
| 60 | |
Chris Sosa | e4a8603 | 2010-06-16 17:08:34 -0700 | [diff] [blame] | 61 | collector_.Initialize(CountCrash, |
| 62 | kFilePath, |
| 63 | IsMetrics, |
Steve Fung | d6169a2 | 2014-08-11 15:52:23 -0700 | [diff] [blame] | 64 | false, |
| 65 | false, |
| 66 | false, |
| 67 | ""); |
Steve Fung | 78fcf66 | 2016-01-20 01:45:11 -0800 | [diff] [blame] | 68 | |
| 69 | EXPECT_TRUE(test_dir_.CreateUniqueTempDir()); |
| 70 | |
| 71 | mkdir(test_dir_.path().Append("test").value().c_str(), 0777); |
Ken Mixter | 777484c | 2010-07-23 16:22:44 -0700 | [diff] [blame] | 72 | pid_ = getpid(); |
Alex Vakulenko | 74dc624 | 2015-10-13 09:23:34 -0700 | [diff] [blame] | 73 | brillo::ClearLog(); |
Chris Sosa | e4a8603 | 2010-06-16 17:08:34 -0700 | [diff] [blame] | 74 | } |
Ben Chan | f13bb58 | 2012-01-06 08:22:07 -0800 | [diff] [blame] | 75 | |
Chris Sosa | e4a8603 | 2010-06-16 17:08:34 -0700 | [diff] [blame] | 76 | protected: |
Ken Mixter | 2953c3a | 2010-10-18 14:42:20 -0700 | [diff] [blame] | 77 | void ExpectFileEquals(const char *golden, |
Lei Zhang | 9b1f300 | 2014-04-24 02:10:57 -0700 | [diff] [blame] | 78 | const FilePath &file_path) { |
Ken Mixter | 2953c3a | 2010-10-18 14:42:20 -0700 | [diff] [blame] | 79 | std::string contents; |
Lei Zhang | 9b1f300 | 2014-04-24 02:10:57 -0700 | [diff] [blame] | 80 | EXPECT_TRUE(base::ReadFileToString(file_path, &contents)); |
Ken Mixter | 2953c3a | 2010-10-18 14:42:20 -0700 | [diff] [blame] | 81 | EXPECT_EQ(golden, contents); |
| 82 | } |
| 83 | |
Ben Chan | f13bb58 | 2012-01-06 08:22:07 -0800 | [diff] [blame] | 84 | std::vector<std::string> SplitLines(const std::string &lines) const { |
Alex Vakulenko | ea05ff9 | 2016-01-20 07:53:57 -0800 | [diff] [blame] | 85 | return base::SplitString(lines, "\n", base::TRIM_WHITESPACE, |
| 86 | base::SPLIT_WANT_ALL); |
Ben Chan | f13bb58 | 2012-01-06 08:22:07 -0800 | [diff] [blame] | 87 | } |
| 88 | |
Steve Fung | 6e13952 | 2015-02-05 14:54:16 -0800 | [diff] [blame] | 89 | UserCollectorMock collector_; |
Ken Mixter | 777484c | 2010-07-23 16:22:44 -0700 | [diff] [blame] | 90 | pid_t pid_; |
Steve Fung | 78fcf66 | 2016-01-20 01:45:11 -0800 | [diff] [blame] | 91 | base::ScopedTempDir test_dir_; |
Chris Sosa | e4a8603 | 2010-06-16 17:08:34 -0700 | [diff] [blame] | 92 | }; |
| 93 | |
Ken Mixter | 1b8fe01 | 2011-01-25 13:33:05 -0800 | [diff] [blame] | 94 | TEST_F(UserCollectorTest, ParseCrashAttributes) { |
| 95 | pid_t pid; |
| 96 | int signal; |
Michael Krebs | 1c57e9e | 2012-09-25 18:03:13 -0700 | [diff] [blame] | 97 | uid_t uid; |
Steve Fung | 773fd3c | 2015-10-09 17:01:35 -0700 | [diff] [blame] | 98 | gid_t gid; |
Ken Mixter | 1b8fe01 | 2011-01-25 13:33:05 -0800 | [diff] [blame] | 99 | std::string exec_name; |
Steve Fung | 773fd3c | 2015-10-09 17:01:35 -0700 | [diff] [blame] | 100 | EXPECT_TRUE(collector_.ParseCrashAttributes("123456:11:1000:2000:foobar", |
| 101 | &pid, &signal, &uid, &gid, &exec_name)); |
Ken Mixter | 1b8fe01 | 2011-01-25 13:33:05 -0800 | [diff] [blame] | 102 | EXPECT_EQ(123456, pid); |
| 103 | EXPECT_EQ(11, signal); |
James Hawkins | a28317d | 2016-02-26 11:24:38 -0800 | [diff] [blame] | 104 | EXPECT_EQ(1000U, uid); |
| 105 | EXPECT_EQ(2000U, gid); |
Ken Mixter | 1b8fe01 | 2011-01-25 13:33:05 -0800 | [diff] [blame] | 106 | EXPECT_EQ("foobar", exec_name); |
Michael Krebs | 1c57e9e | 2012-09-25 18:03:13 -0700 | [diff] [blame] | 107 | EXPECT_TRUE(collector_.ParseCrashAttributes("4321:6:barfoo", |
Steve Fung | 773fd3c | 2015-10-09 17:01:35 -0700 | [diff] [blame] | 108 | &pid, &signal, &uid, &gid, &exec_name)); |
Michael Krebs | 1c57e9e | 2012-09-25 18:03:13 -0700 | [diff] [blame] | 109 | EXPECT_EQ(4321, pid); |
| 110 | EXPECT_EQ(6, signal); |
James Hawkins | a28317d | 2016-02-26 11:24:38 -0800 | [diff] [blame] | 111 | EXPECT_EQ(-1U, uid); |
| 112 | EXPECT_EQ(-1U, gid); |
Michael Krebs | 1c57e9e | 2012-09-25 18:03:13 -0700 | [diff] [blame] | 113 | EXPECT_EQ("barfoo", exec_name); |
Ken Mixter | 1b8fe01 | 2011-01-25 13:33:05 -0800 | [diff] [blame] | 114 | |
| 115 | EXPECT_FALSE(collector_.ParseCrashAttributes("123456:11", |
Steve Fung | 773fd3c | 2015-10-09 17:01:35 -0700 | [diff] [blame] | 116 | &pid, &signal, &uid, &gid, &exec_name)); |
Ken Mixter | 1b8fe01 | 2011-01-25 13:33:05 -0800 | [diff] [blame] | 117 | |
| 118 | EXPECT_TRUE(collector_.ParseCrashAttributes("123456:11:exec:extra", |
Steve Fung | 773fd3c | 2015-10-09 17:01:35 -0700 | [diff] [blame] | 119 | &pid, &signal, &uid, &gid, &exec_name)); |
Ken Mixter | 1b8fe01 | 2011-01-25 13:33:05 -0800 | [diff] [blame] | 120 | EXPECT_EQ("exec:extra", exec_name); |
| 121 | |
| 122 | EXPECT_FALSE(collector_.ParseCrashAttributes("12345p:11:foobar", |
Steve Fung | 773fd3c | 2015-10-09 17:01:35 -0700 | [diff] [blame] | 123 | &pid, &signal, &uid, &gid, &exec_name)); |
Ken Mixter | 1b8fe01 | 2011-01-25 13:33:05 -0800 | [diff] [blame] | 124 | |
| 125 | EXPECT_FALSE(collector_.ParseCrashAttributes("123456:1 :foobar", |
Steve Fung | 773fd3c | 2015-10-09 17:01:35 -0700 | [diff] [blame] | 126 | &pid, &signal, &uid, &gid, &exec_name)); |
Ken Mixter | 1b8fe01 | 2011-01-25 13:33:05 -0800 | [diff] [blame] | 127 | |
| 128 | EXPECT_FALSE(collector_.ParseCrashAttributes("123456::foobar", |
Steve Fung | 773fd3c | 2015-10-09 17:01:35 -0700 | [diff] [blame] | 129 | &pid, &signal, &uid, &gid, &exec_name)); |
Ken Mixter | 1b8fe01 | 2011-01-25 13:33:05 -0800 | [diff] [blame] | 130 | } |
| 131 | |
Ken Mixter | 5d3a1a2 | 2011-03-16 12:47:20 -0700 | [diff] [blame] | 132 | TEST_F(UserCollectorTest, ShouldDumpDeveloperImageOverridesConsent) { |
| 133 | std::string reason; |
Steve Fung | c8b7414 | 2015-08-05 15:45:20 -0700 | [diff] [blame] | 134 | EXPECT_TRUE(collector_.ShouldDump(false, true, &reason)); |
Ken Mixter | 5d3a1a2 | 2011-03-16 12:47:20 -0700 | [diff] [blame] | 135 | EXPECT_EQ("developer build - not testing - always dumping", reason); |
| 136 | |
| 137 | // When running a crash test, behave as normal. |
Steve Fung | c8b7414 | 2015-08-05 15:45:20 -0700 | [diff] [blame] | 138 | EXPECT_FALSE(collector_.ShouldDump(false, false, &reason)); |
Ken Mixter | 5d3a1a2 | 2011-03-16 12:47:20 -0700 | [diff] [blame] | 139 | EXPECT_EQ("ignoring - no consent", reason); |
| 140 | } |
| 141 | |
Ken Mixter | 5d3a1a2 | 2011-03-16 12:47:20 -0700 | [diff] [blame] | 142 | TEST_F(UserCollectorTest, ShouldDumpUseConsentProductionImage) { |
| 143 | std::string result; |
Steve Fung | c8b7414 | 2015-08-05 15:45:20 -0700 | [diff] [blame] | 144 | EXPECT_FALSE(collector_.ShouldDump(false, false, &result)); |
Ken Mixter | 5d3a1a2 | 2011-03-16 12:47:20 -0700 | [diff] [blame] | 145 | EXPECT_EQ("ignoring - no consent", result); |
| 146 | |
Steve Fung | c8b7414 | 2015-08-05 15:45:20 -0700 | [diff] [blame] | 147 | EXPECT_TRUE(collector_.ShouldDump(true, false, &result)); |
Ken Mixter | 5d3a1a2 | 2011-03-16 12:47:20 -0700 | [diff] [blame] | 148 | EXPECT_EQ("handling", result); |
| 149 | } |
| 150 | |
| 151 | TEST_F(UserCollectorTest, HandleCrashWithoutConsent) { |
Chris Sosa | e4a8603 | 2010-06-16 17:08:34 -0700 | [diff] [blame] | 152 | s_metrics = false; |
Ken Mixter | 1b8fe01 | 2011-01-25 13:33:05 -0800 | [diff] [blame] | 153 | collector_.HandleCrash("20:10:ignored", "foobar"); |
Ken Mixter | a324932 | 2011-03-03 08:47:38 -0800 | [diff] [blame] | 154 | EXPECT_TRUE(FindLog( |
| 155 | "Received crash notification for foobar[20] sig 10")); |
Chris Sosa | e4a8603 | 2010-06-16 17:08:34 -0700 | [diff] [blame] | 156 | ASSERT_EQ(s_crashes, 0); |
| 157 | } |
| 158 | |
Ken Mixter | 5d3a1a2 | 2011-03-16 12:47:20 -0700 | [diff] [blame] | 159 | TEST_F(UserCollectorTest, HandleNonChromeCrashWithConsent) { |
Ken Mixter | 2105b49 | 2010-11-09 16:14:38 -0800 | [diff] [blame] | 160 | s_metrics = true; |
Ken Mixter | 1b8fe01 | 2011-01-25 13:33:05 -0800 | [diff] [blame] | 161 | collector_.HandleCrash("5:2:ignored", "chromeos-wm"); |
Ken Mixter | a324932 | 2011-03-03 08:47:38 -0800 | [diff] [blame] | 162 | EXPECT_TRUE(FindLog( |
| 163 | "Received crash notification for chromeos-wm[5] sig 2")); |
Ken Mixter | 2105b49 | 2010-11-09 16:14:38 -0800 | [diff] [blame] | 164 | ASSERT_EQ(s_crashes, 1); |
| 165 | } |
| 166 | |
Ken Mixter | 777484c | 2010-07-23 16:22:44 -0700 | [diff] [blame] | 167 | TEST_F(UserCollectorTest, GetProcessPath) { |
| 168 | FilePath path = collector_.GetProcessPath(100); |
| 169 | ASSERT_EQ("/proc/100", path.value()); |
| 170 | } |
| 171 | |
| 172 | TEST_F(UserCollectorTest, GetSymlinkTarget) { |
| 173 | FilePath result; |
| 174 | ASSERT_FALSE(collector_.GetSymlinkTarget(FilePath("/does_not_exist"), |
| 175 | &result)); |
Ken Mixter | a324932 | 2011-03-03 08:47:38 -0800 | [diff] [blame] | 176 | ASSERT_TRUE(FindLog( |
| 177 | "Readlink failed on /does_not_exist with 2")); |
Steve Fung | 78fcf66 | 2016-01-20 01:45:11 -0800 | [diff] [blame] | 178 | std::string long_link = test_dir_.path().value(); |
Ken Mixter | 777484c | 2010-07-23 16:22:44 -0700 | [diff] [blame] | 179 | for (int i = 0; i < 50; ++i) |
| 180 | long_link += "0123456789"; |
| 181 | long_link += "/gold"; |
| 182 | |
| 183 | for (size_t len = 1; len <= long_link.size(); ++len) { |
| 184 | std::string this_link; |
Steve Fung | 78fcf66 | 2016-01-20 01:45:11 -0800 | [diff] [blame] | 185 | static const char* kLink = |
| 186 | test_dir_.path().Append("test/this_link").value().c_str(); |
Ken Mixter | 777484c | 2010-07-23 16:22:44 -0700 | [diff] [blame] | 187 | this_link.assign(long_link.c_str(), len); |
| 188 | ASSERT_EQ(len, this_link.size()); |
Ken Mixter | 777484c | 2010-07-23 16:22:44 -0700 | [diff] [blame] | 189 | ASSERT_EQ(0, symlink(this_link.c_str(), kLink)); |
| 190 | ASSERT_TRUE(collector_.GetSymlinkTarget(FilePath(kLink), &result)); |
| 191 | ASSERT_EQ(this_link, result.value()); |
Steve Fung | 7ee2f36 | 2016-02-25 16:01:00 -0800 | [diff] [blame] | 192 | unlink(kLink); |
Ken Mixter | 777484c | 2010-07-23 16:22:44 -0700 | [diff] [blame] | 193 | } |
| 194 | } |
| 195 | |
Ken Mixter | d49d362 | 2011-02-09 18:23:00 -0800 | [diff] [blame] | 196 | TEST_F(UserCollectorTest, GetExecutableBaseNameFromPid) { |
| 197 | std::string base_name; |
| 198 | EXPECT_FALSE(collector_.GetExecutableBaseNameFromPid(0, &base_name)); |
Ken Mixter | a324932 | 2011-03-03 08:47:38 -0800 | [diff] [blame] | 199 | EXPECT_TRUE(FindLog( |
| 200 | "Readlink failed on /proc/0/exe with 2")); |
| 201 | EXPECT_TRUE(FindLog( |
| 202 | "GetSymlinkTarget failed - Path /proc/0 DirectoryExists: 0")); |
| 203 | EXPECT_TRUE(FindLog("stat /proc/0/exe failed: -1 2")); |
Ken Mixter | d49d362 | 2011-02-09 18:23:00 -0800 | [diff] [blame] | 204 | |
Alex Vakulenko | 74dc624 | 2015-10-13 09:23:34 -0700 | [diff] [blame] | 205 | brillo::ClearLog(); |
Ken Mixter | d49d362 | 2011-02-09 18:23:00 -0800 | [diff] [blame] | 206 | pid_t my_pid = getpid(); |
| 207 | EXPECT_TRUE(collector_.GetExecutableBaseNameFromPid(my_pid, &base_name)); |
Ken Mixter | a324932 | 2011-03-03 08:47:38 -0800 | [diff] [blame] | 208 | EXPECT_FALSE(FindLog("Readlink failed")); |
Steve Fung | 8ed101b | 2015-12-02 16:18:07 -0800 | [diff] [blame] | 209 | EXPECT_EQ("crash_reporter_tests", base_name); |
Ken Mixter | d49d362 | 2011-02-09 18:23:00 -0800 | [diff] [blame] | 210 | } |
| 211 | |
Ben Chan | f13bb58 | 2012-01-06 08:22:07 -0800 | [diff] [blame] | 212 | TEST_F(UserCollectorTest, GetFirstLineWithPrefix) { |
| 213 | std::vector<std::string> lines; |
| 214 | std::string line; |
| 215 | |
| 216 | EXPECT_FALSE(collector_.GetFirstLineWithPrefix(lines, "Name:", &line)); |
| 217 | EXPECT_EQ("", line); |
| 218 | |
| 219 | lines.push_back("Name:\tls"); |
| 220 | lines.push_back("State:\tR (running)"); |
| 221 | lines.push_back(" Foo:\t1000"); |
| 222 | |
| 223 | line.clear(); |
| 224 | EXPECT_TRUE(collector_.GetFirstLineWithPrefix(lines, "Name:", &line)); |
| 225 | EXPECT_EQ(lines[0], line); |
| 226 | |
| 227 | line.clear(); |
| 228 | EXPECT_TRUE(collector_.GetFirstLineWithPrefix(lines, "State:", &line)); |
| 229 | EXPECT_EQ(lines[1], line); |
| 230 | |
| 231 | line.clear(); |
| 232 | EXPECT_FALSE(collector_.GetFirstLineWithPrefix(lines, "Foo:", &line)); |
| 233 | EXPECT_EQ("", line); |
| 234 | |
| 235 | line.clear(); |
| 236 | EXPECT_TRUE(collector_.GetFirstLineWithPrefix(lines, " Foo:", &line)); |
| 237 | EXPECT_EQ(lines[2], line); |
| 238 | |
| 239 | line.clear(); |
| 240 | EXPECT_FALSE(collector_.GetFirstLineWithPrefix(lines, "Bar:", &line)); |
| 241 | EXPECT_EQ("", line); |
| 242 | } |
| 243 | |
Ken Mixter | 777484c | 2010-07-23 16:22:44 -0700 | [diff] [blame] | 244 | TEST_F(UserCollectorTest, GetIdFromStatus) { |
| 245 | int id = 1; |
| 246 | EXPECT_FALSE(collector_.GetIdFromStatus(UserCollector::kUserId, |
| 247 | UserCollector::kIdEffective, |
Ben Chan | f13bb58 | 2012-01-06 08:22:07 -0800 | [diff] [blame] | 248 | SplitLines("nothing here"), |
Ken Mixter | 777484c | 2010-07-23 16:22:44 -0700 | [diff] [blame] | 249 | &id)); |
| 250 | EXPECT_EQ(id, 1); |
| 251 | |
| 252 | // Not enough parameters. |
| 253 | EXPECT_FALSE(collector_.GetIdFromStatus(UserCollector::kUserId, |
| 254 | UserCollector::kIdReal, |
Ben Chan | f13bb58 | 2012-01-06 08:22:07 -0800 | [diff] [blame] | 255 | SplitLines("line 1\nUid:\t1\n"), |
| 256 | &id)); |
Ken Mixter | 777484c | 2010-07-23 16:22:44 -0700 | [diff] [blame] | 257 | |
Ben Chan | f13bb58 | 2012-01-06 08:22:07 -0800 | [diff] [blame] | 258 | const std::vector<std::string> valid_contents = |
| 259 | SplitLines("\nUid:\t1\t2\t3\t4\nGid:\t5\t6\t7\t8\n"); |
Ken Mixter | 777484c | 2010-07-23 16:22:44 -0700 | [diff] [blame] | 260 | EXPECT_TRUE(collector_.GetIdFromStatus(UserCollector::kUserId, |
| 261 | UserCollector::kIdReal, |
| 262 | valid_contents, |
| 263 | &id)); |
| 264 | EXPECT_EQ(1, id); |
| 265 | |
| 266 | EXPECT_TRUE(collector_.GetIdFromStatus(UserCollector::kUserId, |
| 267 | UserCollector::kIdEffective, |
| 268 | valid_contents, |
| 269 | &id)); |
| 270 | EXPECT_EQ(2, id); |
| 271 | |
| 272 | EXPECT_TRUE(collector_.GetIdFromStatus(UserCollector::kUserId, |
| 273 | UserCollector::kIdFileSystem, |
| 274 | valid_contents, |
| 275 | &id)); |
| 276 | EXPECT_EQ(4, id); |
| 277 | |
| 278 | EXPECT_TRUE(collector_.GetIdFromStatus(UserCollector::kGroupId, |
| 279 | UserCollector::kIdEffective, |
| 280 | valid_contents, |
| 281 | &id)); |
| 282 | EXPECT_EQ(6, id); |
| 283 | |
| 284 | EXPECT_TRUE(collector_.GetIdFromStatus(UserCollector::kGroupId, |
| 285 | UserCollector::kIdSet, |
| 286 | valid_contents, |
| 287 | &id)); |
| 288 | EXPECT_EQ(7, id); |
| 289 | |
| 290 | EXPECT_FALSE(collector_.GetIdFromStatus(UserCollector::kGroupId, |
| 291 | UserCollector::IdKind(5), |
| 292 | valid_contents, |
| 293 | &id)); |
| 294 | EXPECT_FALSE(collector_.GetIdFromStatus(UserCollector::kGroupId, |
| 295 | UserCollector::IdKind(-1), |
| 296 | valid_contents, |
| 297 | &id)); |
| 298 | |
| 299 | // Fail if junk after number |
| 300 | EXPECT_FALSE(collector_.GetIdFromStatus(UserCollector::kUserId, |
| 301 | UserCollector::kIdReal, |
Ben Chan | f13bb58 | 2012-01-06 08:22:07 -0800 | [diff] [blame] | 302 | SplitLines("Uid:\t1f\t2\t3\t4\n"), |
Ken Mixter | 777484c | 2010-07-23 16:22:44 -0700 | [diff] [blame] | 303 | &id)); |
| 304 | EXPECT_TRUE(collector_.GetIdFromStatus(UserCollector::kUserId, |
| 305 | UserCollector::kIdReal, |
Ben Chan | f13bb58 | 2012-01-06 08:22:07 -0800 | [diff] [blame] | 306 | SplitLines("Uid:\t1\t2\t3\t4\n"), |
Ken Mixter | 777484c | 2010-07-23 16:22:44 -0700 | [diff] [blame] | 307 | &id)); |
| 308 | EXPECT_EQ(1, id); |
| 309 | |
| 310 | // Fail if more than 4 numbers. |
| 311 | EXPECT_FALSE(collector_.GetIdFromStatus(UserCollector::kUserId, |
| 312 | UserCollector::kIdReal, |
Ben Chan | f13bb58 | 2012-01-06 08:22:07 -0800 | [diff] [blame] | 313 | SplitLines("Uid:\t1\t2\t3\t4\t5\n"), |
Ken Mixter | 777484c | 2010-07-23 16:22:44 -0700 | [diff] [blame] | 314 | &id)); |
| 315 | } |
| 316 | |
Ben Chan | f13bb58 | 2012-01-06 08:22:07 -0800 | [diff] [blame] | 317 | TEST_F(UserCollectorTest, GetStateFromStatus) { |
| 318 | std::string state; |
| 319 | EXPECT_FALSE(collector_.GetStateFromStatus(SplitLines("nothing here"), |
| 320 | &state)); |
| 321 | EXPECT_EQ("", state); |
| 322 | |
| 323 | EXPECT_TRUE(collector_.GetStateFromStatus(SplitLines("State:\tR (running)"), |
| 324 | &state)); |
| 325 | EXPECT_EQ("R (running)", state); |
| 326 | |
| 327 | EXPECT_TRUE(collector_.GetStateFromStatus( |
| 328 | SplitLines("Name:\tls\nState:\tZ (zombie)\n"), &state)); |
| 329 | EXPECT_EQ("Z (zombie)", state); |
| 330 | } |
| 331 | |
Ken Mixter | 777484c | 2010-07-23 16:22:44 -0700 | [diff] [blame] | 332 | TEST_F(UserCollectorTest, GetUserInfoFromName) { |
| 333 | gid_t gid = 100; |
| 334 | uid_t uid = 100; |
| 335 | EXPECT_TRUE(collector_.GetUserInfoFromName("root", &uid, &gid)); |
James Hawkins | a28317d | 2016-02-26 11:24:38 -0800 | [diff] [blame] | 336 | EXPECT_EQ(0U, uid); |
| 337 | EXPECT_EQ(0U, gid); |
Ken Mixter | 777484c | 2010-07-23 16:22:44 -0700 | [diff] [blame] | 338 | } |
| 339 | |
Ken Mixter | 777484c | 2010-07-23 16:22:44 -0700 | [diff] [blame] | 340 | TEST_F(UserCollectorTest, CopyOffProcFilesBadPath) { |
| 341 | // Try a path that is not writable. |
| 342 | ASSERT_FALSE(collector_.CopyOffProcFiles(pid_, FilePath("/bad/path"))); |
Ken Mixter | a324932 | 2011-03-03 08:47:38 -0800 | [diff] [blame] | 343 | EXPECT_TRUE(FindLog("Could not create /bad/path")); |
Ken Mixter | 777484c | 2010-07-23 16:22:44 -0700 | [diff] [blame] | 344 | } |
| 345 | |
| 346 | TEST_F(UserCollectorTest, CopyOffProcFilesBadPid) { |
Steve Fung | 78fcf66 | 2016-01-20 01:45:11 -0800 | [diff] [blame] | 347 | FilePath container_path(test_dir_.path().Append("test/container")); |
Ken Mixter | 777484c | 2010-07-23 16:22:44 -0700 | [diff] [blame] | 348 | ASSERT_FALSE(collector_.CopyOffProcFiles(0, container_path)); |
Ken Mixter | a324932 | 2011-03-03 08:47:38 -0800 | [diff] [blame] | 349 | EXPECT_TRUE(FindLog("Path /proc/0 does not exist")); |
Ken Mixter | 777484c | 2010-07-23 16:22:44 -0700 | [diff] [blame] | 350 | } |
| 351 | |
| 352 | TEST_F(UserCollectorTest, CopyOffProcFilesOK) { |
Steve Fung | 78fcf66 | 2016-01-20 01:45:11 -0800 | [diff] [blame] | 353 | FilePath container_path(test_dir_.path().Append("test/container")); |
Ken Mixter | 777484c | 2010-07-23 16:22:44 -0700 | [diff] [blame] | 354 | ASSERT_TRUE(collector_.CopyOffProcFiles(pid_, container_path)); |
Ken Mixter | a324932 | 2011-03-03 08:47:38 -0800 | [diff] [blame] | 355 | EXPECT_FALSE(FindLog("Could not copy")); |
Ken Mixter | 777484c | 2010-07-23 16:22:44 -0700 | [diff] [blame] | 356 | static struct { |
| 357 | const char *name; |
| 358 | bool exists; |
| 359 | } expectations[] = { |
| 360 | { "auxv", true }, |
| 361 | { "cmdline", true }, |
| 362 | { "environ", true }, |
| 363 | { "maps", true }, |
| 364 | { "mem", false }, |
| 365 | { "mounts", false }, |
| 366 | { "sched", false }, |
| 367 | { "status", true } |
| 368 | }; |
| 369 | for (unsigned i = 0; i < sizeof(expectations)/sizeof(expectations[0]); ++i) { |
| 370 | EXPECT_EQ(expectations[i].exists, |
Mike Frysinger | a557c11 | 2014-02-05 22:55:39 -0500 | [diff] [blame] | 371 | base::PathExists( |
Ken Mixter | 777484c | 2010-07-23 16:22:44 -0700 | [diff] [blame] | 372 | container_path.Append(expectations[i].name))); |
| 373 | } |
| 374 | } |
| 375 | |
Ben Chan | f13bb58 | 2012-01-06 08:22:07 -0800 | [diff] [blame] | 376 | TEST_F(UserCollectorTest, ValidateProcFiles) { |
Steve Fung | 78fcf66 | 2016-01-20 01:45:11 -0800 | [diff] [blame] | 377 | FilePath container_dir = test_dir_.path(); |
Ben Chan | f13bb58 | 2012-01-06 08:22:07 -0800 | [diff] [blame] | 378 | |
| 379 | // maps file not exists (i.e. GetFileSize fails) |
| 380 | EXPECT_FALSE(collector_.ValidateProcFiles(container_dir)); |
| 381 | |
| 382 | // maps file is empty |
| 383 | FilePath maps_file = container_dir.Append("maps"); |
Ben Chan | 262d798 | 2014-09-18 08:05:20 -0700 | [diff] [blame] | 384 | ASSERT_EQ(0, base::WriteFile(maps_file, nullptr, 0)); |
Mike Frysinger | a557c11 | 2014-02-05 22:55:39 -0500 | [diff] [blame] | 385 | ASSERT_TRUE(base::PathExists(maps_file)); |
Ben Chan | f13bb58 | 2012-01-06 08:22:07 -0800 | [diff] [blame] | 386 | EXPECT_FALSE(collector_.ValidateProcFiles(container_dir)); |
| 387 | |
| 388 | // maps file is not empty |
| 389 | const char data[] = "test data"; |
James Hawkins | a28317d | 2016-02-26 11:24:38 -0800 | [diff] [blame] | 390 | unsigned int numBytesWritten = |
| 391 | base::WriteFile(maps_file, data, sizeof(data)); |
| 392 | ASSERT_EQ(sizeof(data), numBytesWritten); |
Mike Frysinger | a557c11 | 2014-02-05 22:55:39 -0500 | [diff] [blame] | 393 | ASSERT_TRUE(base::PathExists(maps_file)); |
Ben Chan | f13bb58 | 2012-01-06 08:22:07 -0800 | [diff] [blame] | 394 | EXPECT_TRUE(collector_.ValidateProcFiles(container_dir)); |
| 395 | } |
| 396 | |
Ben Chan | 6e709a1 | 2012-02-29 12:10:44 -0800 | [diff] [blame] | 397 | TEST_F(UserCollectorTest, ValidateCoreFile) { |
Steve Fung | 78fcf66 | 2016-01-20 01:45:11 -0800 | [diff] [blame] | 398 | FilePath container_dir = test_dir_.path(); |
Ben Chan | 6e709a1 | 2012-02-29 12:10:44 -0800 | [diff] [blame] | 399 | FilePath core_file = container_dir.Append("core"); |
| 400 | |
| 401 | // Core file does not exist |
| 402 | EXPECT_EQ(UserCollector::kErrorInvalidCoreFile, |
| 403 | collector_.ValidateCoreFile(core_file)); |
| 404 | char e_ident[EI_NIDENT]; |
| 405 | e_ident[EI_MAG0] = ELFMAG0; |
| 406 | e_ident[EI_MAG1] = ELFMAG1; |
| 407 | e_ident[EI_MAG2] = ELFMAG2; |
| 408 | e_ident[EI_MAG3] = ELFMAG3; |
| 409 | #if __WORDSIZE == 32 |
| 410 | e_ident[EI_CLASS] = ELFCLASS32; |
| 411 | #elif __WORDSIZE == 64 |
| 412 | e_ident[EI_CLASS] = ELFCLASS64; |
| 413 | #else |
| 414 | #error Unknown/unsupported value of __WORDSIZE. |
| 415 | #endif |
| 416 | |
| 417 | // Core file has the expected header |
Ben Chan | f30c641 | 2014-05-22 23:09:01 -0700 | [diff] [blame] | 418 | ASSERT_TRUE(base::WriteFile(core_file, e_ident, sizeof(e_ident))); |
Ben Chan | 6e709a1 | 2012-02-29 12:10:44 -0800 | [diff] [blame] | 419 | EXPECT_EQ(UserCollector::kErrorNone, |
| 420 | collector_.ValidateCoreFile(core_file)); |
| 421 | |
| 422 | #if __WORDSIZE == 64 |
| 423 | // 32-bit core file on 64-bit platform |
| 424 | e_ident[EI_CLASS] = ELFCLASS32; |
Ben Chan | f30c641 | 2014-05-22 23:09:01 -0700 | [diff] [blame] | 425 | ASSERT_TRUE(base::WriteFile(core_file, e_ident, sizeof(e_ident))); |
Ben Chan | 6e709a1 | 2012-02-29 12:10:44 -0800 | [diff] [blame] | 426 | EXPECT_EQ(UserCollector::kErrorUnsupported32BitCoreFile, |
| 427 | collector_.ValidateCoreFile(core_file)); |
| 428 | e_ident[EI_CLASS] = ELFCLASS64; |
| 429 | #endif |
| 430 | |
| 431 | // Invalid core files |
Ben Chan | f30c641 | 2014-05-22 23:09:01 -0700 | [diff] [blame] | 432 | ASSERT_TRUE(base::WriteFile(core_file, e_ident, sizeof(e_ident) - 1)); |
Ben Chan | 6e709a1 | 2012-02-29 12:10:44 -0800 | [diff] [blame] | 433 | EXPECT_EQ(UserCollector::kErrorInvalidCoreFile, |
| 434 | collector_.ValidateCoreFile(core_file)); |
| 435 | |
| 436 | e_ident[EI_MAG0] = 0; |
Ben Chan | f30c641 | 2014-05-22 23:09:01 -0700 | [diff] [blame] | 437 | ASSERT_TRUE(base::WriteFile(core_file, e_ident, sizeof(e_ident))); |
Ben Chan | 6e709a1 | 2012-02-29 12:10:44 -0800 | [diff] [blame] | 438 | EXPECT_EQ(UserCollector::kErrorInvalidCoreFile, |
| 439 | collector_.ValidateCoreFile(core_file)); |
| 440 | } |