/chromium-webcl/src/media/tools/constrained_network_server/cn.py
https://bitbucket.org/peixuan/chromium_r197479_base · Python · 123 lines · 72 code · 24 blank · 27 comment · 10 complexity · 76d7c8dc0399ff7949cc551a0d7b577a MD5 · raw file
- #!/usr/bin/env python
- # 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.
- """A script for configuring constraint networks.
- Sets up a constrained network configuration on a specific port. Traffic on this
- port will be redirected to another local server port.
- The configuration includes bandwidth, latency, and packet loss.
- """
- import collections
- import logging
- import optparse
- import traffic_control
- # Default logging is ERROR. Use --verbose to enable DEBUG logging.
- _DEFAULT_LOG_LEVEL = logging.ERROR
- Dispatcher = collections.namedtuple('Dispatcher', ['dispatch', 'requires_ports',
- 'desc'])
- # Map of command names to traffic_control functions.
- COMMANDS = {
- # Adds a new constrained network configuration.
- 'add': Dispatcher(traffic_control.CreateConstrainedPort,
- requires_ports=True, desc='Add a new constrained port.'),
- # Deletes an existing constrained network configuration.
- 'del': Dispatcher(traffic_control.DeleteConstrainedPort,
- requires_ports=True, desc='Delete a constrained port.'),
- # Deletes all constrained network configurations.
- 'teardown': Dispatcher(traffic_control.TearDown,
- requires_ports=False,
- desc='Teardown all constrained ports.')
- }
- def _ParseArgs():
- """Define and parse command-line arguments.
- Returns:
- tuple as (command, configuration):
- command: one of the possible commands to setup, delete or teardown the
- constrained network.
- configuration: a map of constrained network properties to their values.
- """
- parser = optparse.OptionParser()
- indent_first = parser.formatter.indent_increment
- opt_width = parser.formatter.help_position - indent_first
- cmd_usage = []
- for s in COMMANDS:
- cmd_usage.append('%*s%-*s%s' %
- (indent_first, '', opt_width, s, COMMANDS[s].desc))
- parser.usage = ('usage: %%prog {%s} [options]\n\n%s' %
- ('|'.join(COMMANDS.keys()), '\n'.join(cmd_usage)))
- parser.add_option('--port', type='int',
- help='The port to apply traffic control constraints to.')
- 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 kbit/s.')
- parser.add_option('--latency', type='int',
- help=('Latency (delay) added to each outgoing packet in '
- 'ms.'))
- parser.add_option('--loss', type='int',
- help='Packet-loss percentage on outgoing packets. ')
- parser.add_option('--interface', type='string',
- help=('Interface to setup constraints on. Use "lo" for a '
- 'local client.'))
- parser.add_option('-v', '--verbose', action='store_true', dest='verbose',
- default=False, help='Turn on verbose output.')
- options, args = parser.parse_args()
- _SetLogger(options.verbose)
- # Check a valid command was entered
- if not args or args[0].lower() not in COMMANDS:
- parser.error('Please specify a command {%s}.' % '|'.join(COMMANDS.keys()))
- user_cmd = args[0].lower()
- # Check if required options are available
- if COMMANDS[user_cmd].requires_ports:
- if not (options.port and options.server_port):
- parser.error('Please provide port and server-port values.')
- config = {
- 'port': options.port,
- 'server_port': options.server_port,
- 'interface': options.interface,
- 'latency': options.latency,
- 'bandwidth': options.bandwidth,
- 'loss': options.loss
- }
- return user_cmd, config
- def _SetLogger(verbose):
- log_level = _DEFAULT_LOG_LEVEL
- if verbose:
- log_level = logging.DEBUG
- logging.basicConfig(level=log_level, format='%(message)s')
- def Main():
- """Get the command and configuration of the network to set up."""
- user_cmd, config = _ParseArgs()
- try:
- COMMANDS[user_cmd].dispatch(config)
- except traffic_control.TrafficControlError as e:
- logging.error('Error: %s\n\nOutput: %s', e.msg, e.error)
- if __name__ == '__main__':
- Main()