blob: 3d2f1979aae7d392d9bea29ee902bc3451a7b308 [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
62 std::string GetArcBugReport(const std::string& username) {
63 return log_tool_->GetArcBugReport(username);
64 }
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) {
77 std::string userhash = "userhash";
78 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
89 std::string report = GetArcBugReport("username");
90
91 EXPECT_EQ(report, "test");
92}
93
94TEST_F(LogToolTest, GetArcBugReport_DeletesFile_WhenBackupNotSet) {
95 std::string userhash = "userhash";
96 base::FilePath logPath =
97 temp_dir_.GetPath().Append(userhash).Append("arc-bugreport.log");
98 EXPECT_TRUE(WriteFile(logPath, "test"));
99 EXPECT_TRUE(base::PathExists(logPath));
100 EXPECT_CALL(*GetFakeLog(), GetLogData);
101 EXPECT_CALL(*GetCryptHomeProxy(), GetSanitizedUsername("username", _, _, _))
102 .WillOnce(WithArg<1>(Invoke([&userhash](std::string* out_sanitized) {
103 *out_sanitized = userhash;
104 return true;
105 })));
106
107 std::string report = GetArcBugReport("username");
108
109 EXPECT_EQ(report, "fake");
110 EXPECT_FALSE(base::PathExists(logPath));
111}
112
mhasank80cbe4d2020-04-02 22:46:08 -0700113TEST_F(LogToolTest, DeleteArcBugReportBackup) {
114 std::string userhash = "user";
115 base::FilePath logPath = temp_dir_.GetPath()
116 .Append(userhash)
117 .Append("arc-bugreport.log");
118 EXPECT_TRUE(WriteFile(logPath, userhash));
mhasankaf5251d2020-04-29 18:53:03 -0700119 EXPECT_TRUE(base::PathExists(logPath));
mhasank80cbe4d2020-04-02 22:46:08 -0700120 log_tool_->DeleteArcBugReportBackup(userhash);
mhasankaf5251d2020-04-29 18:53:03 -0700121 EXPECT_FALSE(base::PathExists(logPath));
mhasank80cbe4d2020-04-02 22:46:08 -0700122}
123
Chris Morin790fd262019-04-03 20:29:36 -0700124TEST_F(LogToolTest, EncodeString) {
Luis Hector Chavezfc2566f2018-09-13 15:00:36 -0700125 // U+1F600 GRINNING FACE
126 constexpr const char kGrinningFaceUTF8[] = "\xF0\x9F\x98\x80";
127 constexpr const char kGrinningFaceBase64[] = "<base64>: 8J+YgA==";
128 EXPECT_EQ(kGrinningFaceUTF8,
Chris Morin790fd262019-04-03 20:29:36 -0700129 LogTool::EncodeString(kGrinningFaceUTF8,
130 LogTool::Encoding::kAutodetect));
Luis Hector Chavezfc2566f2018-09-13 15:00:36 -0700131 EXPECT_EQ(
132 kGrinningFaceUTF8,
Chris Morin790fd262019-04-03 20:29:36 -0700133 LogTool::EncodeString(kGrinningFaceUTF8, LogTool::Encoding::kUtf8));
Luis Hector Chavezfc2566f2018-09-13 15:00:36 -0700134 EXPECT_EQ(
135 kGrinningFaceBase64,
Chris Morin790fd262019-04-03 20:29:36 -0700136 LogTool::EncodeString(kGrinningFaceUTF8, LogTool::Encoding::kBase64));
Luis Hector Chavezfc2566f2018-09-13 15:00:36 -0700137
138 // .xz Stream Header Magic Bytes
139 constexpr const char kXzStreamHeaderMagicBytes[] = "\xFD\x37\x7A\x58\x5A\x00";
140 constexpr const char kXzStreamHeaderMagicUTF8[] =
141 "\xEF\xBF\xBD"
142 "7zXZ";
143 constexpr const char kXzStreamHeaderMagicBase64[] = "<base64>: /Td6WFo=";
144 EXPECT_EQ(kXzStreamHeaderMagicBase64,
Chris Morin790fd262019-04-03 20:29:36 -0700145 LogTool::EncodeString(kXzStreamHeaderMagicBytes,
146 LogTool::Encoding::kAutodetect));
Luis Hector Chavezfc2566f2018-09-13 15:00:36 -0700147 EXPECT_EQ(kXzStreamHeaderMagicUTF8,
Chris Morin790fd262019-04-03 20:29:36 -0700148 LogTool::EncodeString(kXzStreamHeaderMagicBytes,
149 LogTool::Encoding::kUtf8));
Luis Hector Chavezfc2566f2018-09-13 15:00:36 -0700150 EXPECT_EQ(kXzStreamHeaderMagicBase64,
Chris Morin790fd262019-04-03 20:29:36 -0700151 LogTool::EncodeString(kXzStreamHeaderMagicBytes,
152 LogTool::Encoding::kBase64));
153
154 EXPECT_EQ(kXzStreamHeaderMagicBytes,
155 LogTool::EncodeString(kXzStreamHeaderMagicBytes,
156 LogTool::Encoding::kBinary));
Luis Hector Chavezfc2566f2018-09-13 15:00:36 -0700157}
158
Fletcher Woodruff07c28532019-01-24 11:08:53 -0700159class LogTest : public testing::Test {
160 protected:
161 void SetUp() override {
162 std::vector<char> buf(1024);
163
164 uid_t uid = getuid();
165 struct passwd pw_entry;
166 struct passwd* pw_result;
167 ASSERT_EQ(getpwuid_r(uid, &pw_entry, &buf[0], buf.size(), &pw_result), 0);
168 ASSERT_NE(pw_result, nullptr);
169 user_name_ = pw_entry.pw_name;
170
171 gid_t gid = getgid();
172 struct group gr_entry;
173 struct group* gr_result;
174 ASSERT_EQ(getgrgid_r(gid, &gr_entry, &buf[0], buf.size(), &gr_result), 0);
175 ASSERT_NE(gr_result, nullptr);
176 group_name_ = gr_entry.gr_name;
177 }
178
179 std::string user_name_;
180 std::string group_name_;
181};
182
183TEST_F(LogTest, GetFileLogData) {
184 base::ScopedTempDir temp;
185 ASSERT_TRUE(temp.CreateUniqueTempDir());
186
187 base::FilePath file_one = temp.GetPath().Append("test/file_one");
188 ASSERT_TRUE(WriteFile(file_one, "test_one_contents"));
189 const LogTool::Log log_one(LogTool::Log::kFile, "test_log_one",
190 file_one.value(), user_name_, group_name_);
Chris Morin790fd262019-04-03 20:29:36 -0700191 EXPECT_EQ(log_one.GetLogData(), "test_one_contents");
Fletcher Woodruff07c28532019-01-24 11:08:53 -0700192
193 base::FilePath file_two = temp.GetPath().Append("test/file_two");
194 ASSERT_TRUE(WriteFile(file_two, ""));
195 const LogTool::Log log_two(LogTool::Log::kFile, "test_log_two",
196 file_two.value(), user_name_, group_name_);
Chris Morin790fd262019-04-03 20:29:36 -0700197 EXPECT_EQ(log_two.GetLogData(), "<empty>");
Fletcher Woodruff07c28532019-01-24 11:08:53 -0700198
199 base::FilePath file_three = temp.GetPath().Append("test/file_three");
200 ASSERT_TRUE(WriteFile(file_three, "long input value"));
201 const LogTool::Log log_three(LogTool::Log::kFile, "test_log_three",
202 file_three.value(), user_name_, group_name_, 5);
Chris Morin790fd262019-04-03 20:29:36 -0700203 EXPECT_EQ(log_three.GetLogData(), "value");
Fletcher Woodruff07c28532019-01-24 11:08:53 -0700204}
205
206TEST_F(LogTest, GetCommandLogData) {
207 LogTool::Log log_one(LogTool::Log::kCommand, "test_log_one", "printf ''",
208 user_name_, group_name_);
209 log_one.DisableMinijailForTest();
Chris Morin790fd262019-04-03 20:29:36 -0700210 EXPECT_EQ(log_one.GetLogData(), "<empty>");
Fletcher Woodruff07c28532019-01-24 11:08:53 -0700211
212 LogTool::Log log_two(LogTool::Log::kCommand, "test_log_two",
213 "printf 'test_output'", user_name_, group_name_);
214 log_two.DisableMinijailForTest();
Chris Morin790fd262019-04-03 20:29:36 -0700215 EXPECT_EQ(log_two.GetLogData(), "test_output");
Fletcher Woodruff07c28532019-01-24 11:08:53 -0700216
217 LogTool::Log log_three(LogTool::Log::kCommand, "test_log_three",
218 "echo a,b,c | cut -d, -f2", user_name_,
219 group_name_);
220 log_three.DisableMinijailForTest();
Chris Morin790fd262019-04-03 20:29:36 -0700221 EXPECT_EQ(log_three.GetLogData(), "b\n");
Fletcher Woodruff07c28532019-01-24 11:08:53 -0700222}
Darin Petkovce9b3a12013-01-10 16:38:54 +0100223} // namespace debugd