2 # ***** BEGIN LICENSE BLOCK *****
3 # This Source Code Form is subject to the terms of the Mozilla Public
4 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 # You can obtain one at http://mozilla.org/MPL/2.0/.
6 # ***** END LICENSE BLOCK *****
9 Runs a thing to see if it crashes within a set period.
18 sys
.path
.insert(1, os
.path
.dirname(sys
.path
[0]))
22 from mozharness
.base
.script
import BaseScript
25 class DoesItCrash(BaseScript
):
35 "help": "An URL that points to a package containing the thing to run",
44 "dest": "thing_to_run",
46 "help": "The thing to run. If --thing-url is a package, this should be "
47 "its location relative to the root of the package.",
59 "help": "Args for the thing. May be passed multiple times",
71 "help": "How long to run the thing for, in seconds",
77 super(DoesItCrash
, self
).__init
__(
86 config_options
=self
.config_options
,
89 def downloadFile(self
, url
, file_name
):
90 req
= requests
.get(url
, stream
=True, timeout
=30)
91 file_path
= os
.path
.join(os
.getcwd(), file_name
)
93 with
open(file_path
, "wb") as f
:
94 for chunk
in req
.iter_content(chunk_size
=1024):
102 url
= self
.config
["thing_url"]
103 fn
= "thing." + url
.split(".")[-1]
104 self
.downloadFile(url
=url
, file_name
=fn
)
105 if mozinstall
.is_installer(fn
):
106 self
.install_dir
= mozinstall
.install(fn
, "thing")
108 self
.install_dir
= ""
110 def kill(self
, proc
):
111 is_win
= os
.name
== "nt"
112 for retry
in range(3):
114 proc
.send_signal(signal
.CTRL_BREAK_EVENT
)
116 os
.killpg(proc
.pid
, signal
.SIGKILL
)
119 self
.log("process terminated")
121 except subprocess
.TimeoutExpired
:
122 self
.error("unable to terminate process!")
125 self
.timed_out
= False
127 def timeout_handler(proc
):
128 self
.log(f
"timeout detected: killing pid {proc.pid}")
129 self
.timed_out
= True
134 def output_line_handler(proc
, line
):
135 self
.output
.append(line
)
137 thing
= os
.path
.abspath(
138 os
.path
.join(self
.install_dir
, self
.config
["thing_to_run"])
140 # thing_args is a LockedTuple, which mozprocess doesn't like
141 args
= list(self
.config
["thing_args"])
142 timeout
= self
.config
["run_for"]
144 self
.log(f
"Running {thing} with args {args}")
147 mozprocess
.run_and_wait(
150 timeout_handler
=timeout_handler
,
151 output_line_handler
=output_line_handler
,
153 if not self
.timed_out
:
156 f
"TEST-UNEXPECTED-FAIL: {thing} did not run for {timeout} seconds"
158 self
.critical("Output was:")
159 for l
in self
.output
:
163 self
.info(f
"PASS: {thing} ran successfully for {timeout} seconds")
167 if __name__
== "__main__":
168 crashit
= DoesItCrash()
169 crashit
.run_and_exit()