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.
5 #include "chromecast/crash/linux/crash_testing_utils.h"
7 #include "base/files/file_util.h"
8 #include "base/strings/string_split.h"
9 #include "base/strings/stringprintf.h"
10 #include "base/values.h"
11 #include "chromecast/base/path_utils.h"
12 #include "chromecast/base/serializers.h"
13 #include "chromecast/crash/linux/dump_info.h"
15 #define RCHECK(cond, retval, err) \
17 LOG(ERROR) << (err); \
23 namespace chromecast
{
26 const char kRatelimitKey
[] = "ratelimit";
27 const char kRatelimitPeriodStartKey
[] = "period_start";
28 const char kRatelimitPeriodDumpsKey
[] = "period_dumps";
30 scoped_ptr
<base::ListValue
> ParseLockFile(const std::string
& path
) {
31 std::string lockfile_string
;
32 RCHECK(base::ReadFileToString(base::FilePath(path
), &lockfile_string
),
34 "Failed to read file");
36 std::vector
<std::string
> lines
= base::SplitString(
37 lockfile_string
, "\n", base::KEEP_WHITESPACE
, base::SPLIT_WANT_NONEMPTY
);
39 scoped_ptr
<base::ListValue
> dumps
= make_scoped_ptr(new base::ListValue());
42 for (const std::string
& line
: lines
) {
45 scoped_ptr
<base::Value
> dump_info
= DeserializeFromJson(line
);
46 DumpInfo
info(dump_info
.get());
47 RCHECK(info
.valid(), nullptr, "Invalid DumpInfo");
48 dumps
->Append(dump_info
.Pass());
54 scoped_ptr
<base::Value
> ParseMetadataFile(const std::string
& path
) {
55 return DeserializeJsonFromFile(base::FilePath(path
));
58 int WriteLockFile(const std::string
& path
, base::ListValue
* contents
) {
62 for (const base::Value
* elem
: *contents
) {
63 scoped_ptr
<std::string
> dump_info
= SerializeToJson(*elem
);
64 RCHECK(dump_info
, -1, "Failed to serialize DumpInfo");
65 lockfile
+= *dump_info
;
66 lockfile
+= "\n"; // Add line seperatators
69 return WriteFile(base::FilePath(path
), lockfile
.c_str(), lockfile
.size()) >= 0
74 bool WriteMetadataFile(const std::string
& path
, const base::Value
* metadata
) {
76 return SerializeJsonToFile(base::FilePath(path
), *metadata
);
81 scoped_ptr
<DumpInfo
> CreateDumpInfo(const std::string
& json_string
) {
82 scoped_ptr
<base::Value
> value(DeserializeFromJson(json_string
));
83 return make_scoped_ptr(new DumpInfo(value
.get()));
86 bool FetchDumps(const std::string
& lockfile_path
,
87 ScopedVector
<DumpInfo
>* dumps
) {
89 scoped_ptr
<base::ListValue
> dump_list
= ParseLockFile(lockfile_path
);
90 RCHECK(dump_list
, false, "Failed to parse lockfile");
94 for (base::Value
* elem
: *dump_list
) {
95 scoped_ptr
<DumpInfo
> dump
= make_scoped_ptr(new DumpInfo(elem
));
96 RCHECK(dump
->valid(), false, "Invalid DumpInfo");
97 dumps
->push_back(dump
.Pass());
103 bool ClearDumps(const std::string
& lockfile_path
) {
104 scoped_ptr
<base::ListValue
> dump_list
=
105 make_scoped_ptr(new base::ListValue());
106 return WriteLockFile(lockfile_path
, dump_list
.get()) == 0;
109 bool CreateFiles(const std::string
& lockfile_path
,
110 const std::string
& metadata_path
) {
111 scoped_ptr
<base::DictionaryValue
> metadata
=
112 make_scoped_ptr(new base::DictionaryValue());
114 base::DictionaryValue
* ratelimit_fields
= new base::DictionaryValue();
115 metadata
->Set(kRatelimitKey
, make_scoped_ptr(ratelimit_fields
));
116 ratelimit_fields
->SetString(kRatelimitPeriodStartKey
, "0");
117 ratelimit_fields
->SetInteger(kRatelimitPeriodDumpsKey
, 0);
119 scoped_ptr
<base::ListValue
> dumps
= make_scoped_ptr(new base::ListValue());
121 return WriteLockFile(lockfile_path
, dumps
.get()) == 0 &&
122 WriteMetadataFile(metadata_path
, metadata
.get());
125 bool AppendLockFile(const std::string
& lockfile_path
,
126 const std::string
& metadata_path
,
127 const DumpInfo
& dump
) {
128 scoped_ptr
<base::ListValue
> contents
= ParseLockFile(lockfile_path
);
130 CreateFiles(lockfile_path
, metadata_path
);
131 if (!(contents
= ParseLockFile(lockfile_path
))) {
136 contents
->Append(dump
.GetAsValue());
138 return WriteLockFile(lockfile_path
, contents
.get()) == 0;
141 bool SetRatelimitPeriodStart(const std::string
& metadata_path
, time_t start
) {
142 scoped_ptr
<base::Value
> contents
= ParseMetadataFile(metadata_path
);
144 base::DictionaryValue
* dict
;
145 base::DictionaryValue
* ratelimit_params
;
146 if (!contents
|| !contents
->GetAsDictionary(&dict
) ||
147 !dict
->GetDictionary(kRatelimitKey
, &ratelimit_params
)) {
151 std::string period_start_str
=
152 base::StringPrintf("%lld", static_cast<long long>(start
));
153 ratelimit_params
->SetString(kRatelimitPeriodStartKey
, period_start_str
);
155 return WriteMetadataFile(metadata_path
, contents
.get()) == 0;
158 } // namespace chromecast