Beispiel #1
0
    def test_xml_emane_node_config(self, session: Session,
                                   tmpdir: TemporaryFile,
                                   ip_prefixes: IpPrefixes):
        # create nodes
        options = NodeOptions(model="mdr", x=50, y=50)
        node1 = session.add_node(CoreNode, options=options)
        iface1_data = ip_prefixes.create_iface(node1)
        node2 = session.add_node(CoreNode, options=options)
        iface2_data = ip_prefixes.create_iface(node2)

        # create emane node
        options = NodeOptions(model=None, emane=EmaneRfPipeModel.name)
        emane_node = session.add_node(EmaneNet, options=options)

        # create links
        session.add_link(node1.id, emane_node.id, iface1_data)
        session.add_link(node2.id, emane_node.id, iface2_data)

        # set node specific config
        datarate = "101"
        session.emane.set_config(node1.id, EmaneRfPipeModel.name,
                                 {"datarate": datarate})

        # instantiate session
        session.instantiate()

        # save xml
        xml_file = tmpdir.join("session.xml")
        file_path = xml_file.strpath
        session.save_xml(Path(file_path))

        # verify xml file was created and can be parsed
        assert xml_file.isfile()
        assert ElementTree.parse(file_path)

        # stop current session, clearing data
        session.shutdown()

        # verify nodes have been removed from session
        with pytest.raises(CoreError):
            assert not session.get_node(node1.id, CoreNode)
        with pytest.raises(CoreError):
            assert not session.get_node(node2.id, CoreNode)
        with pytest.raises(CoreError):
            assert not session.get_node(emane_node.id, EmaneNet)

        # load saved xml
        session.open_xml(Path(file_path), start=True)

        # verify nodes have been recreated
        assert session.get_node(node1.id, CoreNode)
        assert session.get_node(node2.id, CoreNode)
        assert session.get_node(emane_node.id, EmaneNet)
        links = []
        for node_id in session.nodes:
            node = session.nodes[node_id]
            links += node.links()
        assert len(links) == 2
        config = session.emane.get_config(node1.id, EmaneRfPipeModel.name)
        assert config["datarate"] == datarate
Beispiel #2
0
    def test_wired_ping(self, session: Session, net_type: Type[NodeBase],
                        ip_prefixes: IpPrefixes):
        """
        Test ptp node network.

        :param session: session for test
        :param core.enumerations.NodeTypes net_type: type of net node to create
        :param ip_prefixes: generates ip addresses for nodes
        """

        # create net node
        net_node = session.add_node(net_type)

        # create nodes
        node_one = session.add_node(CoreNode)
        node_two = session.add_node(CoreNode)

        # link nodes to net node
        for node in [node_one, node_two]:
            interface = ip_prefixes.create_interface(node)
            session.add_link(node.id, net_node.id, interface_one=interface)

        # instantiate session
        session.instantiate()

        # ping n2 from n1 and assert success
        status = ping(node_one, node_two, ip_prefixes)
        assert not status
Beispiel #3
0
    def test_vnode_client(self, request, session: Session,
                          ip_prefixes: IpPrefixes):
        """
        Test vnode client methods.

        :param request: pytest request
        :param session: session for test
        :param ip_prefixes: generates ip addresses for nodes
        """
        # create ptp
        ptp_node = session.add_node(PtpNet)

        # create nodes
        node_one = session.add_node(CoreNode)
        node_two = session.add_node(CoreNode)

        # link nodes to ptp net
        for node in [node_one, node_two]:
            interface = ip_prefixes.create_interface(node)
            session.add_link(node.id, ptp_node.id, interface_one=interface)

        # get node client for testing
        client = node_one.client

        # instantiate session
        session.instantiate()

        # check we are connected
        assert client.connected()

        # validate command
        if not request.config.getoption("mock"):
            assert client.check_cmd("echo hello") == "hello"
Beispiel #4
0
    def test_wlan_ping(self, session: Session, ip_prefixes: IpPrefixes):
        """
        Test basic wlan network.

        :param core.emulator.coreemu.EmuSession session: session for test
        :param ip_prefixes: generates ip addresses for nodes
        """

        # create wlan
        wlan_node = session.add_node(WlanNode)
        session.mobility.set_model(wlan_node, BasicRangeModel)

        # create nodes
        options = NodeOptions(model="mdr")
        options.set_position(0, 0)
        node_one = session.add_node(CoreNode, options=options)
        node_two = session.add_node(CoreNode, options=options)

        # link nodes
        for node in [node_one, node_two]:
            interface = ip_prefixes.create_interface(node)
            session.add_link(node.id, wlan_node.id, interface_one=interface)

        # instantiate session
        session.instantiate()

        # ping n2 from n1 and assert success
        status = ping(node_one, node_two, ip_prefixes)
        assert not status
Beispiel #5
0
    def test_xml_ptp(
        self, session: Session, tmpdir: TemporaryFile, ip_prefixes: IpPrefixes
    ):
        """
        Test xml client methods for a ptp network.

        :param session: session for test
        :param tmpdir: tmpdir to create data in
        :param ip_prefixes: generates ip addresses for nodes
        """
        # create ptp
        ptp_node = session.add_node(PtpNet)

        # create nodes
        node1 = session.add_node(CoreNode)
        node2 = session.add_node(CoreNode)

        # link nodes to ptp net
        for node in [node1, node2]:
            iface_data = ip_prefixes.create_iface(node)
            session.add_link(node.id, ptp_node.id, iface1_data=iface_data)

        # instantiate session
        session.instantiate()

        # get ids for nodes
        node1_id = node1.id
        node2_id = node2.id

        # save xml
        xml_file = tmpdir.join("session.xml")
        file_path = xml_file.strpath
        session.save_xml(file_path)

        # verify xml file was created and can be parsed
        assert xml_file.isfile()
        assert ElementTree.parse(file_path)

        # stop current session, clearing data
        session.shutdown()

        # verify nodes have been removed from session
        with pytest.raises(CoreError):
            assert not session.get_node(node1_id, CoreNode)
        with pytest.raises(CoreError):
            assert not session.get_node(node2_id, CoreNode)

        # load saved xml
        session.open_xml(file_path, start=True)

        # verify nodes have been recreated
        assert session.get_node(node1_id, CoreNode)
        assert session.get_node(node2_id, CoreNode)
