OLD | NEW |
---|---|
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 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 """Constrained network server (CNS) test base.""" | 5 """Constrained network server (CNS) test base.""" |
6 | 6 |
7 import logging | 7 import logging |
8 import os | 8 import os |
9 import Queue | 9 import Queue |
10 import subprocess | 10 import subprocess |
11 import sys | 11 import sys |
12 import threading | 12 import threading |
13 import urllib2 | 13 import urllib2 |
14 | 14 |
15 import pyauto | 15 import pyauto |
16 import pyauto_paths | 16 import pyauto_paths |
17 | 17 |
18 WINDOWS = 'win32' in sys.platform | |
19 | 18 |
20 # List of commonly used network constraints settings. | 19 # List of commonly used network constraints settings. |
21 # Each setting is a tuppe of the form: | 20 # Each setting is a tuppe of the form: |
22 # ('TEST_NAME', [BANDWIDTH_Kbps, LATENCY_ms, PACKET_LOSS_%]) | 21 # ('TEST_NAME', [BANDWIDTH_Kbps, LATENCY_ms, PACKET_LOSS_%]) |
23 # | 22 # |
24 # Note: The test name should satisfy the regex [\w\.-]+ (check | 23 # Note: The test name should satisfy the regex [\w\.-]+ (check |
25 # tools/perf_expectations/tests/perf_expectations_unittest.py for details). It | 24 # tools/perf_expectations/tests/perf_expectations_unittest.py for details). It |
26 # is used to name the result graphs on the dashboards. | 25 # is used to name the result graphs on the dashboards. |
27 # | 26 # |
28 # The WiFi, DSL, and Cable settings were taken from webpagetest.org as | 27 # The WiFi, DSL, and Cable settings were taken from webpagetest.org as |
29 # approximations of their respective real world networks. The settings were | 28 # approximations of their respective real world networks. The settings were |
30 # based on 2011 FCC Broadband Data report (http://www.fcc.gov/document/ | 29 # based on 2011 FCC Broadband Data report (http://www.fcc.gov/document/ |
31 # measuring-broadband-america-report-consumer-broadband-performance-us). | 30 # measuring-broadband-america-report-consumer-broadband-performance-us). |
32 DialUp = ('DialUp', [56, 120, 5]) | 31 DialUp = ('DialUp', [56, 120, 5]) |
33 Slow = ('Slow', [256, 105, 1]) | 32 Slow = ('Slow', [256, 105, 1]) |
34 Wifi = ('Wifi', [1024, 60, 0]) | 33 Wifi = ('Wifi', [1024, 60, 0]) |
35 DSL = ('DSL', [1541, 50, 0]) | 34 DSL = ('DSL', [1541, 50, 0]) |
36 Cable = ('Cable', [5120, 28, 0]) | 35 Cable = ('Cable', [5120, 28, 0]) |
37 NoConstraints = ('NoConstraints', [0, 0, 0]) | 36 NoConstraints = ('NoConstraints', [0, 0, 0]) |
38 | 37 |
39 # Path to CNS executable relative to source root. | 38 # Path to CNS executable relative to source root. |
40 _CNS_PATH = os.path.join( | 39 _CNS_PATH = os.path.join( |
41 'media', 'tools', 'constrained_network_server', 'cns.py') | 40 'media', 'tools', 'constrained_network_server', 'cns.py') |
42 | 41 |
43 # Port to start the CNS on. | 42 # Port to start the CNS on. |
44 _CNS_PORT = 9000 | 43 _CNS_PORT = 9000 |
45 | 44 |
45 # A flag to determine whether to launch a local CNS instance or to connect | |
46 # to the external CNS server. Default to True since all current bots use an | |
47 # external instance. Set to false when running a local test. | |
48 USE_EXTERNAL_SERVER = False | |
DaleCurtis
2012/08/16 00:15:58
Can we make this a command line option? Also the c
shadi
2012/08/16 19:49:27
After offline discussion, we decided to use an env
| |
49 | |
46 # Base CNS URL, only requires & separated parameter names appended. | 50 # Base CNS URL, only requires & separated parameter names appended. |
47 if WINDOWS: | 51 if USE_EXTERNAL_SERVER: |
48 CNS_BASE_URL = 'http://chromeperf34:%d/ServeConstrained?' % _CNS_PORT | 52 CNS_BASE_URL = 'http://chromeperf34:%d/ServeConstrained?' % _CNS_PORT |
53 CNS_CLEANUP_URL = 'http://chromeperf34:%d/Cleanup' % _CNS_PORT | |
49 else: | 54 else: |
50 CNS_BASE_URL = 'http://127.0.0.1:%d/ServeConstrained?' % _CNS_PORT | 55 CNS_BASE_URL = 'http://127.0.0.1:%d/ServeConstrained?' % _CNS_PORT |
51 | 56 |
52 # Used for server sanity check. | 57 # Used for server sanity check. |
53 _TEST_VIDEO = 'roller.webm' | 58 _TEST_VIDEO = 'roller.webm' |
54 | 59 |
55 # Directory root to serve files from. | 60 # Directory root to serve files from. |
56 _ROOT_PATH = os.path.join(pyauto.PyUITest.DataDir(), 'pyauto_private', 'media') | 61 _ROOT_PATH = os.path.join(pyauto.PyUITest.DataDir(), 'pyauto_private', 'media') |
57 | 62 |
58 | 63 |
59 class CNSTestBase(pyauto.PyUITest): | 64 class CNSTestBase(pyauto.PyUITest): |
60 """CNS test base hadles startup and teardown of CNS server.""" | 65 """CNS test base hadles startup and teardown of CNS server.""" |
61 | 66 |
62 def __init__(self, *args, **kwargs): | 67 def __init__(self, *args, **kwargs): |
63 """Initialize CNSTestBase by setting the arguments for CNS server. | 68 """Initialize CNSTestBase by setting the arguments for CNS server. |
64 | 69 |
65 Args: | 70 Args: |
66 Check cns.py command line argument list for details. | 71 Check cns.py command line argument list for details. |
67 """ | 72 """ |
68 self._port = kwargs.get('port', _CNS_PORT) | 73 self._port = kwargs.get('port', _CNS_PORT) |
69 self._interface = kwargs.get('interface', 'lo') | 74 self._interface = kwargs.get('interface', 'lo') |
70 self._www_root = kwargs.get('www_root', _ROOT_PATH) | 75 self._www_root = kwargs.get('www_root', _ROOT_PATH) |
71 self._verbose = kwargs.get('verbose', True) | 76 self._verbose = kwargs.get('verbose', True) |
72 self._expiry_time = kwargs.get('expiry_time', 0) | 77 self._expiry_time = kwargs.get('expiry_time', 0) |
73 self._socket_timeout = kwargs.get('socket_timeout') | 78 self._socket_timeout = kwargs.get('socket_timeout') |
74 pyauto.PyUITest.__init__(self, *args, **kwargs) | 79 pyauto.PyUITest.__init__(self, *args, **kwargs) |
75 | 80 |
76 def setUp(self): | 81 def setUp(self): |
77 """Ensures the Constrained Network Server (CNS) server is up and running.""" | 82 """Ensures the Constrained Network Server (CNS) server is up and running.""" |
78 if WINDOWS: | 83 if USE_EXTERNAL_SERVER: |
79 self._SetUpWin() | 84 self._SetUpExternal() |
80 else: | 85 else: |
81 self._SetUpLinux() | 86 self._SetUpLocal() |
82 | 87 |
83 def _SetUpWin(self): | 88 def _SetUpExternal(self): |
84 """Ensures the test can connect to the external CNS server.""" | 89 """Ensures the test can connect to the external CNS server.""" |
85 if self.WaitUntil(self._CanAccessServer, retry_sleep=3, timeout=30, | 90 if self.WaitUntil(self._CanAccessServer, retry_sleep=3, timeout=30, |
86 debug=False): | 91 debug=False): |
87 pyauto.PyUITest.setUp(self) | 92 pyauto.PyUITest.setUp(self) |
88 else: | 93 else: |
89 self.fail('Failed to connect to CNS.') | 94 self.fail('Failed to connect to CNS.') |
90 | 95 |
91 def _SetUpLinux(self): | 96 def _SetUpLocal(self): |
92 """Starts the CNS server locally.""" | 97 """Starts the CNS server locally.""" |
93 cmd = [sys.executable, os.path.join(pyauto_paths.GetSourceDir(), _CNS_PATH), | 98 cmd = [sys.executable, os.path.join(pyauto_paths.GetSourceDir(), _CNS_PATH), |
94 '--port', str(self._port), | 99 '--port', str(self._port), |
95 '--interface', self._interface, | 100 '--interface', self._interface, |
96 '--www-root', self._www_root, | 101 '--www-root', self._www_root, |
97 '--expiry-time', str(self._expiry_time)] | 102 '--expiry-time', str(self._expiry_time)] |
98 | 103 |
99 if self._socket_timeout: | 104 if self._socket_timeout: |
100 cmd.extend(['--socket-timeout', str(self._socket_timeout)]) | 105 cmd.extend(['--socket-timeout', str(self._socket_timeout)]) |
101 if self._verbose: | 106 if self._verbose: |
(...skipping 13 matching lines...) Expand all Loading... | |
115 def _CanAccessServer(self): | 120 def _CanAccessServer(self): |
116 """Checks if the CNS server can serve a file with no network constraints.""" | 121 """Checks if the CNS server can serve a file with no network constraints.""" |
117 test_url = ''.join([CNS_BASE_URL, 'f=', _TEST_VIDEO]) | 122 test_url = ''.join([CNS_BASE_URL, 'f=', _TEST_VIDEO]) |
118 try: | 123 try: |
119 return urllib2.urlopen(test_url) is not None | 124 return urllib2.urlopen(test_url) is not None |
120 except Exception: | 125 except Exception: |
121 return False | 126 return False |
122 | 127 |
123 def tearDown(self): | 128 def tearDown(self): |
124 """Stops the Constrained Network Server (CNS).""" | 129 """Stops the Constrained Network Server (CNS).""" |
125 pyauto.PyUITest.tearDown(self) | 130 if USE_EXTERNAL_SERVER: |
126 if not WINDOWS: | 131 # Call CNS Cleanup to remove all ports created by this client. |
132 self.NavigateToURL(CNS_CLEANUP_URL) | |
133 else: | |
127 logging.debug('Stopping CNS server.') | 134 logging.debug('Stopping CNS server.') |
128 # Do not use process.kill(), it will not clean up cns. | 135 # Do not use process.kill(), it will not clean up cns. |
129 self.Kill(self._cns_process.pid) | 136 self.Kill(self._cns_process.pid) |
130 # Need to wait since the process logger has a lock on the process stderr. | 137 # Need to wait since the process logger has a lock on the process stderr. |
131 self._cns_process.wait() | 138 self._cns_process.wait() |
132 self.assertFalse(self._cns_process.returncode is None) | 139 self.assertFalse(self._cns_process.returncode is None) |
133 logging.debug('CNS server stopped.') | 140 logging.debug('CNS server stopped.') |
141 pyauto.PyUITest.tearDown(self) | |
134 | 142 |
135 | 143 |
136 class ProcessLogger(threading.Thread): | 144 class ProcessLogger(threading.Thread): |
137 """A thread to log a process's stderr output.""" | 145 """A thread to log a process's stderr output.""" |
138 | 146 |
139 def __init__(self, process): | 147 def __init__(self, process): |
140 """Starts the process logger thread. | 148 """Starts the process logger thread. |
141 | 149 |
142 Args: | 150 Args: |
143 process: The process to log. | 151 process: The process to log. |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
182 """ | 190 """ |
183 # Convert relative test path into an absolute path. | 191 # Convert relative test path into an absolute path. |
184 tasks = Queue.Queue() | 192 tasks = Queue.Queue() |
185 for file_name in test_media_files: | 193 for file_name in test_media_files: |
186 for series_name, settings in network_constraints_settings: | 194 for series_name, settings in network_constraints_settings: |
187 logging.debug('Add test: %s\tSettings: %s\tMedia: %s', series_name, | 195 logging.debug('Add test: %s\tSettings: %s\tMedia: %s', series_name, |
188 settings, file_name) | 196 settings, file_name) |
189 tasks.put((series_name, settings, file_name)) | 197 tasks.put((series_name, settings, file_name)) |
190 | 198 |
191 return tasks | 199 return tasks |
OLD | NEW |