1 // Copyright 2015 The Chromium 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.
7 #include "base/base_paths.h"
9 #include "base/files/file_path.h"
10 #include "base/files/file_util.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/test/scoped_path_override.h"
13 #include "chromecast/crash/linux/minidump_generator.h"
14 #include "chromecast/crash/linux/minidump_writer.h"
15 #include "testing/gtest/include/gtest/gtest.h"
17 namespace chromecast
{
20 const char kDumplogFile
[] = "dumplog";
21 const char kLockfileName
[] = "lockfile";
22 const char kMinidumpSubdir
[] = "minidumps";
24 std::string
GetCurrentTimeASCII() {
26 time_t now
= time(NULL
);
27 struct tm
* tm
= gmtime(&now
);
28 strftime(cur_time
, 20, "%Y-%m-%d %H:%M:%S", tm
);
29 return std::string(cur_time
);
32 class FakeMinidumpGenerator
: public MinidumpGenerator
{
34 FakeMinidumpGenerator() {}
35 ~FakeMinidumpGenerator() override
{}
37 // MinidumpGenerator implementation:
38 bool Generate(const std::string
& minidump_path
) override
{ return true; }
41 int FakeDumpState(const std::string
& minidump_path
) {
47 class MinidumpWriterTest
: public testing::Test
{
49 MinidumpWriterTest() {}
50 ~MinidumpWriterTest() override
{}
52 void SetUp() override
{
53 // Set up a temporary directory which will be used as our fake home dir.
54 base::FilePath fake_home_dir
;
55 ASSERT_TRUE(base::CreateNewTempDirectory("", &fake_home_dir
));
56 home_
.reset(new base::ScopedPathOverride(base::DIR_HOME
, fake_home_dir
));
57 minidump_dir_
= fake_home_dir
.Append(kMinidumpSubdir
);
58 dumplog_file_
= minidump_dir_
.Append(kDumplogFile
);
60 // Create the minidump directory and lockfile.
61 ASSERT_TRUE(base::CreateDirectory(minidump_dir_
));
63 minidump_dir_
.Append(kLockfileName
),
64 base::File::FLAG_CREATE_ALWAYS
| base::File::FLAG_WRITE
);
65 ASSERT_TRUE(lockfile
.IsValid());
68 FakeMinidumpGenerator fake_generator_
;
69 base::FilePath minidump_dir_
;
70 base::FilePath dumplog_file_
;
73 scoped_ptr
<base::ScopedPathOverride
> home_
;
75 DISALLOW_COPY_AND_ASSIGN(MinidumpWriterTest
);
78 TEST_F(MinidumpWriterTest
, Write_FailsWithIncorrectMinidumpPath
) {
79 MinidumpWriter
writer(&fake_generator_
,
82 base::Bind(&FakeDumpState
));
84 ASSERT_EQ(-1, writer
.Write());
87 TEST_F(MinidumpWriterTest
, Write_FailsWithMultiLevelRelativeMinidumpPath
) {
88 MinidumpWriter
writer(&fake_generator_
,
91 base::Bind(&FakeDumpState
));
93 ASSERT_EQ(-1, writer
.Write());
96 TEST_F(MinidumpWriterTest
, Write_SucceedsWithSimpleFilename
) {
97 MinidumpWriter
writer(&fake_generator_
,
100 base::Bind(&FakeDumpState
));
102 ASSERT_EQ(0, writer
.Write());
105 TEST_F(MinidumpWriterTest
, Write_SucceedsWithCorrectMinidumpPath
) {
106 MinidumpWriter
writer(&fake_generator_
,
107 dumplog_file_
.value(),
109 base::Bind(&FakeDumpState
));
111 ASSERT_EQ(0, writer
.Write());
114 TEST_F(MinidumpWriterTest
, Write_FailsWithSubdirInCorrectPath
) {
115 MinidumpWriter
writer(&fake_generator_
,
116 dumplog_file_
.Append("subdir/logfile").value(),
118 base::Bind(&FakeDumpState
));
119 ASSERT_EQ(-1, writer
.Write());
122 TEST_F(MinidumpWriterTest
, Write_FailsWhenTooManyDumpsPresent
) {
123 MinidumpWriter
writer(&fake_generator_
,
124 dumplog_file_
.value(),
126 base::Bind(&FakeDumpState
));
128 // Write dump logs to the lockfile.
129 std::ofstream
lockfile(minidump_dir_
.Append(kLockfileName
).value());
130 ASSERT_TRUE(lockfile
.is_open());
131 size_t too_many_dumps
= writer
.max_dumps() + 1;
132 for (size_t i
= 0; i
< too_many_dumps
; ++i
) {
133 lockfile
<< "p|2012-01-01 01:02:03|/dump/path||" << std::endl
;
137 ASSERT_EQ(-1, writer
.Write());
140 TEST_F(MinidumpWriterTest
, Write_FailsWhenTooManyRecentDumpsPresent
) {
141 MinidumpWriter
writer(&fake_generator_
,
142 dumplog_file_
.value(),
144 base::Bind(&FakeDumpState
));
146 // Write dump logs to the lockfile.
147 std::ofstream
lockfile(minidump_dir_
.Append(kLockfileName
).value());
148 ASSERT_TRUE(lockfile
.is_open());
149 size_t too_many_recent_dumps
= writer
.max_recent_dumps() + 1;
150 for (size_t i
= 0; i
< too_many_recent_dumps
; ++i
) {
151 lockfile
<< "|" << GetCurrentTimeASCII() << "|/dump/path||" << std::endl
;
154 ASSERT_EQ(-1, writer
.Write());
157 TEST_F(MinidumpWriterTest
, Write_SucceedsWhenDumpLimitsNotExceeded
) {
158 MinidumpWriter
writer(&fake_generator_
,
159 dumplog_file_
.value(),
161 base::Bind(&FakeDumpState
));
163 ASSERT_GT(writer
.max_dumps(), 1);
164 ASSERT_GT(writer
.max_recent_dumps(), 0);
166 // Write an old dump logs to the lockfile.
167 std::ofstream
lockfile(minidump_dir_
.Append(kLockfileName
).value());
168 ASSERT_TRUE(lockfile
.is_open());
169 lockfile
<< "p|2012-01-01 01:02:03|/dump/path||" << std::endl
;
172 } // namespace chromecast