OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "components/crash/core/common/crash_keys.h" | 5 #include "components/crash/core/common/crash_keys.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <map> | 9 #include <map> |
10 #include <string> | 10 #include <string> |
11 | 11 |
12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
13 #include "base/compiler_specific.h" | 13 #include "base/compiler_specific.h" |
14 #include "base/debug/crash_logging.h" | 14 #include "base/debug/crash_logging.h" |
15 #include "base/format_macros.h" | 15 #include "base/format_macros.h" |
16 #include "base/strings/string_piece.h" | 16 #include "base/strings/string_piece.h" |
17 #include "base/strings/stringprintf.h" | 17 #include "base/strings/stringprintf.h" |
18 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
19 | 19 |
20 class CrashKeysTest : public testing::Test { | 20 class CrashKeysTest : public testing::Test { |
21 public: | 21 public: |
22 void SetUp() override { | 22 void SetUp() override { |
23 self_ = this; | 23 self_ = this; |
24 base::debug::SetCrashKeyReportingFunctions( | 24 base::debug::SetCrashKeyReportingFunctions( |
25 &SetCrashKeyValue, &ClearCrashKey); | 25 &SetCrashKeyValue, &ClearCrashKey); |
| 26 } |
26 | 27 |
| 28 bool InitSwitchesCrashKeys() { |
27 std::vector<base::debug::CrashKey> keys; | 29 std::vector<base::debug::CrashKey> keys; |
28 crash_keys::GetCrashKeysForCommandLineSwitches(&keys); | 30 crash_keys::GetCrashKeysForCommandLineSwitches(&keys); |
29 base::debug::InitCrashKeys(keys.data(), keys.size(), | 31 return InitCrashKeys(keys); |
30 crash_keys::kChunkMaxLength); | 32 } |
31 ASSERT_FALSE(keys.empty()); | 33 |
| 34 bool InitVariationsCrashKeys() { |
| 35 std::vector<base::debug::CrashKey> keys = { |
| 36 {crash_keys::kNumVariations, crash_keys::kSmallSize}, |
| 37 {crash_keys::kVariations, crash_keys::kHugeSize}}; |
| 38 return InitCrashKeys(keys); |
32 } | 39 } |
33 | 40 |
34 void TearDown() override { | 41 void TearDown() override { |
35 base::debug::ResetCrashLoggingForTesting(); | 42 base::debug::ResetCrashLoggingForTesting(); |
36 self_ = NULL; | 43 self_ = NULL; |
37 } | 44 } |
38 | 45 |
39 bool HasCrashKey(const std::string& key) { | 46 bool HasCrashKey(const std::string& key) { |
40 return keys_.find(key) != keys_.end(); | 47 return keys_.find(key) != keys_.end(); |
41 } | 48 } |
42 | 49 |
43 std::string GetKeyValue(const std::string& key) { | 50 std::string GetKeyValue(const std::string& key) { |
44 std::map<std::string, std::string>::const_iterator it = keys_.find(key); | 51 std::map<std::string, std::string>::const_iterator it = keys_.find(key); |
45 if (it == keys_.end()) | 52 if (it == keys_.end()) |
46 return std::string(); | 53 return std::string(); |
47 return it->second; | 54 return it->second; |
48 } | 55 } |
49 | 56 |
50 private: | 57 private: |
| 58 bool InitCrashKeys(const std::vector<base::debug::CrashKey>& keys) { |
| 59 base::debug::InitCrashKeys(keys.data(), keys.size(), |
| 60 crash_keys::kChunkMaxLength); |
| 61 return !keys.empty(); |
| 62 } |
| 63 |
51 static void SetCrashKeyValue(const base::StringPiece& key, | 64 static void SetCrashKeyValue(const base::StringPiece& key, |
52 const base::StringPiece& value) { | 65 const base::StringPiece& value) { |
53 self_->keys_[key.as_string()] = value.as_string(); | 66 self_->keys_[key.as_string()] = value.as_string(); |
54 } | 67 } |
55 | 68 |
56 static void ClearCrashKey(const base::StringPiece& key) { | 69 static void ClearCrashKey(const base::StringPiece& key) { |
57 self_->keys_.erase(key.as_string()); | 70 self_->keys_.erase(key.as_string()); |
58 } | 71 } |
59 | 72 |
60 static CrashKeysTest* self_; | 73 static CrashKeysTest* self_; |
61 | 74 |
62 std::map<std::string, std::string> keys_; | 75 std::map<std::string, std::string> keys_; |
63 }; | 76 }; |
64 | 77 |
65 CrashKeysTest* CrashKeysTest::self_ = NULL; | 78 CrashKeysTest* CrashKeysTest::self_ = NULL; |
66 | 79 |
67 TEST_F(CrashKeysTest, Switches) { | 80 TEST_F(CrashKeysTest, Switches) { |
| 81 ASSERT_TRUE(InitSwitchesCrashKeys()); |
| 82 |
68 // Set three switches. | 83 // Set three switches. |
69 { | 84 { |
70 base::CommandLine command_line(base::CommandLine::NO_PROGRAM); | 85 base::CommandLine command_line(base::CommandLine::NO_PROGRAM); |
71 for (size_t i = 1; i <= 3; ++i) | 86 for (size_t i = 1; i <= 3; ++i) |
72 command_line.AppendSwitch(base::StringPrintf("--flag-%" PRIuS, i)); | 87 command_line.AppendSwitch(base::StringPrintf("--flag-%" PRIuS, i)); |
73 crash_keys::SetSwitchesFromCommandLine(command_line, nullptr); | 88 crash_keys::SetSwitchesFromCommandLine(command_line, nullptr); |
74 EXPECT_EQ("--flag-1", GetKeyValue("switch-1")); | 89 EXPECT_EQ("--flag-1", GetKeyValue("switch-1")); |
75 EXPECT_EQ("--flag-2", GetKeyValue("switch-2")); | 90 EXPECT_EQ("--flag-2", GetKeyValue("switch-2")); |
76 EXPECT_EQ("--flag-3", GetKeyValue("switch-3")); | 91 EXPECT_EQ("--flag-3", GetKeyValue("switch-3")); |
77 EXPECT_FALSE(HasCrashKey("switch-4")); | 92 EXPECT_FALSE(HasCrashKey("switch-4")); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 | 126 |
112 namespace { | 127 namespace { |
113 | 128 |
114 bool IsBoringFlag(const std::string& flag) { | 129 bool IsBoringFlag(const std::string& flag) { |
115 return flag.compare("--boring") == 0; | 130 return flag.compare("--boring") == 0; |
116 } | 131 } |
117 | 132 |
118 } // namespace | 133 } // namespace |
119 | 134 |
120 TEST_F(CrashKeysTest, FilterFlags) { | 135 TEST_F(CrashKeysTest, FilterFlags) { |
| 136 ASSERT_TRUE(InitSwitchesCrashKeys()); |
| 137 |
121 using crash_keys::kSwitchesMaxCount; | 138 using crash_keys::kSwitchesMaxCount; |
122 | 139 |
123 base::CommandLine command_line(base::CommandLine::NO_PROGRAM); | 140 base::CommandLine command_line(base::CommandLine::NO_PROGRAM); |
124 command_line.AppendSwitch("--not-boring-1"); | 141 command_line.AppendSwitch("--not-boring-1"); |
125 command_line.AppendSwitch("--boring"); | 142 command_line.AppendSwitch("--boring"); |
126 | 143 |
127 // Include the max number of non-boring switches, to make sure that only the | 144 // Include the max number of non-boring switches, to make sure that only the |
128 // switches actually included in the crash keys are counted. | 145 // switches actually included in the crash keys are counted. |
129 for (size_t i = 2; i <= kSwitchesMaxCount; ++i) | 146 for (size_t i = 2; i <= kSwitchesMaxCount; ++i) |
130 command_line.AppendSwitch(base::StringPrintf("--not-boring-%" PRIuS, i)); | 147 command_line.AppendSwitch(base::StringPrintf("--not-boring-%" PRIuS, i)); |
131 | 148 |
132 crash_keys::SetSwitchesFromCommandLine(command_line, &IsBoringFlag); | 149 crash_keys::SetSwitchesFromCommandLine(command_line, &IsBoringFlag); |
133 | 150 |
134 // If the boring keys are filtered out, every single key should now be | 151 // If the boring keys are filtered out, every single key should now be |
135 // not-boring. | 152 // not-boring. |
136 for (size_t i = 1; i <= kSwitchesMaxCount; ++i) { | 153 for (size_t i = 1; i <= kSwitchesMaxCount; ++i) { |
137 std::string switch_name = base::StringPrintf(crash_keys::kSwitchFormat, i); | 154 std::string switch_name = base::StringPrintf(crash_keys::kSwitchFormat, i); |
138 std::string switch_value = base::StringPrintf("--not-boring-%" PRIuS, i); | 155 std::string switch_value = base::StringPrintf("--not-boring-%" PRIuS, i); |
139 EXPECT_EQ(switch_value, GetKeyValue(switch_name)) << "switch_name is " << | 156 EXPECT_EQ(switch_value, GetKeyValue(switch_name)) << "switch_name is " << |
140 switch_name; | 157 switch_name; |
141 } | 158 } |
142 } | 159 } |
| 160 |
| 161 TEST_F(CrashKeysTest, VariationsCapacity) { |
| 162 ASSERT_TRUE(InitVariationsCrashKeys()); |
| 163 |
| 164 // Variation encoding: two 32bit numbers encorded as hex with a '-' separator. |
| 165 const char kSampleVariation[] = "12345678-12345678"; |
| 166 const size_t kVariationLen = std::strlen(kSampleVariation); |
| 167 const size_t kSeparatedVariationLen = kVariationLen + 1U; |
| 168 ASSERT_EQ(17U, kVariationLen); |
| 169 |
| 170 // The expected capacity factors in a separator (','). |
| 171 const size_t kExpectedCapacity = 112U; |
| 172 ASSERT_EQ(kExpectedCapacity, |
| 173 crash_keys::kHugeSize / (kSeparatedVariationLen)); |
| 174 |
| 175 // Create some variations and set the crash keys. |
| 176 std::vector<std::string> variations; |
| 177 for (size_t i = 0; i < kExpectedCapacity + 2; ++i) |
| 178 variations.push_back(kSampleVariation); |
| 179 crash_keys::SetVariationsList(variations); |
| 180 |
| 181 // Validate crash keys. |
| 182 ASSERT_TRUE(HasCrashKey(crash_keys::kNumVariations)); |
| 183 EXPECT_EQ("114", GetKeyValue(crash_keys::kNumVariations)); |
| 184 |
| 185 const size_t kExpectedChunks = (kSeparatedVariationLen * kExpectedCapacity) / |
| 186 crash_keys::kChunkMaxLength; |
| 187 for (size_t i = 0; i < kExpectedChunks; ++i) { |
| 188 ASSERT_TRUE(HasCrashKey( |
| 189 base::StringPrintf("%s-%" PRIuS, crash_keys::kVariations, i + 1))); |
| 190 } |
| 191 } |
OLD | NEW |