1 # This Source Code Form is subject to the terms of the Mozilla Public
2 # License, v. 2.0. If a copy of the MPL was not distributed with this
3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 from __future__
import absolute_import
, unicode_literals
12 from mozbuild
.base
import (
14 MachCommandConditions
as conditions
,
17 from mach
.decorators
import (
27 def setup_awsy_argument_parser():
28 from marionette_harness
.runtests
import MarionetteArguments
29 from mozlog
.structured
import commandline
31 parser
= MarionetteArguments()
32 commandline
.add_logging_group(parser
)
38 class MachCommands(MachCommandBase
):
39 AWSY_PATH
= os
.path
.dirname(os
.path
.realpath(__file__
))
40 if AWSY_PATH
not in sys
.path
:
41 sys
.path
.append(AWSY_PATH
)
42 from awsy
import ITERATIONS
, PER_TAB_PAUSE
, SETTLE_WAIT_TIME
, MAX_TABS
44 def run_awsy(self
, tests
, binary
=None, **kwargs
):
46 from mozlog
.structured
import commandline
48 from marionette_harness
.runtests
import (
53 parser
= setup_awsy_argument_parser()
55 awsy_source_dir
= os
.path
.join(self
.topsrcdir
, 'testing', 'awsy')
57 tests
= [os
.path
.join(awsy_source_dir
,
59 'test_memory_usage.py')]
61 args
= argparse
.Namespace(tests
=tests
)
66 kwargs
['entities'] = 3
67 kwargs
['iterations'] = 1
68 kwargs
['perTabPause'] = 1
69 kwargs
['settleWaitTime'] = 1
71 if 'single_stylo_traversal' in kwargs
and kwargs
['single_stylo_traversal']:
72 os
.environ
['STYLO_THREADS'] = '1'
74 os
.environ
['STYLO_THREADS'] = '4'
77 for arg
in ('webRootDir', 'pageManifest', 'resultsDir', 'entities', 'iterations',
78 'perTabPause', 'settleWaitTime', 'maxTabs', 'dmd', 'tp6'):
79 if arg
in kwargs
and kwargs
[arg
] is not None:
80 runtime_testvars
[arg
] = kwargs
[arg
]
82 if 'webRootDir' not in runtime_testvars
:
83 awsy_tests_dir
= os
.path
.join(self
.topobjdir
, '_tests', 'awsy')
84 web_root_dir
= os
.path
.join(awsy_tests_dir
, 'html')
85 runtime_testvars
['webRootDir'] = web_root_dir
87 web_root_dir
= runtime_testvars
['webRootDir']
88 awsy_tests_dir
= os
.path
.dirname(web_root_dir
)
90 if 'resultsDir' not in runtime_testvars
:
91 runtime_testvars
['resultsDir'] = os
.path
.join(awsy_tests_dir
,
94 runtime_testvars
['bin'] = binary
95 runtime_testvars
['run_local'] = True
97 page_load_test_dir
= os
.path
.join(web_root_dir
, 'page_load_test')
98 if not os
.path
.isdir(page_load_test_dir
):
99 os
.makedirs(page_load_test_dir
)
101 if not os
.path
.isdir(runtime_testvars
['resultsDir']):
102 os
.makedirs(runtime_testvars
['resultsDir'])
104 runtime_testvars_path
= os
.path
.join(awsy_tests_dir
, 'runtime-testvars.json')
105 if kwargs
['testvars']:
106 kwargs
['testvars'].append(runtime_testvars_path
)
108 kwargs
['testvars'] = [runtime_testvars_path
]
110 runtime_testvars_file
= open(runtime_testvars_path
, 'wb')
111 runtime_testvars_file
.write(json
.dumps(runtime_testvars
, indent
=2))
112 runtime_testvars_file
.close()
114 manifest_file
= os
.path
.join(awsy_source_dir
,
115 'tp5n-pageset.manifest')
116 tooltool_args
= {'args': [
118 os
.path
.join(self
.topsrcdir
, 'mach'),
119 'artifact', 'toolchain', '-v',
120 '--tooltool-manifest=%s' % manifest_file
,
121 '--cache-dir=%s' % os
.path
.join(self
.topsrcdir
, 'tooltool-cache'),
123 self
.run_process(cwd
=page_load_test_dir
, **tooltool_args
)
124 tp5nzip
= os
.path
.join(page_load_test_dir
, 'tp5n.zip')
125 tp5nmanifest
= os
.path
.join(page_load_test_dir
, 'tp5n', 'tp5n.manifest')
126 if not os
.path
.exists(tp5nmanifest
):
127 unzip_args
= {'args': [
135 self
.run_process(**unzip_args
)
136 except Exception as exc
:
138 if mozinfo
.os
== 'win':
139 troubleshoot
= ' Try using --web-root to specify a ' \
140 'directory closer to the drive root.'
142 self
.log(logging
.ERROR
, 'awsy',
143 {'directory': page_load_test_dir
, 'exception': exc
},
144 'Failed to unzip `tp5n.zip` into '
145 '`{directory}` with `{exception}`.' + troubleshoot
)
148 # If '--preferences' was not specified supply our default set.
149 if not kwargs
['prefs_files']:
150 kwargs
['prefs_files'] = [os
.path
.join(awsy_source_dir
, 'conf', 'prefs.json')]
152 # Setup DMD env vars if necessary.
154 bin_dir
= os
.path
.dirname(binary
)
156 if 'DMD' not in os
.environ
:
157 os
.environ
['DMD'] = '1'
159 # Work around a startup crash with DMD on windows
160 if mozinfo
.os
== 'win':
161 kwargs
['pref'] = 'security.sandbox.content.level:0'
162 self
.log(logging
.WARNING
, 'awsy', {},
163 'Forcing \'security.sandbox.content.level\' = 0 because DMD is enabled.')
164 elif mozinfo
.os
== 'mac':
165 # On mac binary is in MacOS and dmd.py is in Resources, ie:
166 # Name.app/Contents/MacOS/libdmd.dylib
167 # Name.app/Contents/Resources/dmd.py
168 bin_dir
= os
.path
.join(bin_dir
, "../Resources/")
170 # Also add the bin dir to the python path so we can use dmd.py
171 if bin_dir
not in sys
.path
:
172 sys
.path
.append(bin_dir
)
174 for k
, v
in kwargs
.iteritems():
177 parser
.verify_usage(args
)
179 args
.logger
= commandline
.setup_logging('Are We Slim Yet Tests',
181 {'mach': sys
.stdout
})
182 failed
= MarionetteHarness(MarionetteTestRunner
, args
=vars(args
)).run()
188 @Command('awsy-test', category
='testing',
189 description
='Run Are We Slim Yet (AWSY) memory usage testing using marionette.',
190 parser
=setup_awsy_argument_parser
,
192 @CommandArgumentGroup('AWSY')
193 @CommandArgument('--web-root', group
='AWSY', action
='store', type=str,
195 help='Path to web server root directory. If not specified, '
196 'defaults to topobjdir/_tests/awsy/html.')
197 @CommandArgument('--page-manifest', group
='AWSY', action
='store', type=str,
199 help='Path to page manifest text file containing a list '
200 'of urls to test. The urls must be served from localhost. If not '
201 'specified, defaults to page_load_test/tp5n/tp5n.manifest under '
203 @CommandArgument('--results', group
='AWSY', action
='store', type=str,
205 help='Path to results directory. If not specified, defaults '
206 'to the parent directory of the web root.')
207 @CommandArgument('--quick', group
='AWSY', action
='store_true',
208 dest
='quick', default
=False,
209 help='Set --entities=3, --iterations=1, --per-tab-pause=1, '
210 '--settle-wait-time=1 for a quick test. Overrides any explicit '
211 'argument settings.')
212 @CommandArgument('--entities', group
='AWSY', action
='store', type=int,
214 help='Number of urls to load. Defaults to the total number of '
216 @CommandArgument('--max-tabs', group
='AWSY', action
='store', type=int,
218 help='Maximum number of tabs to open. '
219 'Defaults to %s.' % MAX_TABS
)
220 @CommandArgument('--iterations', group
='AWSY', action
='store', type=int,
222 help='Number of times to run through the test suite. '
223 'Defaults to %s.' % ITERATIONS
)
224 @CommandArgument('--per-tab-pause', group
='AWSY', action
='store', type=int,
226 help='Seconds to wait in between opening tabs. '
227 'Defaults to %s.' % PER_TAB_PAUSE
)
228 @CommandArgument('--settle-wait-time', group
='AWSY', action
='store', type=int,
229 dest
='settleWaitTime',
230 help='Seconds to wait for things to settled down. '
231 'Defaults to %s.' % SETTLE_WAIT_TIME
)
232 @CommandArgument('--dmd', group
='AWSY', action
='store_true',
233 dest
='dmd', default
=False,
234 help='Enable DMD during testing. Requires a DMD-enabled build.')
235 @CommandArgument('--tp6', group
='AWSY', action
='store_true',
236 dest
='tp6', default
=False,
237 help='Use the tp6 pageset during testing.')
238 def run_awsy_test(self
, tests
, **kwargs
):
239 """mach awsy-test runs the in-tree version of the Are We Slim Yet
242 awsy-test is implemented as a marionette test and marionette
243 test arguments also apply although they are not necessary
244 since reasonable defaults will be chosen.
246 The AWSY specific arguments can be found in the Command
247 Arguments for AWSY section below.
249 awsy-test will automatically download the tp5n.zip talos
250 pageset from tooltool and install it under
251 topobjdir/_tests/awsy/html. You can specify your own page set
252 by specifying --web-root and --page-manifest.
254 The results of the test will be placed in the results
255 directory specified by the --results argument.
257 On Windows, you may experience problems due to path length
258 errors when extracting the tp5n.zip file containing the
259 test pages or when attempting to write checkpoints to the
260 results directory. In that case, you should specify both
261 the --web-root and --results arguments pointing to a location
262 with a short path. For example:
264 --web-root=c:\\\\tmp\\\\html --results=c:\\\\tmp\\\\results
266 Note that the double backslashes are required.
268 kwargs
['logger_name'] = 'Awsy Tests'
269 if 'test_objects' in kwargs
:
271 for obj
in kwargs
['test_objects']:
272 tests
.append(obj
['file_relpath'])
273 del kwargs
['test_objects']
275 if not kwargs
.get('binary') and conditions
.is_firefox(self
):
276 kwargs
['binary'] = self
.get_binary_path('app')
277 return self
.run_awsy(tests
, **kwargs
)