Beispiel #1
0
    def test_clear(self, sim_engine):
        sim_engine = sim_engine(
            diff_config={
                'exec_numMotes': 2,
                'sf_class': 'MSF',
                'conn_class': 'Linear',
                'secjoin_enabled': False
            })

        root = sim_engine.motes[0]
        mote = sim_engine.motes[1]
        root_mac_addr = root.get_mac_addr()

        u.run_until_mote_is_ready_for_app(sim_engine, mote)

        cells = mote.tsch.get_cells(mac_addr=root_mac_addr,
                                    slotframe_handle=mote.sf.SLOTFRAME_HANDLE)
        assert len(cells) == 1
        # mote should have a SHARED autonomous cell of the root
        assert cells[0].mac_addr == root_mac_addr
        assert d.CELLOPTION_TX in cells[0].options
        assert d.CELLOPTION_RX in cells[0].options
        assert d.CELLOPTION_SHARED in cells[0].options
        # keep the reference to the SHARED autonomous cell
        root_autonomous_cell = cells[0]

        # execute CLEAR (call the equivalent internal method of the
        # SF)
        mote.sf._clear_cells(root_mac_addr)

        # get the autonomous cell again
        cells = mote.tsch.get_cells(mac_addr=root_mac_addr,
                                    slotframe_handle=mote.sf.SLOTFRAME_HANDLE)
        assert len(cells) == 1
        assert cells[0] == root_autonomous_cell
Beispiel #2
0
    def test_parent_switch(self, sim_engine):
        sim_engine = sim_engine(
            diff_config={
                'exec_numSlotframesPerRun': 4000,
                'exec_numMotes': 3,
                'app_pkPeriod': 0,
                'sf_class': 'MSF',
                'conn_class': 'Linear'
            })

        # for quick access
        root = sim_engine.motes[0]
        mote_1 = sim_engine.motes[1]
        mote_2 = sim_engine.motes[2]
        asn_at_end_of_simulation = (
            sim_engine.settings.tsch_slotframeLength *
            sim_engine.settings.exec_numSlotframesPerRun)

        # wait for hop_2 to get ready. this is when the network is ready to
        # operate.
        u.run_until_mote_is_ready_for_app(sim_engine, mote_2)
        assert sim_engine.getAsn() < asn_at_end_of_simulation

        # stop DIO (and EB) transmission
        sim_engine.settings.tsch_probBcast_ebProb = 0

        # force mote_1 to switch its preferred parent
        old_parent = root
        new_parent = mote_2

        # invalidate old_parent
        dio = old_parent.rpl._create_DIO()
        dio['mac'] = {'srcMac': old_parent.get_mac_addr()}
        dio['app']['rank'] = 65535
        mote_1.rpl.action_receiveDIO(dio)
        # give a DIO from new_parent with a good rank
        dio = new_parent.rpl._create_DIO()
        dio['mac'] = {'srcMac': new_parent.get_mac_addr()}
        dio['app']['rank'] = 255
        mote_1.rpl.action_receiveDIO(dio)

        # mote_1 should issue CLEAR to the old preferred parent and ADD to the
        # new one
        asn_start_testing = sim_engine.getAsn()
        u.run_until_end(sim_engine)
        logs = u.read_log_file(filter=[SimLog.LOG_SIXP_TX['type']],
                               after_asn=asn_start_testing)

        def it_is_clear_request(packet):
            # return if the packet is a CLEAR request sent from mote_1 to
            # new_parent
            return ((packet['mac']['srcMac'] == mote_1.get_mac_addr())
                    and (packet['mac']['dstMac'] == old_parent.get_mac_addr())
                    and (packet['type'] == d.PKT_TYPE_SIXP)
                    and (packet['app']['msgType'] == d.SIXP_MSG_TYPE_REQUEST)
                    and (packet['app']['code'] == d.SIXP_CMD_CLEAR))

        assert len([l for l in logs if it_is_clear_request(l['packet'])]) > 0
