Beispiel #1
0
def test_two_branch_cascading_schedule_installation_4(motes):
    # even tree with random pick
    params = {
        'withJoin': False,
        'topology': 'twoBranch',
        'cascadingScheduling': True,
        'schedulingMode': 'random-pick'
    }

    settings = SimSettings.SimSettings(**params)
    engine = SimEngine.SimEngine()
    motes1 = engine.motes
    engine.destroy()
    settings.destroy()

    settings = SimSettings.SimSettings(**params)
    engine = SimEngine.SimEngine()
    motes2 = engine.motes
    engine.destroy()
    settings.destroy()

    assert len(motes1) == len(motes2)
    prev_ret = True
    for i, v in enumerate(motes1):
        assert len(motes1[i].schedule) == len(motes2[i].schedule)
        for j, cell in enumerate(motes1[i].schedule):
            if j not in motes1[i].schedule:
                continue

            try:
                cell1 = motes1[i].schedule[j]
                cell2 = motes2[i].schedule[j]
            except KeyError:
                ret = False
                break

            if type(cell1['neighbor']) is list:
                ret = (cell1['ch'] == cell2['ch']
                       and cell1['dir'] == Mote.DIR_TXRX_SHARED
                       and cell1['dir'] == cell2['dir']
                       and (sorted(map(lambda x: x.id, cell1['neighbor']))
                            == sorted(map(lambda x: x.id, cell2['neighbor']))))
            else:
                ret = (cell1['ch'] == cell2['ch']
                       and cell1['dir'] == cell2['dir']
                       and cell1['neighbor'].id == cell2['neighbor'].id)

            ret = prev_ret and ret

        if ret is False:
            break

    # all schedules must not be the same
    assert ret is False
Beispiel #2
0
def runSimsSequentially(params):

    (cpuID, numRuns, options, verbose) = params

    # record simulation start time
    simStartTime = time.time()

    # compute all the simulation parameter combinations
    combinationKeys = sorted(
        [k for (k, v) in options.items() if type(v) == list])
    simParams = []
    for p in itertools.product(*[options[k] for k in combinationKeys]):
        simParam = {}
        for (k, v) in zip(combinationKeys, p):
            simParam[k] = v
        for (k, v) in options.items():
            if k not in simParam:
                simParam[k] = v
        simParams += [simParam]

    # run a simulation for each set of simParams
    for (simParamNum, simParam) in enumerate(simParams):

        # record run start time
        runStartTime = time.time()

        # run the simulation runs
        for runNum in xrange(numRuns):

            # print
            output = 'parameters {0}/{1}, run {2}/{3}'.format(
                simParamNum + 1, len(simParams), runNum + 1, numRuns)
            printOrLog(cpuID, output, verbose)

            # create singletons
            settings = SimSettings.SimSettings(cpuID=cpuID,
                                               runNum=runNum,
                                               **simParam)
            settings.setStartTime(runStartTime)
            settings.setCombinationKeys(combinationKeys)
            simengine = SimEngine.SimEngine(cpuID=cpuID, runNum=runNum)
            simstats = SimStats.SimStats(cpuID=cpuID,
                                         runNum=runNum,
                                         verbose=verbose)

            # start simulation run
            simengine.start()

            # wait for simulation run to end
            simengine.join()

            # destroy singletons
            simstats.destroy()
            simengine.destroy()
            settings.destroy()

        # print
        output = 'simulation ended after {0:.0f}s.'.format(time.time() -
                                                           simStartTime)
        printOrLog(cpuID, output, verbose)
    def create_motes(num_motes, **kwargs):

        # Mote needs SimEngine has already instantiated when its constructor is
        # called
        params = {'numMotes': num_motes, 'topology': 'linear'}
        params['linearTopologyStaticScheduling'] = True

        # there are prerequisite parameters for Mote.Mote()
        params['pkPeriod'] = 0
        params['minRssi'] = 0
        params['withJoin'] = False
        params['slotframeLength'] = 101
        params['slotDuration'] = 0.010
        params['bayesianBroadcast'] = False

        # disable interference model
        params['noInterference'] = True

        # override by kwargs is any specified
        if kwargs:
            params.update(kwargs)

        settings = SimSettings.SimSettings(**params)
        engine = SimEngine.SimEngine()

        def fin():

            engine.destroy()
            settings.destroy()

        request.addfinalizer(fin)

        return engine.motes
Beispiel #4
0
    def create_sim_engine(
            diff_config                                = {},
            force_initial_routing_and_scheduling_state = False,
            run_id                                     = None
        ):
        
        engine = None
        sim_log = None
        sim_settings = None

        # add a finalizer
        def fin():
            if engine:
                engine.connectivity.destroy()
                engine.destroy()
            if sim_log:
                sim_log.destroy()
            if sim_settings:
                sim_settings.destroy()
        request.addfinalizer(fin)
        
        # get default configuration
        sim_config = SimConfig.SimConfig(u.CONFIG_FILE_PATH)
        config = sim_config.settings['regular']
        assert 'exec_numMotes' not in config
        config['exec_numMotes'] = sim_config.settings['combination']['exec_numMotes'][0]

        # update default configuration with parameters
        for (k,v) in list(diff_config.items()):
            assert k in config
        config.update(**diff_config)

        # create sim settings
        sim_settings = SimSettings.SimSettings(**config)
        sim_settings.setLogDirectory(
            '{0}-{1:03d}'.format(
                time.strftime('%Y%m%d-%H%M%S'),
                int(round(time.time() * 1000))%1000
            )
        )
        sim_settings.setCombinationKeys([])

        # create sim log
        sim_log = SimEngine.SimLog.SimLog()
        sim_log.set_log_filters('all') # do not log

        # create sim engine
        engine = SimEngine.SimEngine(run_id=run_id)
        
        # force initial routing and schedule, if appropriate
        if force_initial_routing_and_scheduling_state:
            set_initial_routing_and_scheduling_state(engine)

        return engine
Beispiel #5
0
def runSims(options):

    # compute all the simulation parameter combinations
    combinationKeys = sorted(
        [k for (k, v) in options.items() if type(v) == list])
    print options.items()
    simParams = []
    for p in itertools.product(*[options[k] for k in combinationKeys]):
        simParam = {}
        for (k, v) in zip(combinationKeys, p):
            simParam[k] = v
        for (k, v) in options.items():
            if k not in simParam:
                simParam[k] = v
        simParams += [simParam]

    # run a simulation for each set of simParams
    for (simParamNum, simParam) in enumerate(simParams):

        # print
        if simParam['processID'] == None:
            print('parameters {0}/{1}'.format(simParamNum + 1, len(simParams)))
        else:
            print('parameters {0}/{1}, processID {2}'.format(
                simParamNum + 1, len(simParams), simParam['processID']))

        # record run start time
        runStartTime = time.time()

        # run the simulation runs
        for runNum in xrange(simParam['numRuns']):

            # print
            if simParam['processID'] == None:
                print('   run {0}/{1}'.format(runNum + 1, simParam['numRuns']))

            # create singletons
            settings = SimSettings.SimSettings(**simParam)
            settings.setStartTime(runStartTime)
            settings.setCombinationKeys(combinationKeys)
            simengine = SimEngine.SimEngine(runNum)
            simstats = SimStats.SimStats(runNum, simParam['numRuns'])
            #passing the number of runs to enable the display  of them while the code is runnig

            # start simulation run
            simengine.start()

            # wait for simulation run to end
            simengine.join()

            # destroy singletons
            simstats.destroy()
            simengine.destroy()
            settings.destroy()
