OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <fstream> | 5 #include <fstream> |
6 | 6 |
7 #include "base/base_paths.h" | 7 #include "base/base_paths.h" |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/files/file_path.h" | 9 #include "base/files/file_path.h" |
10 #include "base/files/file_util.h" | 10 #include "base/files/file_util.h" |
11 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
12 #include "base/test/scoped_path_override.h" | 12 #include "base/test/scoped_path_override.h" |
13 #include "chromecast/base/serializers.h" | 13 #include "chromecast/crash/linux/crash_testing_utils.h" |
14 #include "chromecast/crash/linux/dump_info.h" | 14 #include "chromecast/crash/linux/dump_info.h" |
15 #include "chromecast/crash/linux/minidump_generator.h" | 15 #include "chromecast/crash/linux/minidump_generator.h" |
16 #include "chromecast/crash/linux/minidump_writer.h" | 16 #include "chromecast/crash/linux/minidump_writer.h" |
17 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
18 | 18 |
19 namespace chromecast { | 19 namespace chromecast { |
20 namespace { | 20 namespace { |
21 | 21 |
22 const char kDumplogFile[] = "dumplog"; | 22 const char kDumplogFile[] = "dumplog"; |
23 const char kLockfileName[] = "lockfile"; | 23 const char kLockfileName[] = "lockfile"; |
24 const char kMinidumpSubdir[] = "minidumps"; | 24 const char kMinidumpSubdir[] = "minidumps"; |
25 const char kDumpsKey[] = "dumps"; | |
26 | 25 |
27 class FakeMinidumpGenerator : public MinidumpGenerator { | 26 class FakeMinidumpGenerator : public MinidumpGenerator { |
28 public: | 27 public: |
29 FakeMinidumpGenerator() {} | 28 FakeMinidumpGenerator() {} |
30 ~FakeMinidumpGenerator() override {} | 29 ~FakeMinidumpGenerator() override {} |
31 | 30 |
32 // MinidumpGenerator implementation: | 31 // MinidumpGenerator implementation: |
33 bool Generate(const std::string& minidump_path) override { return true; } | 32 bool Generate(const std::string& minidump_path) override { return true; } |
34 }; | 33 }; |
35 | 34 |
36 int FakeDumpState(const std::string& minidump_path) { | 35 int FakeDumpState(const std::string& minidump_path) { |
37 return 0; | 36 return 0; |
38 } | 37 } |
39 | 38 |
40 scoped_ptr<DumpInfo> CreateDumpInfo(const std::string& json_string) { | |
41 scoped_ptr<base::Value> value(DeserializeFromJson(json_string)); | |
42 return make_scoped_ptr(new DumpInfo(value.get())); | |
43 } | |
44 | |
45 } // namespace | 39 } // namespace |
46 | 40 |
47 class MinidumpWriterTest : public testing::Test { | 41 class MinidumpWriterTest : public testing::Test { |
48 protected: | 42 protected: |
49 MinidumpWriterTest() {} | 43 MinidumpWriterTest() {} |
50 ~MinidumpWriterTest() override {} | 44 ~MinidumpWriterTest() override {} |
51 | 45 |
52 void SetUp() override { | 46 void SetUp() override { |
53 // Set up a temporary directory which will be used as our fake home dir. | 47 // Set up a temporary directory which will be used as our fake home dir. |
54 base::FilePath fake_home_dir; | 48 base::FilePath fake_home_dir; |
55 ASSERT_TRUE(base::CreateNewTempDirectory("", &fake_home_dir)); | 49 ASSERT_TRUE(base::CreateNewTempDirectory("", &fake_home_dir)); |
56 home_.reset(new base::ScopedPathOverride(base::DIR_HOME, fake_home_dir)); | 50 home_.reset(new base::ScopedPathOverride(base::DIR_HOME, fake_home_dir)); |
57 minidump_dir_ = fake_home_dir.Append(kMinidumpSubdir); | 51 minidump_dir_ = fake_home_dir.Append(kMinidumpSubdir); |
58 dumplog_file_ = minidump_dir_.Append(kDumplogFile); | 52 dumplog_file_ = minidump_dir_.Append(kDumplogFile); |
59 lockfile_path_ = minidump_dir_.Append(kLockfileName); | 53 lockfile_path_ = minidump_dir_.Append(kLockfileName); |
60 | 54 |
61 // Create the minidump directory and lockfile. | 55 // Create the minidump directory and lockfile. |
62 ASSERT_TRUE(base::CreateDirectory(minidump_dir_)); | 56 ASSERT_TRUE(base::CreateDirectory(minidump_dir_)); |
63 base::File lockfile( | 57 base::File lockfile( |
64 lockfile_path_, | 58 lockfile_path_, |
65 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE); | 59 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE); |
66 ASSERT_TRUE(lockfile.IsValid()); | 60 ASSERT_TRUE(lockfile.IsValid()); |
67 } | 61 } |
68 | 62 |
69 int AppendLockFile(const DumpInfo& dump) { | 63 bool AppendLockFile(const DumpInfo& dump) { |
70 scoped_ptr<base::Value> contents(DeserializeJsonFromFile(lockfile_path_)); | 64 return chromecast::AppendLockFile(lockfile_path_.value(), dump); |
71 if (!contents) { | |
72 base::DictionaryValue* dict = new base::DictionaryValue(); | |
73 contents = make_scoped_ptr(dict); | |
74 dict->Set(kDumpsKey, make_scoped_ptr(new base::ListValue())); | |
75 } | |
76 | |
77 base::DictionaryValue* dict; | |
78 base::ListValue* dump_list; | |
79 if (!contents || !contents->GetAsDictionary(&dict) || | |
80 !dict->GetList(kDumpsKey, &dump_list) || !dump_list) { | |
81 return -1; | |
82 } | |
83 | |
84 dump_list->Append(dump.GetAsValue()); | |
85 | |
86 return SerializeJsonToFile(lockfile_path_, *contents) ? 0 : -1; | |
87 } | 65 } |
88 | 66 |
89 FakeMinidumpGenerator fake_generator_; | 67 FakeMinidumpGenerator fake_generator_; |
90 base::FilePath minidump_dir_; | 68 base::FilePath minidump_dir_; |
91 base::FilePath dumplog_file_; | 69 base::FilePath dumplog_file_; |
92 base::FilePath lockfile_path_; | 70 base::FilePath lockfile_path_; |
93 | 71 |
94 private: | 72 private: |
95 scoped_ptr<base::ScopedPathOverride> home_; | 73 scoped_ptr<base::ScopedPathOverride> home_; |
96 | 74 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 for (size_t i = 0; i < too_many_dumps; ++i) { | 130 for (size_t i = 0; i < too_many_dumps; ++i) { |
153 scoped_ptr<DumpInfo> info(CreateDumpInfo( | 131 scoped_ptr<DumpInfo> info(CreateDumpInfo( |
154 "{" | 132 "{" |
155 "\"name\": \"p\"," | 133 "\"name\": \"p\"," |
156 "\"dump_time\" : \"2012-01-01 01:02:03\"," | 134 "\"dump_time\" : \"2012-01-01 01:02:03\"," |
157 "\"dump\": \"dump_string\"," | 135 "\"dump\": \"dump_string\"," |
158 "\"uptime\": \"123456789\"," | 136 "\"uptime\": \"123456789\"," |
159 "\"logfile\": \"logfile.log\"" | 137 "\"logfile\": \"logfile.log\"" |
160 "}")); | 138 "}")); |
161 ASSERT_TRUE(info->valid()); | 139 ASSERT_TRUE(info->valid()); |
162 ASSERT_EQ(0, AppendLockFile(*info)); | 140 ASSERT_TRUE(AppendLockFile(*info)); |
163 } | 141 } |
164 | 142 |
165 ASSERT_EQ(-1, writer.Write()); | 143 ASSERT_EQ(-1, writer.Write()); |
166 } | 144 } |
167 | 145 |
168 TEST_F(MinidumpWriterTest, Write_FailsWhenTooManyRecentDumpsPresent) { | 146 TEST_F(MinidumpWriterTest, Write_FailsWhenTooManyRecentDumpsPresent) { |
169 MinidumpWriter writer(&fake_generator_, | 147 MinidumpWriter writer(&fake_generator_, |
170 dumplog_file_.value(), | 148 dumplog_file_.value(), |
171 MinidumpParams(), | 149 MinidumpParams(), |
172 base::Bind(&FakeDumpState)); | 150 base::Bind(&FakeDumpState)); |
173 | 151 |
174 // Write dump logs to the lockfile. | 152 // Write dump logs to the lockfile. |
175 size_t too_many_recent_dumps = writer.max_recent_dumps() + 1; | 153 size_t too_many_recent_dumps = writer.max_recent_dumps() + 1; |
176 for (size_t i = 0; i < too_many_recent_dumps; ++i) { | 154 for (size_t i = 0; i < too_many_recent_dumps; ++i) { |
177 MinidumpParams params; | 155 MinidumpParams params; |
178 DumpInfo info("dump", "/dump/path", time(nullptr), params); | 156 DumpInfo info("dump", "/dump/path", time(nullptr), params); |
179 ASSERT_EQ(0, AppendLockFile(info)); | 157 ASSERT_TRUE(AppendLockFile(info)); |
180 } | 158 } |
181 | 159 |
182 ASSERT_EQ(-1, writer.Write()); | 160 ASSERT_EQ(-1, writer.Write()); |
183 } | 161 } |
184 | 162 |
185 TEST_F(MinidumpWriterTest, Write_SucceedsWhenDumpLimitsNotExceeded) { | 163 TEST_F(MinidumpWriterTest, Write_SucceedsWhenDumpLimitsNotExceeded) { |
186 MinidumpWriter writer(&fake_generator_, | 164 MinidumpWriter writer(&fake_generator_, |
187 dumplog_file_.value(), | 165 dumplog_file_.value(), |
188 MinidumpParams(), | 166 MinidumpParams(), |
189 base::Bind(&FakeDumpState)); | 167 base::Bind(&FakeDumpState)); |
190 | 168 |
191 ASSERT_GT(writer.max_dumps(), 1); | 169 ASSERT_GT(writer.max_dumps(), 1); |
192 ASSERT_GT(writer.max_recent_dumps(), 0); | 170 ASSERT_GT(writer.max_recent_dumps(), 0); |
193 | 171 |
194 // Write an old dump logs to the lockfile. | 172 // Write an old dump logs to the lockfile. |
195 scoped_ptr<DumpInfo> info(CreateDumpInfo( | 173 scoped_ptr<DumpInfo> info(CreateDumpInfo( |
196 "{" | 174 "{" |
197 "\"name\": \"p\"," | 175 "\"name\": \"p\"," |
198 "\"dump_time\" : \"2012-01-01 01:02:03\"," | 176 "\"dump_time\" : \"2012-01-01 01:02:03\"," |
199 "\"dump\": \"dump_string\"," | 177 "\"dump\": \"dump_string\"," |
200 "\"uptime\": \"123456789\"," | 178 "\"uptime\": \"123456789\"," |
201 "\"logfile\": \"logfile.log\"" | 179 "\"logfile\": \"logfile.log\"" |
202 "}")); | 180 "}")); |
203 ASSERT_TRUE(info->valid()); | 181 ASSERT_TRUE(info->valid()); |
204 ASSERT_EQ(0, AppendLockFile(*info)); | 182 ASSERT_TRUE(AppendLockFile(*info)); |
205 ASSERT_EQ(0, writer.Write()); | 183 ASSERT_EQ(0, writer.Write()); |
206 } | 184 } |
207 | 185 |
208 } // namespace chromecast | 186 } // namespace chromecast |
OLD | NEW |