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.
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
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
22 maximum_batch_size
= multiprocessing
.cpu_count() * 2
23 super(HistoryProfileExtender
, self
).__init
__(maximum_batch_size
)
25 # A list of paths of temporary files. The instance is responsible for
26 # making sure that the files are deleted before they are removed from this
28 self
._generated
_temp
_files
= []
30 def _MakeTemporaryFile(self
):
31 """Makes a temporary file and returns a URI to the file.
33 This method has the side effect of appending the temporary file to
34 self._generated_temp_files. The instance is responsible for deleting the
35 file at a later point in time.
37 # Adding a long suffix to the name of the file fills up the history
38 # database faster. The suffix can't be too long, since some file systems
39 # have a 256 character limit on the length of the path. While we could
40 # dynamically vary the length of the path, that would generate different
41 # profiles on different OSes, which is not ideal.
42 suffix
= "reallylongsuffixintendedtoartificiallyincreasethelengthoftheurl"
44 # Neither tempfile.TemporaryFile() nor tempfile.NamedTemporaryFile() work
45 # well here. The former doesn't work at all, since it doesn't gaurantee a
46 # file-system visible path. The latter doesn't work well, since the
47 # returned file cannot be opened a second time on Windows. The returned
48 # file would have to be closed, and the method would need to be called with
49 # Delete=False, which makes its functionality no simpler than
51 handle
, path
= tempfile
.mkstemp(suffix
=suffix
)
53 self
._generated
_temp
_files
.append(path
)
55 file_url
= "file://" + path
58 def GetUrlIterator(self
):
59 """Superclass override."""
61 yield self
._MakeTemporaryFile
()
63 def ShouldExitAfterBatchNavigation(self
):
64 """Superclass override."""
65 return self
._IsHistoryDBAtMaxSize
()
68 """Superclass override."""
69 super(HistoryProfileExtender
, self
).TearDown()
70 for path
in self
._generated
_temp
_files
:
72 self
._generated
_temp
_files
= []
74 def CleanUpAfterBatchNavigation(self
):
75 """Superclass override."""
76 for path
in self
._generated
_temp
_files
:
78 self
._generated
_temp
_files
= []
80 def _IsHistoryDBAtMaxSize(self
):
81 """Whether the history DB has reached its maximum size."""
82 history_db_path
= os
.path
.join(self
.profile_path
, "Default", "History")
83 stat_info
= os
.stat(history_db_path
)
84 size
= stat_info
.st_size
86 max_size_threshold
= 0.95
87 bytes_in_megabyte
= 2**20
88 max_size
= (bytes_in_megabyte
*
89 HistoryProfileExtender
._HISTORY
_DB
_MAX
_SIZE
_IN
_MB
* max_size_threshold
)
90 return size
> max_size