def __init__(self, *args): super(HostapdTest, self).__init__(*args) rospy.init_node('hostapd_access_point_test') self.ap1_iface = rospy.get_param('~ap1_iface') self.ap2_iface = rospy.get_param('~ap2_iface') self.sta_iface = rospy.get_param('~sta_iface') self.dyn_ap1 = dynamic_reconfigure.client.Client("hostapd1") self.dyn_ap2 = dynamic_reconfigure.client.Client("hostapd2") self.reset_params = { "enabled": False, "ssid": "test", "wmm": False, "mode": 'b', "freq": 2412e6, "ieee80211n": False, "encryption_mode": "open", "encryption_pass": "", "txpower_auto": "True", "txpower": 0, "bitrate": 0 } self.dyn_ap1.update_configuration(self.reset_params) self.dyn_ap2.update_configuration(self.reset_params) self.hwsim_nat_setup_path = \ roslib.packages.find_node('hostapd_access_point', 'hwsim_nat_setup.sh') self.srcnode = UdpmonsourceHandle('performance_test') self.srcnode.cancel_all_tests()
def __init__(self, *args): super(DynreconfTest, self).__init__(*args) rospy.init_node('network_traffic_control_test') self.srcnode = UdpmonsourceHandle('performance_test') self.dynclient = dynamic_reconfigure.client.Client("tc_lo") self.no_traffic_control_params = { "bandwidth_egress" : 0.0, "bandwidth_ingress" : 0.0, "latency_egress" : 0.0, "latency_ingress" : 0.0, "loss_egress" : 0.0, "loss_ingress" : 0.0, "packet_size" : 1500 } self.reset_tc_rules_via_dynreconf()
def __init__(self, *args): super(HostapdTest, self).__init__(*args) rospy.init_node('hostapd_access_point_test') self.ap1_iface = rospy.get_param('~ap1_iface') self.ap2_iface = rospy.get_param('~ap2_iface') self.sta_iface = rospy.get_param('~sta_iface') self.dyn_ap1 = dynamic_reconfigure.client.Client("hostapd1") self.dyn_ap2 = dynamic_reconfigure.client.Client("hostapd2") self.reset_params = { "enabled" : False, "ssid": "test", "wmm": False, "mode": 'b', "freq": 2412e6, "ieee80211n": False, "encryption_mode": "open", "encryption_pass": "", "txpower_auto": "True", "txpower": 0, "bitrate": 0 } self.dyn_ap1.update_configuration(self.reset_params) self.dyn_ap2.update_configuration(self.reset_params) self.hwsim_nat_setup_path = \ roslib.packages.find_node('hostapd_access_point', 'hwsim_nat_setup.sh') self.srcnode = UdpmonsourceHandle('performance_test') self.srcnode.cancel_all_tests()
def measure_link(tx_bandwidth, bandwidth_limit, latency, loss, packet_size, max_allowed_latency, max_return_time, sink_ip, direction, duration): (proj_bandwidth, proj_latency, proj_loss) = get_projected_link_metrics(bandwidth_limit, latency, loss, \ packet_size, tx_bandwidth) if proj_latency > max_allowed_latency: rospy.logerr("Max allowed latency %.2fms is smaller than projected latency %.2fms," "results will be flawed, exiting", max_allowed_latency * 1e3, proj_latency * 1e3) exit(1) dynclient = dynamic_reconfigure.client.Client("tc") config = dynclient.update_configuration({"bandwidth_egress" : 0.0, "bandwidth_ingress" : 0.0, "latency_egress" : 0.0, "latency_ingress" : 0.0, "loss_egress" : 0.0, "loss_ingress" : 0.0 }) if config['status'] != "OK": rospy.logerr("Initalizing tc node failed: " + config['errmsg']) exit(1) config = dynclient.update_configuration({"bandwidth_" + direction: bandwidth_limit, "latency_" + direction: latency, "loss_" + direction: loss }) if config['status'] != "OK": rospy.logerr("Setting tc node config failed: " + config['errmsg']) srcnode = UdpmonsourceHandle('performance_test') test = srcnode.create_test(bw = tx_bandwidth, pktsize = packet_size, duration = duration, sink_ip = sink_ip, sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT, max_return_time = max_return_time, latencybins = [ max_allowed_latency/4, max_allowed_latency/2, max_allowed_latency]) test.start() time.sleep(duration + 0.5) rospy.loginfo("Link measurement completed!") rospy.loginfo("Link parameters: bandwidth_limit %.2fkbit/s latency %.2fms loss %.2f%% tx_bandwidth %.2fkbit/s\n" " packet_size %dbytes max_allowed_latency %.2fms max_return_time %.2fms\n" " direction %s duration %.2fs", bandwidth_limit/1e3, latency*1e3, loss, tx_bandwidth/1e3, packet_size, max_allowed_latency*1e3, max_return_time*1e3, direction, duration) rospy.loginfo("\nRESULTS: measured_bandwidth %.2fkbit/s measured_latency %.2fms measured_loss %.2f%%", test.bandwidth.avg()/1e3, test.latency.avg() * 1e3, test.loss.avg())
class MultipleEndsTest(unittest.TestCase): def __init__(self, *args): super(MultipleEndsTest, self).__init__(*args) rospy.init_node('network_monitor_udp_test') self.srcnode = UdpmonsourceHandle('performance_test') self.tc = TcPortControl(self) self.tc.reset() def setUp(self): self.srcnode.cancel_all_tests() self.tc.init() def tearDown(self): self.tc.reset() def test_multiple_sources_single_sink(self): self.tc.set_rate_limit(1e6) test1 = self.srcnode.create_test(bw=1.0 * 10**6, pktsize=1500, duration=5.0, sink_ip="127.0.0.1", sink_port=12345, bw_type=LinktestGoal.BW_CONSTANT, update_interval=0.2) test2 = self.srcnode.create_test(bw=1.0 * 10**6, pktsize=1500, duration=10.0, sink_ip="127.0.0.1", sink_port=12345, bw_type=LinktestGoal.BW_CONSTANT, update_interval=0.2) test3 = self.srcnode.create_test(bw=1.0 * 10**6, pktsize=1500, duration=15.0, sink_ip="127.0.0.1", sink_port=12345, bw_type=LinktestGoal.BW_CONSTANT, update_interval=0.2) test1.start() test2.start() test3.start() time.sleep(3.0) bwsum = test1.bandwidth.movavg(5) + test2.bandwidth.movavg( 5) + test3.bandwidth.movavg(5) self.assertTrue( bwsum > 0.8e6 and bwsum < 1.2e6, "Expected the combined bandwidth of three tests to be ~1Mbit/s, instead it was %.2fMbit/s" % (bwsum)) time.sleep(2.5) self.assertTrue(test1.done, "Expected test1 to have finished at time = 5.5s") self.assertFalse(test2.done, "Expected test2 to be still running at time = 5.5s") self.assertFalse(test3.done, "Expected test3 to be still running at time = 5.5s") time.sleep(2.5) bwsum = test2.bandwidth.movavg(5) + test3.bandwidth.movavg(5) self.assertTrue( bwsum > 0.8e6 and bwsum < 1.2e6, "Expected the combined bandwidth of two tests to be ~1Mbit/s, instead it was %.2fMbit/s" % (bwsum)) time.sleep(2.5) self.assertTrue(test2.done, "Expected test2 to have finished at time = 10.5s") self.assertFalse(test3.done, "Expected test3 to be still running at time = 10.5s") time.sleep(2.5) self.assertTrue( test3.bandwidth.movavg(5) > 0.80e6 and test3.bandwidth.movavg(5) < 1.20e6, "Expected test3 bandwidth to be ~1Mbit/s (with 1 test running concurrently)" + ", instead it was %.2fMbit/s" % (test3.bandwidth.movavg(5) / 1e6)) time.sleep(2.5) self.assertTrue(test2.done, "Expected test2 to have finished at time = 10.5s") self.assertTrue( test3.latency.duration() > test2.latency.duration() and test2.latency.duration() > test1.latency.duration(), "Expected test3 duration (%.2fs) to be greater than test2 (%.2fs)" " and still greater than test1 (%.2fs)" % (test3.latency.duration(), test2.latency.duration(), test1.latency.duration())) def test_multiple_sinks(self): self.tc.set_rate_limit(1e6) test1 = self.srcnode.create_test(bw=5.0 * 10**6, pktsize=1500, duration=3.0, sink_ip="127.0.0.1", sink_port=12345, bw_type=LinktestGoal.BW_CONSTANT, update_interval=0.2) test2 = self.srcnode.create_test(bw=5.0 * 10**6, pktsize=1500, duration=3.0, sink_ip="127.0.0.1", sink_port=12346, bw_type=LinktestGoal.BW_CONSTANT, update_interval=0.2) test1.start() test2.start() time.sleep(3.5) self.assertTrue(test1.done, "Expected test2 to have finished at time = 3.5s") self.assertTrue(test2.done, "Expected test2 to have finished at time = 3.5s") self.assertTrue( test2.overall_bandwidth > 4 * test1.overall_bandwidth, "Expected test2 bw (%.2fMbit/s) to be at least 4x larger" " than test1 bw (%.2fMbit/s)" % (test2.overall_bandwidth / 1e6, test1.overall_bandwidth / 1e6))
def __init__(self, *args): super(MultipleEndsTest, self).__init__(*args) rospy.init_node('network_monitor_udp_test') self.srcnode = UdpmonsourceHandle('performance_test') self.tc = TcPortControl(self) self.tc.reset()
class BasicTest(unittest.TestCase): def __init__(self, *args): super(BasicTest, self).__init__(*args) rospy.init_node("network_monitor_udp_test") self.srcnode = UdpmonsourceHandle("performance_test") def setUp(self): self.srcnode.cancel_all_tests() def test_finite_duration(self): scheduled_duration = 3.0 # seconds test = self.srcnode.create_test( "finite_duration_test", sink_ip="127.0.0.1", sink_port=12345, duration=scheduled_duration ) start_time = time.time() test_duration = 0.0 test.start() while not test.done and test_duration < scheduled_duration + 2.0: time.sleep(0.2) test_duration = time.time() - start_time self.assertTrue( test.done, "Test did not end within time limit. " + "Scheduled duration was %.2fsec while elapsed duration so far is %.2fsec" % (scheduled_duration, test_duration), ) self.assertTrue( time.time() - start_time > scheduled_duration - 0.5, "Test ended too fast, it was scheduled for %.2fsec and it lasted for only %.2fsec" % (scheduled_duration, time.time() - start_time), ) def run_periodic_feedback_test(self, update_interval, test_duration=5.0): self.last_feedback_time = None self.feedback_interval_too_small = False self.feedback_interval_too_large = False self.feedback_interval_too_small_value = 0.0 self.feedback_interval_too_large_value = 0.0 self.feedback_calls = 0 self.update_interval = update_interval test = self.srcnode.create_test( sink_ip="127.0.0.1", sink_port=12345, duration=test_duration, update_interval=update_interval ) test.set_custom_feedback_handler(self.feedback_period_test_handler) test.start() while not test.done: time.sleep(1.0) self.assertFalse( self.feedback_interval_too_large, "Interval between two feedback calls was too large: expected (%.2f sec) was (%.2f sec)" % (self.update_interval, self.feedback_interval_too_large_value), ) self.assertFalse( self.feedback_interval_too_small, "Interval between two feedback calls was too small: expected (%.2f sec) was (%.2f sec)" % (self.update_interval, self.feedback_interval_too_small_value), ) conservative_expected_feedback_calls = int((test_duration - 1.0) / self.update_interval) self.assertTrue( self.feedback_calls >= conservative_expected_feedback_calls, "Expected at least (%d) feedback calls, but got only (%d)" % (conservative_expected_feedback_calls, self.feedback_calls), ) def test_feedback_period(self): self.run_periodic_feedback_test(0.5, 5.0) self.run_periodic_feedback_test(0.2, 3.0) self.run_periodic_feedback_test(0.05, 3.0) def feedback_period_test_handler(self, gh, feedback): self.feedback_calls += 1 curr_time = time.time() if self.last_feedback_time is not None: if curr_time - self.last_feedback_time > self.update_interval * 1.5: self.feedback_interval_too_large = True self.feedback_interval_too_large_value = curr_time - self.last_feedback_time elif curr_time - self.last_feedback_time < self.update_interval * 0.5: self.feedback_interval_too_small = True self.feedback_interval_too_small_value = curr_time - self.last_feedback_time self.last_feedback_time = curr_time def test_stop_test(self): test = self.srcnode.create_test( "finite_duration_test", sink_ip="127.0.0.1", sink_port=12345, duration=5.0, bw=1e6 ) test.start() time.sleep(1.0) test.stop() time.sleep(1.0) self.assertTrue(test.done, "Test should have been stopped") self.assertTrue( test.overall_bandwidth > 0.6e6, "Expected overall bandwidth to be ~1Mbit/s, instead it was %.2fMbit/s" % (test.overall_bandwidth / 1e6), )
def __init__(self, *args): super(BasicTest, self).__init__(*args) rospy.init_node("network_monitor_udp_test") self.srcnode = UdpmonsourceHandle("performance_test")
def measure_link( tx_bandwidth, bandwidth_limit, latency, loss, packet_size, max_allowed_latency, max_return_time, sink_ip, direction, duration, ): (proj_bandwidth, proj_latency, proj_loss) = get_projected_link_metrics( bandwidth_limit, latency, loss, packet_size, tx_bandwidth ) if proj_latency > max_allowed_latency: rospy.logerr( "Max allowed latency %.2fms is smaller than projected latency %.2fms," "results will be flawed, exiting", max_allowed_latency * 1e3, proj_latency * 1e3, ) exit(1) dynclient = dynamic_reconfigure.client.Client("tc") config = dynclient.update_configuration( { "bandwidth_egress": 0.0, "bandwidth_ingress": 0.0, "latency_egress": 0.0, "latency_ingress": 0.0, "loss_egress": 0.0, "loss_ingress": 0.0, } ) if config["status"] != "OK": rospy.logerr("Initalizing tc node failed: " + config["errmsg"]) exit(1) config = dynclient.update_configuration( {"bandwidth_" + direction: bandwidth_limit, "latency_" + direction: latency, "loss_" + direction: loss} ) if config["status"] != "OK": rospy.logerr("Setting tc node config failed: " + config["errmsg"]) srcnode = UdpmonsourceHandle("performance_test") test = srcnode.create_test( bw=tx_bandwidth, pktsize=packet_size, duration=duration, sink_ip=sink_ip, sink_port=12345, bw_type=LinktestGoal.BW_CONSTANT, max_return_time=max_return_time, latencybins=[max_allowed_latency / 4, max_allowed_latency / 2, max_allowed_latency], ) test.start() time.sleep(duration + 0.5) rospy.loginfo("Link measurement completed!") rospy.loginfo( "Link parameters: bandwidth_limit %.2fkbit/s latency %.2fms loss %.2f%% tx_bandwidth %.2fkbit/s\n" " packet_size %dbytes max_allowed_latency %.2fms max_return_time %.2fms\n" " direction %s duration %.2fs", bandwidth_limit / 1e3, latency * 1e3, loss, tx_bandwidth / 1e3, packet_size, max_allowed_latency * 1e3, max_return_time * 1e3, direction, duration, ) rospy.loginfo( "\nRESULTS: measured_bandwidth %.2fkbit/s measured_latency %.2fms measured_loss %.2f%%", test.bandwidth.avg() / 1e3, test.latency.avg() * 1e3, test.loss.avg(), )
def __init__(self, *args): super(ParameterTest, self).__init__(*args) rospy.init_node('network_monitor_udp_test') self.srcnode = UdpmonsourceHandle('performance_test') self.tc = TcPortControl(self) self.tc.reset()
class BasicTest(unittest.TestCase): def __init__(self, *args): super(BasicTest, self).__init__(*args) rospy.init_node('network_monitor_udp_test') self.srcnode = UdpmonsourceHandle('performance_test') def setUp(self): self.srcnode.cancel_all_tests() def test_finite_duration(self): scheduled_duration = 3.0 # seconds test = self.srcnode.create_test("finite_duration_test", sink_ip="127.0.0.1", sink_port=12345, duration=scheduled_duration) start_time = time.time() test_duration = 0.0 test.start() while not test.done and test_duration < scheduled_duration + 2.0: time.sleep(0.2) test_duration = time.time() - start_time self.assertTrue( test.done, "Test did not end within time limit. " + "Scheduled duration was %.2fsec while elapsed duration so far is %.2fsec" % (scheduled_duration, test_duration)) self.assertTrue( time.time() - start_time > scheduled_duration - 0.5, "Test ended too fast, it was scheduled for %.2fsec and it lasted for only %.2fsec" % (scheduled_duration, time.time() - start_time)) def run_periodic_feedback_test(self, update_interval, test_duration=5.0): self.last_feedback_time = None self.feedback_interval_too_small = False self.feedback_interval_too_large = False self.feedback_interval_too_small_value = 0.0 self.feedback_interval_too_large_value = 0.0 self.feedback_calls = 0 self.update_interval = update_interval test = self.srcnode.create_test(sink_ip="127.0.0.1", sink_port=12345, duration=test_duration, update_interval=update_interval) test.set_custom_feedback_handler(self.feedback_period_test_handler) test.start() while not test.done: time.sleep(1.0) self.assertFalse( self.feedback_interval_too_large, "Interval between two feedback calls was too large: expected (%.2f sec) was (%.2f sec)" % (self.update_interval, self.feedback_interval_too_large_value)) self.assertFalse( self.feedback_interval_too_small, "Interval between two feedback calls was too small: expected (%.2f sec) was (%.2f sec)" % (self.update_interval, self.feedback_interval_too_small_value)) conservative_expected_feedback_calls = int( (test_duration - 1.0) / self.update_interval) self.assertTrue( self.feedback_calls >= conservative_expected_feedback_calls, "Expected at least (%d) feedback calls, but got only (%d)" % (conservative_expected_feedback_calls, self.feedback_calls)) def test_feedback_period(self): self.run_periodic_feedback_test(0.5, 5.0) self.run_periodic_feedback_test(0.2, 3.0) self.run_periodic_feedback_test(0.05, 3.0) def feedback_period_test_handler(self, gh, feedback): self.feedback_calls += 1 curr_time = time.time() if self.last_feedback_time is not None: if curr_time - self.last_feedback_time > self.update_interval * 1.5: self.feedback_interval_too_large = True self.feedback_interval_too_large_value = curr_time - self.last_feedback_time elif curr_time - self.last_feedback_time < self.update_interval * 0.5: self.feedback_interval_too_small = True self.feedback_interval_too_small_value = curr_time - self.last_feedback_time self.last_feedback_time = curr_time def test_stop_test(self): test = self.srcnode.create_test("finite_duration_test", sink_ip="127.0.0.1", sink_port=12345, duration=5.0, bw=1e6) test.start() time.sleep(1.0) test.stop() time.sleep(1.0) self.assertTrue(test.done, "Test should have been stopped") self.assertTrue( test.overall_bandwidth > 0.6e6, "Expected overall bandwidth to be ~1Mbit/s, instead it was %.2fMbit/s" % (test.overall_bandwidth / 1e6))
class HostapdTest(unittest.TestCase): def __init__(self, *args): super(HostapdTest, self).__init__(*args) rospy.init_node('hostapd_access_point_test') self.ap1_iface = rospy.get_param('~ap1_iface') self.ap2_iface = rospy.get_param('~ap2_iface') self.sta_iface = rospy.get_param('~sta_iface') self.dyn_ap1 = dynamic_reconfigure.client.Client("hostapd1") self.dyn_ap2 = dynamic_reconfigure.client.Client("hostapd2") self.reset_params = { "enabled": False, "ssid": "test", "wmm": False, "mode": 'b', "freq": 2412e6, "ieee80211n": False, "encryption_mode": "open", "encryption_pass": "", "txpower_auto": "True", "txpower": 0, "bitrate": 0 } self.dyn_ap1.update_configuration(self.reset_params) self.dyn_ap2.update_configuration(self.reset_params) self.hwsim_nat_setup_path = \ roslib.packages.find_node('hostapd_access_point', 'hwsim_nat_setup.sh') self.srcnode = UdpmonsourceHandle('performance_test') self.srcnode.cancel_all_tests() def setUp(self): pass def tearDown(self): self.srcnode.cancel_all_tests() self.dyn_ap1.update_configuration(self.reset_params) self.dyn_ap2.update_configuration(self.reset_params) subprocess.call(["wpa_cli", "-i", self.sta_iface, "terminate"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) def setup_nat_rules(self): p = subprocess.Popen([ self.hwsim_nat_setup_path, self.ap1_iface, AP_REAL_IP, AP_FAKE_IP, self.sta_iface, STA_REAL_IP, STA_FAKE_IP ], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) (out, err) = p.communicate() self.assertEqual( p.returncode, 0, "Setting hwsim NAT rules on %s and %s failed: %s" % (self.ap1_iface, self.sta_iface, out)) def start_wpa_supplicant(self, conffile): supp_conf_path = roslib.packages.find_resource("network_control_tests", conffile) supp_conf_path = supp_conf_path[0] ret = subprocess.call([ "wpa_supplicant", "-Dnl80211", "-i" + self.sta_iface, "-B", "-c" + supp_conf_path ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) self.assertEqual( ret, 0, "Starting wpa_supplicant with WEP conf on %s failed with ret code %d" % (self.sta_iface, ret)) def test_freq(self): freq = IEEE80211_Channels.get_freq(5, IEEE80211_Channels.BAND_2400_MHz) config = self.dyn_ap1.update_configuration({ "enabled": True, "ssid": "testnet1", "mode": 'b', "freq": freq }) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) ap1_info = IwconfigInfo(self.ap1_iface) self.assertEqual( ap1_info.freq(), freq, "Expected freq to be %ld, but instead it was %ld" % (freq, ap1_info.freq())) freq = IEEE80211_Channels.get_freq(44, IEEE80211_Channels.BAND_5000_MHz) config = self.dyn_ap1.update_configuration({"freq": freq}) ap1_info = IwconfigInfo(self.ap1_iface) self.assertEqual( config['status'], "FAIL", "Expected setting an 802.11a freq when in 802.11b mode to fail: %s" % (ap1_info.out)) config = self.dyn_ap1.update_configuration({ "freq": freq, "mode": "a", "enabled": True }) ap1_info = IwconfigInfo(self.ap1_iface) self.assertEqual( ap1_info.freq(), freq, "Expected freq to be %ld, but instead it was %ld" % (freq, ap1_info.freq())) def test_txpower(self): # set txpower to 0dBm config = self.dyn_ap1.update_configuration({ "enabled": True, "ssid": "testnet1", "mode": 'b', "txpower_auto": False, "txpower": 0 }) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) self.assertEqual( config['txpower'], 0, "Expected configuration txpower to be 0 instead it was %d" % (config['txpower'])) ap1_info = IwconfigInfo(self.ap1_iface) self.assertEqual( ap1_info.txpower(), 0, "Expected iwconfig txpower to be 0 instead it was %d" % (ap1_info.txpower())) # set txpower to 10dBm config = self.dyn_ap1.update_configuration({"txpower": 10}) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) self.assertEqual( config['txpower'], 10, "Expected configuration txpower to be 10 instead it was %d" % (config['txpower'])) ap1_info = IwconfigInfo(self.ap1_iface) self.assertEqual( ap1_info.txpower(), 10, "Expected iwconfig txpower to be 10 instead it was %d" % (ap1_info.txpower())) # set txpower to -10dBm, this is not legal so expecting to move to the nearest legal value, which is 0 config = self.dyn_ap1.update_configuration({"txpower": -10}) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) self.assertEqual( config['txpower'], 0, "Expected configuration txpower to be 0 instead it was %d" % (config['txpower'])) ap1_info = IwconfigInfo(self.ap1_iface) self.assertEqual( ap1_info.txpower(), 0, "Expected iwconfig txpower to be 0 instead it was %d" % (ap1_info.txpower())) # set txpower to 30dBm, this is not legal so expecting to move to the nearest legal value, which is 20 config = self.dyn_ap1.update_configuration({"txpower": 30}) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) self.assertEqual( config['txpower'], 20, "Expected configuration txpower to be 20 instead it was %d" % (config['txpower'])) ap1_info = IwconfigInfo(self.ap1_iface) self.assertEqual( ap1_info.txpower(), 20, "Expected iwconfig txpower to be 20 instead it was %d" % (ap1_info.txpower())) # just tests that legal values are accepted since there is no way to read the bitrate while in master mode # and mac80211_hwsim does not actually limit rate (does not emulate rates) def test_bitrate(self): config = self.dyn_ap1.update_configuration({ "enabled": True, "ssid": "testnet1", "mode": 'g', "bitrate": 1 * 10**6 }) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) self.assertEqual( config['bitrate'], 1 * 10**6, "Expected configuration bitrate to be %d instead it was %d" % (1 * 10**6, config['bitrate'])) config = self.dyn_ap1.update_configuration({"bitrate": 54 * 10**6}) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) self.assertEqual( config['bitrate'], 54 * 10**6, "Expected configuration bitrate to be %d instead it was %d" % (54 * 10**6, config['bitrate'])) config = self.dyn_ap1.update_configuration({"bitrate": 3 * 10**6}) self.assertEqual( config['status'], "FAIL", "Setting an illegal bitrate of 3Mbit/s should have failed") def test_txpower_auto(self): config = self.dyn_ap1.update_configuration({ "enabled": True, "ssid": "testnet1", "txpower_auto": True, "txpower": 0 }) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) self.assertTrue(config['txpower_auto'], "Expected txpower_auto to be True") self.assertEqual( config['txpower'], 20, "Expected txpower to be maximum (20) instead it was %d" % (config['txpower'])) def test_start_stop(self): config = self.dyn_ap1.update_configuration({ "enabled": True, "ssid": "testnet1" }) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) self.assertTrue(config['enabled'], "Expected hostapd to be running") for i in range(3): config = self.dyn_ap1.update_configuration({"enabled": False}) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) self.assertFalse(config['enabled'], "Expected hostapd to be stopped") config = self.dyn_ap1.update_configuration({"enabled": True}) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) self.assertTrue(config['enabled'], "Expected hostapd to be running") def test_multiple_aps(self): config = self.dyn_ap1.update_configuration({ "enabled": True, "ssid": "testnet1" }) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) self.assertTrue(config['enabled'], "Expected hostapd to be running") config = self.dyn_ap2.update_configuration({ "enabled": True, "ssid": "testnet2" }) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) self.assertTrue(config['enabled'], "Expected hostapd to be running") ret = subprocess.call(["ifconfig", self.sta_iface, "up"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) self.assertEqual( ret, 0, "ifup on interface %s failed with ret code %d" % (self.sta_iface, ret)) p = subprocess.Popen(["iwlist", self.sta_iface, "scan"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) (out, err) = p.communicate() self.assertTrue( re.findall('testnet1', out), "Expected testnet1 ssid to be found in station scan: " + out) self.assertTrue( re.findall('testnet2', out), "Expected testnet2 ssid to be found in station scan: " + out) def test_ieee80211n(self): config = self.dyn_ap1.update_configuration({ "ieee80211n": True, "enabled": True }) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) # needs a newer hostapd version than available in Ubuntu 10.04 # it has been tested with hostapd 0.7.3 which has wmm support def disabled_test_wmm(self): config = self.dyn_ap1.update_configuration({ "wmm": True, "enabled": True }) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) def test_encryption(self): #bring up AP in WPA mode (with wrong key) config = self.dyn_ap1.update_configuration({ "ssid": "testnet1", "enabled": True, "encryption_mode": "wpa", "encryption_pass": "******" }) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) # setup NAT rules self.setup_nat_rules() # starting wpa_supplicant on sta_interface in WEP mode self.start_wpa_supplicant("wpa_supplicant_wpa.conf") # give it some time to connect time.sleep(5.0) test = self.srcnode.create_test(bw=2.0 * 10**6, pktsize=1500, duration=5.0, sink_ip=AP_FAKE_IP, sink_port=12345, update_interval=0.2) test.start() time.sleep(5.5) self.assertTrue(test.linkdown(), "Link should be down since WPA pass is wrong") # set the correct key config = self.dyn_ap1.update_configuration( {"encryption_pass": "******"}) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) # setup NAT rules again to make sure ARP entries are in place self.setup_nat_rules() # give it some time to reconnect time.sleep(5.0) test = self.srcnode.create_test(bw=2.0 * 10**6, pktsize=1500, duration=5.0, sink_ip=AP_FAKE_IP, sink_port=12345, update_interval=0.2) test.start() time.sleep(5.5) self.assertFalse(test.linkdown(), "Link should be up since WPA pass is now correct") # stop wpa_supplicant subprocess.call(["wpa_cli", "-i", self.sta_iface, "terminate"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) # starting wpa_supplicant on sta_interface in WPA2 mode self.start_wpa_supplicant("wpa_supplicant_wpa2.conf") # give it some time to reconnect time.sleep(5.0) test = self.srcnode.create_test(bw=2.0 * 10**6, pktsize=1500, duration=5.0, sink_ip=AP_FAKE_IP, sink_port=12345, update_interval=0.2) test.start() time.sleep(5.5) self.assertTrue( test.linkdown(), "Link should be down since client wants WPA2, but AP is in WPA mode" ) # set the correct key config = self.dyn_ap1.update_configuration( {"encryption_mode": "wpa_wpa2"}) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) # setup NAT rules again to make sure ARP entries are in place self.setup_nat_rules() # give it some time to reconnect time.sleep(5.0) test = self.srcnode.create_test(bw=2.0 * 10**6, pktsize=1500, duration=5.0, sink_ip=AP_FAKE_IP, sink_port=12345, update_interval=0.2) test.start() time.sleep(5.5) self.assertFalse( test.linkdown(), "Link should be up because AP is in WPA-WPA2 mode, and STA in WPA2" )
class AdaptiveBandwidthTest(unittest.TestCase): def __init__(self, *args): super(AdaptiveBandwidthTest, self).__init__(*args) rospy.init_node('network_monitor_udp_test') self.srcnode = UdpmonsourceHandle('performance_test') self.tc = TcPortControl(self) self.tc.reset() def setUp(self): self.srcnode.cancel_all_tests() self.tc.init() def tearDown(self): self.tc.reset() def test_ramp_up(self): test = self.srcnode.create_test(bw=1.0 * 10**6, pktsize=1500, duration=5.0, sink_ip="127.0.0.1", sink_port=12345, bw_type=LinktestGoal.BW_ADAPTIVE, update_interval=0.2, latency_threshold=0.1) self.tc.set_rate_limit(5e6) test.start() time.sleep(5.5) self.assertTrue( test.bandwidth.movavg(5) > 4.3e6 and test.bandwidth.movavg(5) < 5.7e6, "Expected capacity on loopback interface to be ~5Mbit/s, instead it was %.2fMbit/s" % (test.bandwidth.movavg(5) / 1e6)) def test_ramp_down(self): test = self.srcnode.create_test(bw=5.0 * 10**6, pktsize=1500, duration=5.0, sink_ip="127.0.0.1", sink_port=12345, bw_type=LinktestGoal.BW_ADAPTIVE, update_interval=0.2, latency_threshold=0.1) self.tc.set_rate_limit(5e6) test.start() time.sleep(2.0) self.tc.set_rate_limit(1e6) time.sleep(3.0) self.assertTrue( test.bandwidth.movavg(5) > 0.6e6 and test.bandwidth.movavg(5) < 1.4e6, "Expected capacity on loopback interface to be ~1Mbit/s, instead it was %.2fMbit/s" % (test.bandwidth.movavg(5) / 1e6)) def test_varying_capacity(self): test = self.srcnode.create_test(bw=2 * 10**6, pktsize=1500, duration=15.0, sink_ip="127.0.0.1", sink_port=12345, bw_type=LinktestGoal.BW_ADAPTIVE, update_interval=0.2, latency_threshold=0.1) self.tc.set_rate_limit(10e6) test.start() time.sleep(4.0) self.assertTrue( test.bandwidth.movavg(5) > 9e6 and test.bandwidth.movavg(5) < 11e6, "Expected capacity on loopback interface to be ~10Mbit/s, instead it was %.2fMbit/s" % (test.bandwidth.movavg(5) / 1e6)) self.tc.set_rate_limit(1e6) time.sleep(4.0) self.assertTrue( test.bandwidth.movavg(5) > 0.6e6 and test.bandwidth.movavg(5) < 1.4e6, "Expected capacity on loopback interface to be ~1Mbit/s, instead it was %.2fMbit/s" % (test.bandwidth.movavg(5) / 1e6)) self.tc.set_rate_limit(5e6) time.sleep(6.0) self.assertTrue( test.bandwidth.movavg(5) > 3.5e6 and test.bandwidth.movavg(5) < 5.7e6, "Expected capacity on loopback interface to be ~5Mbit/s, instead it was %.2fMbit/s" % (test.bandwidth.movavg(5) / 1e6)) def test_get_capacity(self): self.tc.set_rate_limit(5e6) capacity = self.srcnode.get_link_capacity(sink_ip="127.0.0.1", sink_port=12345, latency_threshold=0.1) self.assertTrue( capacity > 4.3e6 and capacity < 5.7e6, "Expected capacity on loopback interface to be ~5Mbit/s, instead it was %.2fMbit/s" % (capacity / 1e6)) self.tc.set_rate_limit(20e6) capacity = self.srcnode.get_link_capacity(sink_ip="127.0.0.1", sink_port=12345, latency_threshold=0.1) self.assertTrue( capacity > 15e6 and capacity < 25e6, "Expected capacity on loopback interface to be ~20Mbit/s, instead it was %.2fMbit/s" % (capacity / 1e6)) self.tc.set_rate_limit(0.5e6) capacity = self.srcnode.get_link_capacity(sink_ip="127.0.0.1", sink_port=12345, latency_threshold=0.1) self.assertTrue( capacity > 0.3e6 and capacity < 0.7e6, "Expected capacity on loopback interface to be ~0.5Mbit/s, instead it was %.2fMbit/s" % (capacity / 1e6))
class ConstantBandwidthTest(unittest.TestCase): def __init__(self, *args): super(ConstantBandwidthTest, self).__init__(*args) rospy.init_node('network_monitor_udp_test') self.srcnode = UdpmonsourceHandle('performance_test') self.tc = TcPortControl(self) self.tc.reset() def setUp(self): self.srcnode.cancel_all_tests() self.tc.init() def tearDown(self): self.tc.reset() def test_basic(self): test = self.srcnode.create_test(bw = 1.0*10**6, pktsize = 1500, duration = 3.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT) test.start() time.sleep(3.5) self.assertTrue(test.done, "Test should have finished already") self.assertTrue(test.overall_latency > 0.0 and test.overall_latency < 0.005, "Expected latency on loopback interface to be positive and under 5ms, instead it was %.2fms"% (test.overall_latency * 1000)) self.assertAlmostEqual(test.overall_loss, 0.0, 2, "Expected packet loss on loopback interface to be zero, instead it was %.2f%%"% (test.overall_loss)) self.assertTrue(test.overall_bandwidth > 0.9 * 10**6, "Expected useful bandwidth on loopback interface to be at least 0.9Mbit/s, instead it was %.2fMbit/s"% (test.overall_bandwidth/1e6)) def test_bw_measurement(self): test = self.srcnode.create_test(bw = 3.0*10**6, pktsize = 1500, duration = 5.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT) self.tc.set_rate_limit(1e6) test.start() time.sleep(5.5) self.assertTrue(test.done, "Test should have finished already") self.assertTrue(test.overall_bandwidth < 1e6 and test.overall_bandwidth > 0.9e6, "Expected useful bandwidth on loopback interface to be at least 0.9Mbit/s, instead it was %.2fMbit/s"% (test.overall_bandwidth/1e6)) def test_bw_measurement_variable_bw(self): test = self.srcnode.create_test(bw = 5.0*10**6, pktsize = 1500, duration = 5.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT, update_interval = 0.15) self.tc.set_rate_limit(1e6) test.start() time.sleep(2.0) self.assertTrue(test.bandwidth.movavg(5) < 1.15e6 and test.bandwidth.movavg(5) > 0.85e6, "Expected useful bandwidth on loopback interface to be ~1Mbit/s, instead it was %.2fMbit/s"% (test.bandwidth.movavg(5)/1e6)) self.tc.set_rate_limit(4e6) time.sleep(2.0) self.assertTrue(test.bandwidth.movavg(5) < 4.2e6 and test.bandwidth.movavg(5) > 3.8e6, "Expected useful bandwidth on loopback interface to be ~4Mbit/s, instead it was %.2fMbit/s"% (test.bandwidth.movavg(5)/1e6)) self.tc.set_rate_limit(0.25e6) time.sleep(2.0) self.assertTrue(test.bandwidth.movavg(5) < 0.35e6 and test.bandwidth.movavg(5) > 0.15e6, "Expected useful bandwidth on loopback interface to be ~0.25Mbit/s, instead it was %.2fMbit/s"% (test.bandwidth.movavg(5)/1e6)) def test_loss_measurement(self): test = self.srcnode.create_test(bw = 1.0*10**6, pktsize = 200, duration = 12.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT, update_interval = 0.15) self.tc.set_latency_loss(loss = 5) test.start() time.sleep(4.0) self.assertTrue(test.loss.movavg() < 8.5 and test.loss.movavg() > 1.5, "Expected packet loss on loopback interface to be ~5%%, instead it was %.2f%%"% (test.loss.movavg())) self.tc.set_latency_loss(loss = 20) time.sleep(4.0) self.assertTrue(test.loss.movavg() < 25.0 and test.loss.movavg() > 15.0, "Expected packet loss on loopback interface to be ~20%%, instead it was %.2f%%"% (test.loss.movavg())) self.tc.set_latency_loss(loss = 0) time.sleep(4.0) self.assertTrue(test.loss.movavg() < 1.0, "Expected packet loss on loopback interface to be ~0%%, instead it was %.2f%%"% (test.loss.movavg())) def test_latency_measurement(self): test = self.srcnode.create_test(bw = 1.0*10**6, pktsize = 200, duration = 6.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT, update_interval = 0.2) test.start() time.sleep(1.5) lo_latency = test.latency.movavg(3) self.tc.set_latency_loss(latency = 0.02) time.sleep(1.5) added_latency = test.latency.movavg(3) - lo_latency self.assertTrue(added_latency > 0.015 and added_latency < 0.025, "Expected added latency on loopback interface to be ~20ms, instead it was %.2fms"% (added_latency * 1000)) self.tc.set_latency_loss(latency = 0.06) time.sleep(1.5) added_latency = test.latency.movavg(3) - lo_latency self.assertTrue(added_latency > 0.052 and added_latency < 0.068, "Expected added latency on loopback interface to be ~60ms, instead it was %.2fms"% (added_latency * 1000)) self.tc.set_latency_loss(latency = 0) time.sleep(1.5) added_latency = test.latency.movavg(3) - lo_latency self.assertTrue(added_latency < 0.002, "Expected added latency on loopback interface to be ~0ms, instead it was %.2fms"% (added_latency * 1000)) def test_latency_loss(self): test = self.srcnode.create_test(bw = 1.0*10**6, pktsize = 200, duration = 3.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT, update_interval = 0.2) self.tc.set_latency_loss(loss = 5, latency = 0.05) test.start() time.sleep(3.5) self.assertTrue(test.loss.movavg(10) < 7.5 and test.loss.movavg(10) > 2.5, "Expected packet loss on loopback interface to be ~5%%, instead it was %.2f%%"% (test.loss.movavg(10))) self.assertTrue(test.latency.movavg(10) < 0.07 and test.latency.movavg(10) > 0.05, "Expected latency on loopback interface to be ~60ms, instead it was %.2fms"% (test.latency.movavg(10)* 1000))
class AdaptiveBandwidthTest(unittest.TestCase): def __init__(self, *args): super(AdaptiveBandwidthTest, self).__init__(*args) rospy.init_node('network_monitor_udp_test') self.srcnode = UdpmonsourceHandle('performance_test') self.tc = TcPortControl(self) self.tc.reset() def setUp(self): self.srcnode.cancel_all_tests() self.tc.init() def tearDown(self): self.tc.reset() def test_ramp_up(self): test = self.srcnode.create_test(bw = 1.0*10**6, pktsize = 1500, duration = 5.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_ADAPTIVE, update_interval = 0.2, latency_threshold = 0.1) self.tc.set_rate_limit(5e6) test.start() time.sleep(5.5) self.assertTrue(test.bandwidth.movavg(5) > 4.3e6 and test.bandwidth.movavg(5) < 5.7e6, "Expected capacity on loopback interface to be ~5Mbit/s, instead it was %.2fMbit/s"% (test.bandwidth.movavg(5)/1e6)) def test_ramp_down(self): test = self.srcnode.create_test(bw = 5.0*10**6, pktsize = 1500, duration = 5.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_ADAPTIVE, update_interval = 0.2, latency_threshold = 0.1) self.tc.set_rate_limit(5e6) test.start() time.sleep(2.0) self.tc.set_rate_limit(1e6) time.sleep(3.0) self.assertTrue(test.bandwidth.movavg(5) > 0.6e6 and test.bandwidth.movavg(5) < 1.4e6, "Expected capacity on loopback interface to be ~1Mbit/s, instead it was %.2fMbit/s"% (test.bandwidth.movavg(5)/1e6)) def test_varying_capacity(self): test = self.srcnode.create_test(bw = 2*10**6, pktsize = 1500, duration = 15.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_ADAPTIVE, update_interval = 0.2, latency_threshold = 0.1) self.tc.set_rate_limit(10e6) test.start() time.sleep(4.0) self.assertTrue(test.bandwidth.movavg(5) > 9e6 and test.bandwidth.movavg(5) < 11e6, "Expected capacity on loopback interface to be ~10Mbit/s, instead it was %.2fMbit/s"% (test.bandwidth.movavg(5)/1e6)) self.tc.set_rate_limit(1e6) time.sleep(4.0) self.assertTrue(test.bandwidth.movavg(5) > 0.6e6 and test.bandwidth.movavg(5) < 1.4e6, "Expected capacity on loopback interface to be ~1Mbit/s, instead it was %.2fMbit/s"% (test.bandwidth.movavg(5)/1e6)) self.tc.set_rate_limit(5e6) time.sleep(6.0) self.assertTrue(test.bandwidth.movavg(5) > 3.5e6 and test.bandwidth.movavg(5) < 5.7e6, "Expected capacity on loopback interface to be ~5Mbit/s, instead it was %.2fMbit/s"% (test.bandwidth.movavg(5)/1e6)) def test_get_capacity(self): self.tc.set_rate_limit(5e6) capacity = self.srcnode.get_link_capacity(sink_ip = "127.0.0.1", sink_port = 12345, latency_threshold = 0.1) self.assertTrue(capacity > 4.3e6 and capacity < 5.7e6, "Expected capacity on loopback interface to be ~5Mbit/s, instead it was %.2fMbit/s"% (capacity/1e6)) self.tc.set_rate_limit(20e6) capacity = self.srcnode.get_link_capacity(sink_ip = "127.0.0.1", sink_port = 12345, latency_threshold = 0.1) self.assertTrue(capacity > 15e6 and capacity < 25e6, "Expected capacity on loopback interface to be ~20Mbit/s, instead it was %.2fMbit/s"% (capacity/1e6)) self.tc.set_rate_limit(0.5e6) capacity = self.srcnode.get_link_capacity(sink_ip = "127.0.0.1", sink_port = 12345, latency_threshold = 0.1) self.assertTrue(capacity > 0.3e6 and capacity < 0.7e6, "Expected capacity on loopback interface to be ~0.5Mbit/s, instead it was %.2fMbit/s"% (capacity/1e6))
#! /usr/bin/env python import roslib roslib.load_manifest("network_monitor_udp") import rospy from network_monitor_udp.linktest import UdpmonsourceHandle from network_monitor_udp.linktest import LinkTest from network_monitor_udp.msg import LinktestGoal if __name__ == "__main__": rospy.init_node("test_node") source = UdpmonsourceHandle() source.cancel_all_tests() try: print "Link capacity: %.2fMbit/s" % (source.get_link_capacity(sink_ip="127.0.0.1", sink_port=12345) / 1e6) finally: source.cancel_all_tests()
def setup_hostapd_ap(): config = dynclient.update_configuration({ "enabled": True, "ssid": "testnet", "mode": "g" }) if config["status"] != "OK": raise ValueError(config["errmsg"]) if __name__ == '__main__': pktsize = DEFAULT_PACKET_SIZE if len(sys.argv) == 2: pktsize = int(sys.argv[1]) rospy.init_node('testnode') dynclient = dynamic_reconfigure.client.Client(HOSTAPD_NODE) ap_source = UdpmonsourceHandle('/ap_atheros/performance_test') sta_source = UdpmonsourceHandle('/sta/performance_test') ap_source.cancel_all_tests() sta_source.cancel_all_tests() setup_hostapd_ap() print "Up: ", get_link_capacity("up") print "Down: ", get_link_capacity("down")
class HostapdTest(unittest.TestCase): def __init__(self, *args): super(HostapdTest, self).__init__(*args) rospy.init_node('hostapd_access_point_test') self.ap1_iface = rospy.get_param('~ap1_iface') self.ap2_iface = rospy.get_param('~ap2_iface') self.sta_iface = rospy.get_param('~sta_iface') self.dyn_ap1 = dynamic_reconfigure.client.Client("hostapd1") self.dyn_ap2 = dynamic_reconfigure.client.Client("hostapd2") self.reset_params = { "enabled" : False, "ssid": "test", "wmm": False, "mode": 'b', "freq": 2412e6, "ieee80211n": False, "encryption_mode": "open", "encryption_pass": "", "txpower_auto": "True", "txpower": 0, "bitrate": 0 } self.dyn_ap1.update_configuration(self.reset_params) self.dyn_ap2.update_configuration(self.reset_params) self.hwsim_nat_setup_path = \ roslib.packages.find_node('hostapd_access_point', 'hwsim_nat_setup.sh') self.srcnode = UdpmonsourceHandle('performance_test') self.srcnode.cancel_all_tests() def setUp(self): pass def tearDown(self): self.srcnode.cancel_all_tests() self.dyn_ap1.update_configuration(self.reset_params) self.dyn_ap2.update_configuration(self.reset_params) subprocess.call(["wpa_cli", "-i", self.sta_iface, "terminate"], stdout = subprocess.PIPE, stderr = subprocess.STDOUT) def setup_nat_rules(self): p = subprocess.Popen([self.hwsim_nat_setup_path, self.ap1_iface, AP_REAL_IP, AP_FAKE_IP, self.sta_iface, STA_REAL_IP, STA_FAKE_IP], stdout = subprocess.PIPE, stderr = subprocess.STDOUT) (out, err) = p.communicate() self.assertEqual(p.returncode, 0, "Setting hwsim NAT rules on %s and %s failed: %s"% (self.ap1_iface, self.sta_iface, out)) def start_wpa_supplicant(self, conffile): supp_conf_path = roslib.packages.find_resource("network_control_tests", conffile) supp_conf_path = supp_conf_path[0] ret = subprocess.call(["wpa_supplicant", "-Dnl80211", "-i" + self.sta_iface, "-B", "-c" + supp_conf_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE) self.assertEqual(ret, 0, "Starting wpa_supplicant with WEP conf on %s failed with ret code %d"% (self.sta_iface, ret)) def test_freq(self): freq = IEEE80211_Channels.get_freq(5, IEEE80211_Channels.BAND_2400_MHz) config = self.dyn_ap1.update_configuration({"enabled": True, "ssid": "testnet1", "mode": 'b', "freq": freq}) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) ap1_info = IwconfigInfo(self.ap1_iface) self.assertEqual(ap1_info.freq(), freq, "Expected freq to be %ld, but instead it was %ld"%(freq, ap1_info.freq())) freq = IEEE80211_Channels.get_freq(44, IEEE80211_Channels.BAND_5000_MHz) config = self.dyn_ap1.update_configuration({"freq": freq}) ap1_info = IwconfigInfo(self.ap1_iface) self.assertEqual(config['status'], "FAIL", "Expected setting an 802.11a freq when in 802.11b mode to fail: %s"% (ap1_info.out)) config = self.dyn_ap1.update_configuration({"freq": freq, "mode": "a", "enabled": True}) ap1_info = IwconfigInfo(self.ap1_iface) self.assertEqual(ap1_info.freq(), freq, "Expected freq to be %ld, but instead it was %ld"%(freq, ap1_info.freq())) def test_txpower(self): # set txpower to 0dBm config = self.dyn_ap1.update_configuration({"enabled": True, "ssid": "testnet1", "mode": 'b', "txpower_auto": False, "txpower": 0}) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) self.assertEqual(config['txpower'], 0, "Expected configuration txpower to be 0 instead it was %d"%(config['txpower'])) ap1_info = IwconfigInfo(self.ap1_iface) self.assertEqual(ap1_info.txpower(), 0, "Expected iwconfig txpower to be 0 instead it was %d"%(ap1_info.txpower())) # set txpower to 10dBm config = self.dyn_ap1.update_configuration({"txpower": 10}) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) self.assertEqual(config['txpower'], 10, "Expected configuration txpower to be 10 instead it was %d"%(config['txpower'])) ap1_info = IwconfigInfo(self.ap1_iface) self.assertEqual(ap1_info.txpower(), 10, "Expected iwconfig txpower to be 10 instead it was %d"%(ap1_info.txpower())) # set txpower to -10dBm, this is not legal so expecting to move to the nearest legal value, which is 0 config = self.dyn_ap1.update_configuration({"txpower": -10}) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) self.assertEqual(config['txpower'], 0, "Expected configuration txpower to be 0 instead it was %d"%(config['txpower'])) ap1_info = IwconfigInfo(self.ap1_iface) self.assertEqual(ap1_info.txpower(), 0, "Expected iwconfig txpower to be 0 instead it was %d"%(ap1_info.txpower())) # set txpower to 30dBm, this is not legal so expecting to move to the nearest legal value, which is 20 config = self.dyn_ap1.update_configuration({"txpower": 30}) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) self.assertEqual(config['txpower'], 20, "Expected configuration txpower to be 20 instead it was %d"%(config['txpower'])) ap1_info = IwconfigInfo(self.ap1_iface) self.assertEqual(ap1_info.txpower(), 20, "Expected iwconfig txpower to be 20 instead it was %d"%(ap1_info.txpower())) # just tests that legal values are accepted since there is no way to read the bitrate while in master mode # and mac80211_hwsim does not actually limit rate (does not emulate rates) def test_bitrate(self): config = self.dyn_ap1.update_configuration({"enabled": True, "ssid": "testnet1", "mode": 'g', "bitrate": 1*10**6}) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) self.assertEqual(config['bitrate'], 1*10**6, "Expected configuration bitrate to be %d instead it was %d"% (1*10**6, config['bitrate'])) config = self.dyn_ap1.update_configuration({"bitrate": 54*10**6}) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) self.assertEqual(config['bitrate'], 54*10**6, "Expected configuration bitrate to be %d instead it was %d"% (54*10**6, config['bitrate'])) config = self.dyn_ap1.update_configuration({"bitrate": 3*10**6}) self.assertEqual(config['status'], "FAIL", "Setting an illegal bitrate of 3Mbit/s should have failed") def test_txpower_auto(self): config = self.dyn_ap1.update_configuration({"enabled": True, "ssid": "testnet1", "txpower_auto": True, "txpower": 0}) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) self.assertTrue(config['txpower_auto'], "Expected txpower_auto to be True") self.assertEqual(config['txpower'], 20, "Expected txpower to be maximum (20) instead it was %d"%(config['txpower'])) def test_start_stop(self): config = self.dyn_ap1.update_configuration({"enabled": True, "ssid": "testnet1"}) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) self.assertTrue(config['enabled'], "Expected hostapd to be running") for i in range(3): config = self.dyn_ap1.update_configuration({"enabled": False}) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) self.assertFalse(config['enabled'], "Expected hostapd to be stopped") config = self.dyn_ap1.update_configuration({"enabled": True}) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) self.assertTrue(config['enabled'], "Expected hostapd to be running") def test_multiple_aps(self): config = self.dyn_ap1.update_configuration({"enabled": True, "ssid": "testnet1"}) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) self.assertTrue(config['enabled'], "Expected hostapd to be running") config = self.dyn_ap2.update_configuration({"enabled": True, "ssid": "testnet2"}) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) self.assertTrue(config['enabled'], "Expected hostapd to be running") ret = subprocess.call(["ifconfig", self.sta_iface, "up"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) self.assertEqual(ret, 0, "ifup on interface %s failed with ret code %d"% (self.sta_iface, ret)) p = subprocess.Popen(["iwlist", self.sta_iface, "scan"], stdout = subprocess.PIPE, stderr = subprocess.PIPE) (out, err) = p.communicate() self.assertTrue(re.findall('testnet1', out), "Expected testnet1 ssid to be found in station scan: " + out) self.assertTrue(re.findall('testnet2', out), "Expected testnet2 ssid to be found in station scan: " + out) def test_ieee80211n(self): config = self.dyn_ap1.update_configuration({"ieee80211n": True, "enabled": True}) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) # needs a newer hostapd version than available in Ubuntu 10.04 # it has been tested with hostapd 0.7.3 which has wmm support def disabled_test_wmm(self): config = self.dyn_ap1.update_configuration({"wmm": True, "enabled": True}) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) def test_encryption(self): #bring up AP in WPA mode (with wrong key) config = self.dyn_ap1.update_configuration({"ssid": "testnet1", "enabled": True, "encryption_mode": "wpa", "encryption_pass": "******"}) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) # setup NAT rules self.setup_nat_rules() # starting wpa_supplicant on sta_interface in WEP mode self.start_wpa_supplicant("wpa_supplicant_wpa.conf") # give it some time to connect time.sleep(5.0) test = self.srcnode.create_test(bw = 2.0 * 10**6, pktsize = 1500, duration = 5.0, sink_ip = AP_FAKE_IP, sink_port = 12345, update_interval = 0.2) test.start() time.sleep(5.5) self.assertTrue(test.linkdown(), "Link should be down since WPA pass is wrong") # set the correct key config = self.dyn_ap1.update_configuration({"encryption_pass": "******"}) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) # setup NAT rules again to make sure ARP entries are in place self.setup_nat_rules() # give it some time to reconnect time.sleep(5.0) test = self.srcnode.create_test(bw = 2.0 * 10**6, pktsize = 1500, duration = 5.0, sink_ip = AP_FAKE_IP, sink_port = 12345, update_interval = 0.2) test.start() time.sleep(5.5) self.assertFalse(test.linkdown(), "Link should be up since WPA pass is now correct") # stop wpa_supplicant subprocess.call(["wpa_cli", "-i", self.sta_iface, "terminate"], stdout = subprocess.PIPE, stderr = subprocess.STDOUT) # starting wpa_supplicant on sta_interface in WPA2 mode self.start_wpa_supplicant("wpa_supplicant_wpa2.conf") # give it some time to reconnect time.sleep(5.0) test = self.srcnode.create_test(bw = 2.0 * 10**6, pktsize = 1500, duration = 5.0, sink_ip = AP_FAKE_IP, sink_port = 12345, update_interval = 0.2) test.start() time.sleep(5.5) self.assertTrue(test.linkdown(), "Link should be down since client wants WPA2, but AP is in WPA mode") # set the correct key config = self.dyn_ap1.update_configuration({"encryption_mode": "wpa_wpa2"}) self.assertEqual(config['status'], "OK", "Operation failed: " + config['errmsg']) # setup NAT rules again to make sure ARP entries are in place self.setup_nat_rules() # give it some time to reconnect time.sleep(5.0) test = self.srcnode.create_test(bw = 2.0 * 10**6, pktsize = 1500, duration = 5.0, sink_ip = AP_FAKE_IP, sink_port = 12345, update_interval = 0.2) test.start() time.sleep(5.5) self.assertFalse(test.linkdown(), "Link should be up because AP is in WPA-WPA2 mode, and STA in WPA2")
class MultipleEndsTest(unittest.TestCase): def __init__(self, *args): super(MultipleEndsTest, self).__init__(*args) rospy.init_node('network_monitor_udp_test') self.srcnode = UdpmonsourceHandle('performance_test') self.tc = TcPortControl(self) self.tc.reset() def setUp(self): self.srcnode.cancel_all_tests() self.tc.init() def tearDown(self): self.tc.reset() def test_multiple_sources_single_sink(self): self.tc.set_rate_limit(1e6) test1 = self.srcnode.create_test(bw = 1.0*10**6, pktsize = 1500, duration = 5.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT, update_interval = 0.2) test2 = self.srcnode.create_test(bw = 1.0*10**6, pktsize = 1500, duration = 10.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT, update_interval = 0.2) test3 = self.srcnode.create_test(bw = 1.0*10**6, pktsize = 1500, duration = 15.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT, update_interval = 0.2) test1.start() test2.start() test3.start() time.sleep(3.0) bwsum = test1.bandwidth.movavg(5) + test2.bandwidth.movavg(5) + test3.bandwidth.movavg(5) self.assertTrue(bwsum > 0.8e6 and bwsum < 1.2e6, "Expected the combined bandwidth of three tests to be ~1Mbit/s, instead it was %.2fMbit/s"% (bwsum)) time.sleep(2.5) self.assertTrue(test1.done, "Expected test1 to have finished at time = 5.5s") self.assertFalse(test2.done, "Expected test2 to be still running at time = 5.5s") self.assertFalse(test3.done, "Expected test3 to be still running at time = 5.5s") time.sleep(2.5) bwsum = test2.bandwidth.movavg(5) + test3.bandwidth.movavg(5) self.assertTrue(bwsum > 0.8e6 and bwsum < 1.2e6, "Expected the combined bandwidth of two tests to be ~1Mbit/s, instead it was %.2fMbit/s"% (bwsum)) time.sleep(2.5) self.assertTrue(test2.done, "Expected test2 to have finished at time = 10.5s") self.assertFalse(test3.done, "Expected test3 to be still running at time = 10.5s") time.sleep(2.5) self.assertTrue(test3.bandwidth.movavg(5) > 0.80e6 and test3.bandwidth.movavg(5) < 1.20e6, "Expected test3 bandwidth to be ~1Mbit/s (with 1 test running concurrently)" + ", instead it was %.2fMbit/s"% (test3.bandwidth.movavg(5)/1e6)) time.sleep(2.5) self.assertTrue(test2.done, "Expected test2 to have finished at time = 10.5s") self.assertTrue(test3.latency.duration() > test2.latency.duration() and test2.latency.duration() > test1.latency.duration(), "Expected test3 duration (%.2fs) to be greater than test2 (%.2fs)" " and still greater than test1 (%.2fs)"% (test3.latency.duration(), test2.latency.duration(), test1.latency.duration())) def test_multiple_sinks(self): self.tc.set_rate_limit(1e6) test1 = self.srcnode.create_test(bw = 5.0*10**6, pktsize = 1500, duration = 3.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT, update_interval = 0.2) test2 = self.srcnode.create_test(bw = 5.0*10**6, pktsize = 1500, duration = 3.0, sink_ip = "127.0.0.1", sink_port = 12346, bw_type = LinktestGoal.BW_CONSTANT, update_interval = 0.2) test1.start() test2.start() time.sleep(3.5) self.assertTrue(test1.done, "Expected test2 to have finished at time = 3.5s") self.assertTrue(test2.done, "Expected test2 to have finished at time = 3.5s") self.assertTrue(test2.overall_bandwidth > 4 * test1.overall_bandwidth, "Expected test2 bw (%.2fMbit/s) to be at least 4x larger" " than test1 bw (%.2fMbit/s)"% (test2.overall_bandwidth/1e6, test1.overall_bandwidth/1e6))
class ConstantBandwidthTest(unittest.TestCase): def __init__(self, *args): super(ConstantBandwidthTest, self).__init__(*args) rospy.init_node('network_monitor_udp_test') self.srcnode = UdpmonsourceHandle('performance_test') self.tc = TcPortControl(self) self.tc.reset() def setUp(self): self.srcnode.cancel_all_tests() self.tc.init() def tearDown(self): self.tc.reset() def test_basic(self): test = self.srcnode.create_test(bw=1.0 * 10**6, pktsize=1500, duration=3.0, sink_ip="127.0.0.1", sink_port=12345, bw_type=LinktestGoal.BW_CONSTANT) test.start() time.sleep(3.5) self.assertTrue(test.done, "Test should have finished already") self.assertTrue( test.overall_latency > 0.0 and test.overall_latency < 0.005, "Expected latency on loopback interface to be positive and under 5ms, instead it was %.2fms" % (test.overall_latency * 1000)) self.assertAlmostEqual( test.overall_loss, 0.0, 2, "Expected packet loss on loopback interface to be zero, instead it was %.2f%%" % (test.overall_loss)) self.assertTrue( test.overall_bandwidth > 0.9 * 10**6, "Expected useful bandwidth on loopback interface to be at least 0.9Mbit/s, instead it was %.2fMbit/s" % (test.overall_bandwidth / 1e6)) def test_bw_measurement(self): test = self.srcnode.create_test(bw=3.0 * 10**6, pktsize=1500, duration=5.0, sink_ip="127.0.0.1", sink_port=12345, bw_type=LinktestGoal.BW_CONSTANT) self.tc.set_rate_limit(1e6) test.start() time.sleep(5.5) self.assertTrue(test.done, "Test should have finished already") self.assertTrue( test.overall_bandwidth < 1e6 and test.overall_bandwidth > 0.9e6, "Expected useful bandwidth on loopback interface to be at least 0.9Mbit/s, instead it was %.2fMbit/s" % (test.overall_bandwidth / 1e6)) def test_bw_measurement_variable_bw(self): test = self.srcnode.create_test(bw=5.0 * 10**6, pktsize=1500, duration=5.0, sink_ip="127.0.0.1", sink_port=12345, bw_type=LinktestGoal.BW_CONSTANT, update_interval=0.15) self.tc.set_rate_limit(1e6) test.start() time.sleep(2.0) self.assertTrue( test.bandwidth.movavg(5) < 1.15e6 and test.bandwidth.movavg(5) > 0.85e6, "Expected useful bandwidth on loopback interface to be ~1Mbit/s, instead it was %.2fMbit/s" % (test.bandwidth.movavg(5) / 1e6)) self.tc.set_rate_limit(4e6) time.sleep(2.0) self.assertTrue( test.bandwidth.movavg(5) < 4.2e6 and test.bandwidth.movavg(5) > 3.8e6, "Expected useful bandwidth on loopback interface to be ~4Mbit/s, instead it was %.2fMbit/s" % (test.bandwidth.movavg(5) / 1e6)) self.tc.set_rate_limit(0.25e6) time.sleep(2.0) self.assertTrue( test.bandwidth.movavg(5) < 0.35e6 and test.bandwidth.movavg(5) > 0.15e6, "Expected useful bandwidth on loopback interface to be ~0.25Mbit/s, instead it was %.2fMbit/s" % (test.bandwidth.movavg(5) / 1e6)) def test_loss_measurement(self): test = self.srcnode.create_test(bw=1.0 * 10**6, pktsize=200, duration=12.0, sink_ip="127.0.0.1", sink_port=12345, bw_type=LinktestGoal.BW_CONSTANT, update_interval=0.15) self.tc.set_latency_loss(loss=5) test.start() time.sleep(4.0) self.assertTrue( test.loss.movavg() < 8.5 and test.loss.movavg() > 1.5, "Expected packet loss on loopback interface to be ~5%%, instead it was %.2f%%" % (test.loss.movavg())) self.tc.set_latency_loss(loss=20) time.sleep(4.0) self.assertTrue( test.loss.movavg() < 25.0 and test.loss.movavg() > 15.0, "Expected packet loss on loopback interface to be ~20%%, instead it was %.2f%%" % (test.loss.movavg())) self.tc.set_latency_loss(loss=0) time.sleep(4.0) self.assertTrue( test.loss.movavg() < 1.0, "Expected packet loss on loopback interface to be ~0%%, instead it was %.2f%%" % (test.loss.movavg())) def test_latency_measurement(self): test = self.srcnode.create_test(bw=1.0 * 10**6, pktsize=200, duration=6.0, sink_ip="127.0.0.1", sink_port=12345, bw_type=LinktestGoal.BW_CONSTANT, update_interval=0.2) test.start() time.sleep(1.5) lo_latency = test.latency.movavg(3) self.tc.set_latency_loss(latency=0.02) time.sleep(1.5) added_latency = test.latency.movavg(3) - lo_latency self.assertTrue( added_latency > 0.015 and added_latency < 0.025, "Expected added latency on loopback interface to be ~20ms, instead it was %.2fms" % (added_latency * 1000)) self.tc.set_latency_loss(latency=0.06) time.sleep(1.5) added_latency = test.latency.movavg(3) - lo_latency self.assertTrue( added_latency > 0.052 and added_latency < 0.068, "Expected added latency on loopback interface to be ~60ms, instead it was %.2fms" % (added_latency * 1000)) self.tc.set_latency_loss(latency=0) time.sleep(1.5) added_latency = test.latency.movavg(3) - lo_latency self.assertTrue( added_latency < 0.002, "Expected added latency on loopback interface to be ~0ms, instead it was %.2fms" % (added_latency * 1000)) def test_latency_loss(self): test = self.srcnode.create_test(bw=1.0 * 10**6, pktsize=200, duration=3.0, sink_ip="127.0.0.1", sink_port=12345, bw_type=LinktestGoal.BW_CONSTANT, update_interval=0.2) self.tc.set_latency_loss(loss=5, latency=0.05) test.start() time.sleep(3.5) self.assertTrue( test.loss.movavg(10) < 7.5 and test.loss.movavg(10) > 2.5, "Expected packet loss on loopback interface to be ~5%%, instead it was %.2f%%" % (test.loss.movavg(10))) self.assertTrue( test.latency.movavg(10) < 0.07 and test.latency.movavg(10) > 0.05, "Expected latency on loopback interface to be ~60ms, instead it was %.2fms" % (test.latency.movavg(10) * 1000))
class ParameterTest(unittest.TestCase): def __init__(self, *args): super(ParameterTest, self).__init__(*args) rospy.init_node('network_monitor_udp_test') self.srcnode = UdpmonsourceHandle('performance_test') self.tc = TcPortControl(self) self.tc.reset() def setUp(self): self.srcnode.cancel_all_tests() self.tc.init() def tearDown(self): self.tc.reset() def test_tos(self): time.sleep(1.0) test1 = self.srcnode.create_test(bw = 1.0*10**6, pktsize = 1500, duration = 1.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT, update_interval = 0.2, tos = 0x10) test2 = self.srcnode.create_test(bw = 1.0*10**6, pktsize = 1500, duration = 1.0, sink_ip = "127.0.0.1", sink_port = 12346, bw_type = LinktestGoal.BW_CONSTANT, update_interval = 0.2, tos = 0x11) test1.start() test2.start() s = scapy.L2Socket(iface='lo', filter='udp and port 12345') while True: pkt = s.recv(2048) if pkt is None: continue if pkt.type != 0x800: print "Unexpected protocol 0x%04x"%pkt.type continue if pkt.dport == 12345: tos = pkt.payload.tos break self.assertEqual(tos, 0x10, "Unexpected TOS value for test1" + str(pkt)) s = scapy.L2Socket(iface='lo', filter='udp and port 12346') while True: pkt = s.recv(2048) if pkt is None: continue if pkt.type != 0x800: print "Unexpected protocol 0x%04x"%pkt.type continue if pkt.dport == 12346: tos = pkt.payload.tos break self.assertEqual(tos, 0x11, "Unexpected TOS value for test2: " + str(pkt)) def test_latencybins(self): self.tc.set_latency_loss(latency = 0.15) test = self.srcnode.create_test(bw = 1.0*10**6, pktsize = 500, duration = 1.5, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT, update_interval = 0.2) test.start() time.sleep(2.0) self.assertTrue(test.done, "Expected test to have ended") self.assertTrue(test.overall_loss > 90.0, "Expected 100%% loss, instead it was %.2f%%"%(test.overall_loss)) self.assertTrue(test.latency_histogram[-1] > 0.95 and sum(test.latency_histogram[:-1]) < 0.05, "Expected all packets to be in the last bin (100ms, infinity)") test = self.srcnode.create_test(bw = 1.0*10**6, pktsize = 500, duration = 1.5, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT, update_interval = 0.2, latencybins = [ 0.01, 0.1, 0.5 ]) test.start() time.sleep(2.0) self.assertTrue(test.done, "Expected test to have ended") self.assertTrue( test.overall_loss < 2.0, "Expected 0%% loss, instead it was %.2f%%"% (test.overall_loss)) def test_max_return_time(self): self.tc.set_latency_loss(latency = 0.075) self.tc.set_latency_loss_udp_returnpath(latency = 0.175) test = self.srcnode.create_test(bw = 1.0*10**6, pktsize = 500, duration = 1.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT, update_interval = 0.05, ros_returnpath = False) test.start() time.sleep(1.5) self.assertTrue(test.done, "Expected test to have ended") self.assertEqual(test.latency.min(), 0.0, "Expected min latency to be 0.0ms meaning that for at least one interval " "(in fact, this should hold for all intervals) no packets were restricted [1]") test = self.srcnode.create_test(bw = 1.0*10**6, pktsize = 500, duration = 1.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT, update_interval = 0.05, max_return_time = 0.01) test.start() time.sleep(1.5) self.assertTrue(test.done, "Expected test to have ended") self.assertEqual(test.latency.min(), 0.0, "Expected min latency to be 0.0ms meaning that for at least one interval " "(in fact, this should hold for all intervals) no packets were restricted [1]") test = self.srcnode.create_test(bw = 1.0*10**6, pktsize = 500, duration = 1.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT, update_interval = 0.05, max_return_time = 0.225) test.start() time.sleep(1.5) self.assertTrue(test.done, "Expected test to have ended") self.assertTrue(test.latency.min() > 0.05, "Expected min latency to be ~75ms (meaning that there was no interval which had " " no restricted packets), instead it was %.2fms"% (test.latency.min())) self.assertTrue(test.loss.min() < 2.0, "Expected 0%% loss during all intervals, instead for one interval it was %.2f%%"% (test.loss.min()) ) def test_udp_return(self): self.tc.set_latency_loss_udp_returnpath(loss = 20.0) test = self.srcnode.create_test(bw = 2.0*10**6, pktsize = 500, duration = 1.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT, update_interval = 0.05, ros_returnpath = False) test.start() time.sleep(1.5) self.assertTrue(test.done, "Expected test to have ended") self.assertTrue(test.loss.movavg() > 10.0, "Expected loss to be ~20%% on UDP return path instead it was %.2f%%"% (test.loss.movavg())) test = self.srcnode.create_test(bw = 2.0*10**6, pktsize = 500, duration = 1.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT, update_interval = 0.05, ros_returnpath = True) test.start() time.sleep(1.5) self.assertTrue(test.done, "Expected test to have ended") self.assertTrue(test.loss.movavg() < 2.0, "Expected loss to be ~0%% with ROS return path instead it was %.2f%%"% (test.loss.movavg())) def test_roundtrip(self): self.tc.set_latency_loss_udp_returnpath(latency = 0.05) test = self.srcnode.create_test(bw = 2.0*10**6, pktsize = 500, duration = 1.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT, update_interval = 0.05, ros_returnpath = False, roundtrip = False) test.start() time.sleep(1.5) self.assertTrue(test.done, "Expected test to have ended") self.assertTrue(test.latency.movavg() < 0.01, "Expected latency to be < 1ms, instead it was %.2fms"% (test.latency.movavg() * 1e3)) test = self.srcnode.create_test(bw = 2.0*10**6, pktsize = 500, duration = 1.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT, update_interval = 0.05, ros_returnpath = False, roundtrip = True) test.start() time.sleep(1.5) self.assertTrue(test.done, "Expected test to have ended") self.assertTrue(test.latency.movavg() > 0.03, "Expected latency to be ~50ms, instead it was %.2fms"% (test.latency.movavg() * 1e3))
def get_link_capacity(direction = "down"): if direction == "up": return sta_source.get_link_capacity(sink_ip=AP_SINK_IP, sink_port=AP_SINK_PORT, rostopic_prefix=AP_PREFIX, pktsize=pktsize) elif direction == "down": return ap_source.get_link_capacity(sink_ip=STA_SINK_IP, sink_port=STA_SINK_PORT, rostopic_prefix=STA_PREFIX, pktsize=pktsize) def setup_hostapd_ap(): config = dynclient.update_configuration({"enabled": True, "ssid": "testnet", "mode": "g"}) if config["status"] != "OK": raise ValueError(config["errmsg"]) if __name__ == '__main__': pktsize = DEFAULT_PACKET_SIZE if len(sys.argv) == 2: pktsize = int(sys.argv[1]) rospy.init_node('testnode') dynclient = dynamic_reconfigure.client.Client(HOSTAPD_NODE) ap_source = UdpmonsourceHandle('/ap_atheros/performance_test') sta_source = UdpmonsourceHandle('/sta/performance_test') ap_source.cancel_all_tests() sta_source.cancel_all_tests() setup_hostapd_ap() print "Up: ", get_link_capacity("up") print "Down: ", get_link_capacity("down")
class DynreconfTest(unittest.TestCase): def __init__(self, *args): super(DynreconfTest, self).__init__(*args) rospy.init_node('network_traffic_control_test') self.srcnode = UdpmonsourceHandle('performance_test') self.dynclient = dynamic_reconfigure.client.Client("tc_lo") self.no_traffic_control_params = { "bandwidth_egress" : 0.0, "bandwidth_ingress" : 0.0, "latency_egress" : 0.0, "latency_ingress" : 0.0, "loss_egress" : 0.0, "loss_ingress" : 0.0, "packet_size" : 1500 } self.reset_tc_rules_via_dynreconf() def reset_tc_rules_via_dynreconf(self): config = self.dynclient.update_configuration(self.no_traffic_control_params) if config['status'] != "OK": raise(ValueError(config['errmsg'])) def setUp(self): self.srcnode.cancel_all_tests() def tearDown(self): self.reset_tc_rules_via_dynreconf() def test_latency(self): test = self.srcnode.create_test(bw = 1.0*10**6, pktsize = 1500, duration = 3.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT) test.start() time.sleep(3.5) self.assertTrue(test.done, "Test should have finished already") self.assertTrue(test.overall_latency < 0.01, "Expected latency to be < 1ms, instead it was %.2fms"% (test.overall_latency * 1e3)) config = self.dynclient.update_configuration({ "latency_egress": 0.03 }) self.assertTrue(config['status'] == "OK", "Operation FAILed: " + config['errmsg']) self.assertAlmostEqual(config['latency_egress'], 0.03, 3, "Expected latency_egress dynreconf parameter to be ~30ms, instead it was %.2fms"% (config['latency_egress'] * 1e3)) test = self.srcnode.create_test(bw = 1.0*10**6, pktsize = 1500, duration = 3.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT) test.start() time.sleep(3.5) self.assertTrue(test.done, "Test should have finished already") self.assertTrue(test.overall_latency > 0.02 and test.overall_latency < 0.04, "Expected latency to be ~30ms, instead it was %.2fms"% (test.overall_latency * 1e3)) self.assertTrue(test.overall_bandwidth > 0.7e6, "Expected overall bandwidth to be ~1Mbit/s, instead it was %.2fMbit/s"% (test.overall_bandwidth/1e6)) self.assertTrue(test.overall_loss < 5.0, "Expected packet loss to be 0%%, instead it was %.2f%%"% (test.overall_loss)) config = self.dynclient.update_configuration({ "latency_egress": 0.01, "latency_ingress": 0.05 }) self.assertTrue(config['status'] == "OK", "Operation FAILed: " + config['errmsg']) self.assertAlmostEqual(config['latency_egress'], 0.01, 3, "Expected latency_egress dynreconf parameter to be ~10ms, instead it was %.2fms"% (config['latency_egress'] * 1e3)) self.assertAlmostEqual(config['latency_ingress'], 0.05, 3, "Expected latency_ingress dynreconf parameter to be ~50ms, instead it was %.2fms"% (config['latency_ingress'] * 1e3)) test = self.srcnode.create_test(bw = 1.0*10**6, pktsize = 1500, duration = 3.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT, max_return_time = 0.1) test.start() time.sleep(3.5) self.assertTrue(test.done, "Test should have finished already") self.assertTrue(test.overall_latency > 0.045 and test.overall_latency < 0.075, "Expected latency to be ~ 60ms, instead it was %.2fms"% (test.overall_latency * 1e3)) self.assertTrue(test.overall_bandwidth > 0.7e6, "Expected overall bandwidth to be ~1Mbit/s, instead it was %.2fMbit/s"% (test.overall_bandwidth/1e6)) self.assertTrue(test.overall_loss < 5.0, "Expected packet loss to be 0%%, instead it was %.2f%%"% (test.overall_loss)) def test_bandwidth(self): test = self.srcnode.create_test(bw = 3.0*10**6, pktsize = 1500, duration = 3.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT) test.start() time.sleep(3.5) self.assertTrue(test.done, "Test should have finished already") self.assertTrue(test.overall_latency < 0.01, "Expected latency to be < 1ms, instead it was %.2fms"% (test.overall_latency * 1e3)) self.assertTrue(test.overall_bandwidth > 2.7e6, "Expected overall bandwidth to be ~3Mbit/s, instead it was %.2fMbit/s"% (test.overall_bandwidth/1e6)) config = self.dynclient.update_configuration({ "bandwidth_egress": 2e6, "bandwidth_ingress": 2e6 }) self.assertTrue(config['status'] == "OK", "Operation FAILed: " + config['errmsg']) self.assertAlmostEqual(config['bandwidth_egress']/1e6, 2.0, 3, "Expected bandwidth_egress dynreconf parameter to be ~2Mbit/s, instead it was %.2fMbit/s"% (config['bandwidth_egress']/1e6)) self.assertAlmostEqual(config['bandwidth_ingress']/1e6, 2.0, 3, "Expected bandwidth_ingress dynreconf parameter to be ~2Mbit/s, instead it was %.2fMbit/s"% (config['bandwidth_ingress']/1e6)) test = self.srcnode.create_test(bw = 3.0*10**6, pktsize = 1500, duration = 3.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT, latencybins = [ 0.01, 0.1, 0.3], max_return_time = 0.25) test.start() time.sleep(3.5) self.assertTrue(test.done, "Test should have finished already") self.assertTrue(test.overall_bandwidth > 1.5e6 and test.overall_bandwidth < 2.5e6, "Expected measured bandwidth to be ~2Mbit/s, instead it was %.2fMbit/s"% (test.overall_bandwidth/1e6)) config = self.dynclient.update_configuration({ "bandwidth_ingress": 1e6 }) test = self.srcnode.create_test(bw = 3.0*10**6, pktsize = 1500, duration = 3.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT) test.start() time.sleep(3.5) self.assertTrue(test.done, "Test should have finished already") self.assertTrue(test.overall_bandwidth > 0.7e6 and test.overall_bandwidth < 1.3e6, "Expected overall bandwidth to be ~1Mbit/s, instead it was %.2fMbit/s"% (test.overall_bandwidth/1e6)) def test_bandwidth_latency(self): config = self.dynclient.update_configuration({ "bandwidth_egress": 1e6, "latency_ingress": 0.03 }) test = self.srcnode.create_test(bw = 0.7*10**6, pktsize = 1500, duration = 5.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT, max_return_time = 0.01) test.start() time.sleep(5.5) self.assertTrue(test.done, "Test should have finished already") self.assertTrue(test.overall_bandwidth > 0.5e6 and test.overall_bandwidth < 0.9e6, "Expected overall bandwidth to be ~1Mbit/s, instead it was %.2fMbit/s"% (test.overall_bandwidth/1e6)) self.assertTrue(test.latency.avg() > 0.025 and test.latency.avg() < 0.045, "Expected latency to be ~30ms (since capacity was not overrun), instead it was %.2fms"% (test.latency.avg()*1e3)) test = self.srcnode.create_test(bw = 3.0*10**6, pktsize = 1500, duration = 5.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT, max_return_time = 0.01) test.start() time.sleep(5.5) self.assertTrue(test.done, "Test should have finished already") self.assertTrue(test.overall_bandwidth > 0.8e6 and test.overall_bandwidth < 1.2e6, "Expected overall bandwidth to be ~1Mbit/s, instead it was %.2fMbit/s"% (test.overall_bandwidth/1e6)) expected_latency = 1500.0/(1e6/8) + 0.03 self.assertTrue(test.latency.avg() > expected_latency - 0.005 and test.latency.avg() < expected_latency + 0.005, "Expected latency to be ~%.2fms (since capacity was not overrun), instead it was %.2fms"% (expected_latency * 1e3, test.latency.avg()*1e3)) def test_ingress_egress_loss(self): config = self.dynclient.update_configuration({ "loss_egress": 20.0, "loss_ingress": 30.0 }) test = self.srcnode.create_test(bw = 5*10**6, pktsize = 1500, duration = 5.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT, max_return_time = 0.01) test.start() time.sleep(5.5) self.assertTrue(test.done, "Test should have finished already") self.assertTrue(test.loss.avg() > 44.0 - 10.0 and test.loss.avg() < 44.0 + 10.0, "Expected aggregated loss (ingress+egress) to be ~44%%, instead it was %.2f%%"% (test.loss.avg())) def test_packet_size(self): test = self.srcnode.create_test(bw = 3*10**6, pktsize = 500, duration = 3.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT, max_return_time = 0.01) config = self.dynclient.update_configuration({ "packet_size": 5000, "bandwidth_egress": 1e6 }) test.start() time.sleep(3.5) self.assertTrue(test.done, "Test should have finished already") self.assertTrue(test.latency.avg() > 0.035 and test.latency.avg() < 0.045, "Expected latency to be ~40ms, instead it was %.2fms"% (test.latency.avg()*1e3)) test = self.srcnode.create_test(bw = 3*10**6, pktsize = 500, duration = 3.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT, max_return_time = 0.01) config = self.dynclient.update_configuration({ "packet_size": 500 }) test.start() time.sleep(3.5) self.assertTrue(test.done, "Test should have finished already") self.assertTrue(test.latency.avg() > 0.002 and test.latency.avg() < 0.006, "Expected latency to be ~4ms, instead it was %.2fms"% (test.latency.avg()*1e3)) test = self.srcnode.create_test(bw = 3*10**6, pktsize = 500, duration = 3.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT, max_return_time = 0.01) config = self.dynclient.update_configuration({ "bandwidth_ingress": 0.5e6 }) test.start() time.sleep(3.5) self.assertTrue(test.done, "Test should have finished already") self.assertTrue(test.latency.avg() > 0.008 and test.latency.avg() < 0.015, "Expected latency to be ~12ms, instead it was %.2fms"% (test.latency.avg()*1e3)) test = self.srcnode.create_test(bw = 3*10**6, pktsize = 500, duration = 3.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT, max_return_time = 0.01) config = self.dynclient.update_configuration({ "packet_size": 300 }) test.start() time.sleep(3.5) self.assertTrue(test.done, "Test should have finished already") self.assertTrue(test.loss.avg() > 95.0, "Expected loss to be 100% (tc limit smaller than packet size)") def bandwidth_latency_loss_test(self, direction, bw_tx, bw_limit, latency, loss, expected_bw = None, expected_loss = None, expected_latency = None): self.reset_tc_rules_via_dynreconf() config = self.dynclient.update_configuration({ "bandwidth_" + direction: bw_limit, "latency_" + direction: latency, "loss_" + direction: loss }) self.assertTrue(config['status'] == "OK", "Operation FAILed: " + config['errmsg']) test = self.srcnode.create_test(bw = bw_tx, pktsize = 1500, duration = 5.0, sink_ip = "127.0.0.1", sink_port = 12345, bw_type = LinktestGoal.BW_CONSTANT, max_return_time = 0.01) test.start() time.sleep(5.5) self.assertTrue(test.done, "Test should have finished already") (expected_bw, expected_latency, expected_loss) = get_projected_link_metrics(bw_limit, latency, loss, 1500.0, bw_tx) print "bw_limit: ", bw_limit, "loss: ", loss, "latency: ", latency, "bw_tx: ", bw_tx print "meas_bw: ", test.bandwidth.avg(), " meas_latency: ", test.latency.avg()*1e3, " meas_loss: ", test.loss.avg() print "exp_bw", expected_bw, " exp_latency: ", expected_latency * 1e3, " exp_loss: ", expected_loss self.assertTrue(test.bandwidth.avg() > expected_bw * 0.75 and test.bandwidth.avg() < expected_bw * 1.25, "Expected measured bandwidth to be ~%.2fMbit/s, instead it was %.2fMbit/s"% (expected_bw/1e6, test.bandwidth.avg()/1e6)) self.assertTrue(test.latency.avg() > expected_latency - 0.015 and test.latency.avg() < expected_latency + 0.015, "Expected latency to be ~%.2fms, instead it was %.2fms"% (expected_latency * 1e3, test.latency.avg() * 1e3)) self.assertTrue((test.loss.avg() < 4.0 and expected_loss < 2.0) or (test.loss.avg() > expected_loss - 10.0 and test.latency.avg() < expected_loss + 10.0), "Expected loss to be ~%.2f%%, instead it was %.2f%%"% (expected_loss, test.loss.avg())) def test_bandwidth_latency_loss(self): # just bw_limit specified, bw_tx < bw_limit self.bandwidth_latency_loss_test("egress", bw_tx = 0.5*10**6, bw_limit=1.0*10**6, latency = 0.0, loss = 0.0) # just bw_limit specified, bw_tx > bw_limit self.bandwidth_latency_loss_test("egress", bw_tx = 1.5*10**6, bw_limit=1.0*10**6, latency = 0.0, loss = 0.0) # bw_limit + latency, bw_tx < bw_limit self.bandwidth_latency_loss_test("egress", bw_tx = 0.5*10**6, bw_limit=1.0*10**6, latency = 0.01, loss = 0.0) # bw_limit + latency, bw_tx > bw_limit self.bandwidth_latency_loss_test("egress", bw_tx = 1.5*10**6, bw_limit=1.0*10**6, latency = 0.01, loss = 0.0) # bw_limit + latency + loss, bw_tx < bw_limit, loss < bw_loss self.bandwidth_latency_loss_test("egress", bw_tx = 0.5*10**6, bw_limit=1.0*10**6, latency = 0.03, loss = 10.0) # bw_limit + latency + loss, bw_tx < bw_limit, loss > bw_loss self.bandwidth_latency_loss_test("egress", bw_tx = 0.5*10**6, bw_limit=1.0*10**6, latency = 0.03, loss = 50.0) # bw_limit + latency + loss, bw_tx > bw_limit, loss < bw-loss self.bandwidth_latency_loss_test("egress", bw_tx = 1.5*10**6, bw_limit=1.0*10**6, latency = 0.03, loss = 10.0) # bw_limit + latency + loss, bw_tx > bw_limit, loss < bw-loss self.bandwidth_latency_loss_test("egress", bw_tx = 1.5*10**6, bw_limit=1.0*10**6, latency = 0.03, loss = 50.0) # ingress tests self.bandwidth_latency_loss_test("ingress", bw_tx = 0.5*10**6, bw_limit=1.0*10**6, latency = 0.0, loss = 0.0) self.bandwidth_latency_loss_test("ingress", bw_tx = 1.5*10**6, bw_limit=1.0*10**6, latency = 0.0, loss = 0.0) self.bandwidth_latency_loss_test("ingress", bw_tx = 0.5*10**6, bw_limit=1.0*10**6, latency = 0.01, loss = 0.0) self.bandwidth_latency_loss_test("ingress", bw_tx = 1.5*10**6, bw_limit=1.0*10**6, latency = 0.01, loss = 0.0) self.bandwidth_latency_loss_test("ingress", bw_tx = 0.5*10**6, bw_limit=1.0*10**6, latency = 0.02, loss = 0.0) self.bandwidth_latency_loss_test("ingress", bw_tx = 1.5*10**6, bw_limit=1.0*10**6, latency = 0.03, loss = 10.0) self.bandwidth_latency_loss_test("ingress", bw_tx = 0.5*10**6, bw_limit=1.0*10**6, latency = 0.04, loss = 20.0)
def __init__(self, *args): super(BasicTest, self).__init__(*args) rospy.init_node('network_monitor_udp_test') self.srcnode = UdpmonsourceHandle('performance_test')
#! /usr/bin/env python import roslib; roslib.load_manifest('network_monitor_udp') import rospy from network_monitor_udp.linktest import UdpmonsourceHandle from network_monitor_udp.linktest import LinkTest from network_monitor_udp.msg import LinktestGoal if __name__ == '__main__': rospy.init_node('test_node') source = UdpmonsourceHandle() source.cancel_all_tests() try: print "Link capacity: %.2fMbit/s"%(source.get_link_capacity(sink_ip="127.0.0.1", sink_port=12345)/1e6) finally: source.cancel_all_tests()