Skip to content

Commit

Permalink
Update FFPuppet support
Browse files Browse the repository at this point in the history
Support use of Path objects with FFpuppet
  • Loading branch information
tysmith committed Apr 19, 2023
1 parent 56ff0e4 commit 0badb98
Show file tree
Hide file tree
Showing 19 changed files with 117 additions and 99 deletions.
8 changes: 4 additions & 4 deletions grizzly/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from argparse import ArgumentParser, HelpFormatter
from logging import CRITICAL, DEBUG, ERROR, INFO, WARNING
from os import getenv
from os.path import exists, isfile
from os.path import exists
from pathlib import Path
from platform import system

Expand Down Expand Up @@ -53,7 +53,7 @@ def __init__(self):
if not targets:
self.parser.error("No Platforms (Targets) are installed")

self.parser.add_argument("binary", help="Firefox binary to run")
self.parser.add_argument("binary", type=Path, help="Firefox binary to run")
self.parser.add_argument(
"--log-level",
choices=sorted(self._level_map),
Expand Down Expand Up @@ -250,8 +250,8 @@ def parse_args(self, argv=None):
return args

def sanity_check(self, args):
if not isfile(args.binary):
self.parser.error(f"file not found: {args.binary!r}")
if not args.binary.is_file():
self.parser.error(f"file not found: '{args.binary!s}'")

if args.launch_attempts < 1:
self.parser.error("--launch-attempts must be >= 1")
Expand Down
4 changes: 2 additions & 2 deletions grizzly/common/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@ class Report:

def __init__(self, log_path, target_binary, is_hang=False, size_limit=MAX_LOG_SIZE):
assert isinstance(log_path, Path)
assert isinstance(target_binary, str)
assert isinstance(target_binary, Path)
self._crash_info = None
self._logs = self._select_logs(log_path)
assert self._logs is not None
self._signature = None
self._target_binary = Path(target_binary)
self._target_binary = target_binary
self.is_hang = is_hang
self.path = log_path
# tail files in log_path if needed
Expand Down
4 changes: 2 additions & 2 deletions grizzly/common/reporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ def sanity_check(bin_file):
"""Perform FuzzManager sanity check.
Args:
bin_file (str): Binary file being tested.
bin_file (Path): Binary file being tested.
Returns:
None
Expand All @@ -196,7 +196,7 @@ def sanity_check(bin_file):
raise OSError(f"Missing: {FuzzManagerReporter.FM_CONFIG}")
if not Path(f"{bin_file}.fuzzmanagerconf").is_file():
raise OSError(f"Missing: {bin_file}.fuzzmanagerconf")
ProgramConfiguration.fromBinary(bin_file)
ProgramConfiguration.fromBinary(str(bin_file))

def add_extra_metadata(self, key, value):
"""Add extra metadata to be reported with any CrashEntrys reported.
Expand Down
13 changes: 7 additions & 6 deletions grizzly/common/test_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
"""test Grizzly Report"""
# pylint: disable=protected-access
from pathlib import Path

from FTB.Signatures.CrashInfo import CrashInfo
from pytest import mark, raises
Expand All @@ -23,7 +24,7 @@ def test_report_01(tmp_path):
(tmp_path / "not_a_log.txt").touch()
(tmp_path / "log_stderr.txt").write_bytes(b"STDERR log")
(tmp_path / "log_stdout.txt").write_bytes(b"STDOUT log")
report = Report(tmp_path, "a.bin", size_limit=0)
report = Report(tmp_path, Path("a.bin"), size_limit=0)
assert report._target_binary.name == "a.bin"
assert report.path == tmp_path
assert report._logs.aux is None
Expand All @@ -43,7 +44,7 @@ def test_report_02(tmp_path):
(tmp_path / "log_stderr.txt").write_bytes(b"STDERR log")
(tmp_path / "log_stdout.txt").write_bytes(b"STDOUT log")
_create_crash_log(tmp_path / "log_asan_blah.txt")
report = Report(tmp_path, "bin")
report = Report(tmp_path, Path("bin"))
assert report.path == tmp_path
assert report._logs.aux.name == "log_asan_blah.txt"
assert report._logs.stderr.name == "log_stderr.txt"
Expand Down Expand Up @@ -249,7 +250,7 @@ def test_report_10(tmp_path):
(tmp_path / "unrelated.txt").write_bytes(b"nothing burger\n" * 200)
(tmp_path / "rr-trace").mkdir()
size_limit = len("STDERR log\n")
report = Report(tmp_path, "bin", size_limit=size_limit)
report = Report(tmp_path, Path("bin"), size_limit=size_limit)
assert report.path == tmp_path
assert report._logs.aux is None
assert report._logs.stderr.name == "log_stderr.txt"
Expand Down Expand Up @@ -281,7 +282,7 @@ def test_report_12(tmp_path):
(tmp_path / "log_stdout.txt").write_bytes(b"STDOUT log")
_create_crash_log(tmp_path / "log_asan_blah.txt")
# no binary.fuzzmanagerconf
report = Report(tmp_path, target_binary="fake_bin")
report = Report(tmp_path, Path("bin"))
assert report._crash_info is None
assert report.crash_info is not None
assert report._crash_info is not None
Expand All @@ -291,7 +292,7 @@ def test_report_12(tmp_path):
conf.write(b"platform = x86-64\n")
conf.write(b"product = mozilla-central\n")
conf.write(b"os = linux\n")
report = Report(tmp_path, target_binary=str(tmp_path / "fake_bin"))
report = Report(tmp_path, Path("bin"))
assert report._crash_info is None
assert report.crash_info is not None
assert report._crash_info is not None
Expand Down Expand Up @@ -323,7 +324,7 @@ def test_report_13(mocker, tmp_path, sig_cache, has_sig):
(tmp_path / "log_stdout.txt").write_bytes(b"STDOUT log")
if has_sig:
_create_crash_log(tmp_path / "log_asan_blah.txt")
report = Report(tmp_path, "bin")
report = Report(tmp_path, Path("bin"))
assert report._signature is None
if has_sig:
assert report.crash_signature
Expand Down
13 changes: 7 additions & 6 deletions grizzly/common/test_reporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
"""test Grizzly Reporter"""
# pylint: disable=protected-access
from pathlib import Path

from FTB.ProgramConfiguration import ProgramConfiguration
from pytest import mark, raises
Expand Down Expand Up @@ -69,7 +70,7 @@ def test_filesystem_reporter_01(tmp_path):
report_path = tmp_path / "reports"
report_path.mkdir()
reporter = FilesystemReporter(report_path)
reporter.submit([], Report(log_path, "fake_bin"))
reporter.submit([], Report(log_path, Path("bin")))
buckets = tuple(report_path.iterdir())
# check major bucket
assert len(buckets) == 1
Expand All @@ -92,7 +93,7 @@ def test_filesystem_reporter_02(tmp_path, mocker):
report_path = tmp_path / "reports"
assert not report_path.exists()
reporter = FilesystemReporter(report_path)
reporter.submit(tests, Report(log_path, "fake_bin"))
reporter.submit(tests, Report(log_path, Path("bin")))
assert not log_path.exists()
assert report_path.exists()
assert len(tuple(report_path.iterdir())) == 1
Expand All @@ -102,7 +103,7 @@ def test_filesystem_reporter_02(tmp_path, mocker):
(log_path / "log_stderr.txt").write_bytes(b"STDERR log")
(log_path / "log_stdout.txt").write_bytes(b"STDOUT log")
tests = list(mocker.Mock(spec_set=TestCase, timestamp=1) for _ in range(2))
reporter.submit(tests, Report(log_path, "fake_bin"))
reporter.submit(tests, Report(log_path, Path("bin")))
assert all(x.dump.call_count == 1 for x in tests)
assert len(tuple(report_path.iterdir())) == 2
assert len(tuple(report_path.glob("NO_STACK"))) == 1
Expand All @@ -117,7 +118,7 @@ def test_filesystem_reporter_03(tmp_path):
reporter = FilesystemReporter(tmp_path / "reports")
reporter.min_space = 2**50
with raises(RuntimeError, match="Low disk space: "):
reporter.submit([], Report(log_path, "fake_bin"))
reporter.submit([], Report(log_path, Path("bin")))


def test_filesystem_reporter_04(mocker, tmp_path):
Expand Down Expand Up @@ -208,7 +209,7 @@ def test_fuzzmanager_reporter_02(
test_cases.append(fake_test)
reporter = FuzzManagerReporter("fake-tool")
reporter.force_report = force
reporter.submit(test_cases, Report(log_path, "fake_bin", is_hang=True))
reporter.submit(test_cases, Report(log_path, Path("bin"), is_hang=True))
assert not log_path.is_dir()
assert fake_collector.call_args == ({"tool": "fake-tool"},)
if (frequent and not force) or ignored:
Expand Down Expand Up @@ -262,5 +263,5 @@ def test_failed_launch_reporter_01(mocker, tmp_path):
report_path.mkdir()
(report_path / "log_stderr.txt").write_bytes(b"STDERR log")
(report_path / "log_stdout.txt").write_bytes(b"STDOUT log")
FailedLaunchReporter().submit([], Report(report_path, "fake_bin"))
FailedLaunchReporter().submit([], Report(report_path, Path("bin")))
assert any(gtp.glob("*_logs"))
19 changes: 10 additions & 9 deletions grizzly/reduce/test_reduce.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from functools import partial, wraps
from itertools import count
from logging import getLogger
from pathlib import Path

from pytest import mark, param, raises

Expand All @@ -29,7 +30,7 @@
)


def _fake_save_logs_foo(result_logs, meta=False): # pylint: disable=unused-argument
def _fake_save_logs_foo(result_logs):
"""write fake log data to disk"""
(result_logs / "log_stderr.txt").write_text("STDERR log\n")
(result_logs / "log_stdout.txt").write_text("STDOUT log\n")
Expand All @@ -41,7 +42,7 @@ def _fake_save_logs_foo(result_logs, meta=False): # pylint: disable=unused-argu
)