Beispiel #6
0
def test_two_branch_cascading_schedule_installation(motes):
    # even tree *without* random pick
    params = {
        'withJoin': False,
        'topology': 'twoBranch',
        'cascadingScheduling': True
    }

    settings = SimSettings.SimSettings(**params)
    engine = SimEngine.SimEngine()
    motes1 = engine.motes
    engine.destroy()
    settings.destroy()

    settings = SimSettings.SimSettings(**params)
    engine = SimEngine.SimEngine()
    motes2 = engine.motes
    engine.destroy()
    settings.destroy()

    assert len(motes1) == len(motes2)
    for i, v in enumerate(motes1):
        assert len(motes1[i].schedule) == len(motes2[i].schedule)
        for j, cell in enumerate(motes1[i].schedule):
            if j not in motes1[i].schedule:
                continue

            cell1 = motes1[i].schedule[j]
            cell2 = motes2[i].schedule[j]

            if type(cell1['neighbor']) is list:
                ret = (cell1['ch'] == cell2['ch']
                       and cell1['dir'] == Mote.DIR_TXRX_SHARED
                       and cell1['dir'] == cell2['dir']
                       and (sorted(map(lambda x: x.id, cell1['neighbor']))
                            == sorted(map(lambda x: x.id, cell2['neighbor']))))
            else:
                ret = (cell1['ch'] == cell2['ch']
                       and cell1['dir'] == cell2['dir']
                       and cell1['neighbor'].id == cell2['neighbor'].id)
            assert ret is True
Beispiel #7
0
def runSimCombinations(params):
    """
    Runs simulations for all combinations of simulation settings.
    This function may run independently on different CPUs.
    """

    cpuID = params['cpuID']
    pid = params['pid']
    numRuns = params['numRuns']
    first_run = params['first_run']
    verbose = params['verbose']
    config_data = params['config_data']

    simconfig = SimConfig.SimConfig(configdata=config_data)

    # record simulation start time
    simStartTime = time.time()

    # compute all the simulation parameter combinations
    combinationKeys = simconfig.settings.combination.keys()
    simParams = []
    for p in itertools.product(
            *[simconfig.settings.combination[k] for k in combinationKeys]):
        simParam = {}
        for (k, v) in zip(combinationKeys, p):
            simParam[k] = v
        for (k, v) in simconfig.settings.regular.items():
            if k not in simParam:
                simParam[k] = v
        simParams += [simParam]

    # run a simulation for each set of simParams
    for (simParamNum, simParam) in enumerate(simParams):

        # run the simulation runs
        for run_id in range(first_run, first_run + numRuns):

            # printOrLog
            output = 'parameters {0}/{1}, run {2}/{3}'.format(
                simParamNum + 1, len(simParams), run_id + 1 - first_run,
                numRuns)
            printOrLog(cpuID, pid, output, verbose)

            # create singletons
            settings = SimSettings.SimSettings(cpuID=cpuID,
                                               run_id=run_id,
                                               **simParam)
            settings.setLogDirectory(simconfig.get_log_directory_name())
            settings.setCombinationKeys(combinationKeys)
            simlog = SimLog.SimLog()
            simlog.set_log_filters(simconfig.logging)

            parentlog = ParentLogs.ParentLogs()
            parentlog.set_log_filters(simconfig.logging)
            simengine = SimEngine.SimEngine(run_id=run_id, verbose=verbose)

            # start simulation run
            simengine.start()

            # wait for simulation run to end
            simengine.join()

            # destroy singletons
            simlog.destroy()
            #parentlog.destroy()
            simengine.destroy()
            Connectivity.Connectivity().destroy()
            settings.destroy()  # destroy last, Connectivity needs it

        # printOrLog
        output = 'simulation ended after {0:.0f}s ({1} runs).'.format(
            time.time() - simStartTime, numRuns * len(simParams))
        printOrLog(cpuID, pid, output, verbose)
Beispiel #8
0
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,
            'roupe_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 #9
0
 def settings(self):
     return SimSettings.SimSettings(failIfNotInit=True)