Beispiel #6
0
    def test_network_to_network(self, session: Session, tmpdir: TemporaryFile):
        """
        Test xml generation when dealing with network to network nodes.

        :param session: session for test
        :param tmpdir: tmpdir to create data in
        """
        # create nodes
        switch_one = session.add_node(SwitchNode)
        switch_two = session.add_node(SwitchNode)

        # link nodes
        session.add_link(switch_one.id, switch_two.id)

        # instantiate session
        session.instantiate()

        # get ids for nodes
        n1_id = switch_one.id
        n2_id = switch_two.id

        # save xml
        xml_file = tmpdir.join("session.xml")
        file_path = xml_file.strpath
        session.save_xml(file_path)

        # verify xml file was created and can be parsed
        assert xml_file.isfile()
        assert ElementTree.parse(file_path)

        # stop current session, clearing data
        session.shutdown()

        # verify nodes have been removed from session
        with pytest.raises(CoreError):
            assert not session.get_node(n1_id, SwitchNode)
        with pytest.raises(CoreError):
            assert not session.get_node(n2_id, SwitchNode)

        # load saved xml
        session.open_xml(file_path, start=True)

        # verify nodes have been recreated
        switch_one = session.get_node(n1_id, SwitchNode)
        switch_two = session.get_node(n2_id, SwitchNode)
        assert switch_one
        assert switch_two
        assert len(switch_one.all_link_data() +
                   switch_two.all_link_data()) == 1
Beispiel #7
0
    def test_mobility(self, session: Session, ip_prefixes: IpPrefixes):
        """
        Test basic wlan network.

        :param core.emulator.coreemu.EmuSession session: session for test
        :param ip_prefixes: generates ip addresses for nodes
        """

        # create wlan
        wlan_node = session.add_node(WlanNode)
        session.mobility.set_model(wlan_node, BasicRangeModel)

        # create nodes
        options = NodeOptions(model="mdr")
        options.set_position(0, 0)
        node_one = session.add_node(CoreNode, options=options)
        node_two = session.add_node(CoreNode, options=options)

        # link nodes
        for node in [node_one, node_two]:
            interface = ip_prefixes.create_interface(node)
            session.add_link(node.id, wlan_node.id, interface_one=interface)

        # configure mobility script for session
        config = {
            "file": _MOBILITY_FILE,
            "refresh_ms": "50",
            "loop": "1",
            "autostart": "0.0",
            "map": "",
            "script_start": "",
            "script_pause": "",
            "script_stop": "",
        }
        session.mobility.set_model(wlan_node, Ns2ScriptedMobility, config)

        # add handler for receiving node updates
        event = threading.Event()

        def node_update(_):
            event.set()

        session.node_handlers.append(node_update)

        # instantiate session
        session.instantiate()

        # validate we receive a node message for updating its location
        assert event.wait(5)
Beispiel #8
0
def create_ptp_network(session: Session,
                       ip_prefixes: IpPrefixes) -> Tuple[CoreNode, CoreNode]:
    # create nodes
    node1 = session.add_node(CoreNode)
    node2 = session.add_node(CoreNode)

    # link nodes to net node
    iface1_data = ip_prefixes.create_iface(node1)
    iface2_data = ip_prefixes.create_iface(node2)
    session.add_link(node1.id, node2.id, iface1_data, iface2_data)

    # instantiate session
    session.instantiate()

    return node1, node2
Beispiel #9
0
    def test_remote_node(self, session: Session):
        # given
        server_name = "core2"
        host = "127.0.0.1"

        # when
        session.distributed.add_server(server_name, host)
        options = NodeOptions(server=server_name)
        node = session.add_node(CoreNode, options=options)
        session.instantiate()

        # then
        assert node.server is not None
        assert node.server.name == server_name
        assert node.server.host == host
Beispiel #10
0
def create_ptp_network(
    session: Session, ip_prefixes: IpPrefixes
) -> Tuple[CoreNode, CoreNode]:
    # create nodes
    node_one = session.add_node(CoreNode)
    node_two = session.add_node(CoreNode)

    # link nodes to net node
    interface_one = ip_prefixes.create_interface(node_one)
    interface_two = ip_prefixes.create_interface(node_two)
    session.add_link(node_one.id, node_two.id, interface_one, interface_two)

    # instantiate session
    session.instantiate()

    return node_one, node_two
Beispiel #11
0
    def test_models(self, session: Session, model: Type[EmaneModel],
                    ip_prefixes: IpPrefixes):
        """
        Test emane models within a basic network.

        :param core.emulator.coreemu.EmuSession session: session for test
        :param model: emane model to test
        :param ip_prefixes: generates ip addresses for nodes
        """

        # create emane node for networking the core nodes
        session.set_location(47.57917, -122.13232, 2.00000, 1.0)
        options = NodeOptions()
        options.set_position(80, 50)
        emane_network = session.add_node(EmaneNet, options=options)
        session.emane.set_model(emane_network, model)

        # configure tdma
        if model == EmaneTdmaModel:
            session.emane.set_model_config(
                emane_network.id,
                EmaneTdmaModel.name,
                {
                    "schedule":
                    os.path.join(_DIR, "../../examples/tdma/schedule.xml")
                },
            )

        # create nodes
        options = NodeOptions(model="mdr")
        options.set_position(150, 150)
        node1 = session.add_node(CoreNode, options=options)
        options.set_position(300, 150)
        node2 = session.add_node(CoreNode, options=options)

        for i, node in enumerate([node1, node2]):
            node.setposition(x=150 * (i + 1), y=150)
            iface_data = ip_prefixes.create_iface(node)
            session.add_link(node.id, emane_network.id, iface1_data=iface_data)

        # instantiate session
        session.instantiate()

        # ping node2 from node1 and assert success
        status = ping(node1, node2, ip_prefixes, count=5)
        assert not status