def _fake_save_logs_bar(result_logs, meta=False): # pylint: disable=unused-argument
def _fake_save_logs_bar(result_logs):
"""write fake log data to disk"""
(result_logs / "log_stderr.txt").write_text("STDERR log\n")
(result_logs / "log_stdout.txt").write_text("STDOUT log\n")
Expand Down Expand Up @@ -290,7 +291,7 @@ def replay_run(_tests, _time_limit, **kw):
log_path = tmp_path / f"crash{replayer.run.call_count}_logs"
log_path.mkdir(exist_ok=True)
_fake_save_logs_foo(log_path)
report = Report(log_path, "bin")
report = Report(log_path, Path("bin"))
results.append(ReplayResult(report, [["test.html"]], [], True))
return results

Expand Down Expand Up @@ -553,7 +554,7 @@ def replay_run(testcases, _time_limit, **kw):
_fake_save_logs_foo(log_path)
else:
_fake_save_logs_bar(log_path)
report = Report(log_path, "bin")
report = Report(log_path, Path("bin"))
return [ReplayResult(report, [["test.html"]], [], expected)]
return []

Expand Down Expand Up @@ -623,7 +624,7 @@ def replay_run(_tests, _time_limit, **kw):
log_path = tmp_path / f"crash{replayer.run.call_count}_logs"
log_path.mkdir()
_fake_save_logs_foo(log_path)
report = Report(log_path, "bin")
report = Report(log_path, Path("bin"))
return [ReplayResult(report, [["test.html"]], [], True)]
return []

