blob: 98a5ab1093edd2d35e574bdeb64444cd8924cc3e [file] [log] [blame]
Darin Petkovce9b3a12013-01-10 16:38:54 +01001// Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Fletcher Woodruff07c28532019-01-24 11:08:53 -07005#include <grp.h>
6#include <pwd.h>
7#include <sys/types.h>
8#include <unistd.h>
mhasank80cbe4d2020-04-02 22:46:08 -07009#include <memory>
Fletcher Woodruff07c28532019-01-24 11:08:53 -070010#include <string>
11#include <vector>
12
13#include <base/files/file_path.h>
14#include <base/files/file_util.h>
15#include <base/files/scoped_temp_dir.h>
Eric Carusof9091f82017-04-28 14:18:59 -070016#include <dbus/mock_bus.h>
Darin Petkovce9b3a12013-01-10 16:38:54 +010017#include <gtest/gtest.h>
mhasankaf5251d2020-04-29 18:53:03 -070018#include <cryptohome/proto_bindings/rpc.pb.h>
19#include <cryptohome-client-test/cryptohome/dbus-proxy-mocks.h>
Darin Petkovce9b3a12013-01-10 16:38:54 +010020
Alex Vakulenko262be3f2014-07-30 15:25:50 -070021#include "debugd/src/log_tool.h"
Darin Petkovce9b3a12013-01-10 16:38:54 +010022
mhasankaf5251d2020-04-29 18:53:03 -070023using testing::_;
24using testing::Invoke;
25using testing::Return;
26using testing::WithArg;
27
Fletcher Woodruff07c28532019-01-24 11:08:53 -070028namespace {
Qijiang Fan7410a422020-08-28 15:45:44 +090029bool CreateDirectoryAndWriteFile(const base::FilePath& path,
30 const std::string& contents) {
Fletcher Woodruff07c28532019-01-24 11:08:53 -070031 return base::CreateDirectory(path.DirName()) &&
32 base::WriteFile(path, contents.c_str(), contents.length()) ==
33 contents.length();
34}
35} // namespace
36
Darin Petkovce9b3a12013-01-10 16:38:54 +010037namespace debugd {
38
mhasankaf5251d2020-04-29 18:53:03 -070039class FakeLog : public LogTool::Log {
40 public:
41 MOCK_METHOD(std::string, GetLogData, (), (const, override));
42};
43
Darin Petkovce9b3a12013-01-10 16:38:54 +010044class LogToolTest : public testing::Test {
45 protected:
mhasank80cbe4d2020-04-02 22:46:08 -070046 std::unique_ptr<LogTool> log_tool_;
47 base::ScopedTempDir temp_dir_;
Eric Carusof9091f82017-04-28 14:18:59 -070048
mhasank80cbe4d2020-04-02 22:46:08 -070049 void SetUp() override {
50 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
51 log_tool_ = std::unique_ptr<LogTool>(new LogTool(
mhasankaf5251d2020-04-29 18:53:03 -070052 new dbus::MockBus(dbus::Bus::Options()),
53 std::make_unique<org::chromium::CryptohomeInterfaceProxyMock>(),
54 std::make_unique<FakeLog>(), temp_dir_.GetPath()));
55
56 ON_CALL(*GetFakeLog(), GetLogData).WillByDefault(Return("fake"));
57 }
58
59 FakeLog* GetFakeLog() {
60 return static_cast<FakeLog*>(log_tool_->arc_bug_report_log_.get());
61 }
62
mhasankd2b84882020-05-04 17:02:19 -070063 std::string GetArcBugReport(const std::string& username, bool* is_backup) {
64 return log_tool_->GetArcBugReport(username, is_backup);
mhasankaf5251d2020-04-29 18:53:03 -070065 }
66
67 org::chromium::CryptohomeInterfaceProxyMock* GetCryptHomeProxy() {
68 return static_cast<org::chromium::CryptohomeInterfaceProxyMock*>(
69 log_tool_->cryptohome_proxy_.get());
70 }
71
72 void SetArcBugReportBackup(const std::string& userhash) {
73 log_tool_->arc_bug_report_backups_.insert(userhash);
mhasank80cbe4d2020-04-02 22:46:08 -070074 }
Darin Petkovce9b3a12013-01-10 16:38:54 +010075};
76
mhasankaf5251d2020-04-29 18:53:03 -070077TEST_F(LogToolTest, GetArcBugReport_ReturnsContents_WhenFileExists) {
mhasank86c46c72020-08-13 15:36:29 -070078 std::string userhash = "0abcdef1230abcdef1230abcdef1230abcdef123";
mhasankaf5251d2020-04-29 18:53:03 -070079 base::FilePath logPath =
80 temp_dir_.GetPath().Append(userhash).Append("arc-bugreport.log");
Qijiang Fan7410a422020-08-28 15:45:44 +090081 EXPECT_TRUE(CreateDirectoryAndWriteFile(logPath, "test"));
mhasankaf5251d2020-04-29 18:53:03 -070082 EXPECT_TRUE(base::PathExists(logPath));
83 SetArcBugReportBackup(userhash);
84 EXPECT_CALL(*GetCryptHomeProxy(), GetSanitizedUsername("username", _, _, _))
85 .WillOnce(WithArg<1>(Invoke([&userhash](std::string* out_sanitized) {
86 *out_sanitized = userhash;
87 return true;
88 })));
89
mhasankd2b84882020-05-04 17:02:19 -070090 bool is_backup;
91 std::string report = GetArcBugReport("username", &is_backup);
92
93 EXPECT_EQ(report, "test");
94 EXPECT_TRUE(is_backup);
95}
96
97TEST_F(LogToolTest, GetArcBugReport_Succeeds_WhenIsBackupIsNull) {
mhasank86c46c72020-08-13 15:36:29 -070098 std::string userhash = "0abcdef1230abcdef1230abcdef1230abcdef123";
mhasankd2b84882020-05-04 17:02:19 -070099 base::FilePath logPath =
100 temp_dir_.GetPath().Append(userhash).Append("arc-bugreport.log");
Qijiang Fan7410a422020-08-28 15:45:44 +0900101 EXPECT_TRUE(CreateDirectoryAndWriteFile(logPath, "test"));
mhasankd2b84882020-05-04 17:02:19 -0700102 SetArcBugReportBackup(userhash);
103 EXPECT_CALL(*GetCryptHomeProxy(), GetSanitizedUsername("username", _, _, _))
104 .WillOnce(WithArg<1>(Invoke([&userhash](std::string* out_sanitized) {
105 *out_sanitized = userhash;
106 return true;
107 })));
108
109 std::string report = GetArcBugReport("username", nullptr /*is_backup*/);
mhasankaf5251d2020-04-29 18:53:03 -0700110
111 EXPECT_EQ(report, "test");
112}
113
114TEST_F(LogToolTest, GetArcBugReport_DeletesFile_WhenBackupNotSet) {
mhasank86c46c72020-08-13 15:36:29 -0700115 std::string userhash = "0abcdef1230abcdef1230abcdef1230abcdef123";
mhasankaf5251d2020-04-29 18:53:03 -0700116 base::FilePath logPath =
117 temp_dir_.GetPath().Append(userhash).Append("arc-bugreport.log");
Qijiang Fan7410a422020-08-28 15:45:44 +0900118 EXPECT_TRUE(CreateDirectoryAndWriteFile(logPath, "test"));
mhasankaf5251d2020-04-29 18:53:03 -0700119 EXPECT_TRUE(base::PathExists(logPath));
120 EXPECT_CALL(*GetFakeLog(), GetLogData);
121 EXPECT_CALL(*GetCryptHomeProxy(), GetSanitizedUsername("username", _, _, _))
mhasank40a80482020-09-09 17:44:24 -0700122 .WillRepeatedly(
123 WithArg<1>(Invoke([&userhash](std::string* out_sanitized) {
124 *out_sanitized = userhash;
125 return true;
126 })));
mhasankaf5251d2020-04-29 18:53:03 -0700127
mhasankd2b84882020-05-04 17:02:19 -0700128 bool is_backup;
129 std::string report = GetArcBugReport("username", &is_backup);
mhasankaf5251d2020-04-29 18:53:03 -0700130
131 EXPECT_EQ(report, "fake");
mhasankd2b84882020-05-04 17:02:19 -0700132 EXPECT_FALSE(is_backup);
mhasankaf5251d2020-04-29 18:53:03 -0700133 EXPECT_FALSE(base::PathExists(logPath));
134}
135
mhasank80cbe4d2020-04-02 22:46:08 -0700136TEST_F(LogToolTest, DeleteArcBugReportBackup) {
mhasank86c46c72020-08-13 15:36:29 -0700137 std::string userhash = "0abcdef1230abcdef1230abcdef1230abcdef123";
Tom Hughesd6c2d392020-08-24 18:12:11 -0700138 base::FilePath logPath =
139 temp_dir_.GetPath().Append(userhash).Append("arc-bugreport.log");
Qijiang Fan7410a422020-08-28 15:45:44 +0900140 EXPECT_TRUE(CreateDirectoryAndWriteFile(logPath, userhash));
mhasankaf5251d2020-04-29 18:53:03 -0700141 EXPECT_TRUE(base::PathExists(logPath));
mhasank80cbe4d2020-04-02 22:46:08 -0700142 log_tool_->DeleteArcBugReportBackup(userhash);
mhasankaf5251d2020-04-29 18:53:03 -0700143 EXPECT_FALSE(base::PathExists(logPath));
mhasank80cbe4d2020-04-02 22:46:08 -0700144}
145
mhasank40a80482020-09-09 17:44:24 -0700146TEST_F(LogToolTest, DeleteArcBugReportBackup_HashesTheUsername) {
147 std::string userhash = "0abcdef1230abcdef1230abcdef1230abcdef123";
148 base::FilePath logPath =
149 temp_dir_.GetPath().Append(userhash).Append("arc-bugreport.log");
150 EXPECT_TRUE(CreateDirectoryAndWriteFile(logPath, userhash));
151 EXPECT_TRUE(base::PathExists(logPath));
152 EXPECT_CALL(*GetCryptHomeProxy(), GetSanitizedUsername("username", _, _, _))
153 .WillOnce(WithArg<1>(Invoke([&userhash](std::string* out_sanitized) {
154 *out_sanitized = userhash;
155 return true;
156 })));
157
158 log_tool_->DeleteArcBugReportBackup("username");
159
160 EXPECT_FALSE(base::PathExists(logPath));
161}
162
Chris Morin790fd262019-04-03 20:29:36 -0700163TEST_F(LogToolTest, EncodeString) {
Luis Hector Chavezfc2566f2018-09-13 15:00:36 -0700164 // U+1F600 GRINNING FACE
165 constexpr const char kGrinningFaceUTF8[] = "\xF0\x9F\x98\x80";
166 constexpr const char kGrinningFaceBase64[] = "<base64>: 8J+YgA==";
Luis Hector Chavezfc2566f2018-09-13 15:00:36 -0700167 EXPECT_EQ(
168 kGrinningFaceUTF8,
Tom Hughesd6c2d392020-08-24 18:12:11 -0700169 LogTool::EncodeString(kGrinningFaceUTF8, LogTool::Encoding::kAutodetect));
170 EXPECT_EQ(kGrinningFaceUTF8,
171 LogTool::EncodeString(kGrinningFaceUTF8, LogTool::Encoding::kUtf8));
Luis Hector Chavezfc2566f2018-09-13 15:00:36 -0700172 EXPECT_EQ(
173 kGrinningFaceBase64,
Chris Morin790fd262019-04-03 20:29:36 -0700174 LogTool::EncodeString(kGrinningFaceUTF8, LogTool::Encoding::kBase64));
Luis Hector Chavezfc2566f2018-09-13 15:00:36 -0700175
176 // .xz Stream Header Magic Bytes
177 constexpr const char kXzStreamHeaderMagicBytes[] = "\xFD\x37\x7A\x58\x5A\x00";
178 constexpr const char kXzStreamHeaderMagicUTF8[] =
179 "\xEF\xBF\xBD"
180 "7zXZ";
181 constexpr const char kXzStreamHeaderMagicBase64[] = "<base64>: /Td6WFo=";
182 EXPECT_EQ(kXzStreamHeaderMagicBase64,
Chris Morin790fd262019-04-03 20:29:36 -0700183 LogTool::EncodeString(kXzStreamHeaderMagicBytes,
184 LogTool::Encoding::kAutodetect));
Luis Hector Chavezfc2566f2018-09-13 15:00:36 -0700185 EXPECT_EQ(kXzStreamHeaderMagicUTF8,
Chris Morin790fd262019-04-03 20:29:36 -0700186 LogTool::EncodeString(kXzStreamHeaderMagicBytes,
187 LogTool::Encoding::kUtf8));
Luis Hector Chavezfc2566f2018-09-13 15:00:36 -0700188 EXPECT_EQ(kXzStreamHeaderMagicBase64,
Chris Morin790fd262019-04-03 20:29:36 -0700189 LogTool::EncodeString(kXzStreamHeaderMagicBytes,
190 LogTool::Encoding::kBase64));
191
192 EXPECT_EQ(kXzStreamHeaderMagicBytes,
193 LogTool::EncodeString(kXzStreamHeaderMagicBytes,
194 LogTool::Encoding::kBinary));
Luis Hector Chavezfc2566f2018-09-13 15:00:36 -0700195}
196
Fletcher Woodruff07c28532019-01-24 11:08:53 -0700197class LogTest : public testing::Test {
198 protected:
199 void SetUp() override {
200 std::vector<char> buf(1024);
201
202 uid_t uid = getuid();
203 struct passwd pw_entry;
204 struct passwd* pw_result;
205 ASSERT_EQ(getpwuid_r(uid, &pw_entry, &buf[0], buf.size(), &pw_result), 0);
206 ASSERT_NE(pw_result, nullptr);
207 user_name_ = pw_entry.pw_name;
208
209 gid_t gid = getgid();
210 struct group gr_entry;
211 struct group* gr_result;
212 ASSERT_EQ(getgrgid_r(gid, &gr_entry, &buf[0], buf.size(), &gr_result), 0);
213 ASSERT_NE(gr_result, nullptr);
214 group_name_ = gr_entry.gr_name;
215 }
216
217 std::string user_name_;
218 std::string group_name_;
219};
220
221TEST_F(LogTest, GetFileLogData) {
222 base::ScopedTempDir temp;
223 ASSERT_TRUE(temp.CreateUniqueTempDir());
224
225 base::FilePath file_one = temp.GetPath().Append("test/file_one");
Qijiang Fan7410a422020-08-28 15:45:44 +0900226 ASSERT_TRUE(CreateDirectoryAndWriteFile(file_one, "test_one_contents"));
Fletcher Woodruff07c28532019-01-24 11:08:53 -0700227 const LogTool::Log log_one(LogTool::Log::kFile, "test_log_one",
228 file_one.value(), user_name_, group_name_);
Chris Morin790fd262019-04-03 20:29:36 -0700229 EXPECT_EQ(log_one.GetLogData(), "test_one_contents");
Fletcher Woodruff07c28532019-01-24 11:08:53 -0700230
231 base::FilePath file_two = temp.GetPath().Append("test/file_two");
Qijiang Fan7410a422020-08-28 15:45:44 +0900232 ASSERT_TRUE(CreateDirectoryAndWriteFile(file_two, ""));
Fletcher Woodruff07c28532019-01-24 11:08:53 -0700233 const LogTool::Log log_two(LogTool::Log::kFile, "test_log_two",
234 file_two.value(), user_name_, group_name_);
Chris Morin790fd262019-04-03 20:29:36 -0700235 EXPECT_EQ(log_two.GetLogData(), "<empty>");
Fletcher Woodruff07c28532019-01-24 11:08:53 -0700236
237 base::FilePath file_three = temp.GetPath().Append("test/file_three");
Qijiang Fan7410a422020-08-28 15:45:44 +0900238 ASSERT_TRUE(CreateDirectoryAndWriteFile(file_three, "long input value"));
Fletcher Woodruff07c28532019-01-24 11:08:53 -0700239 const LogTool::Log log_three(LogTool::Log::kFile, "test_log_three",
240 file_three.value(), user_name_, group_name_, 5);
Chris Morin790fd262019-04-03 20:29:36 -0700241 EXPECT_EQ(log_three.GetLogData(), "value");
Fletcher Woodruff07c28532019-01-24 11:08:53 -0700242}
243
244TEST_F(LogTest, GetCommandLogData) {
245 LogTool::Log log_one(LogTool::Log::kCommand, "test_log_one", "printf ''",
246 user_name_, group_name_);
247 log_one.DisableMinijailForTest();
Chris Morin790fd262019-04-03 20:29:36 -0700248 EXPECT_EQ(log_one.GetLogData(), "<empty>");
Fletcher Woodruff07c28532019-01-24 11:08:53 -0700249
250 LogTool::Log log_two(LogTool::Log::kCommand, "test_log_two",
251 "printf 'test_output'", user_name_, group_name_);
252 log_two.DisableMinijailForTest();
Chris Morin790fd262019-04-03 20:29:36 -0700253 EXPECT_EQ(log_two.GetLogData(), "test_output");
Fletcher Woodruff07c28532019-01-24 11:08:53 -0700254
255 LogTool::Log log_three(LogTool::Log::kCommand, "test_log_three",
Tom Hughesd6c2d392020-08-24 18:12:11 -0700256 "echo a,b,c | cut -d, -f2", user_name_, group_name_);
Fletcher Woodruff07c28532019-01-24 11:08:53 -0700257 log_three.DisableMinijailForTest();
Chris Morin790fd262019-04-03 20:29:36 -0700258 EXPECT_EQ(log_three.GetLogData(), "b\n");
Fletcher Woodruff07c28532019-01-24 11:08:53 -0700259}
Darin Petkovce9b3a12013-01-10 16:38:54 +0100260} // namespace debugd