Created
November 22, 2015 18:01
-
-
Save lhchavez/faac814cb599e47376b0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
import argparse | |
import random | |
import subprocess | |
import sys | |
import time | |
PREFIX = '/sbin/ip netns exec' | |
DISRUPTIONS = [ | |
( | |
'100ms delay', | |
'tc qdisc add dev eth0 root netem delay 100ms 50ms 10%', | |
'tc qdisc del dev eth0 root netem' | |
), | |
( | |
'1000ms +/- 500ms delay', | |
'tc qdisc add dev eth0 root netem delay 1000ms 500ms 25%', | |
'tc qdisc del dev eth0 root netem' | |
), | |
( | |
'1% packet loss', | |
'tc qdisc add dev eth0 root netem loss 1%', | |
'tc qdisc del dev eth0 root netem' | |
), | |
( | |
'5% packet loss', | |
'tc qdisc add dev eth0 root netem loss 5% 25%', | |
'tc qdisc del dev eth0 root netem' | |
), | |
( | |
'25% packet loss', | |
'tc qdisc add dev eth0 root netem loss 25% 25%', | |
'tc qdisc del dev eth0 root netem' | |
), | |
( | |
'100% packet loss', | |
'tc qdisc add dev eth0 root netem loss 100%', | |
'tc qdisc del dev eth0 root netem' | |
), | |
( | |
'port blocked', | |
'iptables -A OUTPUT -p tcp --dport 8080 -j DROP', | |
'iptables -D OUTPUT -p tcp --dport 8080 -j DROP' | |
), | |
( | |
'port rejecting', | |
'iptables -A OUTPUT -p tcp --dport 8080 -j REJECT', | |
'iptables -D OUTPUT -p tcp --dport 8080 -j REJECT' | |
), | |
] | |
def exec_disruption(namespace, command): | |
subprocess.check_call(PREFIX.split() + [namespace] + command.split()) | |
def main(args): | |
running = True | |
print '[' | |
sys.stdout.flush() | |
while running: | |
disruption = random.choice(DISRUPTIONS) | |
disrupt = random.random() <= args.probability | |
try: | |
if disrupt: | |
print '{"name":"%s","tid":0,"pid":0,"ts":%d,"ph":"B"},' % \ | |
(disruption[0], time.time() * 1000) | |
sys.stdout.flush() | |
exec_disruption(args.namespace, disruption[1]) | |
time.sleep(args.period) | |
except KeyboardInterrupt: | |
running = False | |
finally: | |
if disrupt: | |
print '{"name":"%s","tid":0,"pid":0,"ts":%d,"ph":"E"},' % \ | |
(disruption[0], time.time() * 1000) | |
sys.stdout.flush() | |
exec_disruption(args.namespace, disruption[2]) | |
return 0 | |
if __name__ == '__main__': | |
parser = argparse.ArgumentParser( | |
description='Simulates bad networking conditions') | |
parser.add_argument('namespace', type=str, | |
help='The network namespace') | |
parser.add_argument('--probability', type=float, default=0.25, | |
help='The probability in [0.0,1.0) of a disruption') | |
parser.add_argument('--period', type=int, default=(5*60), | |
help='The length (in seconds) of a period') | |
sys.exit(main(parser.parse_args())) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment