Skip to content

Commit

Permalink
Handle FFPuppet.InvalidPrefs exception
Browse files Browse the repository at this point in the history
  • Loading branch information
tysmith committed Jul 3, 2019
1 parent 7dfdada commit 8a82de1
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 30 deletions.
6 changes: 2 additions & 4 deletions grizzly/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,11 @@
import logging
import os

from ffpuppet import LaunchError

import grizzly.adapters
from .args import GrizzlyArgs
from .common import FilesystemReporter, FuzzManagerReporter, IOManager, S3FuzzManagerReporter
from .session import Session
from .target import load as load_target
from .target import load as load_target, TargetLaunchError, TargetLaunchTimeout


__author__ = "Tyson Smith"
Expand Down Expand Up @@ -165,7 +163,7 @@ def main(args):
except KeyboardInterrupt:
return Session.EXIT_ABORT

except LaunchError:
except (TargetLaunchError, TargetLaunchTimeout):
return Session.EXIT_LAUNCH_FAILURE

finally:
Expand Down
7 changes: 3 additions & 4 deletions grizzly/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@
import shutil
import tempfile

from ffpuppet import BrowserTerminatedError, BrowserTimeoutError

import sapphire
from .common import Status, TestFile
from .target import TargetLaunchError, TargetLaunchTimeout


__all__ = ("Session",)
Expand Down Expand Up @@ -120,13 +119,13 @@ def launch_target(self):
try:
log.info("Launching target")
self.target.launch(self.location)
except BrowserTerminatedError:
except TargetLaunchError:
# this result likely has nothing to do with Grizzly
self.status.results += 1
log.error("Launch error detected")
self.report_result()
raise
except BrowserTimeoutError:
except TargetLaunchTimeout:
launch_timeouts += 1
log.warning("Launch timeout detected (attempt #%d)", launch_timeouts)
# likely has nothing to do with Grizzly but is seen frequently on machines under a high load
Expand Down
4 changes: 2 additions & 2 deletions grizzly/target/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
import traceback
import pkg_resources

from .target import Target
from .target import Target, TargetError, TargetLaunchError, TargetLaunchTimeout

__all__ = ("Target", "available", "load")
__all__ = ("Target", "TargetError", "TargetLaunchError", "TargetLaunchTimeout", "available", "load")
__author__ = "Tyson Smith"
__credits__ = ["Tyson Smith", "Jesse Schwartzentruber"]
TARGETS = None
Expand Down
14 changes: 9 additions & 5 deletions grizzly/target/puppet_target.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@

import psutil

from ffpuppet import FFPuppet, LaunchError
from ffpuppet import BrowserTimeoutError, FFPuppet, LaunchError
from .target_monitor import TargetMonitor
from .target import Target
from .target import Target, TargetLaunchError, TargetLaunchTimeout, TargetError

__all__ = ("PuppetTarget",)
__author__ = "Tyson Smith"
Expand All @@ -28,7 +28,6 @@ def __init__(self, binary, extension, launch_timeout, log_limit, memory_limit, p
self.use_rr = kwds.pop("rr", False)
self.use_valgrind = kwds.pop("valgrind", False)
use_xvfb = kwds.pop("xvfb", False)

if kwds:
log.warning("PuppetTarget ignoring unsupported arguments: %s", ", ".join(kwds))

Expand Down Expand Up @@ -153,6 +152,8 @@ def dump_coverage(self):
os.kill(pid, signal.SIGUSR1)

def launch(self, location, env_mod=None):
if not self.prefs:
raise TargetError("A prefs.js file is required")
self.rl_countdown = self.rl_reset
env_mod = dict(env_mod or [])
# do not allow network connections to non local endpoints
Expand All @@ -168,9 +169,12 @@ def launch(self, location, env_mod=None):
prefs_js=self.prefs,
extension=self.extension,
env_mod=env_mod)
except LaunchError:
except LaunchError as exc:
log.error("FFPuppet Error: %s", str(exc))
self.close()
raise
if isinstance(exc, BrowserTimeoutError):
raise TargetLaunchTimeout(str(exc))
raise TargetLaunchError(str(exc))

def log_size(self):
return self._puppet.log_length("stderr") + self._puppet.log_length("stdout")
Expand Down
15 changes: 14 additions & 1 deletion grizzly/target/target.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,18 @@
log = logging.getLogger("grizzly") # pylint: disable=invalid-name


class TargetError(Exception):
"""Raised by Target"""


class TargetLaunchError(TargetError):
"""Raised if a failure during launch occurs"""


class TargetLaunchTimeout(TargetError):
"""Raised if the target does not launch within the defined amount of time"""


@six.add_metaclass(abc.ABCMeta)
class Target(object):
RESULT_NONE = 0
Expand All @@ -41,8 +53,9 @@ def __init__(self, binary, extension, launch_timeout, log_limit, memory_limit, p

assert self.binary is not None and os.path.isfile(self.binary)
if self.prefs is not None:
if not os.path.isfile(self.prefs):
raise TargetError("Prefs file does not exist %r" % (self.prefs,))
log.info("Using prefs %r", self.prefs)
assert os.path.isfile(self.prefs)

def add_abort_token(self, token): # pylint: disable=no-self-use,unused-argument
log.warning("add_abort_token() not implemented!")
Expand Down
13 changes: 9 additions & 4 deletions grizzly/target/test_target.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@
import threading
import time

import pytest

from ffpuppet import FFPuppet

from .puppet_target import PuppetTarget
from .target import Target
from .target import Target, TargetError
from .target_monitor import TargetMonitor


Expand Down Expand Up @@ -199,6 +201,9 @@ def test_puppet_target_02(tmp_path):
fake_file = tmp_path / "fake"
fake_file.touch()
target = PuppetTarget(str(fake_file), None, 300, 25, 5000, None, 35)
with pytest.raises(TargetError, match=r"A prefs.js file is required"):
target.launch("launch_target_page")
target.prefs = str(fake_file)
try:
target.launch("launch_target_page")
assert not target.closed
Expand All @@ -213,7 +218,7 @@ def test_puppet_target_03(tmp_path):
PuppetTarget.PUPPET = FakePuppet
fake_file = tmp_path / "fake"
fake_file.touch()
target = PuppetTarget(str(fake_file), None, 300, 25, 5000, None, 25)
target = PuppetTarget(str(fake_file), None, 300, 25, 5000, str(fake_file), 25)
try:
target.launch("launch_target_page")
# no failures
Expand Down Expand Up @@ -277,7 +282,7 @@ def test_puppet_target_03(tmp_path):
# test browser closing test case
target.cleanup()
os.environ["GRZ_FORCED_CLOSE"] = "0"
target = PuppetTarget(str(fake_file), None, 300, 25, 5000, None, 1)
target = PuppetTarget(str(fake_file), None, 300, 25, 5000, str(fake_file), 1)
try:
target.launch("launch_page")
target.step()
Expand All @@ -300,7 +305,7 @@ def signal_handler(*args): # pylint: disable=unused-argument
signal.signal(signal.SIGUSR1, sig_catcher.signal_handler)
fake_file = tmp_path / "fake"
fake_file.touch()
target = PuppetTarget(str(fake_file), None, 300, 25, 5000, None, 10)
target = PuppetTarget(str(fake_file), None, 300, 25, 5000, str(fake_file), 10)
target.dump_coverage()
assert not sig_catcher.CAUGHT
target.launch("launch_page")
Expand Down
5 changes: 2 additions & 3 deletions grizzly/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@

import pytest

from ffpuppet import LaunchError

from sapphire import Sapphire
from .common import Adapter
from .main import main
from .session import Session
from .target import TargetLaunchError


class FakeArgs(object):
Expand Down Expand Up @@ -108,5 +107,5 @@ def test_main_03(tmp_path, mocker):
args.input = "fake"
fake_session.return_value.run.side_effect = KeyboardInterrupt
assert main(args) == Session.EXIT_ABORT
fake_session.return_value.run.side_effect = LaunchError("test")
fake_session.return_value.run.side_effect = TargetLaunchError("test")
assert main(args) == Session.EXIT_LAUNCH_FAILURE
12 changes: 5 additions & 7 deletions grizzly/test_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,10 @@

import pytest

from ffpuppet import BrowserTerminatedError, BrowserTimeoutError

from sapphire import Sapphire, SERVED_ALL, SERVED_TIMEOUT
from grizzly.common import Adapter, IOManager, Reporter, ServerMap, Status, TestCase, TestFile
from grizzly.session import Session
from grizzly.target import Target
from grizzly.target import Target, TargetLaunchError, TargetLaunchTimeout


def test_session_00(tmp_path, mocker):
Expand Down Expand Up @@ -157,20 +155,20 @@ def save_logs(self, result_logs, meta=True):
session.launch_target()
assert not fake_target.closed

fake_target = FakeTarget(launch_raise=BrowserTerminatedError)
fake_target = FakeTarget(launch_raise=TargetLaunchError)
fake_reporter = mocker.Mock(spec=Reporter)
session = Session(fake_adapter, False, [], fake_iomgr, fake_reporter, fake_target)
session.server = fake_server
with pytest.raises(BrowserTerminatedError):
with pytest.raises(TargetLaunchError):
session.launch_target()
assert fake_target.closed
assert session.status.results == 1

fake_target = FakeTarget(launch_raise=BrowserTimeoutError)
fake_target = FakeTarget(launch_raise=TargetLaunchTimeout)
fake_reporter = mocker.Mock(spec=Reporter)
session = Session(fake_adapter, False, [], fake_iomgr, fake_reporter, fake_target)
session.server = fake_server
with pytest.raises(BrowserTimeoutError):
with pytest.raises(TargetLaunchTimeout):
session.launch_target()
assert fake_target.closed

Expand Down

0 comments on commit 8a82de1

Please sign in to comment.