Beispiel #10
0
def test_random_seed(sim_engine, fixture_random_seed):
    diff_config = {
        'exec_randomSeed': fixture_random_seed,
        'exec_numSlotframesPerRun': 100
    }

    log_file_hashes = []

    # compare logs out of 10 runs
    results = []
    for i in range(10):

        sha2 = hashlib.sha256()

        if fixture_random_seed == 'range':
            # ues i for 'exec_randomSeed':
            diff_config['exec_randomSeed'] = i

        engine = sim_engine(diff_config=diff_config)
        log = SimLog.SimLog()
        settings = SimSettings.SimSettings()

        # run the simulator
        u.run_until_end(engine)

        # save the log file name and a random seed for later use
        log_file_name = settings.getOutputFile()
        logs = u.read_log_file(
            filter=[SimLog.LOG_SIMULATOR_RANDOM_SEED['type']])
        assert len(logs) == 1
        random_seed = logs[0]['value']

        # destroy singletons for the next run
        engine.connectivity.destroy()
        engine.destroy()
        log.destroy()
        settings.destroy()
        # this is for test purpose only; reset SimConfig._startTime
        SimConfig.SimConfig._startTime = None

        # compute the file hash
        with open(log_file_name, 'r') as f:
            # skip the very first line in the log file, which has
            # 'logDirectory' etnry and it should have a unique value even if a
            # certain integer is specified for 'exec_randSeed'
            f.readline()

            sha2.update(f.read().encode('utf-8'))
            results.append({
                'log_file_name': log_file_name,
                'sha256': sha2.hexdigest(),
                'random_seed': random_seed
            })

    # collect hash values and print debug messages
    seed_list = []
    hash_list = []
    for entry in results:
        seed_list.append(entry['random_seed'])
        hash_list.append(entry['sha256'])

        # print hash values, which will be printed out when this test fails
        print('{0} {1}'.format(entry['sha256'], entry['log_file_name']))

    # compare hash values and random seeds
    if fixture_random_seed in ['random', 'range', 'context']:
        # different seed values should have been used
        assert (sum([i == j
                     for i, j in zip(seed_list[:-1], seed_list[1:])]) == 0)
        # hash values shouldn't be the same
        assert (sum([i == j
                     for i, j in zip(hash_list[:-1], hash_list[1:])]) == 0)
    else:
        # the random seed values are found in the log files should be identical
        assert (sum([i != j
                     for i, j in zip(seed_list[:-1], seed_list[1:])]) == 0)
        # hash values should be identical as well
        assert (sum([i != j
                     for i, j in zip(hash_list[:-1], hash_list[1:])]) == 0)
Beispiel #11
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
Beispiel #12
0
def collect_setting_keys_in_use():
    sim_engine_dir = os.path.join(
        os.path.abspath(os.path.dirname(__file__)),
        '../SimEngine'
    )

    # collect core files
    core_files = []
    for root, dirs, files in os.walk(sim_engine_dir):
        for file in files:
            if file in ['SimSettings.py', 'SimConfig.py']:
                # skip SimSettings.py and SimConfig.py
                continue
            if re.match(r'^.+\.py$', file):
                core_files.append(
                    os.path.join(
                        root,
                        file
                    )
                )

    # identify SimSettings methods
    sim_settings_methods = [
        name for name, _ in inspect.getmembers(
            SimSettings.SimSettings(),
            predicate=inspect.ismethod
        )
    ]

    # collect settings which are referred in core files
    settings_variables = set([])
    setting_keys = set([])
    for file_path in core_files:
        with open(file_path, 'r') as f:
            for line in f:
                # remote all the white spaces and the new line character
                line = line.rstrip()
                if re.match(r'^import', line):
                    # skip import line
                    continue
                elif re.match(r'^\s*#', line):
                    # skip comment line
                    continue
                elif re.search(r'SimSettings', line):
                    if (
                            re.search(r'SimSettings\(\)\.__dict__', line)
                            and
                            re.search(r' for ', line)
                        ):
                        # this line looks like a 'for' statement; skip this line
                        continue
                    settings = re.sub(r'^(.+)=.+SimSettings.+$', r'\1', line)
                    settings = settings.replace(' ', '')
                    settings_variables.add(settings)
                elif (
                        (len(settings_variables) > 0)
                        and
                        re.search('|'.join(settings_variables), line)
                    ):
                    # identify a setting key in in this line
                    pattern = re.compile(
                        '(' + '|'.join(settings_variables) + ')' +
                        '\.(\w+)'
                    )
                    m = re.search(pattern, line)
                    if m is not None:
                        key = m.group(2)
                        if key in sim_settings_methods:
                            # it's class/instance method; skip it
                            continue
                        elif key == '__dict__':
                            # this is not a key; skip it
                            continue
                        elif key == 'run_id':
                            # run_id is not a setting key; ignore this
                            continue
                        else:
                            # add the key referred from a core file
                            setting_keys.add(m.group(2))

    # add exec_minutesPerRun which is found only in SimSettings, which
    # is not processed in the loop above
    setting_keys.add('exec_minutesPerRun')
    return setting_keys