Beispiel #12
0
    def test_netif(self, session: Session, ip_prefixes: IpPrefixes):
        """
        Test netif methods.

        :param session: session for test
        :param ip_prefixes: generates ip addresses for nodes
        """

        # create ptp
        ptp_node = session.add_node(PtpNet)

        # create nodes
        node_one = session.add_node(CoreNode)
        node_two = session.add_node(CoreNode)

        # link nodes to ptp net
        for node in [node_one, node_two]:
            interface = ip_prefixes.create_interface(node)
            session.add_link(node.id, ptp_node.id, interface_one=interface)

        # instantiate session
        session.instantiate()

        # check link data gets generated
        assert ptp_node.all_link_data(MessageFlags.ADD)

        # check common nets exist between linked nodes
        assert node_one.commonnets(node_two)
        assert node_two.commonnets(node_one)

        # check we can retrieve netif index
        assert node_one.ifname(0)
        assert node_two.ifname(0)

        # check interface parameters
        interface = node_one.netif(0)
        interface.setparam("test", 1)
        assert interface.getparam("test") == 1
        assert interface.getparams()

        # delete netif and test that if no longer exists
        node_one.delnetif(0)
        assert not node_one.netif(0)
Beispiel #13
0
    def test_iface(self, session: Session, ip_prefixes: IpPrefixes):
        """
        Test interface methods.

        :param session: session for test
        :param ip_prefixes: generates ip addresses for nodes
        """

        # create ptp
        ptp_node = session.add_node(PtpNet)

        # create nodes
        node1 = session.add_node(CoreNode)
        node2 = session.add_node(CoreNode)

        # link nodes to ptp net
        for node in [node1, node2]:
            iface = ip_prefixes.create_iface(node)
            session.add_link(node.id, ptp_node.id, iface1_data=iface)

        # instantiate session
        session.instantiate()

        # check link data gets generated
        assert ptp_node.links(MessageFlags.ADD)

        # check common nets exist between linked nodes
        assert node1.commonnets(node2)
        assert node2.commonnets(node1)

        # check we can retrieve interface id
        assert 0 in node1.ifaces
        assert 0 in node2.ifaces

        # check interface parameters
        iface = node1.get_iface(0)
        iface.setparam("test", 1)
        assert iface.getparam("test") == 1
        assert iface.getparams()

        # delete interface and test that if no longer exists
        node1.delete_iface(0)
        assert 0 not in node1.ifaces
Beispiel #14
0
    def test_two_emane_interfaces(self, session: Session):
        """
        Test nodes running multiple emane interfaces.

        :param core.emulator.coreemu.EmuSession session: session for test
        """
        # create emane node for networking the core nodes
        session.set_location(47.57917, -122.13232, 2.00000, 1.0)
        options = NodeOptions()
        options.set_position(80, 50)
        options.emane = EmaneIeee80211abgModel.name
        emane_net1 = session.add_node(EmaneNet, options=options)
        options.emane = EmaneRfPipeModel.name
        emane_net2 = session.add_node(EmaneNet, options=options)

        # create nodes
        options = NodeOptions(model="mdr")
        options.set_position(150, 150)
        node1 = session.add_node(CoreNode, options=options)
        options.set_position(300, 150)
        node2 = session.add_node(CoreNode, options=options)

        # create interfaces
        ip_prefix1 = IpPrefixes("10.0.0.0/24")
        ip_prefix2 = IpPrefixes("10.0.1.0/24")
        for i, node in enumerate([node1, node2]):
            node.setposition(x=150 * (i + 1), y=150)
            iface_data = ip_prefix1.create_iface(node)
            session.add_link(node.id, emane_net1.id, iface1_data=iface_data)
            iface_data = ip_prefix2.create_iface(node)
            session.add_link(node.id, emane_net2.id, iface1_data=iface_data)

        # instantiate session
        session.instantiate()

        # ping node2 from node1 on both interfaces and check success
        status = ping(node1, node2, ip_prefix1, count=5)
        assert not status
        status = ping(node1, node2, ip_prefix2, count=5)
        assert not status
