Skip to content

Instantly share code, notes, and snippets.

@lhchavez
Created November 22, 2015 18:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lhchavez/faac814cb599e47376b0 to your computer and use it in GitHub Desktop.
Save lhchavez/faac814cb599e47376b0 to your computer and use it in GitHub Desktop.
#!/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