Beispiel #13
0
def test_config(sim_engine):

    sim_engine = sim_engine()

    # identify the root directory of the simulator
    root_dir = os.path.realpath(os.path.join(os.path.dirname(__file__), '..'))

    # identify SimEngine directory
    sim_engine_dir = os.path.join(root_dir, 'SimEngine')

    # collect file paths to the core files
    core_files = []
    for root, dirs, files in os.walk(sim_engine_dir):
        for file in files:
            if file in ['SimSettings.py', 'SimConfig.py']:
                # skip SimSettings.py and SimConfig.py
                continue
            if re.match(r'^.+\.py$', file):
                core_files.append(os.path.join(root, file))

    # collect setting keys in the default config.json; each key is converted
    # from a unicode string ('u' prefixed string) to a normal string
    keys_found_in_config_file = [
        '{0}'.format(key) for key in sim_engine.settings.__dict__.keys()
    ]
    # remove elements which are not configuration keys
    keys_found_in_config_file = [
        key for key in keys_found_in_config_file
        if (key not in ['cpuID', 'run_id', 'combinationKeys', 'logDirectory'])
    ]
    # convert keys_found_in_config_file to a set
    keys_found_in_config_file = set(keys_found_in_config_file)

    # collect setting keys referred in the core files
    keys_found_in_core_files = set()
    sim_settings_methods = [
        name for name, _ in inspect.getmembers(SimSettings.SimSettings(),
                                               predicate=inspect.ismethod)
    ]

    for file_path in core_files:
        # put self.settings as the default setting variable
        settings_variables = set(['self.settings'])
        with open(file_path, 'r') as f:
            for line in f:
                # remote all the white spaces and the new line character
                line = line.rstrip()
                if re.match(r'^import', line):
                    # skip import line
                    continue
                elif re.search(r'SimSettings', line):
                    if (re.search(r'SimSettings\(\)\.__dict__', line)
                            and re.search(r' for ', line)):
                        # this line looks like a 'for' statement; skip this line
                        continue
                    settings_variable = re.sub(r'^(.+)=.+SimSettings.+$',
                                               r'\1', line)
                    settings_variable = settings_variable.replace(' ', '')
                    settings_variables.add(settings_variable)
                elif ((len(settings_variables) > 0)
                      and re.search('|'.join(settings_variables), line)):
                    # identify a setting key in in this line
                    pattern = re.compile('(' + '|'.join(settings_variables) +
                                         ')' + '\.(\w+)')
                    m = re.search(pattern, line)
                    key = m.group(2)
                    if key in sim_settings_methods:
                        # it's class/instance method; skip it
                        continue
                    elif key == '__dict__':
                        # this is not a key; skip it
                        continue
                    else:
                        # add the key referred from a core file
                        keys_found_in_core_files.add(m.group(2))

    # ready to test; two sets should be identical
    assert keys_found_in_config_file == keys_found_in_core_files