Beispiel #15
0
class Experiment(object):
    """ Experiment object to organize tests.
    """
    def __init__(self, opt, start):
        """ Initialize with opt and start time. """
        self.session = None
        # node list
        self.nodes = []
        # WLAN network
        self.net = None
        self.verbose = opt.verbose
        # dict from OptionParser
        self.opt = opt
        self.start = start
        self.numping = opt.numping
        self.numiperf = opt.numiperf
        self.nummgen = opt.nummgen
        self.logbegin()

    def info(self, msg):
        """ Utility method for writing output to stdout. """
        print(msg)
        sys.stdout.flush()
        self.log(msg)

    def warn(self, msg):
        """ Utility method for writing output to stderr. """
        sys.stderr.write(msg)
        sys.stderr.flush()
        self.log(msg)

    def logbegin(self):
        """ Start logging. """
        self.logfp = None
        if not self.opt.logfile:
            return
        self.logfp = open(self.opt.logfile, "w")
        self.log("%s begin: %s\n" % (sys.argv[0], self.start.ctime()))
        self.log("%s args: %s\n" % (sys.argv[0], sys.argv[1:]))
        (sysname, rel, ver, machine, nodename) = os.uname()
        self.log("%s %s %s %s on %s" % (sysname, rel, ver, machine, nodename))

    def logend(self):
        """ End logging. """
        if not self.logfp:
            return
        end = datetime.datetime.now()
        self.log("%s end: %s (%s)\n" % \
                 (sys.argv[0], end.ctime(), end - self.start))
        self.logfp.flush()
        self.logfp.close()
        self.logfp = None

    def log(self, msg):
        """ Write to the log file, if any. """
        if not self.logfp:
            return
        self.logfp.write(msg)

    def reset(self):
        """ Prepare for another experiment run.
        """
        if self.session:
            self.session.shutdown()
            del self.session
            self.session = None
        self.nodes = []
        self.net = None

    def createbridgedsession(self, numnodes, verbose=False):
        """ Build a topology consisting of the given number of LxcNodes
            connected to a WLAN.
        """
        # IP subnet
        prefix = ipaddress.Ipv4Prefix("10.0.0.0/16")
        self.session = Session(1)
        # emulated network
        self.net = self.session.create_node(cls=core.nodes.network.WlanNode,
                                            name="wlan1")
        prev = None
        for i in range(1, numnodes + 1):
            addr = "%s/%s" % (prefix.addr(i), 32)
            tmp = self.session.create_node(cls=core.nodes.base.CoreNode,
                                           _id=i,
                                           name="n%d" % i)
            tmp.newnetif(self.net, [addr])
            self.nodes.append(tmp)
            self.session.services.add_services(tmp, "router", "IPForward")
            self.session.services.boot_services(tmp)
            self.staticroutes(i, prefix, numnodes)

            # link each node in a chain, with the previous node
            if prev:
                self.net.link(prev.netif(0), tmp.netif(0))
            prev = tmp

    def createemanesession(self,
                           numnodes,
                           verbose=False,
                           cls=None,
                           values=None):
        """ Build a topology consisting of the given number of LxcNodes
            connected to an EMANE WLAN.
        """
        prefix = ipaddress.Ipv4Prefix("10.0.0.0/16")
        self.session = Session(2)
        self.session.node_count = str(numnodes + 1)
        self.session.master = True
        self.session.location.setrefgeo(47.57917, -122.13232, 2.00000)
        self.session.location.refscale = 150.0
        self.session.emane.loadmodels()
        self.net = self.session.create_node(cls=EmaneNode,
                                            _id=numnodes + 1,
                                            name="wlan1")
        self.net.verbose = verbose
        # self.session.emane.addobj(self.net)
        for i in range(1, numnodes + 1):
            addr = "%s/%s" % (prefix.addr(i), 32)
            tmp = self.session.create_node(cls=core.nodes.base.CoreNode,
                                           _id=i,
                                           name="n%d" % i)
            # tmp.setposition(i * 20, 50, None)
            tmp.setposition(50, 50, None)
            tmp.newnetif(self.net, [addr])
            self.nodes.append(tmp)
            self.session.services.add_services(tmp, "router", "IPForward")

        if values is None:
            values = cls.getdefaultvalues()
        self.session.emane.setconfig(self.net.id, cls.name, values)
        self.session.instantiate()

        self.info("waiting %s sec (TAP bring-up)" % 2)
        time.sleep(2)

        for i in range(1, numnodes + 1):
            tmp = self.nodes[i - 1]
            self.session.services.boot_services(tmp)
            self.staticroutes(i, prefix, numnodes)

    def setnodes(self):
        """ Set the sender and receiver nodes for use in this experiment,
            along with the address of the receiver to be used.
        """
        self.firstnode = self.nodes[0]
        self.lastnode = self.nodes[-1]
        self.lastaddr = self.lastnode.netif(0).addrlist[0].split("/")[0]

    def staticroutes(self, i, prefix, numnodes):
        """ Add static routes on node number i to the other nodes in the chain.
        """
        routecmd = ["/sbin/ip", "route", "add"]
        node = self.nodes[i - 1]
        neigh_left = ""
        neigh_right = ""
        # add direct interface routes first
        if i > 1:
            neigh_left = "%s" % prefix.addr(i - 1)
            cmd = routecmd + [neigh_left, "dev", node.netif(0).name]
            (status, result) = node.cmd_output(cmd)
            if status != 0:
                self.warn("failed to add interface route: %s" % cmd)
        if i < numnodes:
            neigh_right = "%s" % prefix.addr(i + 1)
            cmd = routecmd + [neigh_right, "dev", node.netif(0).name]
            (status, result) = node.cmd_output(cmd)
            if status != 0:
                self.warn("failed to add interface route: %s" % cmd)

        # add static routes to all other nodes via left/right neighbors
        for j in range(1, numnodes + 1):
            if abs(j - i) < 2:
                continue
            addr = "%s" % prefix.addr(j)
            if j < i:
                gw = neigh_left
            else:
                gw = neigh_right
            cmd = routecmd + [addr, "via", gw]
            (status, result) = node.cmd_output(cmd)
            if status != 0:
                self.warn("failed to add route: %s" % cmd)

    def setpathloss(self, numnodes):
        """ Send EMANE pathloss events to connect all NEMs in a chain.
        """
        if self.session.emane.version < self.session.emane.EMANE091:
            service = emaneeventservice.EventService()
            e = emaneeventpathloss.EventPathloss(1)
            old = True
        else:
            if self.session.emane.version == self.session.emane.EMANE091:
                dev = "lo"
            else:
                dev = self.session.obj("ctrlnet").brname
            service = EventService(eventchannel=("224.1.2.8", 45703, dev),
                                   otachannel=None)
            old = False

        for i in range(1, numnodes + 1):
            rxnem = i
            # inform rxnem that it can hear node to the left with 10dB noise
            txnem = rxnem - 1
            if txnem > 0:
                if old:
                    e.set(0, txnem, 10.0, 10.0)
                    service.publish(emaneeventpathloss.EVENT_ID,
                                    emaneeventservice.PLATFORMID_ANY, rxnem,
                                    emaneeventservice.COMPONENTID_ANY,
                                    e.export())
                else:
                    e = PathlossEvent()
                    e.append(txnem, forward=10.0, reverse=10.0)
                    service.publish(rxnem, e)
            # inform rxnem that it can hear node to the right with 10dB noise
            txnem = rxnem + 1
            if txnem > numnodes:
                continue
            if old:
                e.set(0, txnem, 10.0, 10.0)
                service.publish(emaneeventpathloss.EVENT_ID,
                                emaneeventservice.PLATFORMID_ANY, rxnem,
                                emaneeventservice.COMPONENTID_ANY, e.export())
            else:
                e = PathlossEvent()
                e.append(txnem, forward=10.0, reverse=10.0)
                service.publish(rxnem, e)

    def setneteffects(self, bw=None, delay=None):
        """ Set link effects for all interfaces attached to the network node.
        """
        if not self.net:
            self.warn("failed to set effects: no network node")
            return
        for netif in self.net.netifs():
            self.net.linkconfig(netif, bw=bw, delay=delay)

    def runalltests(self, title=""):
        """ Convenience helper to run all defined experiment tests.
            If tests are run multiple times, this returns the average of
            those runs.
        """
        duration = self.opt.duration
        rate = self.opt.rate
        if len(title) > 0:
            self.info("----- running %s tests (duration=%s, rate=%s) -----" % \
                      (title, duration, rate))
        (latency, mdev, throughput, cpu, loss) = (0, 0, 0, 0, 0)

        self.info("number of runs: ping=%d, iperf=%d, mgen=%d" % \
                  (self.numping, self.numiperf, self.nummgen))

        if self.numping > 0:
            (latency, mdev) = self.pingtest(count=self.numping)

        if self.numiperf > 0:
            throughputs = []
            for i in range(1, self.numiperf + 1):
                throughput = self.iperftest(time=duration)
                if self.numiperf > 1:
                    throughputs += throughput
                # iperf is very CPU intensive
                time.sleep(1)
            if self.numiperf > 1:
                throughput = sum(throughputs) / len(throughputs)
                self.info("throughputs=%s" % ["%.2f" % v for v in throughputs])

        if self.nummgen > 0:
            cpus = []
            losses = []
            for i in range(1, self.nummgen + 1):
                (cpu, loss) = self.cputest(time=duration, rate=rate)
                if self.nummgen > 1:
                    cpus += cpu,
                    losses += loss,
            if self.nummgen > 1:
                cpu = sum(cpus) / len(cpus)
                loss = sum(losses) / len(losses)
                self.info("cpus=%s" % ["%.2f" % v for v in cpus])
                self.info("losses=%s" % ["%.2f" % v for v in losses])

        return latency, mdev, throughput, cpu, loss

    def pingtest(self, count=50):
        """ Ping through a chain of nodes and report the average latency.
        """
        p = PingCmd(node=self.firstnode,
                    verbose=self.verbose,
                    addr=self.lastaddr,
                    count=count,
                    interval=0.1).run()
        (latency, mdev) = p
        self.info("latency (ms): %.03f, %.03f" % (latency, mdev))
        return p

    def iperftest(self, time=10):
        """ Run iperf through a chain of nodes and report the maximum
            throughput.
        """
        bps = IperfCmd(node=self.lastnode,
                       client_node=self.firstnode,
                       verbose=False,
                       addr=self.lastaddr,
                       time=time).run()
        self.info("throughput (bps): %s" % bps)
        return bps

    def cputest(self, time=10, rate=512):
        """ Run MGEN through a chain of nodes and report the CPU usage and
            percent of lost packets. Rate is in kbps.
        """
        if self.verbose:
            self.info("%s initial test ping (max 1 second)..." % \
                      self.firstnode.name)
        (status, result) = self.firstnode.cmd_output(
            ["ping", "-q", "-c", "1", "-w", "1", self.lastaddr])
        if status != 0:
            self.warn("initial ping from %s to %s failed! result:\n%s" % \
                      (self.firstnode.name, self.lastaddr, result))
            return 0.0, 0.0
        lines = readstat()
        cpustart = getcputimes(lines[0])
        loss = MgenCmd(node=self.lastnode,
                       client_node=self.firstnode,
                       verbose=False,
                       addr=self.lastaddr,
                       time=time,
                       rate=rate).run()
        lines = readstat()
        cpuend = getcputimes(lines[0])
        percent = calculatecpu(cpustart, cpuend)
        self.info("CPU usage (%%): %.02f, %.02f loss" % (percent, loss))
        return percent, loss
