diff options
author | shadi@chromium.org <shadi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-11 00:11:48 +0000 |
---|---|---|
committer | shadi@chromium.org <shadi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-11 00:11:48 +0000 |
commit | da5241685d3fc6230b356bf6e220cddd92e677fe (patch) | |
tree | 254efd723a21487388cd77ae9f4f476274025745 /media | |
parent | 4f0c429dc7092730d2a5a1277d9d1e72c241793b (diff) | |
download | chromium_src-da5241685d3fc6230b356bf6e220cddd92e677fe.zip chromium_src-da5241685d3fc6230b356bf6e220cddd92e677fe.tar.gz chromium_src-da5241685d3fc6230b356bf6e220cddd92e677fe.tar.bz2 |
Constrained Network test does not fail fast under fatal conditions.
This CL does the following:
- adds a timeout for each perf test, so that if a video does not load the test will time-out. (Currently set to 10 sec for playing event to be fired).
- adds sudo commands to traffic control.
- adds CNS logs to pyauto logs.
- s/kbps/kbit/ where applicable.
BUG=109322
TEST={cns, traffic_control} unit tests, local tests.
Review URL: http://codereview.chromium.org/9127009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@117125 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
5 files changed, 92 insertions, 64 deletions
diff --git a/media/tools/constrained_network_server/cn.py b/media/tools/constrained_network_server/cn.py index b79d8fb..fe5781c 100755 --- a/media/tools/constrained_network_server/cn.py +++ b/media/tools/constrained_network_server/cn.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# Copyright (c) 2011 The Chromium Authors. All rights reserved. +# Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -66,7 +66,7 @@ def _ParseArgs(): parser.add_option('--server-port', type='int', help='Port to forward traffic on --port to.') parser.add_option('--bandwidth', type='int', - help='Bandwidth of the network in kbps.') + help='Bandwidth of the network in kbit/s.') parser.add_option('--latency', type='int', help=('Latency (delay) added to each outgoing packet in ' 'ms.')) diff --git a/media/tools/constrained_network_server/cns.py b/media/tools/constrained_network_server/cns.py index 4f0198d..5b9ff51 100755 --- a/media/tools/constrained_network_server/cns.py +++ b/media/tools/constrained_network_server/cns.py @@ -12,6 +12,7 @@ TODO(dalecurtis): Add some more docs here. """ +import logging import mimetypes import optparse import os @@ -31,6 +32,9 @@ except ImportError: # Add webm file types to mimetypes map since cherrypy's default type is text. mimetypes.types_map['.webm'] = 'video/webm' +# Default logging is ERROR. Use --verbose to enable DEBUG logging. +_DEFAULT_LOG_LEVEL = logging.ERROR + # Default port to serve the CNS on. _DEFAULT_SERVING_PORT = 9000 @@ -287,6 +291,8 @@ def ParseArgs(): parser.add_option('--www-root', default=os.getcwd(), help=('Directory root to serve files from. Defaults to the ' 'current directory: %default')) + parser.add_option('-v', '--verbose', action='store_true', dest='verbose', + default=False, help='Turn on verbose output.') options = parser.parse_args()[0] @@ -300,9 +306,23 @@ def ParseArgs(): # Convert the path to an absolute to remove any . or .. options.www_root = os.path.abspath(options.www_root) + # Required so that cherrypy logs do not get propagated to root logger causing + # the logs to be printed twice. + cherrypy.log.error_log.propagate = False + + _SetLogger(options.verbose) + return options +def _SetLogger(verbose): + # Logging is used for traffic_control debug statements. + log_level = _DEFAULT_LOG_LEVEL + if verbose: + log_level = logging.DEBUG + logging.basicConfig(level=log_level, format='[%(threadName)s] %(message)s') + + def Main(): """Configure and start the ConstrainedNetworkServer.""" options = ParseArgs() diff --git a/media/tools/constrained_network_server/traffic_control.py b/media/tools/constrained_network_server/traffic_control.py index aa8a157..e297968 100755 --- a/media/tools/constrained_network_server/traffic_control.py +++ b/media/tools/constrained_network_server/traffic_control.py @@ -1,4 +1,4 @@ -# Copyright (c) 2011 The Chromium Authors. All rights reserved. +# Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -13,7 +13,7 @@ import re import subprocess # The maximum bandwidth limit. -_DEFAULT_MAX_BANDWIDTH_KBPS = 1000000 +_DEFAULT_MAX_BANDWIDTH_KBIT = 1000000 class TrafficControlError(BaseException): @@ -50,7 +50,7 @@ def CreateConstrainedPort(config): server_port: Port to redirect traffic on [port] to (integer 1-65535). interface: Network interface name (string). latency: Delay added on each packet sent (integer in ms). - bandwidth: Maximum allowed upload bandwidth (integer in kbps). + bandwidth: Maximum allowed upload bandwidth (integer in kbit/s). loss: Percentage of packets to drop (integer 0-100). Raises: @@ -86,7 +86,7 @@ def DeleteConstrainedPort(config): port: Port to constrain (integer 1-65535). server_port: Port to redirect traffic on [port] to (integer 1-65535). interface: Network interface name (string). - bandwidth: Maximum allowed upload bandwidth (integer in kbps). + bandwidth: Maximum allowed upload bandwidth (integer in kbit/s). Raises: TrafficControlError: If any operation fails. The message in the exception @@ -118,7 +118,7 @@ def TearDown(config): """ _CheckArgsExist(config, 'interface') - command = ['tc', 'qdisc', 'del', 'dev', config['interface'], 'root'] + command = ['sudo', 'tc', 'qdisc', 'del', 'dev', config['interface'], 'root'] try: _Exec(command, msg='Could not delete root qdisc.') finally: @@ -150,8 +150,8 @@ def _AddRootQdisc(interface): TrafficControlError: If adding the root qdisc fails for a reason other than it already exists. """ - command = ['tc', 'qdisc', 'add', 'dev', interface, 'root', 'handle', '1:', - 'htb'] + command = ['sudo', 'tc', 'qdisc', 'add', 'dev', interface, 'root', 'handle', + '1:', 'htb'] try: _Exec(command, msg=('Error creating root qdisc. ' 'Make sure you have root access')) @@ -172,19 +172,20 @@ def _ConfigureClass(option, config): config: Constraint configuration dictionary, format: port: Port to constrain (integer 1-65535). interface: Network interface name (string). - bandwidth: Maximum allowed upload bandwidth (integer in kbps). + bandwidth: Maximum allowed upload bandwidth (integer in kbit/s). """ # Use constrained port as class ID so we can attach the qdisc and filter to # it, as well as delete the class, using only the port number. class_id = '1:%x' % config['port'] if 'bandwidth' not in config.keys() or not config['bandwidth']: - bandwidth = _DEFAULT_MAX_BANDWIDTH_KBPS + bandwidth = _DEFAULT_MAX_BANDWIDTH_KBIT else: bandwidth = config['bandwidth'] - bandwidth = '%dkbps' % bandwidth - command = ['tc', 'class', option, 'dev', config['interface'], 'parent', '1:', - 'classid', class_id, 'htb', 'rate', bandwidth, 'ceil', bandwidth] + bandwidth = '%dkbit' % bandwidth + command = ['sudo', 'tc', 'class', option, 'dev', config['interface'], + 'parent', '1:', 'classid', class_id, 'htb', 'rate', bandwidth, + 'ceil', bandwidth] _Exec(command, msg=('Error configuring class ID %s using "%s" command.' % (class_id, option))) @@ -201,7 +202,7 @@ def _AddSubQdisc(config): """ port_hex = '%x' % config['port'] class_id = '1:%x' % config['port'] - command = ['tc', 'qdisc', 'add', 'dev', config['interface'], 'parent', + command = ['sudo', 'tc', 'qdisc', 'add', 'dev', config['interface'], 'parent', class_id, 'handle', port_hex + ':0', 'netem'] # Check if packet-loss is set in the configuration. @@ -225,7 +226,7 @@ def _AddFilter(interface, port): """ class_id = '1:%x' % port - command = ['tc', 'filter', 'add', 'dev', interface, 'protocol', 'ip', + command = ['sudo', 'tc', 'filter', 'add', 'dev', interface, 'protocol', 'ip', 'parent', '1:', 'prio', '1', 'u32', 'match', 'ip', 'sport', port, '0xffff', 'flowid', class_id] _Exec(command, msg='Error adding filter on port %d.' % port) @@ -239,7 +240,7 @@ def _DeleteFilter(interface, port): port: Port number being filtered (integer 1-65535). """ handle_id = _GetFilterHandleId(interface, port) - command = ['tc', 'filter', 'del', 'dev', interface, 'protocol', 'ip', + command = ['sudo', 'tc', 'filter', 'del', 'dev', interface, 'protocol', 'ip', 'parent', '1:0', 'handle', handle_id, 'prio', '1', 'u32'] _Exec(command, msg='Error deleting filter on port %d.' % port) @@ -257,7 +258,7 @@ def _GetFilterHandleId(interface, port): Raises: TrafficControlError: If handle ID was not found. """ - command = ['tc', 'filter', 'list', 'dev', interface, 'parent', '1:'] + command = ['sudo', 'tc', 'filter', 'list', 'dev', interface, 'parent', '1:'] output = _Exec(command, msg='Error listing filters.') # Search for the filter handle ID associated with class ID '1:port'. handle_id_re = re.search( @@ -277,13 +278,14 @@ def _AddIptableRule(interface, port, server_port): server_port: Server port to forward the packets to (integer 1-65535). """ # Preroute rules for accessing the port through external connections. - command = ['iptables', '-t', 'nat', '-A', 'PREROUTING', '-i', interface, '-p', - 'tcp', '--dport', port, '-j', 'REDIRECT', '--to-port', server_port] + command = ['sudo', 'iptables', '-t', 'nat', '-A', 'PREROUTING', '-i', + interface, '-p', 'tcp', '--dport', port, '-j', 'REDIRECT', + '--to-port', server_port] _Exec(command, msg='Error adding iptables rule for port %d.' % port) # Output rules for accessing the rule through localhost or 127.0.0.1 - command = ['iptables', '-t', 'nat', '-A', 'OUTPUT', '-p', 'tcp', '--dport', - port, '-j', 'REDIRECT', '--to-port', server_port] + command = ['sudo', 'iptables', '-t', 'nat', '-A', 'OUTPUT', '-p', 'tcp', + '--dport', port, '-j', 'REDIRECT', '--to-port', server_port] _Exec(command, msg='Error adding iptables rule for port %d.' % port) @@ -295,18 +297,19 @@ def _DeleteIptableRule(interface, port, server_port): port: Port of incoming packets (integer 1-65535). server_port: Server port packets are forwarded to (integer 1-65535). """ - command = ['iptables', '-t', 'nat', '-D', 'PREROUTING', '-i', interface, '-p', - 'tcp', '--dport', port, '-j', 'REDIRECT', '--to-port', server_port] + command = ['sudo', 'iptables', '-t', 'nat', '-D', 'PREROUTING', '-i', + interface, '-p', 'tcp', '--dport', port, '-j', 'REDIRECT', + '--to-port', server_port] _Exec(command, msg='Error deleting iptables rule for port %d.' % port) - command = ['iptables', '-t', 'nat', '-D', 'OUTPUT', '-p', 'tcp', '--dport', - port, '-j', 'REDIRECT', '--to-port', server_port] + command = ['sudo', 'iptables', '-t', 'nat', '-D', 'OUTPUT', '-p', 'tcp', + '--dport', port, '-j', 'REDIRECT', '--to-port', server_port] _Exec(command, msg='Error adding iptables rule for port %d.' % port) def _DeleteAllIpTableRules(): """Deletes all iptables rules.""" - command = ['iptables', '-t', 'nat', '-F'] + command = ['sudo', 'iptables', '-t', 'nat', '-F'] _Exec(command, msg='Error deleting all iptables rules.') diff --git a/media/tools/constrained_network_server/traffic_control_test.py b/media/tools/constrained_network_server/traffic_control_test.py index a84462f..d641253 100644 --- a/media/tools/constrained_network_server/traffic_control_test.py +++ b/media/tools/constrained_network_server/traffic_control_test.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright (c) 2011 The Chromium Authors. All rights reserved. +# Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -75,10 +75,8 @@ class TrafficControlTests(unittest.TestCase): 'server_port': 33333, 'bandwidth': 2000 } - # Convert Kbps to Kbit. - rate = config['bandwidth'] * 8 class_detail = ('class htb 1:%x root prio 0 rate %dKbit ceil %dKbit' % - (config['port'], rate, rate)) + (config['port'], config['bandwidth'], config['bandwidth'])) # Add root qdisc. traffic_control._AddRootQdisc(config['interface']) diff --git a/media/tools/constrained_network_server/traffic_control_unittest.py b/media/tools/constrained_network_server/traffic_control_unittest.py index 29580b4..a6781e9 100644 --- a/media/tools/constrained_network_server/traffic_control_unittest.py +++ b/media/tools/constrained_network_server/traffic_control_unittest.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright (c) 2011 The Chromium Authors. All rights reserved. +# Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -43,17 +43,17 @@ class TrafficControlUnitTests(unittest.TestCase): } traffic_control.CreateConstrainedPort(config) expected = [ - 'tc qdisc add dev fakeeth root handle 1: htb', - 'tc class add dev fakeeth parent 1: classid 1:3039 htb rate 256kbps ' - 'ceil 256kbps', - 'tc qdisc add dev fakeeth parent 1:3039 handle 3039:0 netem loss 2% ' - 'delay 100ms', - 'tc filter add dev fakeeth protocol ip parent 1: prio 1 u32 match ip ' - 'sport 12345 0xffff flowid 1:3039', - 'iptables -t nat -A PREROUTING -i fakeeth -p tcp --dport 12345 -j ' + 'sudo tc qdisc add dev fakeeth root handle 1: htb', + 'sudo tc class add dev fakeeth parent 1: classid 1:3039 htb rate ' + '256kbit ceil 256kbit', + 'sudo tc qdisc add dev fakeeth parent 1:3039 handle 3039:0 netem loss ' + '2% delay 100ms', + 'sudo tc filter add dev fakeeth protocol ip parent 1: prio 1 u32 match ' + 'ip sport 12345 0xffff flowid 1:3039', + 'sudo iptables -t nat -A PREROUTING -i fakeeth -p tcp --dport 12345 -j ' 'REDIRECT --to-port 8888', - 'iptables -t nat -A OUTPUT -p tcp --dport 12345 -j REDIRECT --to-port ' - '8888' + 'sudo iptables -t nat -A OUTPUT -p tcp --dport 12345 -j REDIRECT ' + '--to-port 8888' ] self.assertEqual(expected, self.commands) @@ -66,17 +66,17 @@ class TrafficControlUnitTests(unittest.TestCase): } traffic_control.CreateConstrainedPort(config) expected = [ - 'tc qdisc add dev fakeeth root handle 1: htb', - 'tc class add dev fakeeth parent 1: classid 1:3039 htb rate %dkbps ' - 'ceil %dkbps' % (traffic_control._DEFAULT_MAX_BANDWIDTH_KBPS, - traffic_control._DEFAULT_MAX_BANDWIDTH_KBPS), - 'tc qdisc add dev fakeeth parent 1:3039 handle 3039:0 netem', - 'tc filter add dev fakeeth protocol ip parent 1: prio 1 u32 match ip ' - 'sport 12345 0xffff flowid 1:3039', - 'iptables -t nat -A PREROUTING -i fakeeth -p tcp --dport 12345 -j ' + 'sudo tc qdisc add dev fakeeth root handle 1: htb', + 'sudo tc class add dev fakeeth parent 1: classid 1:3039 htb rate ' + '%dkbit ceil %dkbit' % (traffic_control._DEFAULT_MAX_BANDWIDTH_KBIT, + traffic_control._DEFAULT_MAX_BANDWIDTH_KBIT), + 'sudo tc qdisc add dev fakeeth parent 1:3039 handle 3039:0 netem', + 'sudo tc filter add dev fakeeth protocol ip parent 1: prio 1 u32 ' + 'match ip sport 12345 0xffff flowid 1:3039', + 'sudo iptables -t nat -A PREROUTING -i fakeeth -p tcp --dport 12345 -j ' 'REDIRECT --to-port 8888', - 'iptables -t nat -A OUTPUT -p tcp --dport 12345 -j REDIRECT --to-port ' - '8888' + 'sudo iptables -t nat -A OUTPUT -p tcp --dport 12345 -j REDIRECT ' + '--to-port 8888' ] self.assertEqual(expected, self.commands) @@ -93,13 +93,13 @@ class TrafficControlUnitTests(unittest.TestCase): try: traffic_control.DeleteConstrainedPort(config) expected = [ - 'tc filter del dev fakeeth protocol ip parent 1:0 handle 800::800 ' - 'prio 1 u32', - 'tc class del dev fakeeth parent 1: classid 1:3039 htb rate 256kbps ' - 'ceil 256kbps', - 'iptables -t nat -D PREROUTING -i fakeeth -p tcp --dport 12345 -j ' - 'REDIRECT --to-port 8888', - 'iptables -t nat -D OUTPUT -p tcp --dport 12345 -j REDIRECT ' + 'sudo tc filter del dev fakeeth protocol ip parent 1:0 handle ' + '800::800 prio 1 u32', + 'sudo tc class del dev fakeeth parent 1: classid 1:3039 htb rate ' + '256kbit ceil 256kbit', + 'sudo iptables -t nat -D PREROUTING -i fakeeth -p tcp --dport 12345 ' + '-j REDIRECT --to-port 8888', + 'sudo iptables -t nat -D OUTPUT -p tcp --dport 12345 -j REDIRECT ' '--to-port 8888'] self.assertEqual(expected, self.commands) finally: @@ -110,8 +110,8 @@ class TrafficControlUnitTests(unittest.TestCase): traffic_control.TearDown(config) expected = [ - 'tc qdisc del dev fakeeth root', - 'iptables -t nat -F' + 'sudo tc qdisc del dev fakeeth root', + 'sudo iptables -t nat -F' ] self.assertEqual(expected, self.commands) @@ -119,16 +119,23 @@ class TrafficControlUnitTests(unittest.TestCase): # Check seach for handle ID command. self.assertRaises(traffic_control.TrafficControlError, traffic_control._GetFilterHandleId, 'fakeeth', 1) - self.assertEquals(self.commands, ['tc filter list dev fakeeth parent 1:']) + self.assertEquals(self.commands, ['sudo tc filter list dev fakeeth parent ' + '1:']) # Check with handle ID available. traffic_control._Exec = (lambda command, msg: - 'filter parent 1: protocol ip'' pref 1 u32 fh 800::800 order 2048 key ht ' - '800 bkt 0 flowid 1:1') + 'filter parent 1: protocol ip pref 1 u32 fh 800::800 order 2048 key ht ' + '800 bkt 0 flowid 1:1\nmatch 08ae0000/ffff0000 at 20') output = traffic_control._GetFilterHandleId('fakeeth', 1) self.assertEqual(output, '800::800') # Check with handle ID not available. + traffic_control._Exec = (lambda command, msg: + 'filter parent 1: protocol ip pref 1 u32 fh 800::800 order 2048 key ht ' + '800 bkt 0 flowid 1:11\nmatch 08ae0000/ffff0000 at 20') + self.assertRaises(traffic_control.TrafficControlError, + traffic_control._GetFilterHandleId, 'fakeeth', 1) + traffic_control._Exec = lambda command, msg: 'NO ID IN HERE' self.assertRaises(traffic_control.TrafficControlError, traffic_control._GetFilterHandleId, 'fakeeth', 1) |