| // Copyright 2021 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "base/debug/dump_without_crashing.h" |
| |
| #include "base/hash/hash.h" |
| #include "base/location.h" |
| #include "base/test/metrics/histogram_tester.h" |
| #include "base/test/scoped_mock_clock_override.h" |
| #include "build/build_config.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace base { |
| namespace debug { |
| |
| class DumpWithoutCrashingTest : public testing::Test { |
| public: |
| static void DummyDumpWithoutCrashing() { number_of_dump_calls_++; } |
| |
| static int number_of_dump_calls() { return number_of_dump_calls_; } |
| |
| protected: |
| void SetUp() override { |
| SetDumpWithoutCrashingFunction( |
| &DumpWithoutCrashingTest::DummyDumpWithoutCrashing); |
| number_of_dump_calls_ = 0; |
| } |
| |
| void TearDown() override { |
| SetDumpWithoutCrashingFunction(nullptr); |
| ClearMapsForTesting(); |
| } |
| |
| // Set override. |
| ScopedMockClockOverride clock_; |
| |
| const base::HistogramTester histogram_tester_; |
| const base::Location location1_ = FROM_HERE; |
| const base::Location location2_ = FROM_HERE; |
| const size_t unique_identifier1_ = |
| base::FastHash("DumpWithoutCrashingFirstTest"); |
| const size_t unique_identifier2_ = |
| base::FastHash("DumpWithoutCrashingSecondTest"); |
| |
| private: |
| static int number_of_dump_calls_; |
| }; |
| |
| int DumpWithoutCrashingTest::number_of_dump_calls_ = 0; |
| |
| TEST_F(DumpWithoutCrashingTest, DumpWithoutCrashingWithLocation) { |
| EXPECT_EQ(0, DumpWithoutCrashingTest::number_of_dump_calls()); |
| |
| histogram_tester_.ExpectBucketCount("Stability.DumpWithoutCrashingStatus", |
| DumpWithoutCrashingStatus::kThrottled, 0); |
| histogram_tester_.ExpectBucketCount("Stability.DumpWithoutCrashingStatus", |
| DumpWithoutCrashingStatus::kUploaded, 0); |
| |
| // The first call to DumpWithoutCrashing will always capture the dump and |
| // will return true |
| EXPECT_TRUE(DumpWithoutCrashing(location1_, base::Seconds(1))); |
| EXPECT_EQ(1, DumpWithoutCrashingTest::number_of_dump_calls()); |
| |
| histogram_tester_.ExpectBucketCount("Stability.DumpWithoutCrashingStatus", |
| DumpWithoutCrashingStatus::kThrottled, 0); |
| histogram_tester_.ExpectBucketCount("Stability.DumpWithoutCrashingStatus", |
| DumpWithoutCrashingStatus::kUploaded, 1); |
| |
| // If DumpWithoutCrashing is called within 1 second, expected result is false. |
| EXPECT_FALSE(DumpWithoutCrashing(location1_, base::Seconds(1))); |
| EXPECT_EQ(1, DumpWithoutCrashingTest::number_of_dump_calls()); |
| |
| // For testing, the time for capturing dump again is 1 second and if the |
| // function is called after 1 second, it will return true. |
| clock_.Advance(Seconds(2)); |
| EXPECT_TRUE(DumpWithoutCrashing(location1_, base::Seconds(1))); |
| EXPECT_EQ(2, DumpWithoutCrashingTest::number_of_dump_calls()); |
| |
| histogram_tester_.ExpectBucketCount("Stability.DumpWithoutCrashingStatus", |
| DumpWithoutCrashingStatus::kThrottled, 1); |
| histogram_tester_.ExpectBucketCount("Stability.DumpWithoutCrashingStatus", |
| DumpWithoutCrashingStatus::kUploaded, 2); |
| |
| EXPECT_TRUE(DumpWithoutCrashing(location2_, base::Seconds(1))); |
| EXPECT_EQ(3, DumpWithoutCrashingTest::number_of_dump_calls()); |
| |
| EXPECT_FALSE(DumpWithoutCrashing(location2_, base::Seconds(1))); |
| EXPECT_EQ(3, DumpWithoutCrashingTest::number_of_dump_calls()); |
| |
| histogram_tester_.ExpectBucketCount("Stability.DumpWithoutCrashingStatus", |
| DumpWithoutCrashingStatus::kThrottled, 2); |
| histogram_tester_.ExpectBucketCount("Stability.DumpWithoutCrashingStatus", |
| DumpWithoutCrashingStatus::kUploaded, 3); |
| } |
| |
| TEST_F(DumpWithoutCrashingTest, DumpWithoutCrashingWithLocationAndUniqueId) { |
| EXPECT_EQ(0, DumpWithoutCrashingTest::number_of_dump_calls()); |
| |
| histogram_tester_.ExpectBucketCount("Stability.DumpWithoutCrashingStatus", |
| DumpWithoutCrashingStatus::kThrottled, 0); |
| histogram_tester_.ExpectBucketCount("Stability.DumpWithoutCrashingStatus", |
| DumpWithoutCrashingStatus::kUploaded, 0); |
| |
| // Test the variant of DumpWithoutCrashingWithUniqueId where the function |
| // takes a location and unique id. |
| EXPECT_TRUE(DumpWithoutCrashingWithUniqueId(unique_identifier1_, location1_, |
| base::Seconds(1))); |
| EXPECT_EQ(1, DumpWithoutCrashingTest::number_of_dump_calls()); |
| |
| histogram_tester_.ExpectBucketCount("Stability.DumpWithoutCrashingStatus", |
| DumpWithoutCrashingStatus::kThrottled, 0); |
| histogram_tester_.ExpectBucketCount("Stability.DumpWithoutCrashingStatus", |
| DumpWithoutCrashingStatus::kUploaded, 1); |
| |
| // If DumpWithoutCrashingWithUniqueId called within 1 second, expected result |
| // is false. |
| EXPECT_FALSE(DumpWithoutCrashingWithUniqueId(unique_identifier1_, location1_, |
| base::Seconds(1))); |
| EXPECT_EQ(1, DumpWithoutCrashingTest::number_of_dump_calls()); |
| |
| // For testing, the time for capturing dump again is 1 second and if the |
| // function is called after 1 second, it will return true. |
| clock_.Advance(Seconds(2)); |
| |
| EXPECT_TRUE(DumpWithoutCrashingWithUniqueId(unique_identifier1_, location1_, |
| base::Seconds(1))); |
| EXPECT_EQ(2, DumpWithoutCrashingTest::number_of_dump_calls()); |
| |
| histogram_tester_.ExpectBucketCount("Stability.DumpWithoutCrashingStatus", |
| DumpWithoutCrashingStatus::kThrottled, 1); |
| histogram_tester_.ExpectBucketCount("Stability.DumpWithoutCrashingStatus", |
| DumpWithoutCrashingStatus::kUploaded, 2); |
| |
| EXPECT_TRUE(DumpWithoutCrashingWithUniqueId(unique_identifier2_, location2_, |
| base::Seconds(1))); |
| EXPECT_EQ(3, DumpWithoutCrashingTest::number_of_dump_calls()); |
| EXPECT_FALSE(DumpWithoutCrashingWithUniqueId(unique_identifier2_, location2_, |
| base::Seconds(1))); |
| EXPECT_EQ(3, DumpWithoutCrashingTest::number_of_dump_calls()); |
| histogram_tester_.ExpectBucketCount("Stability.DumpWithoutCrashingStatus", |
| DumpWithoutCrashingStatus::kThrottled, 2); |
| histogram_tester_.ExpectBucketCount("Stability.DumpWithoutCrashingStatus", |
| DumpWithoutCrashingStatus::kUploaded, 3); |
| } |
| |
| } // namespace debug |
| } // namespace base |