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()
Exemple #2
0
 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()
Exemple #3
0
    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()
Exemple #11
0
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")
Exemple #18
0
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))
Exemple #22
0
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")
Exemple #23
0
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)
Exemple #24
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()