Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 34e5565

Browse filesBrowse files
pyoortysmith
andauthored
Add support for running additional services (#484)
* wip: initial attempt at adding webtransport to grizzly * refactor: use future annotations and remove Optional type * refactor: add explicit imports for os methods * docs: remove unnecessary type defintion from docstring * fix: move pathlib import into type checking block * fix: a few more minor nits * docs: add explanation for over-riding wpt _doc_root global --------- Co-authored-by: Tyson Smith <tyson.w.smith@gmail.com>
1 parent 6151e00 commit 34e5565
Copy full SHA for 34e5565

41 files changed

+1,922-2Lines changed: 1922 additions & 2 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Dismiss banner
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎.codecov.yml‎

Copy file name to clipboard
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
ignore:
2+
- "grizzly/services/webtransport/wpt_h3_server"
13
codecov:
24
ci:
35
- community-tc.services.mozilla.com
Collapse file

‎.pre-commit-config.yaml‎

Copy file name to clipboardExpand all lines: .pre-commit-config.yaml
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,5 @@ repos:
6868

6969
default_language_version:
7070
python: python3
71+
72+
exclude: '.*wpt_h3_server/.*'
Collapse file

‎pyproject.toml‎

Copy file name to clipboardExpand all lines: pyproject.toml
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ omit = [
1212
"*/resources/*",
1313
"*/.tox/*",
1414
"*/.egg/*",
15+
"*/wpt_h3_server/*",
1516
]
1617

1718
[tool.coverage.report]
@@ -56,6 +57,7 @@ disable = [
5657
ignored-modules = ["pytest"]
5758

5859
[tool.pytest.ini_options]
60+
asyncio_default_fixture_loop_scope = "function"
5961
filterwarnings = [
6062
"ignore::pytest.PytestCollectionWarning",
6163
]
@@ -64,6 +66,7 @@ log_level = "DEBUG"
6466
[tool.ruff]
6567
fix = true
6668
target-version = "py39"
69+
exclude = ["src/grizzly/services/webtransport/wpt_h3_server"]
6770

6871
[tool.ruff.lint]
6972
select = [
Collapse file

‎setup.cfg‎

Copy file name to clipboardExpand all lines: setup.cfg
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ url = https://github.com/MozillaSecurity/grizzly
2020
[options]
2121
include_package_data = True
2222
install_requires =
23+
aioquic==1.2.0
2324
bugsy
2425
cryptography
2526
cssbeautifier
@@ -40,6 +41,7 @@ packages =
4041
grizzly.reduce.strategies
4142
grizzly.replay
4243
grizzly.target
44+
grizzly.services
4345
loki
4446
sapphire
4547
python_requires = >=3.9
Collapse file

‎src/grizzly/conftest.py‎

Copy file name to clipboardExpand all lines: src/grizzly/conftest.py
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
def session_setup(mocker):
1515
mocker.patch("grizzly.main.FuzzManagerReporter", autospec=True)
1616
mocker.patch("grizzly.main.Sapphire", autospec_set=True)
17+
mocker.patch("grizzly.main.WebServices", autospec_set=True)
1718
adapter_cls = mocker.Mock(spec_set=Adapter)
1819
adapter_cls.return_value.RELAUNCH = Adapter.RELAUNCH
1920
adapter_cls.return_value.TIME_LIMIT = Adapter.TIME_LIMIT
Collapse file

‎src/grizzly/main.py‎

Copy file name to clipboardExpand all lines: src/grizzly/main.py
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
Reporter,
2727
)
2828
from .common.utils import package_version
29+
from .services import WebServices
2930
from .session import LogRate, Session
3031
from .target import Target, TargetLaunchError, TargetLaunchTimeout
3132

@@ -66,6 +67,7 @@ def main(args: Namespace) -> int:
6667
adapter: Adapter | None = None
6768
certs: CertificateBundle | None = None
6869
complete_with_results = False
70+
ext_services = None
6971
target: Target | None = None
7072
try:
7173
LOG.debug("initializing Adapter %r", args.adapter)
@@ -135,6 +137,9 @@ def main(args: Namespace) -> int:
135137
# launch http server used to serve test cases
136138
LOG.debug("starting Sapphire server")
137139
with Sapphire(auto_close=1, timeout=timeout, certs=certs) as server:
140+
if certs is not None:
141+
ext_services = WebServices.start_services(certs.host, certs.key)
142+
138143
target.reverse(server.port, server.port)
139144
LOG.debug("initializing the Session")
140145
with Session(
@@ -163,6 +168,7 @@ def main(args: Namespace) -> int:
163168
log_rate=log_rate,
164169
launch_attempts=args.launch_attempts,
165170
post_launch_delay=args.post_launch_delay,
171+
services=ext_services,
166172
)
167173
complete_with_results = session.status.results.total > 0
168174

@@ -183,6 +189,8 @@ def main(args: Namespace) -> int:
183189
if adapter is not None:
184190
LOG.debug("calling adapter.cleanup()")
185191
adapter.cleanup()
192+
if ext_services is not None:
193+
ext_services.cleanup()
186194
if certs is not None:
187195
certs.cleanup()
188196
clear_cached()
Collapse file

‎src/grizzly/reduce/core.py‎

Copy file name to clipboardExpand all lines: src/grizzly/reduce/core.py
+14Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
from ..common.storage import TestCase, TestCaseLoadFailure
4141
from ..common.utils import package_version
4242
from ..replay import ReplayManager, ReplayResult
43+
from ..services import WebServices
4344
from ..target import AssetManager, Target, TargetLaunchError, TargetLaunchTimeout
4445
from .args import ReduceArgs
4546
from .exceptions import GrizzlyReduceBaseException, NotReproducible
@@ -98,6 +99,7 @@ def __init__(
9899
relaunch: int = 1,
99100
report_period: int | None = None,
100101
report_to_fuzzmanager: bool = False,
102+
services: WebServices | None = None,
101103
signature: CrashSignature | None = None,
102104
signature_desc: str | None = None,
103105
static_timeout: bool = False,
@@ -123,6 +125,7 @@ def __init__(
123125
Target should be relaunched.
124126
report_period: Periodically report best results for long-running strategies.
125127
report_to_fuzzmanager: Report to FuzzManager rather than filesystem.
128+
services: WebServices instance.
126129
signature: Signature for accepting crashes.
127130
signature_desc: Short description of the given signature.
128131
static_timeout: Use only specified timeouts (`--timeout` and
@@ -161,6 +164,7 @@ def __init__(
161164
)
162165
self._use_analysis = use_analysis
163166
self._use_harness = use_harness
167+
self._services = services
164168

165169
def __enter__(self) -> ReduceManager:
166170
return self
@@ -330,6 +334,7 @@ def run_reliability_analysis(self) -> tuple[int, int]:
330334
idle_delay=self._idle_delay,
331335
idle_threshold=self._idle_threshold,
332336
on_iteration_cb=self._on_replay_iteration,
337+
services=self._services,
333338
)
334339
try:
335340
crashes = sum(x.count for x in results if x.expected)
@@ -533,6 +538,7 @@ def run(
533538
repeat=repeat,
534539
on_iteration_cb=self._on_replay_iteration,
535540
post_launch_delay=post_launch_delay,
541+
services=self._services,
536542
)
537543
self._status.attempts += 1
538544
self.update_timeout(results)
@@ -785,6 +791,7 @@ def main(cls, args: Namespace | None = None) -> int:
785791

786792
asset_mgr: AssetManager | None = None
787793
certs = None
794+
ext_services = None
788795
signature = None
789796
signature_desc = None
790797
target: Target | None = None
@@ -854,6 +861,10 @@ def main(cls, args: Namespace | None = None) -> int:
854861
LOG.debug("starting sapphire server")
855862
# launch HTTP server used to serve test cases
856863
with Sapphire(auto_close=1, timeout=timeout, certs=certs) as server:
864+
if certs is not None:
865+
LOG.debug("starting additional web services")
866+
ext_services = WebServices.start_services(certs.host, certs.key)
867+
857868
target.reverse(server.port, server.port)
858869
with ReduceManager(
859870
frozenset(args.ignore),
@@ -876,6 +887,7 @@ def main(cls, args: Namespace | None = None) -> int:
876887
tool=args.tool,
877888
use_analysis=not args.no_analysis,
878889
use_harness=not args.no_harness,
890+
services=ext_services,
879891
) as mgr:
880892
return_code = mgr.run(
881893
repeat=args.repeat,
@@ -918,5 +930,7 @@ def main(cls, args: Namespace | None = None) -> int:
918930
asset_mgr.cleanup()
919931
if certs is not None:
920932
certs.cleanup()
933+
if ext_services is not None:
934+
ext_services.cleanup()
921935
clear_cached()
922936
LOG.info("Done.")
Collapse file

‎src/grizzly/reduce/test_main.py‎

Copy file name to clipboardExpand all lines: src/grizzly/reduce/test_main.py
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ def test_main_https_support(mocker, tmp_path, https_supported):
240240
mocker.patch("grizzly.reduce.core.ReduceManager.run", autospec=True, return_value=0)
241241
mocker.patch("grizzly.reduce.core.ReductionStatus", autospec=True)
242242
mocker.patch("grizzly.reduce.core.Sapphire", autospec=True)
243+
mocker.patch("grizzly.reduce.core.WebServices", autospec=True)
243244
(tmp_path / "test.html").touch()
244245
# setup args
245246
args = mocker.Mock(
Collapse file

‎src/grizzly/replay/replay.py‎

Copy file name to clipboardExpand all lines: src/grizzly/replay/replay.py
+14Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
from ..common.status import SimpleStatus
3434
from ..common.storage import TestCase, TestCaseLoadFailure
3535
from ..common.utils import HARNESS_FILE, grz_tmp, package_version
36+
from ..services import WebServices
3637
from ..target import (
3738
AssetManager,
3839
Result,
@@ -299,6 +300,7 @@ def run(
299300
launch_attempts: int = 3,
300301
on_iteration_cb: Callable[[], None] | None = None,
301302
post_launch_delay: int = -1,
303+
services: WebServices | None = None,
302304
) -> list[ReplayResult]:
303305
"""Run testcase replay.
304306
@@ -319,6 +321,7 @@ def run(
319321
on_iteration_cb: Called every time a single iteration is run.
320322
post_launch_delay: Number of seconds to wait before continuing after the
321323
browser is launched. A negative number skips redirect.
324+
services: WebServices instance.
322325
323326
Returns:
324327
ReplayResults that were found running provided testcases.
@@ -354,6 +357,9 @@ def harness_fn(_: str) -> bytes: # pragma: no cover
354357
)
355358
server_map.set_redirect("grz_start", "grz_harness", required=False)
356359

360+
if services:
361+
services.map_locations(server_map)
362+
357363
# track unprocessed results
358364
reports: dict[str, ReplayResult] = {}
359365
try:
@@ -643,6 +649,7 @@ def main(cls, args: Namespace | None = None) -> int:
643649
certs = None
644650
results: list[ReplayResult] | None = None
645651
target: Target | None = None
652+
ext_services = None
646653
try:
647654
# check if hangs are expected
648655
expect_hang = cls.expect_hang(args.ignore, signature, testcases)
@@ -696,6 +703,10 @@ def main(cls, args: Namespace | None = None) -> int:
696703
LOG.debug("starting sapphire server")
697704
# launch HTTP server used to serve test cases
698705
with Sapphire(auto_close=1, timeout=timeout, certs=certs) as server:
706+
if certs is not None:
707+
LOG.debug("starting additional web services")
708+
ext_services = WebServices.start_services(certs.host, certs.key)
709+
699710
target.reverse(server.port, server.port)
700711
with cls(
701712
frozenset(args.ignore),
@@ -716,6 +727,7 @@ def main(cls, args: Namespace | None = None) -> int:
716727
min_results=args.min_crashes,
717728
post_launch_delay=args.post_launch_delay,
718729
repeat=repeat,
730+
services=ext_services,
719731
)
720732
# handle results
721733
success = any(x.expected for x in results)
@@ -768,5 +780,7 @@ def main(cls, args: Namespace | None = None) -> int:
768780
asset_mgr.cleanup()
769781
if certs is not None:
770782
certs.cleanup()
783+
if ext_services is not None:
784+
ext_services.cleanup()
771785
clear_cached()
772786
LOG.info("Done.")
Collapse file

‎src/grizzly/replay/test_main.py‎

Copy file name to clipboardExpand all lines: src/grizzly/replay/test_main.py
+7Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ def test_main_01(mocker, server, tmp_path):
3636
# Of the four attempts only the first and third will 'reproduce' the result
3737
# and the forth attempt should be skipped.
3838
mocker.patch("grizzly.common.runner.sleep", autospec=True)
39+
mocker.patch("grizzly.replay.replay.WebServices", autospec=True)
3940
server.serve_path.return_value = (Served.ALL, {"test.html": "/fake/path"})
4041
# setup Target
4142
load_target = mocker.patch("grizzly.replay.replay.load_plugin", autospec=True)
@@ -151,6 +152,7 @@ def test_main_02(mocker, server, tmp_path, repro_results):
151152
test_index=[],
152153
time_limit=10,
153154
timeout=None,
155+
use_https=False,
154156
valgrind=False,
155157
)
156158
assert ReplayManager.main(args) == Exit.FAILURE
@@ -215,6 +217,7 @@ def test_main_03(mocker, load_plugin, load_testcases, signature, result):
215217
test_index=[],
216218
time_limit=10,
217219
timeout=None,
220+
use_https=False,
218221
valgrind=False,
219222
)
220223
asset_mgr = load_testcases[1] if isinstance(load_testcases, tuple) else None
@@ -256,6 +259,7 @@ def test_main_04(mocker, tmp_path):
256259
test_index=[],
257260
time_limit=10,
258261
timeout=None,
262+
use_https=False,
259263
valgrind=False,
260264
)
261265
# target launch error
@@ -317,6 +321,7 @@ def test_main_05(mocker, server, tmp_path):
317321
test_index=[],
318322
time_limit=1,
319323
timeout=None,
324+
use_https=False,
320325
valgrind=False,
321326
)
322327
# build a test case
@@ -385,6 +390,7 @@ def test_main_06(
385390
test_index=[],
386391
time_limit=10,
387392
timeout=None,
393+
use_https=False,
388394
valgrind=valgrind,
389395
)
390396
# maximum one debugger allowed at a time
@@ -438,6 +444,7 @@ def test_main_07(mocker, server, tmp_path):
438444
time_limit=10,
439445
timeout=None,
440446
tool=None,
447+
use_https=False,
441448
valgrind=False,
442449
)
443450
assert ReplayManager.main(args) == Exit.SUCCESS

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.