summaryrefslogtreecommitdiffstats
path: root/webkit/tools/test_shell
diff options
context:
space:
mode:
authorager@chromium.org <ager@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-12 09:18:06 +0000
committerager@chromium.org <ager@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-12 09:18:06 +0000
commit7423cb33e329bb72843a8a4ce959b3faf76789d3 (patch)
tree920923c7fb7e2a1749dca28aa300479eeb8d47fe /webkit/tools/test_shell
parenta104f5d38f25ef2eae8fa92ac11982ca36097bb6 (diff)
downloadchromium_src-7423cb33e329bb72843a8a4ce959b3faf76789d3.zip
chromium_src-7423cb33e329bb72843a8a4ce959b3faf76789d3.tar.gz
chromium_src-7423cb33e329bb72843a8a4ce959b3faf76789d3.tar.bz2
Land Vitaly's regression test for event listener memory leak.
BUG=17400 Review URL: http://codereview.chromium.org/164318 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@23181 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/tools/test_shell')
-rw-r--r--webkit/tools/test_shell/listener_leak_test.cc78
-rw-r--r--webkit/tools/test_shell/node_leak_test.cc5
-rw-r--r--webkit/tools/test_shell/run_all_tests.cc8
-rw-r--r--webkit/tools/test_shell/test_shell.gyp1
4 files changed, 87 insertions, 5 deletions
diff --git a/webkit/tools/test_shell/listener_leak_test.cc b/webkit/tools/test_shell/listener_leak_test.cc
new file mode 100644
index 0000000..7064f77
--- /dev/null
+++ b/webkit/tools/test_shell/listener_leak_test.cc
@@ -0,0 +1,78 @@
+// 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 "base/file_path.h"
+#include "base/file_util.h"
+#include "base/path_service.h"
+#include "base/string_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "v8/include/v8.h"
+#include "webkit/glue/webkit_glue.h"
+#include "webkit/tools/test_shell/test_shell.h"
+#include "webkit/tools/test_shell/test_shell_test.h"
+
+static const char kHeapSampleBegin[] = "heap-sample-begin,";
+static const char kHeapObjectLogEntryPrefix[] = "\nheap-js-cons-item,";
+static const char kHeapObjectLogEntrySuffix[] = ",";
+
+class ListenerLeakTest : public TestShellTest {
+};
+
+static std::string GetV8Log(int skip) {
+ std::string v8_log;
+ char buf[1024];
+ int read_size;
+ do {
+ read_size = v8::V8::GetLogLines(skip + static_cast<int>(v8_log.size()),
+ buf, sizeof(buf));
+ v8_log.append(buf, read_size);
+ } while (read_size > 0);
+ return v8_log;
+}
+
+static int GetNumObjects(int log_skip, const std::string& constructor) {
+ std::string v8_log = GetV8Log(log_skip);
+ size_t sample_begin = v8_log.rfind(kHeapSampleBegin);
+ CHECK(sample_begin != std::string::npos);
+ std::string log_entry =
+ kHeapObjectLogEntryPrefix + constructor + kHeapObjectLogEntrySuffix;
+ size_t i = v8_log.find(log_entry, sample_begin);
+ if (i == std::string::npos) return 0;
+ i += log_entry.size();
+ size_t j = v8_log.find(",", i);
+ CHECK(j != std::string::npos);
+ int num_objects;
+ CHECK(StringToInt(v8_log.substr(i, j - i), &num_objects));
+ return num_objects;
+}
+
+// This test tries to create a reference cycle between node and its listener.
+// See http://crbug/17400.
+TEST_F(ListenerLeakTest, ReferenceCycle) {
+ const int log_skip = static_cast<int>(GetV8Log(0).size());
+ FilePath listener_file;
+ ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &listener_file));
+ listener_file = listener_file.Append(FILE_PATH_LITERAL("webkit"))
+ .Append(FILE_PATH_LITERAL("data"))
+ .Append(FILE_PATH_LITERAL("listener"))
+ .Append(FILE_PATH_LITERAL("listener_leak1.html"));
+ test_shell_->LoadURL(listener_file.ToWStringHack().c_str());
+ test_shell_->WaitTestFinished();
+ ASSERT_EQ(0, GetNumObjects(log_skip, "EventListenerLeakTestObject1"));
+}
+
+// This test sets node onclick many times to expose a possible memory
+// leak where all listeners get referenced by the node.
+TEST_F(ListenerLeakTest, HiddenReferences) {
+ const int log_skip = static_cast<int>(GetV8Log(0).size());
+ FilePath listener_file;
+ ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &listener_file));
+ listener_file = listener_file.Append(FILE_PATH_LITERAL("webkit"))
+ .Append(FILE_PATH_LITERAL("data"))
+ .Append(FILE_PATH_LITERAL("listener"))
+ .Append(FILE_PATH_LITERAL("listener_leak2.html"));
+ test_shell_->LoadURL(listener_file.ToWStringHack().c_str());
+ test_shell_->WaitTestFinished();
+ ASSERT_EQ(1, GetNumObjects(log_skip, "EventListenerLeakTestObject2"));
+}
diff --git a/webkit/tools/test_shell/node_leak_test.cc b/webkit/tools/test_shell/node_leak_test.cc
index dd87bef..7739efd 100644
--- a/webkit/tools/test_shell/node_leak_test.cc
+++ b/webkit/tools/test_shell/node_leak_test.cc
@@ -32,11 +32,6 @@ class NodeLeakTest : public TestShellTest {
virtual void SetUp() {
const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
- std::wstring js_flags =
- parsed_command_line.GetSwitchValue(test_shell::kJavaScriptFlags);
- js_flags += L" --expose-gc";
- webkit_glue::SetJavaScriptFlags(js_flags);
-
FilePath cache_path = FilePath::FromWStringHack(
parsed_command_line.GetSwitchValue(test_shell::kCacheDir));
if (cache_path.empty()) {
diff --git a/webkit/tools/test_shell/run_all_tests.cc b/webkit/tools/test_shell/run_all_tests.cc
index 2277c2a..94c08b7 100644
--- a/webkit/tools/test_shell/run_all_tests.cc
+++ b/webkit/tools/test_shell/run_all_tests.cc
@@ -26,6 +26,7 @@
#include "webkit/tools/test_shell/simple_resource_loader_bridge.h"
#include "webkit/tools/test_shell/test_shell.h"
#include "webkit/tools/test_shell/test_shell_platform_delegate.h"
+#include "webkit/tools/test_shell/test_shell_switches.h"
#include "webkit/tools/test_shell/test_shell_test.h"
#include "webkit/tools/test_shell/test_shell_webkit_init.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -58,6 +59,13 @@ int main(int argc, char* argv[]) {
const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
TestShellPlatformDelegate platform(parsed_command_line);
+ // Allow tests to analyze GC information from V8 log, and expose GC
+ // triggering function.
+ std::wstring js_flags =
+ parsed_command_line.GetSwitchValue(test_shell::kJavaScriptFlags);
+ js_flags += L" --logfile=* --log_gc --expose_gc";
+ webkit_glue::SetJavaScriptFlags(js_flags);
+
// Suppress error dialogs and do not show GP fault error box on Windows.
TestShell::InitLogging(true, false, false);
diff --git a/webkit/tools/test_shell/test_shell.gyp b/webkit/tools/test_shell/test_shell.gyp
index 7509cb9..8bd938f 100644
--- a/webkit/tools/test_shell/test_shell.gyp
+++ b/webkit/tools/test_shell/test_shell.gyp
@@ -506,6 +506,7 @@
'image_decoder_unittest.h',
'keyboard_unittest.cc',
'layout_test_controller_unittest.cc',
+ 'listener_leak_test.cc',
'media_leak_test.cc',
'node_leak_test.cc',
'plugin_tests.cc',