Beispiel #3
0
    def test_no_available_cell(self, sim_engine, function_under_test):
        sim_engine = sim_engine(
            diff_config={
                'exec_numSlotframesPerRun': 1000,
                'exec_numMotes': 2,
                'app_pkPeriod': 0,
                'sf_class': 'MSF',
                'conn_class': 'Linear'
            })

        # for quick access
        root = sim_engine.motes[0]
        hop_1 = sim_engine.motes[1]
        asn_at_end_of_simulation = (
            sim_engine.settings.tsch_slotframeLength *
            sim_engine.settings.exec_numSlotframesPerRun)

        # wait for hop_1 to get ready.
        u.run_until_mote_is_ready_for_app(sim_engine, hop_1)
        assert sim_engine.getAsn() < asn_at_end_of_simulation

        # fill up the hop_1's schedule
        channel_offset = 0
        cell_options = [d.CELLOPTION_TX]
        used_slots = hop_1.tsch.get_busy_slots(hop_1.sf.SLOTFRAME_HANDLE)
        for _slot in range(sim_engine.settings.tsch_slotframeLength):
            if _slot in used_slots:
                continue
            else:
                hop_1.tsch.addCell(slotOffset=_slot,
                                   channelOffset=channel_offset,
                                   neighbor=root.get_mac_addr(),
                                   cellOptions=cell_options,
                                   slotframe_handle=hop_1.sf.SLOTFRAME_HANDLE)
        assert (len(hop_1.tsch.get_busy_slots(hop_1.sf.SLOTFRAME_HANDLE)) ==
                sim_engine.settings.tsch_slotframeLength)

        # put dummy stats so that scheduling adaptation can be triggered
        hop_1.sf.num_cells_elapsed = 100
        hop_1.sf.num_cells_used = hop_1.sf.num_cells_elapsed

        # trigger scheduling adaptation
        if function_under_test == 'adapt_to_traffic':
            hop_1.sf._adapt_to_traffic(root.id)
        elif function_under_test == 'relocate':
            relocating_cell = filter(
                lambda cell: cell.options == [d.CELLOPTION_TX],
                hop_1.tsch.get_cells(root.get_mac_addr(),
                                     hop_1.sf.SLOTFRAME_HANDLE))[0]
            hop_1.sf._request_relocating_cells(neighbor=root.get_mac_addr(),
                                               cell_options=[d.CELLOPTION_TX],
                                               num_relocating_cells=1,
                                               cell_list=[relocating_cell])
        else:
            # not implemented
            assert False

        # make sure the log is written into the file
        SimEngine.SimLog.SimLog().flush()

        # MSF should output a "schedule-full" error in the log file
        logs = u.read_log_file(
            filter=[SimLog.LOG_MSF_ERROR_SCHEDULE_FULL['type']],
            after_asn=sim_engine.getAsn() - 1)
        assert len(logs) == 1
        assert logs[0]['_mote_id'] == hop_1.id
Beispiel #4
0
    def test_rank_computation(self, sim_engine):
        # https://tools.ietf.org/html/rfc8180#section-5.1.2
        sim_engine = sim_engine(
            diff_config={
                'exec_numMotes': 6,
                'exec_numSlotframesPerRun': 10000,
                'app_pkPeriod': 0,
                'secjoin_enabled': False,
                'tsch_keep_alive_interval': 0,
                'conn_class': 'Linear',
                'sf_class': 'MSF'
            })

        # shorthand
        motes = sim_engine.motes
        asn_at_end_of_simulation = (
            sim_engine.settings.tsch_slotframeLength *
            sim_engine.settings.exec_numSlotframesPerRun)

        # get the network ready to be test
        u.run_until_mote_is_ready_for_app(sim_engine, motes[-1])
        assert sim_engine.getAsn() < asn_at_end_of_simulation

        # set ETX=100/75 (numTx=100, numTxAck=75)
        for mote_id in range(1, len(motes)):
            mote = motes[mote_id]
            parent = motes[mote_id - 1]

            # inject DIO to the mote
            dio = parent.rpl._create_DIO()
            dio['mac'] = {'srcMac': parent.get_mac_addr()}
            mote.rpl.action_receiveDIO(dio)

            # set numTx and numTxAck
            preferred_parent = mote.rpl.of.preferred_parent
            autonomous_cell = mote.tsch.get_cells(
                mac_addr=preferred_parent['mac_addr'],
                slotframe_handle=mote.sf.SLOTFRAME_HANDLE)[0]
            preferred_parent['numTx'] = 99
            preferred_parent['numTxAck'] = 74
            # inform RPL of the 100th transmission that is success
            mote.rpl.of.update_etx(cell=autonomous_cell,
                                   mac_addr=preferred_parent['mac_addr'],
                                   isACKed=True)

        # test using rank values in Figure 4 of RFC 8180
        assert motes[0].rpl.get_rank() == 256
        assert motes[0].rpl.getDagRank() == 1

        print motes[1].rpl.of.preferred_parent
        assert motes[1].rpl.get_rank() == 768
        assert motes[1].rpl.getDagRank() == 3

        assert motes[2].rpl.get_rank() == 1280
        assert motes[2].rpl.getDagRank() == 5

        assert motes[3].rpl.get_rank() == 1792
        assert motes[3].rpl.getDagRank() == 7

        assert motes[4].rpl.get_rank() == 2304
        assert motes[4].rpl.getDagRank() == 9

        assert motes[5].rpl.get_rank() == 2816
        assert motes[5].rpl.getDagRank() == 11