Beispiel #16
0
    def test_xml_emane(
        self, session: Session, tmpdir: TemporaryFile, ip_prefixes: IpPrefixes
    ):
        """
        Test xml client methods for emane.

        :param session: session for test
        :param tmpdir: tmpdir to create data in
        :param ip_prefixes: generates ip addresses for nodes
        """
        # create emane node for networking the core nodes
        session.set_location(47.57917, -122.13232, 2.00000, 1.0)
        options = NodeOptions()
        options.set_position(80, 50)
        emane_network = session.add_node(EmaneNet, options=options)
        config_key = "txpower"
        config_value = "10"
        session.emane.set_model(
            emane_network, EmaneIeee80211abgModel, {config_key: config_value}
        )

        # create nodes
        options = NodeOptions(model="mdr")
        options.set_position(150, 150)
        node1 = session.add_node(CoreNode, options=options)
        options.set_position(300, 150)
        node2 = session.add_node(CoreNode, options=options)

        for i, node in enumerate([node1, node2]):
            node.setposition(x=150 * (i + 1), y=150)
            iface_data = ip_prefixes.create_iface(node)
            session.add_link(node.id, emane_network.id, iface1_data=iface_data)

        # instantiate session
        session.instantiate()

        # get ids for nodes
        emane_id = emane_network.id
        node1_id = node1.id
        node2_id = node2.id

        # save xml
        xml_file = tmpdir.join("session.xml")
        file_path = xml_file.strpath
        session.save_xml(file_path)

        # verify xml file was created and can be parsed
        assert xml_file.isfile()
        assert ElementTree.parse(file_path)

        # stop current session, clearing data
        session.shutdown()

        # verify nodes have been removed from session
        with pytest.raises(CoreError):
            assert not session.get_node(node1_id, CoreNode)
        with pytest.raises(CoreError):
            assert not session.get_node(node2_id, CoreNode)

        # load saved xml
        session.open_xml(file_path, start=True)

        # retrieve configuration we set originally
        value = str(
            session.emane.get_config(config_key, emane_id, EmaneIeee80211abgModel.name)
        )

        # verify nodes and configuration were restored
        assert session.get_node(node1_id, CoreNode)
        assert session.get_node(node2_id, CoreNode)
        assert session.get_node(emane_id, EmaneNet)
        assert value == config_value
