Skip to content

Commit 14171cf

Browse files
committed
feat: add Servo as web browser subject with tar.gz support (WIP)
1 parent f7463fd commit 14171cf

6 files changed

Lines changed: 128 additions & 8 deletions

File tree

bughog/subject/factory.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,14 @@
1515
from bughog.subject.web_browser.chromium.subject import Chromium
1616
from bughog.subject.web_browser.evaluation_framework import BrowserEvaluationFramework
1717
from bughog.subject.web_browser.firefox.subject import Firefox
18+
from bughog.subject.web_browser.servo.subject import Servo
1819

1920
subjects = {
2021
'js_engine': {'evaluation_framework': JSEngineEvaluationFramework, 'subjects': [V8Subject(), V8SandboxSubject()]},
2122
'wasm_runtime': {'evaluation_framework': WasmRuntimeEvaluationFramework, 'subjects': [WasmtimeSubject()]},
2223
'web_browser': {
2324
'evaluation_framework': BrowserEvaluationFramework,
24-
'subjects': [
25-
Chromium(),
26-
Firefox(),
27-
],
25+
'subjects': [Chromium(), Firefox(), Servo()],
2826
},
2927
}
3028

bughog/subject/web_browser/servo/__init__.py

Whitespace-only changes.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import re
2+
3+
from bughog import cli
4+
from bughog.parameters import SubjectConfiguration
5+
from bughog.subject.web_browser.executable import BrowserExecutable
6+
from bughog.version_control.state.base import State
7+
8+
9+
class ServoExecutable(BrowserExecutable):
10+
def __init__(self, config: SubjectConfiguration, state: State) -> None:
11+
super().__init__(config, state)
12+
self._profile_path = None
13+
14+
@property
15+
def executable_name(self) -> str:
16+
return 'servo'
17+
18+
def _get_version(self) -> str:
19+
command = f'./{self.executable_name} --version'
20+
output = cli.execute_and_return_output(command, cwd=self.staging_folder)
21+
match = re.match(r'Chromium (?P<version>[0-9]+\.[0-9]+\.[0-9]+)', output)
22+
if match:
23+
return match.group('version')
24+
raise AttributeError(f"Could not determine version of executable at '{self.executable_name}'.")
25+
26+
def _optimize_for_storage(self) -> None:
27+
pass
28+
29+
def _configure_executable(self) -> None:
30+
cli.execute_and_return_status(f'chmod -R a+x {self.staging_folder}')
31+
32+
@property
33+
def post_experiment_sleep_duration(self) -> int:
34+
return 1
35+
36+
@property
37+
def open_console_hotkey(self) -> list[str]:
38+
raise NotImplementedError()
39+
40+
@property
41+
def supported_options(self) -> list[str]:
42+
return []
43+
44+
def _get_cli_command(self) -> list[str]:
45+
cmd = [self.executable_path, f'--profile={self._profile_path}']
46+
return cmd
47+
48+
def _prepare_profile_folder(self):
49+
cli.execute_and_return_status(f'mkdir -p {self._profile_path}')
50+
51+
def _remove_profile_folder(self):
52+
if self._profile_path:
53+
cli.execute_and_return_status(f'rm -rf {self._profile_path}')
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
from typing import Literal
2+
3+
from bughog.subject.state_oracle import StateOracle
4+
from bughog.version_control.conversion import bughog_service
5+
6+
7+
class ServoStateOracle(StateOracle):
8+
def find_commit_nb(self, commit_id: str) -> int:
9+
return bughog_service.find_commit_nb(self.subject_name, commit_id)
10+
11+
def find_commit_id(self, commit_nb: int) -> str | None:
12+
return bughog_service.find_commit_id(self.subject_name, commit_nb)
13+
14+
def find_commit_of_release(self, release_version: int) -> tuple[int, str]:
15+
return bughog_service.find_version_commit(self.subject_name, release_version)
16+
17+
def get_oldest_supported_release_version(self) -> int:
18+
return 0
19+
20+
def get_most_recent_major_release_version(self) -> int:
21+
return bughog_service.find_latest_major_version(self.subject_name)
22+
23+
def has_public_executable(self, state_index: int, state_type: Literal['release', 'commit']) -> bool:
24+
match state_type:
25+
case 'release':
26+
# For now, only support commits.
27+
return False
28+
case 'commit':
29+
return bughog_service.find_commit_executable_info(self.subject_name, state_index) is not None
30+
31+
def get_executable_download_urls(self, state_index: int, state_type: Literal['release', 'commit']) -> list[str]:
32+
match state_type:
33+
case 'release':
34+
# For now, only support commits.
35+
return []
36+
case 'commit':
37+
commit_info = bughog_service.find_commit_executable_info(self.subject_name, state_index)
38+
if commit_info is None:
39+
return []
40+
return [commit_info['base_url'] + 'servo-latest.tar.gz']
41+
42+
def get_nearest_commit_with_executable(
43+
self, target_commit_nb: int, lower_bound: int, upper_bound: int
44+
) -> int | None:
45+
commit_info = bughog_service.find_nearest_commit_with_executable(
46+
self.subject_name, target_commit_nb, lower_bound, upper_bound
47+
)
48+
return commit_info.get('nb') if commit_info else None
49+
50+
def get_commit_url(self, commit_nb: int, commit_id: str | None) -> str | None:
51+
commit_info = bughog_service.find_commit_info(self.subject_name, commit_nb)
52+
return commit_info.get('url') if commit_info else None
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from bughog.parameters import SubjectConfiguration
2+
from bughog.subject.state_oracle import StateOracle
3+
from bughog.subject.web_browser.servo.executable import ServoExecutable
4+
from bughog.subject.web_browser.servo.state_oracle import ServoStateOracle
5+
from bughog.subject.web_browser.subject import WebBrowser
6+
from bughog.version_control.state.base import State
7+
8+
9+
class Servo(WebBrowser):
10+
@property
11+
def name(self) -> str:
12+
return 'servo'
13+
14+
@property
15+
def _state_oracle_class(self) -> type[StateOracle]:
16+
return ServoStateOracle
17+
18+
def create_executable(self, subject_configuration: SubjectConfiguration, state: State) -> ServoExecutable:
19+
return ServoExecutable(subject_configuration, state)

bughog/util.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ def __get_session(token: Optional[str] = None, max_retries: int = 3, backoff_fac
170170
def download_and_extract(urls: list[str], dst_folder_path: str) -> bool:
171171
"""
172172
Downloads the archive residing at the given URL and extracts it to the given dest_path.
173-
This method currently supports zip, tar.bz2 and tar.xz archives.
173+
This method currently supports zip, tar.gz, tar.bz2 and tar.xz archives.
174174
175175
:return bool: Returns True if the archive was successfully downloaded and extracted, otherwise False.
176176
"""
@@ -196,9 +196,7 @@ def download_and_extract(urls: list[str], dst_folder_path: str) -> bool:
196196
match file_extension:
197197
case '.zip':
198198
unzip(tmp_file_path, dst_folder_path)
199-
case '.bz2':
200-
untar(tmp_file_path, dst_folder_path)
201-
case '.xz':
199+
case '.gz' | '.bz2' | '.xz':
202200
untar(tmp_file_path, dst_folder_path)
203201
case _:
204202
AttributeError(f'File extension {file_extension} is not supported.')

0 commit comments

Comments
 (0)