| Index: tools/perf/profile_creators/cookie_profile_extender.py
|
| diff --git a/tools/perf/profile_creators/cookie_profile_extender.py b/tools/perf/profile_creators/cookie_profile_extender.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..854e96978b70cc7b73be457a1d98d9b29c79a61c
|
| --- /dev/null
|
| +++ b/tools/perf/profile_creators/cookie_profile_extender.py
|
| @@ -0,0 +1,68 @@
|
| +# Copyright 2015 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.
|
| +import multiprocessing
|
| +import os
|
| +import sqlite3
|
| +
|
| +from profile_creators import fast_navigation_profile_extender
|
| +from profile_creators import profile_safe_url_list
|
| +
|
| +class CookieProfileExtender(
|
| + fast_navigation_profile_extender.FastNavigationProfileExtender):
|
| + """This extender performs a large number of navigations (up to 500), with the
|
| + goal of filling out the cookie database.
|
| +
|
| + By default, Chrome purges the cookie DB down to 3300 cookies. However, it
|
| + won't purge cookies accessed in the last month. This means the extender needs
|
| + to be careful not to create an artificially high number of cookies.
|
| + """
|
| + _COOKIE_DB_EXPECTED_SIZE = 3300
|
| +
|
| + def __init__(self):
|
| + # The rate limiting factors are fetching network resources and executing
|
| + # javascript. There's not much to be done about the former, and having one
|
| + # tab per logical core appears close to optimum for the latter.
|
| + maximum_batch_size = multiprocessing.cpu_count()
|
| + super(CookieProfileExtender, self).__init__(maximum_batch_size)
|
| +
|
| + # A list of urls that have not yet been navigated to. This list will shrink
|
| + # over time. Each navigation will add a diminishing number of new cookies,
|
| + # since there's a high probability that the cookie is already present. If
|
| + # the cookie DB isn't full by 500 navigations, just give up.
|
| + self._navigation_urls = profile_safe_url_list.GetShuffledSafeUrls()[0:500]
|
| +
|
| + def GetUrlIterator(self):
|
| + """Superclass override."""
|
| + return iter(self._navigation_urls)
|
| +
|
| + def ShouldExitAfterBatchNavigation(self):
|
| + """Superclass override."""
|
| + return self._IsCookieDBFull()
|
| +
|
| + @staticmethod
|
| + def _CookieCountInDB(db_path):
|
| + """The number of cookies in the db at |db_path|."""
|
| + connection = sqlite3.connect(db_path)
|
| + try:
|
| + cursor = connection.cursor()
|
| + cursor.execute("select count(*) from cookies")
|
| + cookie_count = cursor.fetchone()[0]
|
| + except:
|
| + raise
|
| + finally:
|
| + connection.close()
|
| + return cookie_count
|
| +
|
| + def _IsCookieDBFull(self):
|
| + """Chrome does not immediately flush cookies to its database. It's possible
|
| + that this method will return a false negative."""
|
| + cookie_db_path = os.path.join(self.profile_path, "Default", "Cookies")
|
| + try:
|
| + cookie_count = CookieProfileExtender._CookieCountInDB(cookie_db_path)
|
| + except sqlite3.OperationalError:
|
| + # There will occasionally be contention for the SQLite database. This
|
| + # shouldn't happen often, so ignore the errors.
|
| + return False
|
| +
|
| + return cookie_count > CookieProfileExtender._COOKIE_DB_EXPECTED_SIZE
|
|
|