Beispiel #17
0
    def test_link_options_bidirectional(self, session: Session,
                                        tmpdir: TemporaryFile,
                                        ip_prefixes: IpPrefixes):
        """
        Test xml client methods for a ptp network.

        :param session: session for test
        :param tmpdir: tmpdir to create data in
        :param ip_prefixes: generates ip addresses for nodes
        """
        # create nodes
        node1 = session.add_node(CoreNode)
        iface1_data = ip_prefixes.create_iface(node1)
        node2 = session.add_node(CoreNode)
        iface2_data = ip_prefixes.create_iface(node2)

        # create link
        options1 = LinkOptions()
        options1.unidirectional = 1
        options1.bandwidth = 5000
        options1.delay = 10
        options1.loss = 10.5
        options1.dup = 5
        options1.jitter = 5
        options1.buffer = 50
        session.add_link(node1.id, node2.id, iface1_data, iface2_data,
                         options1)
        options2 = LinkOptions()
        options2.unidirectional = 1
        options2.bandwidth = 10000
        options2.delay = 20
        options2.loss = 10
        options2.dup = 10
        options2.jitter = 10
        options2.buffer = 100
        session.update_link(node2.id, node1.id, iface2_data.id, iface1_data.id,
                            options2)

        # instantiate session
        session.instantiate()

        # get ids for nodes
        node1_id = node1.id
        node2_id = node2.id

        # save xml
        xml_file = tmpdir.join("session.xml")
        file_path = Path(xml_file.strpath)
        session.save_xml(file_path)

        # verify xml file was created and can be parsed
        assert xml_file.isfile()
        assert ElementTree.parse(file_path)

        # stop current session, clearing data
        session.shutdown()

        # verify nodes have been removed from session
        with pytest.raises(CoreError):
            assert not session.get_node(node1_id, CoreNode)
        with pytest.raises(CoreError):
            assert not session.get_node(node2_id, CoreNode)

        # load saved xml
        session.open_xml(file_path, start=True)

        # verify nodes have been recreated
        assert session.get_node(node1_id, CoreNode)
        assert session.get_node(node2_id, CoreNode)
        links = []
        for node_id in session.nodes:
            node = session.nodes[node_id]
            links += node.links()
        assert len(links) == 2
        link1 = links[0]
        link2 = links[1]
        assert options1.bandwidth == link1.options.bandwidth
        assert options1.delay == link1.options.delay
        assert options1.loss == link1.options.loss
        assert options1.dup == link1.options.dup
        assert options1.jitter == link1.options.jitter
        assert options1.buffer == link1.options.buffer
        assert options2.bandwidth == link2.options.bandwidth
        assert options2.delay == link2.options.delay
        assert options2.loss == link2.options.loss
        assert options2.dup == link2.options.dup
        assert options2.jitter == link2.options.jitter
        assert options2.buffer == link2.options.buffer
Beispiel #18
0
    def test_xml_mobility(self, session: Session, tmpdir: TemporaryFile,
                          ip_prefixes: IpPrefixes):
        """
        Test xml client methods for mobility.

        :param session: session for test
        :param tmpdir: tmpdir to create data in
        :param ip_prefixes: generates ip addresses for nodes
        """
        # create wlan
        wlan_node = session.add_node(WlanNode)
        session.mobility.set_model(wlan_node, BasicRangeModel, {"test": "1"})

        # create nodes
        options = NodeOptions(model="mdr")
        options.set_position(0, 0)
        node1 = session.add_node(CoreNode, options=options)
        node2 = session.add_node(CoreNode, options=options)

        # link nodes
        for node in [node1, node2]:
            iface_data = ip_prefixes.create_iface(node)
            session.add_link(node.id, wlan_node.id, iface1_data=iface_data)

        # instantiate session
        session.instantiate()

        # get ids for nodes
        wlan_id = wlan_node.id
        node1_id = node1.id
        node2_id = node2.id

        # save xml
        xml_file = tmpdir.join("session.xml")
        file_path = Path(xml_file.strpath)
        session.save_xml(file_path)

        # verify xml file was created and can be parsed
        assert xml_file.isfile()
        assert ElementTree.parse(file_path)

        # stop current session, clearing data
        session.shutdown()

        # verify nodes have been removed from session
        with pytest.raises(CoreError):
            assert not session.get_node(node1_id, CoreNode)
        with pytest.raises(CoreError):
            assert not session.get_node(node2_id, CoreNode)

        # load saved xml
        session.open_xml(file_path, start=True)

        # retrieve configuration we set originally
        value = str(
            session.mobility.get_config("test", wlan_id, BasicRangeModel.name))

        # verify nodes and configuration were restored
        assert session.get_node(node1_id, CoreNode)
        assert session.get_node(node2_id, CoreNode)
        assert session.get_node(wlan_id, WlanNode)
        assert value == "1"
