091c8ec4e8e4e9c93ee051623f854741afa12c37
[WebKit.git] / Tools / Scripts / webkitpy / benchmark_runner / http_server_driver / simple_http_server_driver.py
1 #!/usr/bin/env python
2
3 import logging
4 import os
5 import re
6 import socket
7 import subprocess
8 import sys
9 import time
10
11 from http_server_driver import HTTPServerDriver
12
13
14 _log = logging.getLogger(__name__)
15
16
17 class SimpleHTTPServerDriver(HTTPServerDriver):
18
19     """This class depends on unix environment, need to be modified to achieve crossplatform compability
20     """
21
22     platforms = ['osx', 'gtk']
23
24     def __init__(self):
25         self._server_process = None
26         self._server_port = 0
27         self._ip = '127.0.0.1'
28
29     def serve(self, web_root):
30         _log.info('Launching an http server')
31         http_server_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "http_server/twisted_http_server.py")
32         self._server_process = subprocess.Popen(["/usr/bin/python", http_server_path, web_root], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
33
34         max_attempt = 5
35         interval = 0.5
36         _log.info('Start to fetching the port number of the http server')
37         try:
38             import psutil
39             for attempt in xrange(max_attempt):
40                 try:
41                     self._server_port = psutil.Process(self._server_process.pid).connections()[0][3][1]
42                     if self._server_port:
43                         _log.info('HTTP Server is serving at port: %d', self._server_port)
44                         break
45                 except IndexError:
46                     pass
47                 _log.info('Server port is not found this time, retry after %f seconds' % interval)
48                 time.sleep(interval)
49                 interval *= 2
50             else:
51                 raise Exception("Cannot listen to server, max tries exceeded")
52         except ImportError:
53             for attempt in xrange(max_attempt):
54                 try:
55                     output = subprocess.check_output(['/usr/sbin/lsof', '-a', '-iTCP', '-sTCP:LISTEN', '-p', str(self._server_process.pid)])
56                     self._server_port = int(re.search('TCP \*:(\d+) \(LISTEN\)', output).group(1))
57                     if self._server_port:
58                         _log.info('HTTP Server is serving at port: %d', self._server_port)
59                         break
60                 except Exception as error:
61                     _log.info('Error: %s' % error)
62                 _log.info('Server port is not found this time, retry after %f seconds' % interval)
63                 time.sleep(interval)
64                 interval *= 2
65             else:
66                 raise Exception("Cannot listen to server, max tries exceeded")
67
68         # Wait for server to be up completely before exiting
69         for attempt in xrange(max_attempt):
70             try:
71                 subprocess.check_call(["curl", "--silent", "--head", "--fail", "--output", "/dev/null", self.base_url()])
72                 return
73             except Exception as error:
74                 _log.info('Server not running yet: %s' % error)
75                 time.sleep(interval)
76         raise Exception('Server not running, max tries exceeded: %s' % error)
77
78     def base_url(self):
79         return "http://%s:%d" % (self._ip, self._server_port)
80
81     def fetch_result(self):
82         (stdout, stderr) = self._server_process.communicate()
83         print stderr
84         return stdout
85
86     def kill_server(self):
87         try:
88             if self._server_process.poll() is None:
89                 self._server_process.terminate()
90         except OSError as error:
91             _log.info('Error terminating server process: %s' % (error))
92
93     def get_return_code(self):
94         return self._server_process.returncode
95
96     def set_device_id(self, device_id):
97         pass