wptserver.py (2023B)
1 import logging 2 import os 3 import subprocess 4 import time 5 import sys 6 import urllib 7 8 9 class WPTServer(object): 10 def __init__(self, wpt_root): 11 self.logger = logging.getLogger() 12 self.wpt_root = wpt_root 13 14 # This is a terrible hack to get the default config of wptserve. 15 sys.path.insert(0, os.path.join(wpt_root, "tools")) 16 from serve.serve import build_config 17 with build_config(self.logger) as config: 18 self.host = config["browser_host"] 19 self.http_port = config["ports"]["http"][0] 20 self.https_port = config["ports"]["https"][0] 21 22 self.base_url = 'http://%s:%s' % (self.host, self.http_port) 23 self.https_base_url = 'https://%s:%s' % (self.host, self.https_port) 24 25 def start(self, ssl_context): 26 self.devnull = open(os.devnull, 'w') 27 wptserve_cmd = [os.path.join(self.wpt_root, 'wpt'), 'serve'] 28 if sys.executable: 29 wptserve_cmd[0:0] = [sys.executable] 30 self.logger.info('Executing %s' % ' '.join(wptserve_cmd)) 31 self.proc = subprocess.Popen( 32 wptserve_cmd, 33 stderr=self.devnull, 34 cwd=self.wpt_root) 35 36 for retry in range(5): 37 # Exponential backoff. 38 time.sleep(2 ** retry) 39 exit_code = self.proc.poll() 40 if exit_code != None: 41 logging.warning('Command "%s" exited with %s', ' '.join(wptserve_cmd), exit_code) 42 break 43 try: 44 urllib.request.urlopen(self.base_url, timeout=1) 45 urllib.request.urlopen(self.https_base_url, timeout=1, context=ssl_context) 46 return 47 except urllib.error.URLError: 48 pass 49 50 raise Exception('Could not start wptserve on %s' % self.base_url) 51 52 def stop(self): 53 self.proc.terminate() 54 self.proc.wait() 55 self.devnull.close() 56 57 def url(self, abs_path): 58 return self.https_base_url + '/' + os.path.relpath(abs_path, self.wpt_root)