Commit 27ce6c3b authored by Martín Ferrari's avatar Martín Ferrari

Document Link parameters. Fix units. Add a couple more tests

parent ed14e260
...@@ -360,6 +360,20 @@ class Link(ExternalInterface): ...@@ -360,6 +360,20 @@ class Link(ExternalInterface):
loss = None, loss_correlation = None, loss = None, loss_correlation = None,
dup = None, dup_correlation = None, dup = None, dup_correlation = None,
corrupt = None, corrupt_correlation = None): corrupt = None, corrupt_correlation = None):
"""Set the parameters that control the link characteristics. For the
description of each, refer to netem documentation:
http://www.linuxfoundation.org/collaborate/workgroups/networking/netem
Arguments:
- `bandwidth' should be specified in bits per second.
- `delay' and `delay_jitter' are specified in seconds.
- `delay_distribution' is the name of a distribution description file;
`iproute' comes by default with `normal', `pareto', and
`paretonormal'.
- `delay_correlation', `loss', `loss_correlation', `dup',
`dup_correlation', `corrupt', and `corrupt_correlation' take a
percentage value in the form of a number between 0 and 1. (50% is
passed as 0.5)."""
parameters = dict(bandwidth = bandwidth, parameters = dict(bandwidth = bandwidth,
delay = delay, delay_jitter = delay_jitter, delay = delay, delay_jitter = delay_jitter,
delay_correlation = delay_correlation, delay_correlation = delay_correlation,
......
...@@ -753,7 +753,7 @@ def _parse_netem_delay(line): ...@@ -753,7 +753,7 @@ def _parse_netem_delay(line):
ret["delay_jitter"] = delay_jitter ret["delay_jitter"] = delay_jitter
if match.group(5): if match.group(5):
ret["delay_correlation"] = float(match.group(5)) ret["delay_correlation"] = float(match.group(5)) / 100
if match.group(6): if match.group(6):
ret["delay_distribution"] = match.group(6) ret["delay_distribution"] = match.group(6)
...@@ -766,9 +766,9 @@ def _parse_netem_loss(line): ...@@ -766,9 +766,9 @@ def _parse_netem_loss(line):
if not match: if not match:
return ret return ret
ret["loss"] = float(match.group(1)) ret["loss"] = float(match.group(1)) / 100
if match.group(2): if match.group(2):
ret["loss_correlation"] = float(match.group(2)) ret["loss_correlation"] = float(match.group(2)) / 100
return ret return ret
def _parse_netem_dup(line): def _parse_netem_dup(line):
...@@ -777,9 +777,9 @@ def _parse_netem_dup(line): ...@@ -777,9 +777,9 @@ def _parse_netem_dup(line):
if not match: if not match:
return ret return ret
ret["dup"] = float(match.group(1)) ret["dup"] = float(match.group(1)) / 100
if match.group(2): if match.group(2):
ret["dup_correlation"] = float(match.group(2)) ret["dup_correlation"] = float(match.group(2)) / 100
return ret return ret
def _parse_netem_corrupt(line): def _parse_netem_corrupt(line):
...@@ -788,9 +788,9 @@ def _parse_netem_corrupt(line): ...@@ -788,9 +788,9 @@ def _parse_netem_corrupt(line):
if not match: if not match:
return ret return ret
ret["corrupt"] = float(match.group(1)) ret["corrupt"] = float(match.group(1)) / 100
if match.group(2): if match.group(2):
ret["corrupt_correlation"] = float(match.group(2)) ret["corrupt_correlation"] = float(match.group(2)) / 100
return ret return ret
def get_tc_data(): def get_tc_data():
...@@ -888,7 +888,7 @@ def set_tc(iface, bandwidth = None, delay = None, delay_jitter = None, ...@@ -888,7 +888,7 @@ def set_tc(iface, bandwidth = None, delay = None, delay_jitter = None,
cmd = "add" cmd = "add"
if bandwidth: if bandwidth:
rate = "%dbps" % int(bandwidth) rate = "%dbit" % int(bandwidth)
mtu = ifdata[iface.index].mtu mtu = ifdata[iface.index].mtu
burst = max(mtu, int(bandwidth) / _hz) burst = max(mtu, int(bandwidth) / _hz)
limit = burst * 2 # FIXME? limit = burst * 2 # FIXME?
...@@ -918,23 +918,23 @@ def set_tc(iface, bandwidth = None, delay = None, delay_jitter = None, ...@@ -918,23 +918,23 @@ def set_tc(iface, bandwidth = None, delay = None, delay_jitter = None,
if delay_jitter: if delay_jitter:
command += ["%fs" % delay_jitter] command += ["%fs" % delay_jitter]
if delay_correlation: if delay_correlation:
command += ["%f%%" % delay_correlation] command += ["%f%%" % (delay_correlation * 100)]
if delay_distribution: if delay_distribution:
if not delay_jitter: # or not delay_correlation: if not delay_jitter: # or not delay_correlation:
raise ValueError("delay_distribution requires delay_jitter") raise ValueError("delay_distribution requires delay_jitter")
command += ["distribution", delay_distribution] command += ["distribution", delay_distribution]
if loss: if loss:
command += ["loss", "%f%%" % loss] command += ["loss", "%f%%" % (loss * 100)]
if loss_correlation: if loss_correlation:
command += ["%f%%" % loss_correlation] command += ["%f%%" % (loss_correlation * 100)]
if dup: if dup:
command += ["duplicate", "%f%%" % dup] command += ["duplicate", "%f%%" % (dup * 100)]
if dup_correlation: if dup_correlation:
command += ["%f%%" % dup_correlation] command += ["%f%%" % (dup_correlation * 100)]
if corrupt: if corrupt:
command += ["corrupt", "%f%%" % corrupt] command += ["corrupt", "%f%%" % (corrupt * 100)]
if corrupt_correlation: if corrupt_correlation:
command += ["%f%%" % corrupt_correlation] command += ["%f%%" % (corrupt_correlation * 100)]
commands.append(command) commands.append(command)
for c in commands: for c in commands:
......
...@@ -32,13 +32,30 @@ class TestLink(unittest.TestCase): ...@@ -32,13 +32,30 @@ class TestLink(unittest.TestCase):
self.assertEquals(ifdata[i2.control.index].up, True, "UP propagation") self.assertEquals(ifdata[i2.control.index].up, True, "UP propagation")
# None => tbf # None => tbf
l.set_parameters(bandwidth = 100*1024*1024/8) # 100 mbits l.set_parameters(bandwidth = 13107200) # 100 mbits
tcdata = netns.iproute.get_tc_data()[0] tcdata = netns.iproute.get_tc_data()[0]
self.assertEquals(tcdata[i1.control.index], self.assertEquals(tcdata[i1.control.index],
{'bandwidth': 104858000, 'qdiscs': {'tbf': '1'}}) # adjust for tc rounding
{'bandwidth': 13107000, 'qdiscs': {'tbf': '1'}})
self.assertEquals(tcdata[i2.control.index], self.assertEquals(tcdata[i2.control.index],
{'bandwidth': 104858000, 'qdiscs': {'tbf': '1'}}) {'bandwidth': 13107000, 'qdiscs': {'tbf': '1'}})
#bandwidth = 100*1024*1024/8, loss=10, loss_correlation=1,delay=0.001,dup_correlation=0.1);
# none again
l.set_parameters()
tcdata = netns.iproute.get_tc_data()[0]
self.assertEquals(tcdata[i1.control.index], {'qdiscs': {}})
self.assertEquals(tcdata[i2.control.index], {'qdiscs': {}})
# cheat and see what happens
os.system(("tc qd add dev %s root prio bands 3 " +
"priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1") % i1.control.name)
tcdata = netns.iproute.get_tc_data()[0]
self.assertEquals(tcdata[i1.control.index], "foreign")
l.set_parameters(bandwidth = 13107200) # 100 mbits
tcdata = netns.iproute.get_tc_data()[0]
self.assertEquals(tcdata[i1.control.index],
{'bandwidth': 13107000, 'qdiscs': {'tbf': '1'}})
# FIXME: more cases # FIXME: more cases
if __name__ == '__main__': if __name__ == '__main__':
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment