• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (c) 2009 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.
4
5#include "chrome/common/child_process_logging.h"
6
7#import <Foundation/Foundation.h>
8
9#include "base/logging.h"
10#include "testing/gtest/include/gtest/gtest.h"
11#include "testing/platform_test.h"
12
13typedef PlatformTest ChildProcessLoggingTest;
14
15namespace {
16
17// Class to mock breakpad's setkeyvalue/clearkeyvalue functions needed for
18// SetActiveRendererURLImpl.
19// The Keys are stored in a static dictionary and methods are provided to
20// verify correctness.
21class MockBreakpadKeyValueStore {
22 public:
23  MockBreakpadKeyValueStore() {
24    // Only one of these objects can be active at once.
25    DCHECK(dict == NULL);
26    dict = [[NSMutableDictionary alloc] init];
27  }
28
29  ~MockBreakpadKeyValueStore() {
30    // Only one of these objects can be active at once.
31    DCHECK(dict != NULL);
32    [dict release];
33    dict = NULL;
34  }
35
36  static void SetKeyValue(NSString* key, NSString* value) {
37    DCHECK(dict != NULL);
38    [dict setObject:value forKey:key];
39  }
40
41  static void ClearKeyValue(NSString *key) {
42    DCHECK(dict != NULL);
43    [dict removeObjectForKey:key];
44  }
45
46  int CountDictionaryEntries() {
47    return [dict count];
48  }
49
50  bool VerifyDictionaryContents(const std::string &url) {
51    using child_process_logging::kMaxNumCrashURLChunks;
52    using child_process_logging::kMaxNumURLChunkValueLength;
53    using child_process_logging::kUrlChunkFormatStr;
54
55    int num_url_chunks = CountDictionaryEntries();
56    EXPECT_TRUE(num_url_chunks <= kMaxNumCrashURLChunks);
57
58    NSString *kUrlChunkFormatStr_utf8 = [NSString
59        stringWithUTF8String:kUrlChunkFormatStr];
60
61    NSString *accumulated_url = @"";
62    for (int i = 0; i < num_url_chunks; ++i) {
63      // URL chunk names are 1-based.
64      NSString *key = [NSString stringWithFormat:kUrlChunkFormatStr_utf8, i+1];
65      EXPECT_TRUE(key != NULL);
66      NSString *value = [dict objectForKey:key];
67      EXPECT_TRUE([value length] > 0);
68      EXPECT_TRUE([value length] <= (unsigned)kMaxNumURLChunkValueLength);
69      accumulated_url = [accumulated_url stringByAppendingString:value];
70    }
71
72    NSString *expected_url = [NSString stringWithUTF8String:url.c_str()];
73    return([accumulated_url isEqualToString:expected_url]);
74  }
75
76 private:
77  static NSMutableDictionary* dict;
78  DISALLOW_COPY_AND_ASSIGN(MockBreakpadKeyValueStore);
79};
80
81// static
82NSMutableDictionary* MockBreakpadKeyValueStore::dict;
83
84}  // namespace
85
86// Call through to SetActiveURLImpl using the functions from
87// MockBreakpadKeyValueStore.
88void SetActiveURLWithMock(const GURL& url) {
89  using child_process_logging::SetActiveURLImpl;
90
91  SetCrashKeyValueFuncPtr setFunc = MockBreakpadKeyValueStore::SetKeyValue;
92  ClearCrashKeyValueFuncPtr clearFunc =
93      MockBreakpadKeyValueStore::ClearKeyValue;
94
95  SetActiveURLImpl(url, setFunc, clearFunc);
96}
97
98TEST_F(ChildProcessLoggingTest, TestUrlSplitting) {
99  using child_process_logging::kMaxNumCrashURLChunks;
100  using child_process_logging::kMaxNumURLChunkValueLength;
101
102  const std::string short_url("http://abc/");
103  std::string long_url("http://");
104  std::string overflow_url("http://");
105
106  long_url += std::string(kMaxNumURLChunkValueLength * 2, 'a');
107  long_url += "/";
108
109  int max_num_chars_stored_in_dump = kMaxNumURLChunkValueLength *
110      kMaxNumCrashURLChunks;
111  overflow_url += std::string(max_num_chars_stored_in_dump + 1, 'a');
112  overflow_url += "/";
113
114  // Check that Clearing NULL URL works.
115  MockBreakpadKeyValueStore mock;
116  SetActiveURLWithMock(GURL());
117  EXPECT_EQ(mock.CountDictionaryEntries(), 0);
118
119  // Check that we can set a URL.
120  SetActiveURLWithMock(GURL(short_url.c_str()));
121  EXPECT_TRUE(mock.VerifyDictionaryContents(short_url));
122  EXPECT_EQ(mock.CountDictionaryEntries(), 1);
123  SetActiveURLWithMock(GURL());
124  EXPECT_EQ(mock.CountDictionaryEntries(), 0);
125
126  // Check that we can replace a long url with a short url.
127  SetActiveURLWithMock(GURL(long_url.c_str()));
128  EXPECT_TRUE(mock.VerifyDictionaryContents(long_url));
129  SetActiveURLWithMock(GURL(short_url.c_str()));
130  EXPECT_TRUE(mock.VerifyDictionaryContents(short_url));
131  SetActiveURLWithMock(GURL());
132  EXPECT_EQ(mock.CountDictionaryEntries(), 0);
133
134
135  // Check that overflow works correctly.
136  SetActiveURLWithMock(GURL(overflow_url.c_str()));
137  EXPECT_TRUE(mock.VerifyDictionaryContents(
138      overflow_url.substr(0, max_num_chars_stored_in_dump)));
139  SetActiveURLWithMock(GURL());
140  EXPECT_EQ(mock.CountDictionaryEntries(), 0);
141}
142