Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / tools / perf / profile_creators / history_profile_extender.py
blobf68548f31ae57bb6c913511d7fc7e3dce0cb486b
1 # Copyright 2015 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 import multiprocessing
5 import os
6 import tempfile
8 from profile_creators import fast_navigation_profile_extender
11 class HistoryProfileExtender(
12 fast_navigation_profile_extender.FastNavigationProfileExtender):
13 """This extender navigates Chrome to a large number of URIs pointing to local
14 files. It continues running until the history DB becomes full."""
15 _HISTORY_DB_MAX_SIZE_IN_MB = 10
17 def __init__(self, finder_options):
18 # The rate limiting factors are the speed of page navigation, and the speed
19 # of python bindings. The former is larger than the latter, so having a
20 # large batch size skews the amortized average time per page load towards
21 # the latter.
22 maximum_batch_size = multiprocessing.cpu_count() * 2
23 super(HistoryProfileExtender, self).__init__(
24 finder_options, maximum_batch_size)
26 # A list of paths of temporary files. The instance is responsible for
27 # making sure that the files are deleted before they are removed from this
28 # list.
29 self._generated_temp_files = []
31 def _MakeTemporaryFile(self):
32 """Makes a temporary file and returns a URI to the file.
34 This method has the side effect of appending the temporary file to
35 self._generated_temp_files. The instance is responsible for deleting the
36 file at a later point in time.
37 """
38 # Adding a long suffix to the name of the file fills up the history
39 # database faster. The suffix can't be too long, since some file systems
40 # have a 256 character limit on the length of the path. While we could
41 # dynamically vary the length of the path, that would generate different
42 # profiles on different OSes, which is not ideal.
43 suffix = "reallylongsuffixintendedtoartificiallyincreasethelengthoftheurl"
45 # Neither tempfile.TemporaryFile() nor tempfile.NamedTemporaryFile() work
46 # well here. The former doesn't work at all, since it doesn't gaurantee a
47 # file-system visible path. The latter doesn't work well, since the
48 # returned file cannot be opened a second time on Windows. The returned
49 # file would have to be closed, and the method would need to be called with
50 # Delete=False, which makes its functionality no simpler than
51 # tempfile.mkstemp().
52 handle, path = tempfile.mkstemp(suffix=suffix)
53 os.close(handle)
54 self._generated_temp_files.append(path)
56 file_url = "file://" + path
57 return file_url
59 def GetUrlIterator(self):
60 """Superclass override."""
61 while True:
62 yield self._MakeTemporaryFile()
64 def ShouldExitAfterBatchNavigation(self):
65 """Superclass override."""
66 return self._IsHistoryDBAtMaxSize()
68 def TearDownBrowser(self):
69 """Superclass override."""
70 super(HistoryProfileExtender, self).TearDownBrowser()
71 for path in self._generated_temp_files:
72 os.remove(path)
73 self._generated_temp_files = []
75 def CleanUpAfterBatchNavigation(self):
76 """Superclass override."""
77 for path in self._generated_temp_files:
78 os.remove(path)
79 self._generated_temp_files = []
81 def _IsHistoryDBAtMaxSize(self):
82 """Whether the history DB has reached its maximum size."""
83 history_db_path = os.path.join(self.profile_path, "Default", "History")
84 stat_info = os.stat(history_db_path)
85 size = stat_info.st_size
87 max_size_threshold = 0.95
88 bytes_in_megabyte = 2**20
89 max_size = (bytes_in_megabyte *
90 HistoryProfileExtender._HISTORY_DB_MAX_SIZE_IN_MB * max_size_threshold)
91 return size > max_size