Beispiel #1
0
 def settings(self):
     return SimSettings.SimSettings(failIfNotInit=True)
def test_avg_hops(sim_engine, fragmentation, app_pkLength, pkt_loss_mode):
    sim_engine = sim_engine(
        diff_config = {
            'exec_numSlotframesPerRun': 40,
            'exec_numMotes'           : 10,
            'fragmentation'           : fragmentation,
            'app'                     : 'AppPeriodic',
            'app_pkPeriod'            : 0,
            'app_pkLength'            : app_pkLength,
            'tsch_probBcast_ebProb'   : 0,
            'rpl_daoPeriod'           : 0,
            'conn_class'              : 'Linear'
        },
        force_initial_routing_and_scheduling_state = True,
    )

    # in this test, the leaf sends two application packets. when pkt_loss_mode
    # is 'with_pkt_loss', the second application packet will be lost at the
    # root.

    # shorthands
    root = sim_engine.motes[0]
    leaf = sim_engine.motes[-1]
    sim_settings = SimSettings.SimSettings()

    # make the app send an application packet
    leaf.app._send_a_single_packet()

    # wait for some time
    u.run_until_asn(sim_engine, 2020)

    # make sure SimEngine datalock is disengaged
    with pytest.raises(RuntimeError):
        assert sim_engine.dataLock.release()

    # the root should receive the first application packet
    logs = u.read_log_file([SimLog.LOG_APP_RX['type']])
    assert len(logs) == 1
    assert logs[0]['_mote_id'] == root.id
    assert logs[0]['packet']['net']['srcIp'] == leaf.get_ipv6_global_addr()
    assert logs[0]['packet']['net']['dstIp'] == root.get_ipv6_global_addr()
    assert logs[0]['packet']['type'] == d.PKT_TYPE_DATA

    # make the root not receive at 6LoWPAN layer anything if pkt_loss_mode is
    # 'with_pkt_loss'
    if   pkt_loss_mode == 'with_pkt_loss':
        assert root.dagRoot is True
        def recvPacket(self, packet):
            # do nothing; ignore the incoming packet
            pass
        root.sixlowpan.recvPacket = types.MethodType(
            recvPacket,
            root.sixlowpan
        )
    elif pkt_loss_mode == 'without_pkt_loss':
        # do nothing
        pass
    else:
        raise NotImplemented()

    # make the app send another application packet
    leaf.app._send_a_single_packet()

    # run the simulator until it ends
    u.run_until_end(sim_engine)

    # confirm the leaf sent two application packets
    logs = u.read_log_file([SimLog.LOG_APP_TX['type']])
    assert len(logs) == 2
    for i in range(2):
        assert logs[i]['_mote_id'] == leaf.id
        assert logs[i]['packet']['net']['srcIp'] == leaf.get_ipv6_global_addr()
        assert logs[i]['packet']['net']['dstIp'] == root.get_ipv6_global_addr()
        assert logs[i]['packet']['type'] == d.PKT_TYPE_DATA

    # run compute_kpis.py against the log file
    output = run_compute_kpis_py()
    # remove blank lines
    output = [line for line in output if not re.match(r'^\s*$', line)]

    # confirm if compute_kpis.py referred the right log file
    # the first line of output has the log directory name
    assert (
        re.search(
            os.path.basename(sim_settings.getOutputFile()),
            output[0]
        ) is not None
    )

    # convert the body of the output, which is a JSON string, to an object
    json_string = '\n'.join(output[1:-1])
    kpis = json.loads(json_string)

    # the avg_hops should be the same number as leaf.id since we use a linear
    # topology here.
    assert kpis['null'][str(leaf.id)]['avg_hops'] == leaf.id
Beispiel #3
0
def start(settings, log_notification_filter='all', stderr_redirect=True):
    global _sim_engine
    global _elapsed_minutes

    sim_settings = None
    sim_log = None
    ret_val = {}

    if _sim_engine is not None:
        return {
            'status': RETURN_STATUS_FAILURE,
            'message': 'SimEngine has been started already',
            'trace': None
        }

    try:
        sim_settings = SimSettings.SimSettings(
            cpuID=0, run_id=0, log_root_dir=backend.SIM_DATA_PATH, **settings)
        start_time = time.time()
        sim_settings.setLogDirectory('{0}-{1:03d}'.format(
            time.strftime("%Y%m%d-%H%M%S", time.localtime(start_time)),
            int(round(start_time * 1000)) % 1000))
        sim_settings.setCombinationKeys(DUMMY_COMBINATION_KEYS)

        sim_log = SimLog.SimLog()
        sim_log.set_log_filters(SIM_LOG_FILTERS)
        _overwrite_sim_log_log(log_notification_filter)

        _save_config_json(sim_settings,
                          saving_settings={
                              'combination': {},
                              'regular': settings.copy()
                          })

        crash_report_path = os.path.join(sim_settings.logRootDirectoryPath,
                                         sim_settings.logDirectory,
                                         'crash_report.log')
        if stderr_redirect is True:
            _redirect_stderr(redirect_to=open(crash_report_path, 'w'))

        _sim_engine = SimEngine.SimEngine()
        _elapsed_minutes = 0
        _overwrite_sim_engine_actionEndSlotframe()

        # start and wait until the simulation ends
        _sim_engine.start()
        _sim_engine.join()
    except Exception as e:
        ret_val['status'] = RETURN_STATUS_FAILURE
        ret_val['message'] = str(e)
        ret_val['trace'] = traceback.format_exc()
    else:
        if _sim_engine.getAsn() == (sim_settings.exec_numSlotframesPerRun *
                                    sim_settings.tsch_slotframeLength):
            ret_val['status'] = RETURN_STATUS_SUCCESS
            # rename .dat file and remove the subdir
            dat_file_path = sim_settings.getOutputFile()
            subdir_path = os.path.dirname(dat_file_path)
            new_file_name = subdir_path + '.dat'
            os.rename(dat_file_path, new_file_name)
            os.rmdir(subdir_path)
        else:
            # simulation is aborted
            ret_val['status'] = RETURN_STATUS_ABORTED
    finally:
        # housekeeping for crash_report and stderr
        if stderr_redirect is True:
            crash_report = _restore_stderr()
            crash_report.close()
            if os.stat(crash_report.name).st_size == 0:
                os.remove(crash_report.name)
            else:
                ret_val['crash_report_path'] = crash_report.name

        # cleanup
        if _sim_engine is None:
            if sim_settings is not None:
                sim_settings.destroy()
            if sim_log is not None:
                sim_log.destroy()
        else:
            _destroy_sim()

    return ret_val