summaryrefslogtreecommitdiffstats
path: root/webkit/tools/leak_tests
diff options
context:
space:
mode:
authorinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-27 00:20:51 +0000
committerinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-27 00:20:51 +0000
commitf5b16fed647e941aa66933178da85db2860d639b (patch)
treef00e9856c04aad3b558a140955e7674add33f051 /webkit/tools/leak_tests
parent920c091ac3ee15079194c82ae8a7a18215f3f23c (diff)
downloadchromium_src-f5b16fed647e941aa66933178da85db2860d639b.zip
chromium_src-f5b16fed647e941aa66933178da85db2860d639b.tar.gz
chromium_src-f5b16fed647e941aa66933178da85db2860d639b.tar.bz2
Add webkit to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/tools/leak_tests')
-rw-r--r--webkit/tools/leak_tests/run_node_leak_test.py303
-rw-r--r--webkit/tools/leak_tests/test_lists/alexa_100.txt92
2 files changed, 395 insertions, 0 deletions
diff --git a/webkit/tools/leak_tests/run_node_leak_test.py b/webkit/tools/leak_tests/run_node_leak_test.py
new file mode 100644
index 0000000..3d5a815
--- /dev/null
+++ b/webkit/tools/leak_tests/run_node_leak_test.py
@@ -0,0 +1,303 @@
+#!/bin/env python
+# Copyright 2008, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Run node leak tests using the test_shell.
+
+TODO(pjohnson): Add a way for layout tests (and other local files in the
+working copy) to be easily run by specifying paths relative to webkit (or
+something similar).
+"""
+
+import logging
+import optparse
+import os
+import random
+import re
+import sys
+
+import google.logging_utils
+import google.path_utils
+import google.platform_utils
+import google.process_utils
+
+# Magic exit code to indicate a new fix.
+REBASELINE_EXIT_CODE = -88
+
+# Status codes.
+PASS, FAIL, REBASELINE = range(3)
+
+# The test list files are found in this subdirectory, which must be a sibling
+# to this script itself.
+TEST_FILE_DIR = 'test_lists'
+
+# TODO(pjohnson): Find a way to avoid this duplicate code. This function has
+# been shamelessly taken from layout_tests/layout_package.
+_webkit_root = None
+
+def WebKitRoot():
+ """Returns the full path to the directory containing webkit.sln. Raises
+ PathNotFound if we're unable to find webkit.sln.
+ """
+
+ global _webkit_root
+ if _webkit_root:
+ return _webkit_root
+ webkit_sln_path = google.path_utils.FindUpward(google.path_utils.ScriptDir(),
+ 'webkit.sln')
+ _webkit_root = os.path.dirname(webkit_sln_path)
+ return _webkit_root
+
+def GetAbsolutePath(path):
+ platform_util = google.platform_utils.PlatformUtility(WebKitRoot())
+ return platform_util.GetAbsolutePath(path)
+
+# TODO(pjohnson): Find a way to avoid this duplicated code. This function has
+# been mostly copied from another function, TestShellBinary, in
+# layout_tests/layout_package.
+def TestShellTestBinary(target):
+ """Gets the full path to the test_shell_tests binary for the target build
+ configuration. Raises PathNotFound if the file doesn't exist.
+ """
+
+ full_path = os.path.join(WebKitRoot(), target, 'test_shell_tests.exe')
+ if not os.path.exists(full_path):
+ # Try chrome's output directory in case test_shell was built by chrome.sln.
+ full_path = google.path_utils.FindUpward(WebKitRoot(), 'chrome', target,
+ 'test_shell_tests.exe')
+ if not os.path.exists(full_path):
+ raise PathNotFound('unable to find test_shell_tests at %s' % full_path)
+ return full_path
+
+class NodeLeakTestRunner:
+ """A class for managing running a series of node leak tests.
+ """
+
+ def __init__(self, options, urls):
+ """Collect a list of URLs to test.
+
+ Args:
+ options: a dictionary of command line options
+ urls: a list of URLs in the format:
+ (url, expected_node_leaks, expected_js_leaks) tuples
+ """
+
+ self._options = options
+ self._urls = urls
+
+ self._test_shell_test_binary = TestShellTestBinary(options.target)
+
+ self._node_leak_matcher = re.compile('LEAK: (\d+) Node')
+ self._js_leak_matcher = re.compile('Leak (\d+) JS wrappers')
+
+ def RunCommand(self, command):
+ def FindMatch(line, matcher, group_number):
+ match = matcher.match(line)
+ if match:
+ return int(match.group(group_number))
+ return 0
+
+ (code, output) = google.process_utils.RunCommandFull(command, verbose=True,
+ collect_output=True,
+ print_output=False)
+ node_leaks = 0
+ js_leaks = 0
+
+ # Print a row of dashes.
+ if code != 0:
+ print '-' * 75
+ print 'OUTPUT'
+ print
+
+ for line in output:
+ # Sometimes multiple leak lines are printed out, which is why we
+ # accumulate them here.
+ node_leaks += FindMatch(line, self._node_leak_matcher, 1)
+ js_leaks += FindMatch(line, self._js_leak_matcher, 1)
+
+ # If the code indicates there was an error, print the output to help
+ # figure out what happened.
+ if code != 0:
+ print line
+
+ # Print a row of dashes.
+ if code != 0:
+ print '-' * 75
+ print
+
+ return (code, node_leaks, js_leaks)
+
+ def RunUrl(self, test_url, expected_node_leaks, expected_js_leaks):
+ shell_args = ['--gtest_filter=NodeLeakTest.*TestURL',
+ '--time-out-ms=' + str(self._options.time_out_ms),
+ '--test-url=' + test_url,
+ '--playback-mode']
+
+ if self._options.cache_dir != '':
+ shell_args.append('--cache-dir=' + self._options.cache_dir)
+
+ command = [self._test_shell_test_binary] + shell_args
+ (exit_code, actual_node_leaks, actual_js_leaks) = self.RunCommand(command)
+
+ logging.info('%s\n' % test_url)
+
+ if exit_code != 0:
+ # There was a crash, or something else went wrong, so duck out early.
+ logging.error('Test returned: %d\n' % exit_code)
+ return FAIL
+
+ result = ('TEST RESULT\n'
+ ' Node Leaks: %d (actual), %d (expected)\n'
+ ' JS Leaks: %d (actual), %d (expected)\n' %
+ (actual_node_leaks, expected_node_leaks,
+ actual_js_leaks, expected_js_leaks))
+
+ success = (actual_node_leaks <= expected_node_leaks and
+ actual_js_leaks <= expected_js_leaks)
+
+ if success:
+ logging.info(result)
+ else:
+ logging.error(result)
+ logging.error('Unexpected leaks found!\n')
+ return FAIL
+
+ if (expected_node_leaks > actual_node_leaks or
+ expected_js_leaks > actual_js_leaks):
+ logging.warn('Expectations may need to be re-baselined.\n')
+ # TODO(pjohnson): Return REBASELINE here once bug 1177263 is fixed and
+ # the expectations have been lowered again.
+
+ return PASS
+
+ def Run(self):
+ status = PASS
+ results = [0, 0, 0]
+ failed_urls = []
+ rebaseline_urls = []
+
+ for (test_url, expected_node_leaks, expected_js_leaks) in self._urls:
+ result = self.RunUrl(test_url, expected_node_leaks, expected_js_leaks)
+ if result == PASS:
+ results[PASS] += 1
+ elif result == FAIL:
+ results[FAIL] += 1
+ failed_urls.append(test_url)
+ status = FAIL
+ elif result == REBASELINE:
+ results[REBASELINE] += 1
+ rebaseline_urls.append(test_url)
+ if status != FAIL:
+ status = REBASELINE
+ return (status, results, failed_urls, rebaseline_urls)
+
+def main(options, args):
+ if options.seed != None:
+ random.seed(options.seed)
+
+ # Set up logging so any messages below logging.WARNING are sent to stdout,
+ # otherwise they are sent to stderr.
+ google.logging_utils.config_root(level=logging.INFO,
+ threshold=logging.WARNING)
+
+ if options.url_list == '':
+ logging.error('URL test list required')
+ sys.exit(1)
+
+ url_list = os.path.join(os.path.dirname(sys.argv[0]), TEST_FILE_DIR,
+ options.url_list)
+ url_list = GetAbsolutePath(url_list);
+
+ lines = []
+ file = None
+ try:
+ file = open(url_list, 'r')
+ lines = file.readlines()
+ finally:
+ if file != None:
+ file.close()
+
+ expected_matcher = re.compile('(\d+)\s*,\s*(\d+)')
+
+ urls = []
+ for line in lines:
+ line = line.strip()
+ if len(line) == 0 or line.startswith('#'):
+ continue
+ list = line.rsplit('=', 1)
+ if len(list) < 2:
+ logging.error('Line "%s" is not formatted correctly' % line)
+ continue
+ match = expected_matcher.match(list[1].strip())
+ if not match:
+ logging.error('Line "%s" is not formatted correctly' % line)
+ continue
+ urls.append((list[0].strip(), int(match.group(1)), int(match.group(2))))
+
+ random.shuffle(urls)
+ runner = NodeLeakTestRunner(options, urls)
+ (status, results, failed_urls, rebaseline_urls) = runner.Run()
+
+ logging.info('SUMMARY\n'
+ ' %d passed\n'
+ ' %d failed\n'
+ ' %d re-baseline\n' %
+ (results[0], results[1], results[2]))
+
+ if len(failed_urls) > 0:
+ failed_string = '\n'.join(' ' + url for url in failed_urls)
+ logging.error('FAILED URLs\n%s\n' % failed_string)
+
+ if len(rebaseline_urls) > 0:
+ rebaseline_string = '\n'.join(' ' + url for url in rebaseline_urls)
+ logging.warn('RE-BASELINE URLs\n%s\n' % rebaseline_string)
+
+ if status == FAIL:
+ return 1
+ elif status == REBASELINE:
+ return REBASELINE_EXIT_CODE
+ return 0
+
+if '__main__' == __name__:
+ option_parser = optparse.OptionParser()
+ option_parser.add_option('', '--target', default='Debug',
+ help='build target (Debug or Release)')
+ option_parser.add_option('', '--cache-dir', default='',
+ help='use a specified cache directory')
+ option_parser.add_option('', '--url-list', default='',
+ help='URL input file, with leak expectations, '
+ 'relative to webkit/tools/leak_tests')
+ option_parser.add_option('', '--time-out-ms', default=30000,
+ help='time out for each test')
+ option_parser.add_option('', '--seed', default=None,
+ help='seed for random number generator, use to '
+ 'reproduce the exact same order for a '
+ 'specific run')
+ options, args = option_parser.parse_args()
+ sys.exit(main(options, args))
diff --git a/webkit/tools/leak_tests/test_lists/alexa_100.txt b/webkit/tools/leak_tests/test_lists/alexa_100.txt
new file mode 100644
index 0000000..8c04a02
--- /dev/null
+++ b/webkit/tools/leak_tests/test_lists/alexa_100.txt
@@ -0,0 +1,92 @@
+# Format: URL = EXPECTED_NODE_LEAKS, EXPECTED_JS_LEAKS
+#
+# This is a list of the top 100 Alexa URLs (as of 3/28/2008) that loaded
+# successfully into our saved cache.
+#
+# Flaky URLs are covered by bug 1177263.
+# Since this test is so flaky, for now set the expected numbers very high to
+# catch only the most egregious regressions.
+
+http://www.yahoo.com = 200,200
+http://www.youtube.com = 200,200
+http://www.live.com = 200,200
+http://www.google.com = 200,200
+http://www.myspace.com = 200,200
+http://www.facebook.com = 200,200
+http://www.msn.com = 200,200
+http://www.hi5.com = 200,200
+http://www.wikipedia.org = 200,200
+http://www.orkut.com = 200,200
+http://www.blogger.com = 200,200
+http://www.fotolog.net = 200,200
+http://www.google.fr = 200,200
+http://www.friendster.com = 200,200
+http://www.microsoft.com = 200,200
+http://www.baidu.com = 200,200
+http://www.megarotic.com = 200,200
+http://www.google.cl = 200,200
+http://www.yahoo.co.jp = 200,200
+http://www.ebay.com = 200,200
+http://www.google.com.br = 200,200
+http://www.google.es = 200,200
+http://www.seznam.cz = 200,200
+http://www.google.com.mx = 200,200
+http://www.dailymotion.com = 200,200
+http://www.photobucket.com = 200,200
+http://www.youporn.com = 200,200
+http://www.imdb.com = 200,200
+http://www.google.pl = 200,200
+http://www.qq.com = 200,200
+http://www.google.co.uk = 200,200
+http://www.flickr.com = 200,200
+http://www.vkontakte.ru = 200,200
+http://www.nasza-klasa.pl = 200,200
+http://www.odnoklassniki.ru = 200,200
+http://www.google.de = 200,200
+http://www.metroflog.com = 200,200
+http://www.google.co.ve = 200,200
+http://www.google.com.ar = 200,200
+http://www.free.fr = 200,200
+http://www.wordpress.com = 200,200
+http://www.wretch.cc = 200,200
+http://www.mininova.org = 200,200
+http://www.onet.pl = 200,200
+http://www.google.com.pe = 200,200
+http://www.aol.com = 200,200
+http://www.google.com.co = 200,200
+http://www.allegro.pl = 200,200
+http://www.yandex.ru = 200,200
+http://www.deviantart.com = 200,200
+http://www.sina.com.cn = 200,200
+http://www.google.co.in = 200,200
+http://www.bbc.co.uk = 200,200
+http://www.google.ca = 200,200
+http://www.craigslist.org = 200,200
+http://www.google.sk = 200,200
+http://www.livejournal.com = 200,200
+http://www.iwiw.hu = 200,200
+http://www.google.com.vn = 200,200
+http://www.globo.com = 200,200
+http://www.wp.pl = 200,200
+http://www.netlog.com = 200,200
+http://www.perfspot.com = 200,200
+http://www.googlesyndication.com = 200,200
+http://www.google.it = 200,200
+http://www.google.co.hu = 200,200
+http://www.fc2.com = 200,200
+http://www.google.cn = 200,200
+http://www.ebay.fr = 200,200
+http://www.veoh.com = 200,200
+http://www.google.co.th = 200,200
+http://www.fotka.pl = 200,200
+http://www.orange.fr = 200,200
+http://www.google.com.tr = 200,200
+http://www.geocities.com = 200,200
+http://www.apple.com = 200,200
+http://www.onemanga.com = 200,200
+http://www.ebay.de = 200,200
+http://www.google.co.jp = 200,200
+http://www.taobao.com = 200,200
+http://www.megaflirt.com = 200,200
+http://www.ebay.co.uk = 200,200
+http://www.sexyono.com = 200,200