Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chromecast / app / linux / cast_crash_reporter_client_unittest.cc
blobadcfd26cb94d90ebdb36f855a37649465cf2f37e
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 <fstream>
7 #include "base/base_paths.h"
8 #include "base/bind.h"
9 #include "base/files/file.h"
10 #include "base/files/file_util.h"
11 #include "base/memory/scoped_vector.h"
12 #include "base/test/scoped_path_override.h"
13 #include "base/threading/thread_restrictions.h"
14 #include "base/values.h"
15 #include "chromecast/app/linux/cast_crash_reporter_client.h"
16 #include "chromecast/crash/app_state_tracker.h"
17 #include "chromecast/crash/linux/crash_testing_utils.h"
18 #include "chromecast/crash/linux/crash_util.h"
19 #include "chromecast/crash/linux/dump_info.h"
20 #include "testing/gtest/include/gtest/gtest.h"
22 namespace chromecast {
23 namespace {
25 const char kFakeDumpstateContents[] = "Dumpstate Contents\nDumpdumpdumpdump\n";
26 const char kFakeMinidumpContents[] = "Minidump Contents\nLine1\nLine2\n";
28 int WriteFakeDumpStateFile(const std::string& path) {
29 // Append the correct extension and write the data to file.
30 base::File dumpstate(base::FilePath(path).AddExtension(".txt.gz"),
31 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
32 dumpstate.Write(
33 0, kFakeDumpstateContents, sizeof(kFakeDumpstateContents) - 1);
34 return 0;
37 } // namespace
39 class CastCrashReporterClientTest : public testing::Test {
40 protected:
41 CastCrashReporterClientTest() {}
42 ~CastCrashReporterClientTest() override {}
44 static void SetUpTestCase() {
45 // Set a callback to be used in place of the |dumpstate| executable.
46 CrashUtil::SetDumpStateCbForTest(base::Bind(&WriteFakeDumpStateFile));
49 // testing::Test implementation:
50 void SetUp() override {
51 // Set up a temporary directory which will be used as our fake home dir.
52 ASSERT_TRUE(base::CreateNewTempDirectory("", &fake_home_dir_));
53 home_override_.reset(
54 new base::ScopedPathOverride(base::DIR_HOME, fake_home_dir_));
56 // "Launch" YouTube.
57 AppStateTracker::SetLastLaunchedApp("youtube");
58 AppStateTracker::SetCurrentApp("youtube");
60 // "Launch" and switch to Pandora.
61 AppStateTracker::SetLastLaunchedApp("pandora");
62 AppStateTracker::SetCurrentApp("pandora");
64 // "Launch" Netflix.
65 AppStateTracker::SetLastLaunchedApp("netflix");
66 // Netflix crashed.
68 // A minidump file is created.
69 base::CreateTemporaryFile(&minidump_path_);
70 base::File minidump(minidump_path_,
71 base::File::FLAG_OPEN | base::File::FLAG_APPEND);
72 minidump.Write(0, kFakeMinidumpContents, sizeof(kFakeMinidumpContents) - 1);
73 minidump.Close();
76 void TearDown() override {
77 // Remove IO restrictions in order to examine the state of the filesystem.
78 base::ThreadRestrictions::SetIOAllowed(true);
80 // Assert that the original file has been moved.
81 ASSERT_FALSE(base::PathExists(minidump_path_));
83 // Assert that the file has been moved to "minidumps", with the expected
84 // contents.
85 std::string contents;
86 base::FilePath new_minidump =
87 fake_home_dir_.Append("minidumps").Append(minidump_path_.BaseName());
88 ASSERT_TRUE(base::PathExists(new_minidump));
89 ASSERT_TRUE(base::ReadFileToString(new_minidump, &contents));
90 ASSERT_EQ(kFakeMinidumpContents, contents);
92 // Assert that the dumpstate file has been written with the expected
93 // contents.
94 base::FilePath dumpstate = new_minidump.AddExtension(".txt.gz");
95 ASSERT_TRUE(base::PathExists(dumpstate));
96 ASSERT_TRUE(base::ReadFileToString(dumpstate, &contents));
97 ASSERT_EQ(kFakeDumpstateContents, contents);
99 // Assert that the lockfile has logged the correct information.
100 base::FilePath lockfile =
101 fake_home_dir_.Append("minidumps").Append("lockfile");
102 ASSERT_TRUE(base::PathExists(lockfile));
103 ScopedVector<DumpInfo> dumps;
104 ASSERT_TRUE(FetchDumps(lockfile.value(), &dumps));
105 ASSERT_EQ(1u, dumps.size());
107 const DumpInfo& dump_info = *(dumps[0]);
108 ASSERT_TRUE(dump_info.valid());
109 EXPECT_EQ(new_minidump.value(), dump_info.crashed_process_dump());
110 EXPECT_EQ(dumpstate.value(), dump_info.logfile());
111 EXPECT_EQ("youtube", dump_info.params().previous_app_name);
112 EXPECT_EQ("pandora", dump_info.params().current_app_name);
113 EXPECT_EQ("netflix", dump_info.params().last_app_name);
116 const base::FilePath& minidump_path() { return minidump_path_; }
118 private:
119 base::FilePath fake_home_dir_;
120 base::FilePath minidump_path_;
121 scoped_ptr<base::ScopedPathOverride> home_override_;
124 #if ENABLE_THREAD_RESTRICTIONS
125 // This test shall only be run when thread restricitons are enabled. Otherwise,
126 // the thread will not actually be IO-restricted, and the final ASSERT will
127 // fail.
128 TEST_F(CastCrashReporterClientTest, EndToEndTestOnIORestrictedThread) {
129 // Handle a "crash" on an IO restricted thread.
130 base::ThreadRestrictions::SetIOAllowed(false);
131 CastCrashReporterClient client;
132 ASSERT_TRUE(client.HandleCrashDump(minidump_path().value().c_str()));
134 // Assert that the thread is IO restricted when the function exits.
135 // Note that SetIOAllowed returns the previous value.
136 ASSERT_FALSE(base::ThreadRestrictions::SetIOAllowed(true));
138 #endif // ENABLE_THREAD_RESTRICTIONS
140 TEST_F(CastCrashReporterClientTest, EndToEndTestOnNonIORestrictedThread) {
141 // Handle a crash on a non-IO restricted thread.
142 base::ThreadRestrictions::SetIOAllowed(true);
143 CastCrashReporterClient client;
144 ASSERT_TRUE(client.HandleCrashDump(minidump_path().value().c_str()));
146 // Assert that the thread is not IO restricted when the function exits.
147 // Note that SetIOAllowed returns the previous value.
148 ASSERT_TRUE(base::ThreadRestrictions::SetIOAllowed(true));
151 } // namespace chromecast