diff options
Diffstat (limited to 'chrome/common/child_process_logging_mac_unittest.mm')
-rw-r--r-- | chrome/common/child_process_logging_mac_unittest.mm | 141 |
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); +} |