Expand Down Expand Up @@ -694,7 +695,7 @@ def replay_run(_tests, _time_limit, **kw):
log_path = tmp_path / f"crash{replayer.run.call_count}_logs"
log_path.mkdir()
_fake_save_logs_foo(log_path)
report = Report(log_path, "bin")
report = Report(log_path, Path("bin"))
return [ReplayResult(report, [["test.html"]], [], True)]
return []

Expand Down Expand Up @@ -766,7 +767,7 @@ def replay_run(testcases, _time_limit, **kw):
log_path = tmp_path / f"crash{replayer.run.call_count}_logs"
log_path.mkdir()
_fake_save_logs_foo(log_path)
report = Report(log_path, "bin")
report = Report(log_path, Path("bin"))
return [ReplayResult(report, [["test.html"]], [], True)]
return []

Expand Down Expand Up @@ -829,7 +830,7 @@ def replay_run(testcases, _time_limit, **kw):
log_path = tmp_path / f"crash{replayer.run.call_count}_logs"
log_path.mkdir()
_fake_save_logs_foo(log_path)
report = Report(log_path, "bin")
report = Report(log_path, Path("bin"))
return [ReplayResult(report, [["test.html"]], [], True)]
return []

Expand Down Expand Up @@ -966,7 +967,7 @@ def replay_run(_testcases, _time_limit, **kw):
log_path = tmp_path / f"crash{replayer.run.call_count}_logs"
log_path.mkdir()
_fake_save_logs_foo(log_path)
report = Report(log_path, "bin")
report = Report(log_path, Path("bin"))
return [ReplayResult(report, [["test.html"]], durations, interesting)]

replayer.run.side_effect = replay_run
Expand Down
7 changes: 4 additions & 3 deletions grizzly/reduce/test_strategies.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"""Unit tests for `grizzly.reduce.strategies`."""
from collections import namedtuple
from logging import getLogger
from pathlib import Path

from pytest import mark, raises

Expand Down Expand Up @@ -163,7 +164,7 @@ def replay_run(testcases, _time_limit, **kw):
log_path = tmp_path / f"crash{replayer.run.call_count}_logs"
log_path.mkdir()
_fake_save_logs_foo(log_path)
report = Report(log_path, "bin")
report = Report(log_path, Path("bin"))
return [
ReplayResult(report, [["test.html"]] * len(testcases), [], True)
]
Expand Down Expand Up @@ -346,7 +347,7 @@ def replay_run(testcases, _time_limit, **kw):
log_path = tmp_path / f"crash{replayer.run.call_count}_logs"
log_path.mkdir()
_fake_save_logs_foo(log_path)
report = Report(log_path, "bin")
report = Report(log_path, Path("bin"))
return [ReplayResult(report, served.pop(0), [], True)]