Beispiel #19
0
    def test_xml_ptp_services(self, session: Session, tmpdir: TemporaryFile,
                              ip_prefixes: IpPrefixes):
        """
        Test xml client methods for a ptp neetwork.

        :param session: session for test
        :param tmpdir: tmpdir to create data in
        :param ip_prefixes: generates ip addresses for nodes
        """
        # create ptp
        ptp_node = session.add_node(PtpNet)

        # create nodes
        options = NodeOptions(model="host")
        node_one = session.add_node(CoreNode, options=options)
        node_two = session.add_node(CoreNode)

        # link nodes to ptp net
        for node in [node_one, node_two]:
            interface = ip_prefixes.create_interface(node)
            session.add_link(node.id, ptp_node.id, interface_one=interface)

        # set custom values for node service
        session.services.set_service(node_one.id, SshService.name)
        service_file = SshService.configs[0]
        file_data = "# test"
        session.services.set_service_file(node_one.id, SshService.name,
                                          service_file, file_data)

        # instantiate session
        session.instantiate()

        # get ids for nodes
        n1_id = node_one.id
        n2_id = node_two.id

        # save xml
        xml_file = tmpdir.join("session.xml")
        file_path = xml_file.strpath
        session.save_xml(file_path)

        # verify xml file was created and can be parsed
        assert xml_file.isfile()
        assert ElementTree.parse(file_path)

        # stop current session, clearing data
        session.shutdown()

        # verify nodes have been removed from session
        with pytest.raises(CoreError):
            assert not session.get_node(n1_id, CoreNode)
        with pytest.raises(CoreError):
            assert not session.get_node(n2_id, CoreNode)

        # load saved xml
        session.open_xml(file_path, start=True)

        # retrieve custom service
        service = session.services.get_service(node_one.id, SshService.name)

        # verify nodes have been recreated
        assert session.get_node(n1_id, CoreNode)
        assert session.get_node(n2_id, CoreNode)
        assert service.config_data.get(service_file) == file_data
Beispiel #20
0
def main():
    usagestr = "usage: %prog [-h] [options] [args]"
    parser = optparse.OptionParser(usage=usagestr)
    parser.set_defaults(numnodes=5, slave=None)

    parser.add_option("-n",
                      "--numnodes",
                      dest="numnodes",
                      type=int,
                      help="number of nodes")
    parser.add_option("-s",
                      "--slave-server",
                      dest="slave",
                      type=str,
                      help="slave server IP address")

    def usage(msg=None, err=0):
        sys.stdout.write("\n")
        if msg:
            sys.stdout.write(msg + "\n\n")
        parser.print_help()
        sys.exit(err)

    # parse command line options
    (options, args) = parser.parse_args()

    if options.numnodes < 1:
        usage("invalid number of nodes: %s" % options.numnodes)
    if not options.slave:
        usage("slave server IP address (-s) is a required argument")

    for a in args:
        sys.stderr.write("ignoring command line argument: '%s'\n" % a)

    start = datetime.datetime.now()

    prefix = ipaddress.Ipv4Prefix("10.83.0.0/16")
    session = Session(1)
    server = globals().get("server")
    if server is not None:
        server.addsession(session)

    # distributed setup - connect to slave server
    slaveport = options.slave.split(":")
    slave = slaveport[0]
    if len(slaveport) > 1:
        port = int(slaveport[1])
    else:
        port = CORE_API_PORT
    print("connecting to slave at %s:%d" % (slave, port))
    session.broker.addserver(slave, slave, port)
    session.broker.setupserver(slave)
    session.set_state(EventTypes.CONFIGURATION_STATE)
    tlvdata = coreapi.CoreEventTlv.pack(EventTlvs.TYPE.value,
                                        EventTypes.CONFIGURATION_STATE.value)
    session.broker.handlerawmsg(coreapi.CoreEventMessage.pack(0, tlvdata))

    switch = session.create_node(cls=core.nodes.network.SwitchNode,
                                 name="switch")
    switch.setposition(x=80, y=50)
    num_local = options.numnodes / 2
    num_remote = options.numnodes / 2 + options.numnodes % 2
    print("creating %d (%d local / %d remote) nodes with addresses from %s" %
          (options.numnodes, num_local, num_remote, prefix))
    for i in range(1, num_local + 1):
        node = session.create_node(cls=core.nodes.base.CoreNode,
                                   name="n%d" % i,
                                   _id=i)
        node.newnetif(switch, ["%s/%s" % (prefix.addr(i), prefix.prefixlen)])
        node.cmd(
            [constants.SYSCTL_BIN, "net.ipv4.icmp_echo_ignore_broadcasts=0"])
        node.setposition(x=150 * i, y=150)
        n.append(node)

    flags = MessageFlags.ADD.value
    session.broker.handlerawmsg(switch.tonodemsg(flags=flags))

    # create remote nodes via API
    for i in range(num_local + 1, options.numnodes + 1):
        node = core.nodes.base.CoreNode(session=session,
                                        _id=i,
                                        name="n%d" % i,
                                        start=False)
        node.setposition(x=150 * i, y=150)
        node.server = slave
        n.append(node)
        node_data = node.data(flags)
        node_message = dataconversion.convert_node(node_data)
        session.broker.handlerawmsg(node_message)

    # create remote links via API
    for i in range(num_local + 1, options.numnodes + 1):
        tlvdata = coreapi.CoreLinkTlv.pack(LinkTlvs.N1_NUMBER.value, switch.id)
        tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.N2_NUMBER.value, i)
        tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.TYPE.value,
                                            LinkTypes.WIRED.value)
        tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.INTERFACE2_NUMBER.value,
                                            0)
        tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.INTERFACE2_IP4.value,
                                            prefix.addr(i))
        tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.INTERFACE2_IP4_MASK.value,
                                            prefix.prefixlen)
        msg = coreapi.CoreLinkMessage.pack(flags, tlvdata)
        session.broker.handlerawmsg(msg)

    session.instantiate()
    tlvdata = coreapi.CoreEventTlv.pack(EventTlvs.TYPE.value,
                                        EventTypes.INSTANTIATION_STATE.value)
    msg = coreapi.CoreEventMessage.pack(0, tlvdata)
    session.broker.handlerawmsg(msg)

    # start a shell on node 1
    n[1].client.term("bash")

    print("elapsed time: %s" % (datetime.datetime.now() - start))
    print("To stop this session, use the 'core-cleanup' script on this server")
    print("and on the remote slave server.")
