diff --git a/cpp/cmake_modules/ThirdpartyToolchain.cmake b/cpp/cmake_modules/ThirdpartyToolchain.cmake index 1677b188b9ff..c34bd87edd79 100644 --- a/cpp/cmake_modules/ThirdpartyToolchain.cmake +++ b/cpp/cmake_modules/ThirdpartyToolchain.cmake @@ -1451,8 +1451,7 @@ macro(build_snappy) # ignore linker flag errors, as Snappy sets # -Werror -Wall, and Emscripten doesn't support -soname list(APPEND SNAPPY_CMAKE_ARGS - "-DCMAKE_SHARED_LINKER_FLAGS=${CMAKE_SHARED_LINKER_FLAGS}" - "-Wno-error=linkflags") + "-DCMAKE_SHARED_LINKER_FLAGS=${CMAKE_SHARED_LINKER_FLAGS}") endif() externalproject_add(snappy_ep diff --git a/python/scripts/run_emscripten_tests.py b/python/scripts/run_emscripten_tests.py index 002698a77e2b..9ac3e0d8d7f8 100644 --- a/python/scripts/run_emscripten_tests.py +++ b/python/scripts/run_emscripten_tests.py @@ -31,9 +31,18 @@ from io import BytesIO from selenium import webdriver +from selenium.common.exceptions import TimeoutException class TemplateOverrider(http.server.SimpleHTTPRequestHandler): + def handle(self): + try: + super().handle() + except (BrokenPipeError, ConnectionResetError): + # Browser restart while downloading wheel closes connection + # before server response is written so ignore harmless errors + pass + def log_request(self, code="-", size="-"): # don't log successful requests but log errors if isinstance(code, int) and code >= 400: @@ -200,8 +209,9 @@ def wait_for_done(self): class BrowserDriver: def __init__(self, hostname, port, driver): + self.url = f"http://{hostname}:{port}/test.html" self.driver = driver - self.driver.get(f"http://{hostname}:{port}/test.html") + self.driver.get(self.url) # Chrome on CI takes longer than locally to compile. self.driver.set_script_timeout(1200) @@ -209,10 +219,25 @@ def load_pyodide(self, dist_dir): pass def load_arrow(self): - self.execute_python( - f"import pyodide_js as pjs\n" - f"await pjs.loadPackage('{PYARROW_WHEEL_PATH.name}')\n" - ) + code = (f"import pyodide_js as pjs\n" + f"await pjs.loadPackage('{PYARROW_WHEEL_PATH.name}')\n") + for attempt in range(3): + # Set temporary timeout each attempt as Chrome restart creates a driver + self.driver.set_script_timeout(300) + try: + self.execute_python(code) + except TimeoutException: + if attempt == 2: + raise + print("Timed out loading PyArrow in browser. Restarting browser", + flush=True) + self.restart_browser() + else: + self.driver.set_script_timeout(1200) + return + + def restart_browser(self): + self.driver.get(self.url) def execute_python(self, code, wait_for_terminate=True): if wait_for_terminate: @@ -256,7 +281,8 @@ def wait_for_done(self): class ChromeDriver(BrowserDriver): - def __init__(self, hostname, port): + @staticmethod + def _make_driver(): from selenium.webdriver.chrome.options import Options options = Options() @@ -264,7 +290,16 @@ def __init__(self, hostname, port): options.add_argument("--no-sandbox") driver = webdriver.Chrome(options=options) driver.command_executor._client_config.timeout = 1200 - super().__init__(hostname, port, driver) + return driver + + def __init__(self, hostname, port): + super().__init__(hostname, port, self._make_driver()) + + def restart_browser(self): + self.driver.quit() + self.driver = self._make_driver() + self.driver.get(self.url) + self.driver.set_script_timeout(1200) class FirefoxDriver(BrowserDriver):