OLD | NEW |
1 # Copyright 2013 The Chromium Authors. All rights reserved. | 1 # Copyright 2013 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """Host driven test server controller. | 5 """Host driven test server controller. |
6 | 6 |
7 This class controls the startup and shutdown of a python driven test server that | 7 This class controls the startup and shutdown of a python driven test server that |
8 runs in a separate process. | 8 runs in a separate process. |
9 | 9 |
10 The server starts up automatically when the object is created. | 10 The server starts up automatically when the object is created. |
(...skipping 22 matching lines...) Expand all Loading... |
33 'third_party/pyftpdlib/src/', | 33 'third_party/pyftpdlib/src/', |
34 'third_party/pywebsocket/src', | 34 'third_party/pywebsocket/src', |
35 'third_party/tlslite/', | 35 'third_party/tlslite/', |
36 ] | 36 ] |
37 | 37 |
38 # Python files in these directories are generated as part of the build. | 38 # Python files in these directories are generated as part of the build. |
39 # These dirs are located in out/(Debug|Release) directory. | 39 # These dirs are located in out/(Debug|Release) directory. |
40 # The correct path is determined based on the build type. E.g. out/Debug for | 40 # The correct path is determined based on the build type. E.g. out/Debug for |
41 # debug builds and out/Release for release builds. | 41 # debug builds and out/Release for release builds. |
42 _GENERATED_PYTHONPATH_DIRS = [ | 42 _GENERATED_PYTHONPATH_DIRS = [ |
| 43 'pyproto/policy/proto/', |
43 'pyproto/sync/protocol/', | 44 'pyproto/sync/protocol/', |
44 'pyproto/' | 45 'pyproto/' |
45 ] | 46 ] |
46 | 47 |
47 _TEST_SERVER_HOST = '127.0.0.1' | 48 _TEST_SERVER_HOST = '127.0.0.1' |
48 # Paths for supported test server executables. | 49 # Paths for supported test server executables. |
49 TEST_NET_SERVER_PATH = 'net/tools/testserver/testserver.py' | 50 TEST_NET_SERVER_PATH = 'net/tools/testserver/testserver.py' |
50 TEST_SYNC_SERVER_PATH = 'sync/tools/testserver/sync_testserver.py' | 51 TEST_SYNC_SERVER_PATH = 'sync/tools/testserver/sync_testserver.py' |
| 52 TEST_POLICY_SERVER_PATH = 'chrome/browser/policy/test/policy_testserver.py' |
51 # Parameters to check that the server is up and running. | 53 # Parameters to check that the server is up and running. |
52 TEST_SERVER_CHECK_PARAMS = { | 54 TEST_SERVER_CHECK_PARAMS = { |
53 TEST_NET_SERVER_PATH: { | 55 TEST_NET_SERVER_PATH: { |
54 'url_path': '/', | 56 'url_path': '/', |
55 'response': 'Default response given for path' | 57 'response': 'Default response given for path' |
56 }, | 58 }, |
57 TEST_SYNC_SERVER_PATH: { | 59 TEST_SYNC_SERVER_PATH: { |
58 'url_path': 'chromiumsync/time', | 60 'url_path': 'chromiumsync/time', |
59 'response': '0123456789' | 61 'response': '0123456789' |
60 }, | 62 }, |
| 63 TEST_POLICY_SERVER_PATH: { |
| 64 'url_path': 'test/ping', |
| 65 'response': 'Policy server is up.' |
| 66 }, |
61 } | 67 } |
62 | 68 |
63 class TestServer(object): | 69 class TestServer(object): |
64 """Sets up a host driven test server on the host machine. | 70 """Sets up a host driven test server on the host machine. |
65 | 71 |
66 For shutting down the server, call TearDown(). | 72 For shutting down the server, call TearDown(). |
67 """ | 73 """ |
68 | 74 |
69 def __init__(self, shard_index, test_server_port, test_server_path): | 75 def __init__(self, shard_index, test_server_port, test_server_path, |
| 76 test_server_flags=None): |
70 """Sets up a Python driven test server on the host machine. | 77 """Sets up a Python driven test server on the host machine. |
71 | 78 |
72 Args: | 79 Args: |
73 shard_index: Index of the current shard. | 80 shard_index: Index of the current shard. |
74 test_server_port: Port to run the test server on. This is multiplexed with | 81 test_server_port: Port to run the test server on. This is multiplexed with |
75 the shard index. To retrieve the real port access the | 82 the shard index. To retrieve the real port access the |
76 member variable |port|. | 83 member variable |port|. |
77 test_server_path: The path (relative to the root src dir) of the server | 84 test_server_path: The path (relative to the root src dir) of the server |
| 85 test_server_flags: Optional list of additional flags to the test server |
78 """ | 86 """ |
79 self.host = _TEST_SERVER_HOST | 87 self.host = _TEST_SERVER_HOST |
80 self.port = test_server_port + shard_index | 88 self.port = test_server_port + shard_index |
81 | 89 |
82 src_dir = constants.DIR_SOURCE_ROOT | 90 src_dir = constants.DIR_SOURCE_ROOT |
83 # Make dirs into a list of absolute paths. | 91 # Make dirs into a list of absolute paths. |
84 abs_dirs = [os.path.join(src_dir, d) for d in _PYTHONPATH_DIRS] | 92 abs_dirs = [os.path.join(src_dir, d) for d in _PYTHONPATH_DIRS] |
85 # Add the generated python files to the path | 93 # Add the generated python files to the path |
86 abs_dirs.extend([os.path.join(src_dir, constants.GetOutDirectory(), d) | 94 abs_dirs.extend([os.path.join(src_dir, constants.GetOutDirectory(), d) |
87 for d in _GENERATED_PYTHONPATH_DIRS]) | 95 for d in _GENERATED_PYTHONPATH_DIRS]) |
88 current_python_path = os.environ.get('PYTHONPATH') | 96 current_python_path = os.environ.get('PYTHONPATH') |
89 extra_python_path = ':'.join(abs_dirs) | 97 extra_python_path = ':'.join(abs_dirs) |
90 if current_python_path: | 98 if current_python_path: |
91 python_path = current_python_path + ':' + extra_python_path | 99 python_path = current_python_path + ':' + extra_python_path |
92 else: | 100 else: |
93 python_path = extra_python_path | 101 python_path = extra_python_path |
94 | 102 |
95 # NOTE: A separate python process is used to simplify getting the right | 103 # NOTE: A separate python process is used to simplify getting the right |
96 # system path for finding includes. | 104 # system path for finding includes. |
| 105 test_server_flags = test_server_flags or [] |
97 cmd = ['python', os.path.join(src_dir, test_server_path), | 106 cmd = ['python', os.path.join(src_dir, test_server_path), |
98 '--log-to-console', | 107 '--log-to-console', |
99 ('--host=%s' % self.host), | 108 ('--host=%s' % self.host), |
100 ('--port=%d' % self.port)] | 109 ('--port=%d' % self.port)] + test_server_flags |
101 self._test_server_process = subprocess.Popen( | 110 self._test_server_process = subprocess.Popen( |
102 cmd, env={'PYTHONPATH': python_path}) | 111 cmd, env={'PYTHONPATH': python_path}) |
103 test_url = 'http://%s:%d/%s' % (self.host, self.port, | 112 test_url = 'http://%s:%d/%s' % (self.host, self.port, |
104 TEST_SERVER_CHECK_PARAMS[test_server_path]['url_path']) | 113 TEST_SERVER_CHECK_PARAMS[test_server_path]['url_path']) |
105 expected_response = TEST_SERVER_CHECK_PARAMS[test_server_path]['response'] | 114 expected_response = TEST_SERVER_CHECK_PARAMS[test_server_path]['response'] |
106 retries = 0 | 115 retries = 0 |
107 while retries < 5: | 116 while retries < 5: |
108 try: | 117 try: |
109 d = urllib2.urlopen(test_url).read() | 118 d = urllib2.urlopen(test_url).read() |
110 logging.info('URL %s GOT: %s' % (test_url, d)) | 119 logging.info('URL %s GOT: %s' % (test_url, d)) |
111 if d.startswith(expected_response): | 120 if d.startswith(expected_response): |
112 break | 121 break |
113 except Exception as e: | 122 except Exception as e: |
114 logging.info('URL %s GOT: %s' % (test_url, e)) | 123 logging.info('URL %s GOT: %s' % (test_url, e)) |
115 time.sleep(retries * 0.1) | 124 time.sleep(retries * 0.1) |
116 retries += 1 | 125 retries += 1 |
117 | 126 |
118 def TearDown(self): | 127 def TearDown(self): |
119 self._test_server_process.kill() | 128 self._test_server_process.kill() |
120 self._test_server_process.wait() | 129 self._test_server_process.wait() |
OLD | NEW |