replayer.run.side_effect = replay_run
Expand Down Expand Up @@ -407,7 +408,7 @@ def replay_run(testcases, _time_limit, **kw):
log_path = tmp_path / f"crash{replayer.run.call_count}_logs"
log_path.mkdir()
_fake_save_logs_foo(log_path)
report = Report(log_path, "bin")
report = Report(log_path, Path("bin"))
return [ReplayResult(report, [["test.html", "other.html"]], [], True)]
return []

Expand Down
9 changes: 4 additions & 5 deletions grizzly/replay/replay.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def __init__(self, report, served, durations, expected):


class ReplayManager:
HARNESS_FILE = str(Path(__file__).parent / ".." / "common" / "harness.html")
HARNESS_FILE = Path(__file__).parent.parent / "common" / "harness.html"

__slots__ = (
"ignore",
Expand Down Expand Up @@ -81,8 +81,7 @@ def __init__(
self._relaunch = relaunch
self._signature = signature
if use_harness:
with open(self.HARNESS_FILE, "rb") as in_fp:
self._harness = in_fp.read()
self._harness = self.HARNESS_FILE.read_bytes()
else:
# target must relaunch every iteration when not using harness
assert relaunch == 1
Expand Down Expand Up @@ -401,10 +400,10 @@ def run(
# update console to show progress
LOG.info("Processing result...")
# TODO: use self.target.create_report here
log_path = mkdtemp(prefix="logs_", dir=grz_tmp("logs"))
log_path = Path(mkdtemp(prefix="logs_", dir=grz_tmp("logs")))
self.target.save_logs(log_path)
report = Report(
Path(log_path), self.target.binary, is_hang=run_result.timeout
log_path, self.target.binary, is_hang=run_result.timeout
)
# check signatures
if run_result.timeout:
Expand Down
18 changes: 14 additions & 4 deletions grizzly/replay/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
"""
unit tests for grizzly.replay.main
"""
from pathlib import Path

from pytest import mark

from sapphire import Served
Expand Down Expand Up @@ -36,7 +38,9 @@ def test_main_01(mocker, server, tmp_path):
server.serve_path.return_value = (Served.ALL, ["test.html"])
# setup Target
load_target = mocker.patch("grizzly.replay.replay.load_plugin", autospec=True)
target = mocker.Mock(spec_set=Target, binary="bin", environ={}, launch_timeout=30)
target = mocker.Mock(
spec_set=Target, binary=Path("bin"), environ={}, launch_timeout=30
)
target.assets = mocker.Mock(spec_set=AssetManager)
target.check_result.side_effect = (Result.FOUND, Result.NONE, Result.FOUND)
target.filtered_environ.return_value = {"ENV": "123"}
Expand Down Expand Up @@ -108,7 +112,9 @@ def test_main_02(mocker, server, tmp_path, repro_results):
mocker.patch("grizzly.common.runner.sleep", autospec=True)
server.serve_path.return_value = (Served.ALL, ["test.html"])
# setup Target
target = mocker.Mock(spec_set=Target, binary="bin", environ={}, launch_timeout=30)
target = mocker.Mock(
spec_set=Target, binary=Path("bin"), environ={}, launch_timeout=30
)
target.check_result.side_effect = repro_results
target.filtered_environ.return_value = {}
target.save_logs = _fake_save_logs
Expand Down Expand Up @@ -263,7 +269,9 @@ def test_main_05(mocker, server, tmp_path):
"""test ReplayManager.main() loading specified assets"""
server.serve_path.return_value = (None, ["test.html"])
# setup Target
target = mocker.NonCallableMock(spec_set=Target, binary="bin", launch_timeout=30)
target = mocker.NonCallableMock(
spec_set=Target, binary=Path("bin"), launch_timeout=30
)
target.check_result.return_value = Result.FOUND
target.filtered_environ.return_value = {}
target.monitor.is_healthy.return_value = False
Expand Down Expand Up @@ -389,7 +397,9 @@ def test_main_07(mocker, server, tmp_path):
reporter = mocker.patch("grizzly.replay.replay.FuzzManagerReporter", autospec=True)
# setup Target
load_target = mocker.patch("grizzly.replay.replay.load_plugin", autospec=True)
target = mocker.Mock(spec_set=Target, binary="bin", environ={}, launch_timeout=30)
target = mocker.Mock(
spec_set=Target, binary=Path("bin"), environ={}, launch_timeout=30
)
target.assets = mocker.Mock(spec_set=AssetManager)
target.check_result.side_effect = (Result.FOUND,)
target.save_logs = _fake_save_logs
Expand Down
Loading

0 comments on commit 0badb98

Please sign in to comment.