dynreconf_test.py
Go to the documentation of this file.
00001 #! /usr/bin/env python
00002 
00003 import sys
00004 import time
00005 import subprocess
00006 import unittest
00007 
00008 import roslib; roslib.load_manifest('network_control_tests')
00009 import rospy
00010 import rostest 
00011 import math
00012 
00013 from network_monitor_udp.linktest import UdpmonsourceHandle
00014 from network_monitor_udp.linktest import LinkTest
00015 from network_monitor_udp.msg import LinktestGoal
00016 from network_traffic_control.projected_link_metrics import get_projected_link_metrics
00017 import dynamic_reconfigure.client
00018 
00019 class DynreconfTest(unittest.TestCase):
00020     def __init__(self, *args):
00021         super(DynreconfTest, self).__init__(*args)
00022         rospy.init_node('network_traffic_control_test')
00023         self.srcnode = UdpmonsourceHandle('performance_test')
00024         self.dynclient = dynamic_reconfigure.client.Client("tc_lo")
00025         self.no_traffic_control_params = { 
00026             "bandwidth_egress" : 0.0, "bandwidth_ingress" : 0.0,
00027             "latency_egress" : 0.0, "latency_ingress" : 0.0,
00028             "loss_egress" : 0.0, "loss_ingress" : 0.0,
00029             "packet_size" : 1500 }
00030         self.reset_tc_rules_via_dynreconf()
00031         
00032     def reset_tc_rules_via_dynreconf(self):        
00033         config = self.dynclient.update_configuration(self.no_traffic_control_params)
00034         if config['status'] != "OK":
00035             raise(ValueError(config['errmsg']))
00036 
00037     def setUp(self):
00038         self.srcnode.cancel_all_tests()
00039 
00040     def tearDown(self):
00041         self.reset_tc_rules_via_dynreconf()
00042 
00043     def test_latency(self):
00044         test = self.srcnode.create_test(bw = 1.0*10**6, pktsize = 1500, duration = 3.0,
00045                                         sink_ip = "127.0.0.1", sink_port = 12345,
00046                                         bw_type = LinktestGoal.BW_CONSTANT)
00047         test.start()
00048         time.sleep(3.5)
00049         self.assertTrue(test.done, "Test should have finished already")
00050         self.assertTrue(test.overall_latency < 0.01, 
00051                         "Expected latency to be < 1ms, instead it was %.2fms"%
00052                         (test.overall_latency * 1e3))
00053 
00054         config = self.dynclient.update_configuration({ "latency_egress": 0.03 })
00055         self.assertTrue(config['status'] == "OK",
00056                         "Operation FAILed: " + config['errmsg'])
00057         self.assertAlmostEqual(config['latency_egress'], 0.03, 3,
00058                                "Expected latency_egress dynreconf parameter to be ~30ms, instead it was %.2fms"%
00059                                (config['latency_egress'] * 1e3))
00060 
00061         test = self.srcnode.create_test(bw = 1.0*10**6, pktsize = 1500, duration = 3.0,
00062                                         sink_ip = "127.0.0.1", sink_port = 12345,
00063                                         bw_type = LinktestGoal.BW_CONSTANT)
00064         test.start()
00065         time.sleep(3.5)
00066         self.assertTrue(test.done, "Test should have finished already")
00067         self.assertTrue(test.overall_latency > 0.02 and test.overall_latency < 0.04, 
00068                         "Expected latency to be ~30ms, instead it was %.2fms"%
00069                         (test.overall_latency * 1e3))
00070         self.assertTrue(test.overall_bandwidth > 0.7e6,
00071                         "Expected overall bandwidth to be ~1Mbit/s, instead it was %.2fMbit/s"%
00072                         (test.overall_bandwidth/1e6))
00073         self.assertTrue(test.overall_loss < 5.0,
00074                         "Expected packet loss to be 0%%, instead it was %.2f%%"%
00075                         (test.overall_loss))
00076 
00077         config = self.dynclient.update_configuration({ "latency_egress": 0.01, "latency_ingress": 0.05 })
00078         self.assertTrue(config['status'] == "OK",
00079                         "Operation FAILed: " + config['errmsg'])
00080         self.assertAlmostEqual(config['latency_egress'], 0.01, 3,
00081                                "Expected latency_egress dynreconf parameter to be ~10ms, instead it was %.2fms"%
00082                                (config['latency_egress'] * 1e3))        
00083         self.assertAlmostEqual(config['latency_ingress'], 0.05, 3,
00084                                "Expected latency_ingress dynreconf parameter to be ~50ms, instead it was %.2fms"%
00085                                (config['latency_ingress'] * 1e3))        
00086 
00087         test = self.srcnode.create_test(bw = 1.0*10**6, pktsize = 1500, duration = 3.0,
00088                                         sink_ip = "127.0.0.1", sink_port = 12345,
00089                                         bw_type = LinktestGoal.BW_CONSTANT, max_return_time = 0.1)
00090         test.start()
00091         time.sleep(3.5)
00092         self.assertTrue(test.done, "Test should have finished already")
00093         self.assertTrue(test.overall_latency > 0.045 and test.overall_latency < 0.075, 
00094                         "Expected latency to be ~ 60ms, instead it was %.2fms"%
00095                         (test.overall_latency * 1e3))
00096         self.assertTrue(test.overall_bandwidth > 0.7e6,
00097                         "Expected overall bandwidth to be ~1Mbit/s, instead it was %.2fMbit/s"%
00098                         (test.overall_bandwidth/1e6))
00099         self.assertTrue(test.overall_loss < 5.0,
00100                         "Expected packet loss to be 0%%, instead it was %.2f%%"%
00101                         (test.overall_loss))
00102 
00103     def test_bandwidth(self):
00104         test = self.srcnode.create_test(bw = 3.0*10**6, pktsize = 1500, duration = 3.0,
00105                                         sink_ip = "127.0.0.1", sink_port = 12345,
00106                                         bw_type = LinktestGoal.BW_CONSTANT)
00107         test.start()
00108         time.sleep(3.5)
00109         self.assertTrue(test.done, "Test should have finished already")
00110         self.assertTrue(test.overall_latency < 0.01, 
00111                         "Expected latency to be < 1ms, instead it was %.2fms"%
00112                         (test.overall_latency * 1e3))
00113         self.assertTrue(test.overall_bandwidth > 2.7e6,
00114                         "Expected overall bandwidth to be ~3Mbit/s, instead it was %.2fMbit/s"%
00115                         (test.overall_bandwidth/1e6))
00116 
00117         config = self.dynclient.update_configuration({ "bandwidth_egress": 2e6, "bandwidth_ingress": 2e6 })
00118         self.assertTrue(config['status'] == "OK",
00119                         "Operation FAILed: " + config['errmsg'])
00120         self.assertAlmostEqual(config['bandwidth_egress']/1e6, 2.0, 3,
00121                                "Expected bandwidth_egress dynreconf parameter to be ~2Mbit/s, instead it was %.2fMbit/s"%
00122                                (config['bandwidth_egress']/1e6))        
00123         self.assertAlmostEqual(config['bandwidth_ingress']/1e6, 2.0, 3,
00124                                "Expected bandwidth_ingress dynreconf parameter to be ~2Mbit/s, instead it was %.2fMbit/s"%
00125                                (config['bandwidth_ingress']/1e6))        
00126 
00127         test = self.srcnode.create_test(bw = 3.0*10**6, pktsize = 1500, duration = 3.0,
00128                                         sink_ip = "127.0.0.1", sink_port = 12345,
00129                                         bw_type = LinktestGoal.BW_CONSTANT, latencybins = [ 0.01, 0.1, 0.3],
00130                                         max_return_time = 0.25)
00131         test.start()
00132         time.sleep(3.5)
00133         self.assertTrue(test.done, "Test should have finished already")
00134         self.assertTrue(test.overall_bandwidth > 1.5e6 and test.overall_bandwidth < 2.5e6,
00135                         "Expected measured bandwidth to be ~2Mbit/s, instead it was %.2fMbit/s"%
00136                         (test.overall_bandwidth/1e6))
00137 
00138         config = self.dynclient.update_configuration({ "bandwidth_ingress": 1e6 })
00139 
00140         test = self.srcnode.create_test(bw = 3.0*10**6, pktsize = 1500, duration = 3.0,
00141                                         sink_ip = "127.0.0.1", sink_port = 12345,
00142                                         bw_type = LinktestGoal.BW_CONSTANT)
00143         test.start()
00144         time.sleep(3.5)
00145         self.assertTrue(test.done, "Test should have finished already")
00146         self.assertTrue(test.overall_bandwidth > 0.7e6 and test.overall_bandwidth < 1.3e6,
00147                         "Expected overall bandwidth to be ~1Mbit/s, instead it was %.2fMbit/s"%
00148                         (test.overall_bandwidth/1e6))
00149 
00150     def test_bandwidth_latency(self):
00151         config = self.dynclient.update_configuration({ "bandwidth_egress": 1e6, "latency_ingress": 0.03 })
00152         test = self.srcnode.create_test(bw = 0.7*10**6, pktsize = 1500, duration = 5.0,
00153                                         sink_ip = "127.0.0.1", sink_port = 12345,
00154                                         bw_type = LinktestGoal.BW_CONSTANT, max_return_time = 0.01)
00155         test.start()
00156         time.sleep(5.5)
00157         self.assertTrue(test.done, "Test should have finished already")
00158         self.assertTrue(test.overall_bandwidth > 0.5e6 and test.overall_bandwidth < 0.9e6,
00159                         "Expected overall bandwidth to be ~1Mbit/s, instead it was %.2fMbit/s"%
00160                         (test.overall_bandwidth/1e6))
00161         self.assertTrue(test.latency.avg() > 0.025  and test.latency.avg() < 0.045,
00162                         "Expected latency to be ~30ms (since capacity was not overrun), instead it was %.2fms"%
00163                         (test.latency.avg()*1e3))
00164         test = self.srcnode.create_test(bw = 3.0*10**6, pktsize = 1500, duration = 5.0,
00165                                         sink_ip = "127.0.0.1", sink_port = 12345,
00166                                         bw_type = LinktestGoal.BW_CONSTANT, max_return_time = 0.01)
00167         test.start()
00168         time.sleep(5.5)
00169         self.assertTrue(test.done, "Test should have finished already")
00170         self.assertTrue(test.overall_bandwidth > 0.8e6 and test.overall_bandwidth < 1.2e6,
00171                         "Expected overall bandwidth to be ~1Mbit/s, instead it was %.2fMbit/s"%
00172                         (test.overall_bandwidth/1e6))
00173         expected_latency = 1500.0/(1e6/8) + 0.03
00174         self.assertTrue(test.latency.avg() > expected_latency - 0.005  and test.latency.avg() < expected_latency + 0.005,
00175                         "Expected latency to be ~%.2fms (since capacity was not overrun), instead it was %.2fms"%
00176                         (expected_latency * 1e3, test.latency.avg()*1e3))
00177 
00178     def test_ingress_egress_loss(self):
00179         config = self.dynclient.update_configuration({ "loss_egress": 20.0, "loss_ingress": 30.0 })
00180         test = self.srcnode.create_test(bw = 5*10**6, pktsize = 1500, duration = 5.0,
00181                                         sink_ip = "127.0.0.1", sink_port = 12345,
00182                                         bw_type = LinktestGoal.BW_CONSTANT, max_return_time = 0.01)
00183         test.start()
00184         time.sleep(5.5)
00185         self.assertTrue(test.done, "Test should have finished already")
00186         self.assertTrue(test.loss.avg() > 44.0 - 10.0 and test.loss.avg() < 44.0 + 10.0,
00187                         "Expected aggregated loss (ingress+egress) to be ~44%%, instead it was %.2f%%"%
00188                         (test.loss.avg()))
00189 
00190     def test_packet_size(self):
00191         test = self.srcnode.create_test(bw = 3*10**6, pktsize = 500, duration = 3.0,
00192                                         sink_ip = "127.0.0.1", sink_port = 12345,
00193                                         bw_type = LinktestGoal.BW_CONSTANT, max_return_time = 0.01)
00194         config = self.dynclient.update_configuration({ "packet_size": 5000, "bandwidth_egress": 1e6 })
00195         test.start()
00196         time.sleep(3.5)
00197         self.assertTrue(test.done, "Test should have finished already")
00198         self.assertTrue(test.latency.avg() > 0.035 and test.latency.avg() < 0.045, 
00199                         "Expected latency to be ~40ms, instead it was %.2fms"%
00200                         (test.latency.avg()*1e3))
00201 
00202         test = self.srcnode.create_test(bw = 3*10**6, pktsize = 500, duration = 3.0,
00203                                         sink_ip = "127.0.0.1", sink_port = 12345,
00204                                         bw_type = LinktestGoal.BW_CONSTANT, max_return_time = 0.01)
00205         config = self.dynclient.update_configuration({ "packet_size": 500 })
00206 
00207         test.start()
00208         time.sleep(3.5)
00209         self.assertTrue(test.done, "Test should have finished already")
00210         self.assertTrue(test.latency.avg() > 0.002 and test.latency.avg() < 0.006, 
00211                         "Expected latency to be ~4ms, instead it was %.2fms"%
00212                         (test.latency.avg()*1e3))
00213 
00214         test = self.srcnode.create_test(bw = 3*10**6, pktsize = 500, duration = 3.0,
00215                                         sink_ip = "127.0.0.1", sink_port = 12345,
00216                                         bw_type = LinktestGoal.BW_CONSTANT, max_return_time = 0.01)
00217         config = self.dynclient.update_configuration({ "bandwidth_ingress": 0.5e6 })
00218         test.start()
00219         time.sleep(3.5)
00220         self.assertTrue(test.done, "Test should have finished already")
00221         self.assertTrue(test.latency.avg() > 0.008 and test.latency.avg() < 0.015, 
00222                         "Expected latency to be ~12ms, instead it was %.2fms"%
00223                         (test.latency.avg()*1e3))
00224 
00225         test = self.srcnode.create_test(bw = 3*10**6, pktsize = 500, duration = 3.0,
00226                                         sink_ip = "127.0.0.1", sink_port = 12345,
00227                                         bw_type = LinktestGoal.BW_CONSTANT, max_return_time = 0.01)
00228         config = self.dynclient.update_configuration({ "packet_size": 300 })
00229         test.start()
00230         time.sleep(3.5)
00231         self.assertTrue(test.done, "Test should have finished already")
00232         self.assertTrue(test.loss.avg() > 95.0, 
00233                         "Expected loss to be 100% (tc limit smaller than packet size)")
00234 
00235     def bandwidth_latency_loss_test(self, direction, bw_tx, bw_limit, latency, loss,
00236                                     expected_bw = None, expected_loss = None, expected_latency = None):
00237         self.reset_tc_rules_via_dynreconf()
00238         config = self.dynclient.update_configuration({ "bandwidth_" + direction: bw_limit, 
00239                                                        "latency_" + direction: latency,
00240                                                        "loss_" + direction: loss })
00241 
00242         self.assertTrue(config['status'] == "OK",
00243                         "Operation FAILed: " + config['errmsg'])
00244 
00245         test = self.srcnode.create_test(bw = bw_tx, pktsize = 1500, duration = 5.0,
00246                                         sink_ip = "127.0.0.1", sink_port = 12345,
00247                                         bw_type = LinktestGoal.BW_CONSTANT, max_return_time = 0.01)
00248         test.start()
00249         time.sleep(5.5)
00250         self.assertTrue(test.done, "Test should have finished already")
00251 
00252         (expected_bw, expected_latency, expected_loss) = get_projected_link_metrics(bw_limit, latency, loss, 1500.0, bw_tx)
00253 
00254         print "bw_limit: ", bw_limit, "loss: ", loss, "latency: ", latency, "bw_tx: ", bw_tx
00255         print "meas_bw: ", test.bandwidth.avg(), " meas_latency: ", test.latency.avg()*1e3, " meas_loss: ", test.loss.avg()
00256         print "exp_bw", expected_bw, " exp_latency: ", expected_latency * 1e3, " exp_loss: ", expected_loss
00257         self.assertTrue(test.bandwidth.avg() > expected_bw * 0.75  and test.bandwidth.avg() < expected_bw * 1.25,
00258                         "Expected measured bandwidth to be ~%.2fMbit/s, instead it was %.2fMbit/s"%
00259                         (expected_bw/1e6, test.bandwidth.avg()/1e6))
00260         self.assertTrue(test.latency.avg() > expected_latency - 0.015  and test.latency.avg() < expected_latency + 0.015,
00261                         "Expected latency to be ~%.2fms, instead it was %.2fms"%
00262                         (expected_latency * 1e3, test.latency.avg() * 1e3))
00263         self.assertTrue((test.loss.avg() < 4.0 and expected_loss < 2.0) or 
00264                         (test.loss.avg() > expected_loss - 10.0  and test.latency.avg() < expected_loss + 10.0),
00265                         "Expected loss to be ~%.2f%%, instead it was %.2f%%"%
00266                         (expected_loss, test.loss.avg()))
00267 
00268         
00269     def test_bandwidth_latency_loss(self):
00270         # just bw_limit specified, bw_tx < bw_limit
00271         self.bandwidth_latency_loss_test("egress", bw_tx = 0.5*10**6, 
00272                                          bw_limit=1.0*10**6, latency = 0.0, loss = 0.0)
00273         # just bw_limit specified, bw_tx > bw_limit
00274         self.bandwidth_latency_loss_test("egress", bw_tx = 1.5*10**6, 
00275                                          bw_limit=1.0*10**6, latency = 0.0, loss = 0.0)
00276         # bw_limit + latency, bw_tx < bw_limit
00277         self.bandwidth_latency_loss_test("egress", bw_tx = 0.5*10**6, 
00278                                          bw_limit=1.0*10**6, latency = 0.01, loss = 0.0)
00279         # bw_limit + latency, bw_tx > bw_limit
00280         self.bandwidth_latency_loss_test("egress", bw_tx = 1.5*10**6, 
00281                                          bw_limit=1.0*10**6, latency = 0.01, loss = 0.0)
00282         # bw_limit + latency + loss, bw_tx < bw_limit, loss < bw_loss
00283         self.bandwidth_latency_loss_test("egress", bw_tx = 0.5*10**6, 
00284                                          bw_limit=1.0*10**6, latency = 0.03, loss = 10.0)
00285         # bw_limit + latency + loss, bw_tx < bw_limit, loss > bw_loss
00286         self.bandwidth_latency_loss_test("egress", bw_tx = 0.5*10**6, 
00287                                          bw_limit=1.0*10**6, latency = 0.03, loss = 50.0)
00288         # bw_limit + latency + loss, bw_tx > bw_limit, loss < bw-loss
00289         self.bandwidth_latency_loss_test("egress", bw_tx = 1.5*10**6, 
00290                                          bw_limit=1.0*10**6, latency = 0.03, loss = 10.0)
00291         # bw_limit + latency + loss, bw_tx > bw_limit, loss < bw-loss
00292         self.bandwidth_latency_loss_test("egress", bw_tx = 1.5*10**6, 
00293                                          bw_limit=1.0*10**6, latency = 0.03, loss = 50.0)
00294         # ingress tests
00295         self.bandwidth_latency_loss_test("ingress", bw_tx = 0.5*10**6, 
00296                                          bw_limit=1.0*10**6, latency = 0.0, loss = 0.0)
00297         self.bandwidth_latency_loss_test("ingress", bw_tx = 1.5*10**6, 
00298                                          bw_limit=1.0*10**6, latency = 0.0, loss = 0.0)
00299         self.bandwidth_latency_loss_test("ingress", bw_tx = 0.5*10**6, 
00300                                          bw_limit=1.0*10**6, latency = 0.01, loss = 0.0)
00301         self.bandwidth_latency_loss_test("ingress", bw_tx = 1.5*10**6, 
00302                                          bw_limit=1.0*10**6, latency = 0.01, loss = 0.0)
00303         self.bandwidth_latency_loss_test("ingress", bw_tx = 0.5*10**6, 
00304                                          bw_limit=1.0*10**6, latency = 0.02, loss = 0.0)
00305         self.bandwidth_latency_loss_test("ingress", bw_tx = 1.5*10**6, 
00306                                          bw_limit=1.0*10**6, latency = 0.03, loss = 10.0)
00307         self.bandwidth_latency_loss_test("ingress", bw_tx = 0.5*10**6, 
00308                                          bw_limit=1.0*10**6, latency = 0.04, loss = 20.0)
00309 if __name__ == '__main__':
00310     try:
00311         rostest.run('network_control_tests', 'dynreconf_test', DynreconfTest)
00312     except KeyboardInterrupt, e:
00313         pass


network_control_tests
Author(s): Catalin Drula
autogenerated on Thu Apr 24 2014 15:35:20