summaryrefslogtreecommitdiffstats
path: root/chrome/common/child_process_logging_mac_unittest.mm
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/common/child_process_logging_mac_unittest.mm')
-rw-r--r--chrome/common/child_process_logging_mac_unittest.mm141
1 files changed, 141 insertions, 0 deletions
diff --git a/chrome/common/child_process_logging_mac_unittest.mm b/chrome/common/child_process_logging_mac_unittest.mm
new file mode 100644
index 0000000..a751287
--- /dev/null
+++ b/chrome/common/child_process_logging_mac_unittest.mm
@@ -0,0 +1,141 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/common/child_process_logging.h"
+
+#import <Foundation/Foundation.h>
+
+#include "base/logging.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/platform_test.h"
+
+typedef PlatformTest ChildProcessLoggingTest;
+
+namespace {
+
+// Class to mock breakpad's setkeyvalue/clearkeyvalue functions needed for
+// SetActiveRendererURLImpl.
+// The Keys are stored in a static dictionary and methods are provided to
+// verify correctness.
+class MockBreakpadKeyValueStore {
+ public:
+ MockBreakpadKeyValueStore() {
+ // Only one of these objects can be active at once.
+ DCHECK(dict == NULL);
+ dict = [[NSMutableDictionary alloc] init];
+ }
+
+ ~MockBreakpadKeyValueStore() {
+ // Only one of these objects can be active at once.
+ DCHECK(dict != NULL);
+ [dict release];
+ dict = NULL;
+ }
+
+ static void SetKeyValue(NSString* key, NSString* value) {
+ DCHECK(dict != NULL);
+ [dict setObject:value forKey:key];
+ }
+
+ static void ClearKeyValue(NSString *key) {
+ DCHECK(dict != NULL);
+ [dict removeObjectForKey:key];
+ }
+
+ int CountDictionaryEntries() {
+ return [dict count];
+ }
+
+ bool VerifyDictionaryContents(const std::string &url) {
+ using child_process_logging::kMaxNumCrashURLChunks;
+ using child_process_logging::kMaxNumURLChunkValueLength;
+ using child_process_logging::kUrlChunkFormatStr;
+
+ int num_url_chunks = CountDictionaryEntries();
+ EXPECT_TRUE(num_url_chunks <= kMaxNumCrashURLChunks);
+
+ NSString *kUrlChunkFormatStr_utf8 = [NSString
+ stringWithUTF8String:kUrlChunkFormatStr];
+
+ NSString *accumulated_url = @"";
+ for (int i = 0; i < num_url_chunks; ++i) {
+ // URL chunk names are 1-based.
+ NSString *key = [NSString stringWithFormat:kUrlChunkFormatStr_utf8, i+1];
+ EXPECT_TRUE(key != NULL);
+ NSString *value = [dict objectForKey:key];
+ EXPECT_TRUE([value length] > 0);
+ EXPECT_TRUE([value length] <= (unsigned)kMaxNumURLChunkValueLength);
+ accumulated_url = [accumulated_url stringByAppendingString:value];
+ }
+
+ NSString *expected_url = [NSString stringWithUTF8String:url.c_str()];
+ return([accumulated_url isEqualToString:expected_url]);
+ }
+
+ private:
+ static NSMutableDictionary* dict;
+ DISALLOW_COPY_AND_ASSIGN(MockBreakpadKeyValueStore);
+};
+
+// static
+NSMutableDictionary* MockBreakpadKeyValueStore::dict;
+
+} // namespace
+
+// Call through to SetActiveURLImpl using the functions from
+// MockBreakpadKeyValueStore.
+void SetActiveURLWithMock(const GURL& url) {
+ using child_process_logging::SetActiveURLImpl;
+
+ SetCrashKeyValueFuncPtr setFunc = MockBreakpadKeyValueStore::SetKeyValue;
+ ClearCrashKeyValueFuncPtr clearFunc =
+ MockBreakpadKeyValueStore::ClearKeyValue;
+
+ SetActiveURLImpl(url, setFunc, clearFunc);
+}
+
+TEST_F(ChildProcessLoggingTest, TestUrlSplitting) {
+ using child_process_logging::kMaxNumCrashURLChunks;
+ using child_process_logging::kMaxNumURLChunkValueLength;
+
+ const std::string short_url("http://abc/");
+ std::string long_url("http://");
+ std::string overflow_url("http://");
+
+ long_url += std::string(kMaxNumURLChunkValueLength * 2, 'a');
+ long_url += "/";
+
+ int max_num_chars_stored_in_dump = kMaxNumURLChunkValueLength *
+ kMaxNumCrashURLChunks;
+ overflow_url += std::string(max_num_chars_stored_in_dump + 1, 'a');
+ overflow_url += "/";
+
+ // Check that Clearing NULL URL works.
+ MockBreakpadKeyValueStore mock;
+ SetActiveURLWithMock(GURL());
+ EXPECT_EQ(mock.CountDictionaryEntries(), 0);
+
+ // Check that we can set a URL.
+ SetActiveURLWithMock(GURL(short_url.c_str()));
+ EXPECT_TRUE(mock.VerifyDictionaryContents(short_url));
+ EXPECT_EQ(mock.CountDictionaryEntries(), 1);
+ SetActiveURLWithMock(GURL());
+ EXPECT_EQ(mock.CountDictionaryEntries(), 0);
+
+ // Check that we can replace a long url with a short url.
+ SetActiveURLWithMock(GURL(long_url.c_str()));
+ EXPECT_TRUE(mock.VerifyDictionaryContents(long_url));
+ SetActiveURLWithMock(GURL(short_url.c_str()));
+ EXPECT_TRUE(mock.VerifyDictionaryContents(short_url));
+ SetActiveURLWithMock(GURL());
+ EXPECT_EQ(mock.CountDictionaryEntries(), 0);
+
+
+ // Check that overflow works correctly.
+ SetActiveURLWithMock(GURL(overflow_url.c_str()));
+ EXPECT_TRUE(mock.VerifyDictionaryContents(
+ overflow_url.substr(0, max_num_chars_stored_in_dump)));
+ SetActiveURLWithMock(GURL());
+ EXPECT_EQ(mock.CountDictionaryEntries(), 0);
+}