blob: d6b734afe4f4f8e76d7ff9d0b9d9fd4cdb475208 [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 {
29bool WriteFile(const base::FilePath& path, const std::string& contents) {
30 return base::CreateDirectory(path.DirName()) &&
31 base::WriteFile(path, contents.c_str(), contents.length()) ==
32 contents.length();
33}
34} // namespace
35
Darin Petkovce9b3a12013-01-10 16:38:54 +010036namespace debugd {
37
mhasankaf5251d2020-04-29 18:53:03 -070038class FakeLog : public LogTool::Log {
39 public:
40 MOCK_METHOD(std::string, GetLogData, (), (const, override));
41};
42
Darin Petkovce9b3a12013-01-10 16:38:54 +010043class LogToolTest : public testing::Test {
44 protected:
mhasank80cbe4d2020-04-02 22:46:08 -070045 std::unique_ptr<LogTool> log_tool_;
46 base::ScopedTempDir temp_dir_;
Eric Carusof9091f82017-04-28 14:18:59 -070047
mhasank80cbe4d2020-04-02 22:46:08 -070048 void SetUp() override {
49 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
50 log_tool_ = std::unique_ptr<LogTool>(new LogTool(
mhasankaf5251d2020-04-29 18:53:03 -070051 new dbus::MockBus(dbus::Bus::Options()),
52 std::make_unique<org::chromium::CryptohomeInterfaceProxyMock>(),
53 std::make_unique<FakeLog>(), temp_dir_.GetPath()));
54
55 ON_CALL(*GetFakeLog(), GetLogData).WillByDefault(Return("fake"));
56 }
57
58 FakeLog* GetFakeLog() {
59 return static_cast<FakeLog*>(log_tool_->arc_bug_report_log_.get());
60 }
61
mhasankd2b84882020-05-04 17:02:19 -070062 std::string GetArcBugReport(const std::string& username, bool* is_backup) {
63 return log_tool_->GetArcBugReport(username, is_backup);
mhasankaf5251d2020-04-29 18:53:03 -070064 }
65
66 org::chromium::CryptohomeInterfaceProxyMock* GetCryptHomeProxy() {
67 return static_cast<org::chromium::CryptohomeInterfaceProxyMock*>(
68 log_tool_->cryptohome_proxy_.get());
69 }
70
71 void SetArcBugReportBackup(const std::string& userhash) {
72 log_tool_->arc_bug_report_backups_.insert(userhash);
mhasank80cbe4d2020-04-02 22:46:08 -070073 }
Darin Petkovce9b3a12013-01-10 16:38:54 +010074};
75
mhasankaf5251d2020-04-29 18:53:03 -070076TEST_F(LogToolTest, GetArcBugReport_ReturnsContents_WhenFileExists) {
mhasank86c46c72020-08-13 15:36:29 -070077 std::string userhash = "0abcdef1230abcdef1230abcdef1230abcdef123";
mhasankaf5251d2020-04-29 18:53:03 -070078 base::FilePath logPath =
79 temp_dir_.GetPath().Append(userhash).Append("arc-bugreport.log");
80 EXPECT_TRUE(WriteFile(logPath, "test"));
81 EXPECT_TRUE(base::PathExists(logPath));
82 SetArcBugReportBackup(userhash);
83 EXPECT_CALL(*GetCryptHomeProxy(), GetSanitizedUsername("username", _, _, _))
84 .WillOnce(WithArg<1>(Invoke([&userhash](std::string* out_sanitized) {
85 *out_sanitized = userhash;
86 return true;
87 })));
88
mhasankd2b84882020-05-04 17:02:19 -070089 bool is_backup;
90 std::string report = GetArcBugReport("username", &is_backup);
91
92 EXPECT_EQ(report, "test");
93 EXPECT_TRUE(is_backup);
94}
95
96TEST_F(LogToolTest, GetArcBugReport_Succeeds_WhenIsBackupIsNull) {
mhasank86c46c72020-08-13 15:36:29 -070097 std::string userhash = "0abcdef1230abcdef1230abcdef1230abcdef123";
mhasankd2b84882020-05-04 17:02:19 -070098 base::FilePath logPath =
99 temp_dir_.GetPath().Append(userhash).Append("arc-bugreport.log");
100 EXPECT_TRUE(WriteFile(logPath, "test"));
101 SetArcBugReportBackup(userhash);
102 EXPECT_CALL(*GetCryptHomeProxy(), GetSanitizedUsername("username", _, _, _))
103 .WillOnce(WithArg<1>(Invoke([&userhash](std::string* out_sanitized) {
104 *out_sanitized = userhash;
105 return true;
106 })));
107
108 std::string report = GetArcBugReport("username", nullptr /*is_backup*/);
mhasankaf5251d2020-04-29 18:53:03 -0700109
110 EXPECT_EQ(report, "test");
111}
112
113TEST_F(LogToolTest, GetArcBugReport_DeletesFile_WhenBackupNotSet) {
mhasank86c46c72020-08-13 15:36:29 -0700114 std::string userhash = "0abcdef1230abcdef1230abcdef1230abcdef123";
mhasankaf5251d2020-04-29 18:53:03 -0700115 base::FilePath logPath =
116 temp_dir_.GetPath().Append(userhash).Append("arc-bugreport.log");
117 EXPECT_TRUE(WriteFile(logPath, "test"));
118 EXPECT_TRUE(base::PathExists(logPath));
119 EXPECT_CALL(*GetFakeLog(), GetLogData);
120 EXPECT_CALL(*GetCryptHomeProxy(), GetSanitizedUsername("username", _, _, _))
121 .WillOnce(WithArg<1>(Invoke([&userhash](std::string* out_sanitized) {
122 *out_sanitized = userhash;
123 return true;
124 })));
125
mhasankd2b84882020-05-04 17:02:19 -0700126 bool is_backup;
127 std::string report = GetArcBugReport("username", &is_backup);
mhasankaf5251d2020-04-29 18:53:03 -0700128
129 EXPECT_EQ(report, "fake");
mhasankd2b84882020-05-04 17:02:19 -0700130 EXPECT_FALSE(is_backup);
mhasankaf5251d2020-04-29 18:53:03 -0700131 EXPECT_FALSE(base::PathExists(logPath));
132}
133
mhasank80cbe4d2020-04-02 22:46:08 -0700134TEST_F(LogToolTest, DeleteArcBugReportBackup) {
mhasank86c46c72020-08-13 15:36:29 -0700135 std::string userhash = "0abcdef1230abcdef1230abcdef1230abcdef123";
mhasank80cbe4d2020-04-02 22:46:08 -0700136 base::FilePath logPath = temp_dir_.GetPath()
137 .Append(userhash)
138 .Append("arc-bugreport.log");
139 EXPECT_TRUE(WriteFile(logPath, userhash));
mhasankaf5251d2020-04-29 18:53:03 -0700140 EXPECT_TRUE(base::PathExists(logPath));
mhasank80cbe4d2020-04-02 22:46:08 -0700141 log_tool_->DeleteArcBugReportBackup(userhash);
mhasankaf5251d2020-04-29 18:53:03 -0700142 EXPECT_FALSE(base::PathExists(logPath));
mhasank80cbe4d2020-04-02 22:46:08 -0700143}
144
Chris Morin790fd262019-04-03 20:29:36 -0700145TEST_F(LogToolTest, EncodeString) {
Luis Hector Chavezfc2566f2018-09-13 15:00:36 -0700146 // U+1F600 GRINNING FACE
147 constexpr const char kGrinningFaceUTF8[] = "\xF0\x9F\x98\x80";
148 constexpr const char kGrinningFaceBase64[] = "<base64>: 8J+YgA==";
149 EXPECT_EQ(kGrinningFaceUTF8,
Chris Morin790fd262019-04-03 20:29:36 -0700150 LogTool::EncodeString(kGrinningFaceUTF8,
151 LogTool::Encoding::kAutodetect));
Luis Hector Chavezfc2566f2018-09-13 15:00:36 -0700152 EXPECT_EQ(
153 kGrinningFaceUTF8,
Chris Morin790fd262019-04-03 20:29:36 -0700154 LogTool::EncodeString(kGrinningFaceUTF8, LogTool::Encoding::kUtf8));
Luis Hector Chavezfc2566f2018-09-13 15:00:36 -0700155 EXPECT_EQ(
156 kGrinningFaceBase64,
Chris Morin790fd262019-04-03 20:29:36 -0700157 LogTool::EncodeString(kGrinningFaceUTF8, LogTool::Encoding::kBase64));
Luis Hector Chavezfc2566f2018-09-13 15:00:36 -0700158
159 // .xz Stream Header Magic Bytes
160 constexpr const char kXzStreamHeaderMagicBytes[] = "\xFD\x37\x7A\x58\x5A\x00";
161 constexpr const char kXzStreamHeaderMagicUTF8[] =
162 "\xEF\xBF\xBD"
163 "7zXZ";
164 constexpr const char kXzStreamHeaderMagicBase64[] = "<base64>: /Td6WFo=";
165 EXPECT_EQ(kXzStreamHeaderMagicBase64,
Chris Morin790fd262019-04-03 20:29:36 -0700166 LogTool::EncodeString(kXzStreamHeaderMagicBytes,
167 LogTool::Encoding::kAutodetect));
Luis Hector Chavezfc2566f2018-09-13 15:00:36 -0700168 EXPECT_EQ(kXzStreamHeaderMagicUTF8,
Chris Morin790fd262019-04-03 20:29:36 -0700169 LogTool::EncodeString(kXzStreamHeaderMagicBytes,
170 LogTool::Encoding::kUtf8));
Luis Hector Chavezfc2566f2018-09-13 15:00:36 -0700171 EXPECT_EQ(kXzStreamHeaderMagicBase64,
Chris Morin790fd262019-04-03 20:29:36 -0700172 LogTool::EncodeString(kXzStreamHeaderMagicBytes,
173 LogTool::Encoding::kBase64));
174
175 EXPECT_EQ(kXzStreamHeaderMagicBytes,
176 LogTool::EncodeString(kXzStreamHeaderMagicBytes,
177 LogTool::Encoding::kBinary));
Luis Hector Chavezfc2566f2018-09-13 15:00:36 -0700178}
179
Fletcher Woodruff07c28532019-01-24 11:08:53 -0700180class LogTest : public testing::Test {
181 protected:
182 void SetUp() override {
183 std::vector<char> buf(1024);
184
185 uid_t uid = getuid();
186 struct passwd pw_entry;
187 struct passwd* pw_result;
188 ASSERT_EQ(getpwuid_r(uid, &pw_entry, &buf[0], buf.size(), &pw_result), 0);
189 ASSERT_NE(pw_result, nullptr);
190 user_name_ = pw_entry.pw_name;
191
192 gid_t gid = getgid();
193 struct group gr_entry;
194 struct group* gr_result;
195 ASSERT_EQ(getgrgid_r(gid, &gr_entry, &buf[0], buf.size(), &gr_result), 0);
196 ASSERT_NE(gr_result, nullptr);
197 group_name_ = gr_entry.gr_name;
198 }
199
200 std::string user_name_;
201 std::string group_name_;
202};
203
204TEST_F(LogTest, GetFileLogData) {
205 base::ScopedTempDir temp;
206 ASSERT_TRUE(temp.CreateUniqueTempDir());
207
208 base::FilePath file_one = temp.GetPath().Append("test/file_one");
209 ASSERT_TRUE(WriteFile(file_one, "test_one_contents"));
210 const LogTool::Log log_one(LogTool::Log::kFile, "test_log_one",
211 file_one.value(), user_name_, group_name_);
Chris Morin790fd262019-04-03 20:29:36 -0700212 EXPECT_EQ(log_one.GetLogData(), "test_one_contents");
Fletcher Woodruff07c28532019-01-24 11:08:53 -0700213
214 base::FilePath file_two = temp.GetPath().Append("test/file_two");
215 ASSERT_TRUE(WriteFile(file_two, ""));
216 const LogTool::Log log_two(LogTool::Log::kFile, "test_log_two",
217 file_two.value(), user_name_, group_name_);
Chris Morin790fd262019-04-03 20:29:36 -0700218 EXPECT_EQ(log_two.GetLogData(), "<empty>");
Fletcher Woodruff07c28532019-01-24 11:08:53 -0700219
220 base::FilePath file_three = temp.GetPath().Append("test/file_three");
221 ASSERT_TRUE(WriteFile(file_three, "long input value"));
222 const LogTool::Log log_three(LogTool::Log::kFile, "test_log_three",
223 file_three.value(), user_name_, group_name_, 5);
Chris Morin790fd262019-04-03 20:29:36 -0700224 EXPECT_EQ(log_three.GetLogData(), "value");
Fletcher Woodruff07c28532019-01-24 11:08:53 -0700225}
226
227TEST_F(LogTest, GetCommandLogData) {
228 LogTool::Log log_one(LogTool::Log::kCommand, "test_log_one", "printf ''",
229 user_name_, group_name_);
230 log_one.DisableMinijailForTest();
Chris Morin790fd262019-04-03 20:29:36 -0700231 EXPECT_EQ(log_one.GetLogData(), "<empty>");
Fletcher Woodruff07c28532019-01-24 11:08:53 -0700232
233 LogTool::Log log_two(LogTool::Log::kCommand, "test_log_two",
234 "printf 'test_output'", user_name_, group_name_);
235 log_two.DisableMinijailForTest();
Chris Morin790fd262019-04-03 20:29:36 -0700236 EXPECT_EQ(log_two.GetLogData(), "test_output");
Fletcher Woodruff07c28532019-01-24 11:08:53 -0700237
238 LogTool::Log log_three(LogTool::Log::kCommand, "test_log_three",
239 "echo a,b,c | cut -d, -f2", user_name_,
240 group_name_);
241 log_three.DisableMinijailForTest();
Chris Morin790fd262019-04-03 20:29:36 -0700242 EXPECT_EQ(log_three.GetLogData(), "b\n");
Fletcher Woodruff07c28532019-01-24 11:08:53 -0700243}
Darin Petkovce9b3a12013-01-10 16:38:54 +0100244} // namespace debugd