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
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
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
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.
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
52 handle
, path
= tempfile
.mkstemp(suffix
=suffix
)
54 self
._generated
_temp
_files
.append(path
)
56 file_url
= "file://" + path
59 def GetUrlIterator(self
):
60 """Superclass override."""
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
:
73 self
._generated
_temp
_files
= []
75 def CleanUpAfterBatchNavigation(self
):
76 """Superclass override."""
77 for path
in self
._generated
_temp
_files
:
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