1 // Copyright (c) 2011 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 "chrome/common/child_process_logging.h"
10 #import <Foundation/Foundation.h>
12 #include "base/debug/crash_logging.h"
13 #include "base/logging.h"
14 #include "base/strings/stringprintf.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "testing/platform_test.h"
18 typedef PlatformTest ChildProcessLoggingTest;
22 // Class to mock breakpad's setkeyvalue/clearkeyvalue functions needed for
23 // SetActiveRendererURLImpl.
24 // The Keys are stored in a static dictionary and methods are provided to
25 // verify correctness.
26 class MockBreakpadKeyValueStore {
28 MockBreakpadKeyValueStore() {
29 // Only one of these objects can be active at once.
31 dict = new std::map<std::string, std::string>;
34 ~MockBreakpadKeyValueStore() {
35 // Only one of these objects can be active at once.
41 static void SetKeyValue(const base::StringPiece& key,
42 const base::StringPiece& value) {
44 (*dict)[key.as_string()] = value.as_string();
47 static void ClearKeyValue(const base::StringPiece& key) {
49 dict->erase(key.as_string());
52 size_t CountDictionaryEntries() {
56 bool VerifyDictionaryContents(const std::string& url) {
57 using child_process_logging::kMaxNumCrashURLChunks;
58 using child_process_logging::kMaxNumURLChunkValueLength;
59 using child_process_logging::kUrlChunkFormatStr;
61 size_t num_url_chunks = CountDictionaryEntries();
62 EXPECT_LE(num_url_chunks, kMaxNumCrashURLChunks);
64 std::string accumulated_url;
65 for (size_t i = 0; i < num_url_chunks; ++i) {
66 // URL chunk names are 1-based.
67 std::string key = base::StringPrintf(kUrlChunkFormatStr, i + 1);
68 std::string value = (*dict)[key];
69 EXPECT_GT(value.length(), 0u);
70 EXPECT_LE(value.length(),
71 static_cast<size_t>(kMaxNumURLChunkValueLength));
72 accumulated_url += value;
75 return url == accumulated_url;
79 static std::map<std::string, std::string>* dict;
80 DISALLOW_COPY_AND_ASSIGN(MockBreakpadKeyValueStore);
84 std::map<std::string, std::string>* MockBreakpadKeyValueStore::dict;
88 // Call through to SetActiveURLImpl using the functions from
89 // MockBreakpadKeyValueStore.
90 void SetActiveURLWithMock(const GURL& url) {
91 using child_process_logging::SetActiveURLImpl;
93 base::debug::SetCrashKeyValueFuncT setFunc =
94 MockBreakpadKeyValueStore::SetKeyValue;
95 base::debug::ClearCrashKeyValueFuncT clearFunc =
96 MockBreakpadKeyValueStore::ClearKeyValue;
98 SetActiveURLImpl(url, setFunc, clearFunc);
101 TEST_F(ChildProcessLoggingTest, TestUrlSplitting) {
102 using child_process_logging::kMaxNumCrashURLChunks;
103 using child_process_logging::kMaxNumURLChunkValueLength;
105 const std::string short_url("http://abc/");
106 std::string long_url("http://");
107 std::string overflow_url("http://");
109 long_url += std::string(kMaxNumURLChunkValueLength * 2, 'a');
112 int max_num_chars_stored_in_dump = kMaxNumURLChunkValueLength *
113 kMaxNumCrashURLChunks;
114 overflow_url += std::string(max_num_chars_stored_in_dump + 1, 'a');
117 // Check that Clearing NULL URL works.
118 MockBreakpadKeyValueStore mock;
119 SetActiveURLWithMock(GURL());
120 EXPECT_EQ(0u, mock.CountDictionaryEntries());
122 // Check that we can set a URL.
123 SetActiveURLWithMock(GURL(short_url.c_str()));
124 EXPECT_TRUE(mock.VerifyDictionaryContents(short_url));
125 EXPECT_EQ(1u, mock.CountDictionaryEntries());
126 SetActiveURLWithMock(GURL());
127 EXPECT_EQ(0u, mock.CountDictionaryEntries());
129 // Check that we can replace a long url with a short url.
130 SetActiveURLWithMock(GURL(long_url.c_str()));
131 EXPECT_TRUE(mock.VerifyDictionaryContents(long_url));
132 SetActiveURLWithMock(GURL(short_url.c_str()));
133 EXPECT_TRUE(mock.VerifyDictionaryContents(short_url));
134 SetActiveURLWithMock(GURL());
135 EXPECT_EQ(0u, mock.CountDictionaryEntries());
138 // Check that overflow works correctly.
139 SetActiveURLWithMock(GURL(overflow_url.c_str()));
140 EXPECT_TRUE(mock.VerifyDictionaryContents(
141 overflow_url.substr(0, max_num_chars_stored_in_dump)));
142 SetActiveURLWithMock(GURL());
143 EXPECT_EQ(0u, mock.CountDictionaryEntries());