Beispiel #21
0
    def test_link_options_bidirectional(self, session: Session,
                                        tmpdir: TemporaryFile,
                                        ip_prefixes: IpPrefixes):
        """
        Test xml client methods for a ptp network.

        :param session: session for test
        :param tmpdir: tmpdir to create data in
        :param ip_prefixes: generates ip addresses for nodes
        """
        # create nodes
        node_one = session.add_node(CoreNode)
        interface_one = ip_prefixes.create_interface(node_one)
        node_two = session.add_node(CoreNode)
        interface_two = ip_prefixes.create_interface(node_two)

        # create link
        link_options_one = LinkOptions()
        link_options_one.unidirectional = 1
        link_options_one.bandwidth = 5000
        link_options_one.delay = 10
        link_options_one.per = 10.5
        link_options_one.dup = 5
        link_options_one.jitter = 5
        session.add_link(node_one.id, node_two.id, interface_one,
                         interface_two, link_options_one)
        link_options_two = LinkOptions()
        link_options_two.unidirectional = 1
        link_options_two.bandwidth = 10000
        link_options_two.delay = 20
        link_options_two.per = 10
        link_options_two.dup = 10
        link_options_two.jitter = 10
        session.update_link(
            node_two.id,
            node_one.id,
            interface_two.id,
            interface_one.id,
            link_options_two,
        )

        # instantiate session
        session.instantiate()

        # get ids for nodes
        n1_id = node_one.id
        n2_id = node_two.id

        # save xml
        xml_file = tmpdir.join("session.xml")
        file_path = xml_file.strpath
        session.save_xml(file_path)

        # verify xml file was created and can be parsed
        assert xml_file.isfile()
        assert ElementTree.parse(file_path)

        # stop current session, clearing data
        session.shutdown()

        # verify nodes have been removed from session
        with pytest.raises(CoreError):
            assert not session.get_node(n1_id, CoreNode)
        with pytest.raises(CoreError):
            assert not session.get_node(n2_id, CoreNode)

        # load saved xml
        session.open_xml(file_path, start=True)

        # verify nodes have been recreated
        assert session.get_node(n1_id, CoreNode)
        assert session.get_node(n2_id, CoreNode)
        links = []
        for node_id in session.nodes:
            node = session.nodes[node_id]
            links += node.all_link_data()
        assert len(links) == 2
        link_one = links[0]
        link_two = links[1]
        assert link_options_one.bandwidth == link_one.bandwidth
        assert link_options_one.delay == link_one.delay
        assert link_options_one.per == link_one.per
        assert link_options_one.dup == link_one.dup
        assert link_options_one.jitter == link_one.jitter
        assert link_options_two.bandwidth == link_two.bandwidth
        assert link_options_two.delay == link_two.delay
        assert link_options_two.per == link_two.per
        assert link_options_two.dup == link_two.dup
        assert link_options_two.jitter == link_two.jitter
Beispiel #22
0
    def test_link_options(self, session: Session, tmpdir: TemporaryFile,
                          ip_prefixes: IpPrefixes):
        """
        Test xml client methods for a ptp network.

        :param session: session for test
        :param tmpdir: tmpdir to create data in
        :param ip_prefixes: generates ip addresses for nodes
        """
        # create nodes
        node1 = session.add_node(CoreNode)
        iface1_data = ip_prefixes.create_iface(node1)
        switch = session.add_node(SwitchNode)

        # create link
        options = LinkOptions()
        options.loss = 10.5
        options.bandwidth = 50000
        options.jitter = 10
        options.delay = 30
        options.dup = 5
        session.add_link(node1.id, switch.id, iface1_data, options=options)

        # instantiate session
        session.instantiate()

        # get ids for nodes
        node1_id = node1.id
        node2_id = switch.id

        # save xml
        xml_file = tmpdir.join("session.xml")
        file_path = xml_file.strpath
        session.save_xml(file_path)

        # verify xml file was created and can be parsed
        assert xml_file.isfile()
        assert ElementTree.parse(file_path)

        # stop current session, clearing data
        session.shutdown()

        # verify nodes have been removed from session
        with pytest.raises(CoreError):
            assert not session.get_node(node1_id, CoreNode)
        with pytest.raises(CoreError):
            assert not session.get_node(node2_id, SwitchNode)

        # load saved xml
        session.open_xml(file_path, start=True)

        # verify nodes have been recreated
        assert session.get_node(node1_id, CoreNode)
        assert session.get_node(node2_id, SwitchNode)
        links = []
        for node_id in session.nodes:
            node = session.nodes[node_id]
            links += node.links()
        link = links[0]
        assert options.loss == link.options.loss
        assert options.bandwidth == link.options.bandwidth
        assert options.jitter == link.options.jitter
        assert options.delay == link.options.delay
        assert options.dup == link.options.dup