Exemple #1
0
def test_repr():
    cfg = Config()
    rep = cfg.__repr__()

    expected_rep = (f"Current values: \n {cfg.current_config} \n"
                    f"Current paths: \n {cfg._loaded_config_files} \n"
                    f"{super(Config, cfg).__repr__()}")

    assert rep == expected_rep
Exemple #2
0
def test_set_guid_workstatio_code(ws, monkeypatch):
    monkeypatch.setattr('builtins.input', lambda x: str(ws))

    orig_cfg = Config().current_config

    original_ws = orig_cfg['GUID_components']['work_station']

    with protected_config():
        set_guid_work_station_code()

        cfg = Config().current_config

        if 16777216 > ws > 0:
            assert cfg['GUID_components']['work_station'] == ws
        else:
            assert cfg['GUID_components']['work_station'] == original_ws
Exemple #3
0
def test_set_guid_location_code(loc, monkeypatch):
    monkeypatch.setattr('builtins.input', lambda x: str(loc))

    orig_cfg = Config().current_config

    original_loc = orig_cfg['GUID_components']['location']

    with protected_config():
        set_guid_location_code()

        cfg = Config().current_config

        if 257 > loc > 0:
            assert cfg['GUID_components']['location'] == loc
        else:
            assert cfg['GUID_components']['location'] == original_loc
Exemple #4
0
def test_update_from_path(path_to_config_file_on_disk):
    with default_config():
        cfg = Config()

        # check that the default is still the default
        assert cfg["core"]["db_debug"] is False

        cfg.update_config(path=path_to_config_file_on_disk)
        assert cfg['core']['db_debug'] is True

        # check that the settings NOT specified in our config file on path
        # are still saved as configurations
        assert cfg['gui']['notebook'] is True
        assert cfg['station_configurator']['default_folder'] == '.'

        expected_path = os.path.join(path_to_config_file_on_disk,
                                     'qcodesrc.json')
        assert cfg.current_config_path == expected_path
Exemple #5
0
def test_generate_guid(loc, stat, smpl):
    # update config to generate a particular guid. Read it back to verify
    with protected_config():
        cfg = Config()
        cfg['GUID_components']['location'] = loc
        cfg['GUID_components']['work_station'] = stat
        cfg['GUID_components']['sample'] = smpl
        cfg.save_to_home()

        guid = generate_guid()
        gen_time = int(np.round(time.time() * 1000))

        comps = parse_guid(guid)

        if smpl == 0:
            smpl = int('a' * 8, base=16)

        assert comps['location'] == loc
        assert comps['work_station'] == stat
        assert comps['sample'] == smpl
        assert comps['time'] - gen_time < 2
def test_add_and_describe():
    """
    Test that a key an be added and described
    """
    with default_config():

        key = 'newkey'
        value ='testvalue'
        value_type ='string'
        description ='A test'
        default = 'testdefault'

        cfg = Config()
        cfg.add(key=key, value=value, value_type=value_type,
                description=description, default=default)


        desc = cfg.describe(f'user.{key}')
        expected_desc = (f"{description}.\nCurrent value: {value}. "
                         f"Type: {value_type}. Default: {default}.")

        assert desc == expected_desc
Exemple #7
0
def set_guid_location_code() -> None:
    """
    Interactive function to set the location code.
    """
    cfg = Config()
    old_loc = cfg['GUID_components']['location']
    print(f'Updating GUID location code. Current location code is: {old_loc}')
    if old_loc != 0:
        print('That is a non-default location code. Perhaps you should not '
              'change it? Re-enter that code to leave it unchanged.')
    loc_str = input('Please enter the new location code (1-256): ')
    try:
        location = int(loc_str)
    except ValueError:
        print('The location code must be an integer. No update performed.')
        return
    if not (257 > location > 0):
        print('The location code must be between 1 and 256 (both included). '
              'No update performed')
        return

    cfg['GUID_components']['location'] = location
    cfg.save_to_home()
Exemple #8
0
def set_guid_work_station_code() -> None:
    """
    Interactive function to set the work station code
    """
    cfg = Config()
    old_ws = cfg['GUID_components']['work_station']
    print('Updating GUID work station code. '
          f'Current work station code is: {old_ws}')
    if old_ws != 0:
        print('That is a non-default work station code. Perhaps you should not'
              ' change it? Re-enter that code to leave it unchanged.')
    ws_str = input('Please enter the new work station code (1-16777216): ')
    try:
        work_station = int(ws_str)
    except ValueError:
        print('The work station code must be an integer. No update performed.')
        return
    if not (16777216 > work_station > 0):
        print('The work staion code must be between 1 and 256 (both included).'
              ' No update performed')
        return

    cfg['GUID_components']['work_station'] = work_station
    cfg.save_to_home()
def test_update_from_path(path_to_config_file_on_disk):
    cfg = Config()

    # check that the default is still the default
    cfg.update_config()
    assert cfg["core"]["db_debug"] == False

    cfg.update_config(path=path_to_config_file_on_disk)
    assert cfg['a'] == 13
    assert cfg['user']['foo'] == '2'
    expected_path = os.path.join(path_to_config_file_on_disk, 'qcodesrc.json')
    assert cfg.current_config_path == expected_path
Exemple #10
0
def generate_guid(timeint: Union[int, None] = None,
                  sampleint: Union[int, None] = None) -> str:
    """
    Generate a guid string to go into the GUID column of the runs table.
    The GUID is based on the GUID-components in the qcodesrc file.
    The generated string is of the format
    '12345678-1234-1234-1234-123456789abc', where the first eight hex numbers
    comprise the 4 byte sample code, the next 2 hex numbers comprise the 1 byte
    location, the next 2+4 hex numbers are the 3 byte work station code, and
    the final 4+12 hex number give the 8 byte integer time in ms since epoch
    time

    Args:
        timeint: An integer of miliseconds since unix epoch time
        sampleint: A code for the sample
    """
    cfg = Config()

    try:
        guid_comp = cfg['GUID_components']
    except KeyError:
        raise RuntimeError('Invalid QCoDeS config file! No GUID_components '
                           'specified. Can not proceed.')

    location = guid_comp['location']
    station = guid_comp['work_station']

    if timeint is None:
        # ms resolution, checked on windows
        timeint = int(np.round(time.time() * 1000))
    if sampleint is None:
        sampleint = guid_comp['sample']

    if sampleint == 0:
        sampleint = int('a' * 8, base=16)

    loc_str = f'{location:02x}'
    stat_str = f'{station:06x}'
    smpl_str = f'{sampleint:08x}'
    time_str = f'{timeint:016x}'

    guid = (f'{smpl_str}-{loc_str}{stat_str[:2]}-{stat_str[2:]}-'
            f'{time_str[:4]}-{time_str[4:]}')

    return guid
Exemple #11
0
def protected_config():
    """
    Context manager to be used in all tests that modify the config to ensure
    that the config is left untouched even if the tests fail
    """
    ocfg: DotDict = Config().current_config
    original_config = deepcopy(ocfg)

    yield

    cfg = Config()
    cfg.current_config = original_config
    cfg.save_to_home()
Exemple #12
0
"""Set up the main qcodes namespace."""

# flake8: noqa (we don't need the "<...> imported but unused" error)

# config

from qcodes.config import Config
from qcodes.logger import start_all_logging
from qcodes.logger.logger import conditionally_start_all_logging
from qcodes.utils.helpers import add_to_spyder_UMR_excludelist
from .version import __version__

config: Config = Config()

conditionally_start_all_logging()

# we dont want spyder to reload qcodes as this will overwrite the default station
# instrument list and running monitor
add_to_spyder_UMR_excludelist('qcodes')


from qcodes.version import __version__

plotlib = config.gui.plotlib
if plotlib in {'QT', 'all'}:
    try:
        from qcodes.plots.pyqtgraph import QtPlot
    except Exception:
        print('pyqtgraph plotting not supported, '
              'try "from qcodes.plots.pyqtgraph import QtPlot" '
              'to see the full error')
Exemple #13
0
"""Set up the main qcodes namespace."""

# flake8: noqa (we don't need the "<...> imported but unused" error)

# config

from qcodes.config import Config
from qcodes.utils.helpers import add_to_spyder_UMR_excludelist

# we dont want spyder to reload qcodes as this will overwrite the default station
# instrument list and running monitor
add_to_spyder_UMR_excludelist('qcodes')
config = Config()  # type: Config

from qcodes.version import __version__

plotlib = config.gui.plotlib
if plotlib in {'QT', 'all'}:
    try:
        from qcodes.plots.pyqtgraph import QtPlot
    except Exception:
        print('pyqtgraph plotting not supported, '
              'try "from qcodes.plots.pyqtgraph import QtPlot" '
              'to see the full error')

if plotlib in {'matplotlib', 'all'}:
    try:
        from qcodes.plots.qcmatplotlib import MatPlot
    except Exception:
        print('matplotlib plotting not supported, '
              'try "from qcodes.plots.qcmatplotlib import MatPlot" '
Exemple #14
0
"""Set up the main qcodes namespace."""

# flake8: noqa (we don't need the "<...> imported but unused" error)

# config

from qcodes.config import Config

config = Config()

from qcodes.version import __version__

plotlib = config.gui.plotlib
if plotlib in {'QT', 'all'}:
    try:
        from qcodes.plots.pyqtgraph import QtPlot
    except Exception:
        print('pyqtgraph plotting not supported, '
              'try "from qcodes.plots.pyqtgraph import QtPlot" '
              'to see the full error')

if plotlib in {'matplotlib', 'all'}:
    try:
        from qcodes.plots.qcmatplotlib import MatPlot
    except Exception:
        print('matplotlib plotting not supported, '
              'try "from qcodes.plots.qcmatplotlib import MatPlot" '
              'to see the full error')

from qcodes.station import Station
from qcodes.loops import Loop, active_loop, active_data_set
def test_combine_runs(two_empty_temp_db_connections, empty_temp_db_connection,
                      some_interdeps):
    """
    Test that datasets that are exported in random order from 2 datasets
    can be reloaded by the original captured_run_id and the experiment
    name.
    """
    source_conn_1, source_conn_2 = two_empty_temp_db_connections
    target_conn = empty_temp_db_connection

    source_1_exp = Experiment(conn=source_conn_1,
                              name='exp1',
                              sample_name='no_sample')
    source_1_datasets = [
        DataSet(conn=source_conn_1, exp_id=source_1_exp.exp_id)
        for i in range(10)
    ]

    source_2_exp = Experiment(conn=source_conn_2,
                              name='exp2',
                              sample_name='no_sample')

    source_2_datasets = [
        DataSet(conn=source_conn_2, exp_id=source_2_exp.exp_id)
        for i in range(10)
    ]

    source_all_datasets = source_1_datasets + source_2_datasets

    shuffled_datasets = source_all_datasets.copy()
    random.shuffle(shuffled_datasets)

    for ds in source_all_datasets:
        ds.set_interdependencies(some_interdeps[1])
        ds.mark_started()
        ds.add_results([{name: 0.0 for name in some_interdeps[1].names}])
        ds.mark_completed()

    # now let's insert all datasets in random order
    for ds in shuffled_datasets:
        extract_runs_into_db(ds.conn.path_to_dbfile,
                             target_conn.path_to_dbfile, ds.run_id)

    for ds in source_all_datasets:
        loaded_ds = load_by_run_spec(captured_run_id=ds.captured_run_id,
                                     experiment_name=ds.exp_name,
                                     conn=target_conn)
        assert ds.the_same_dataset_as(loaded_ds)

    for ds in source_all_datasets:
        loaded_ds = load_by_run_spec(captured_run_id=ds.captured_counter,
                                     experiment_name=ds.exp_name,
                                     conn=target_conn)
        assert ds.the_same_dataset_as(loaded_ds)

    # Now test that we generate the correct table for the guids above
    # this could be split out into its own test
    # but the test above has the useful side effect of
    # setting up datasets for this test.
    guids = [ds.guid for ds in source_all_datasets]

    table = generate_dataset_table(guids, conn=target_conn)
    lines = table.split('\n')
    headers = re.split(r'\s+', lines[0].strip())

    cfg = Config()
    guid_comp = cfg['GUID_components']

    # borrowed fallback logic from generate_guid
    sampleint = guid_comp['sample']
    if sampleint == 0:
        sampleint = int('a' * 8, base=16)

    for i in range(2, len(lines)):
        split_line = re.split(r'\s+', lines[i].strip())
        mydict = {headers[j]: split_line[j] for j in range(len(split_line))}
        ds = load_by_guid(guids[i - 2], conn=target_conn)
        assert ds.captured_run_id == int(mydict['captured_run_id'])
        assert ds.captured_counter == int(mydict['captured_counter'])
        assert ds.exp_name == mydict['experiment_name']
        assert ds.sample_name == mydict['sample_name']
        assert int(mydict['sample_id']) == sampleint
        assert guid_comp['location'] == int(mydict['location'])
        assert guid_comp['work_station'] == int(mydict['work_station'])
Exemple #16
0
def test_filter_guid(locs, stats, smpls):
    def make_test_guid(cfg, loc: int, smpl: int, stat: int):
        cfg['GUID_components']['location'] = loc
        cfg['GUID_components']['work_station'] = stat
        cfg['GUID_components']['sample'] = smpl
        cfg.save_to_home()

        guid = generate_guid()
        gen_time = int(np.round(time.time() * 1000))

        comps = parse_guid(guid)

        assert comps['location'] == loc
        assert comps['work_station'] == stat
        assert comps['sample'] == smpl
        assert comps['time'] - gen_time < 2

        return guid

    with protected_config():

        guids = []
        cfg = Config()

        corrected_smpls = [
            smpl if smpl != 0 else int('a' * 8, base=16) for smpl in smpls
        ]
        # there is a possibility that we could generate 0 and 2863311530, which
        # are considered equivalent since int('a' * 8, base=16) == 2863311530.
        # We want unique samples, so we exclude this case.
        assume(corrected_smpls[0] != corrected_smpls[1])

        # first we generate a guid that we are going to match against
        guids.append(make_test_guid(cfg, locs[0], corrected_smpls[0],
                                    stats[0]))

        # now generate some guids that will not match because one of the
        # components changed
        guids.append(make_test_guid(cfg, locs[1], corrected_smpls[0],
                                    stats[0]))
        guids.append(make_test_guid(cfg, locs[0], corrected_smpls[1],
                                    stats[0]))
        guids.append(make_test_guid(cfg, locs[0], corrected_smpls[0],
                                    stats[1]))

        assert len(guids) == 4

        # first filter on all parts. This should give exactly one matching guid
        filtered_guids = filter_guids_by_parts(guids,
                                               location=locs[0],
                                               sample_id=corrected_smpls[0],
                                               work_station=stats[0])

        assert len(filtered_guids) == 1
        assert filtered_guids[0] == guids[0]

        # now filter on 2 components
        filtered_guids = filter_guids_by_parts(guids,
                                               location=locs[0],
                                               sample_id=corrected_smpls[0])
        assert len(filtered_guids) == 2
        assert filtered_guids[0] == guids[0]
        assert filtered_guids[1] == guids[3]

        filtered_guids = filter_guids_by_parts(guids,
                                               location=locs[0],
                                               work_station=stats[0])
        assert len(filtered_guids) == 2
        assert filtered_guids[0] == guids[0]
        assert filtered_guids[1] == guids[2]

        filtered_guids = filter_guids_by_parts(guids,
                                               sample_id=corrected_smpls[0],
                                               work_station=stats[0])
        assert len(filtered_guids) == 2
        assert filtered_guids[0] == guids[0]
        assert filtered_guids[1] == guids[1]

        # now filter on 1 component
        filtered_guids = filter_guids_by_parts(guids, location=locs[0])
        assert len(filtered_guids) == 3
        assert filtered_guids[0] == guids[0]
        assert filtered_guids[1] == guids[2]
        assert filtered_guids[2] == guids[3]

        filtered_guids = filter_guids_by_parts(guids, work_station=stats[0])
        assert len(filtered_guids) == 3
        assert filtered_guids[0] == guids[0]
        assert filtered_guids[1] == guids[1]
        assert filtered_guids[2] == guids[2]

        filtered_guids = filter_guids_by_parts(
            guids,
            sample_id=corrected_smpls[0],
        )
        assert len(filtered_guids) == 3
        assert filtered_guids[0] == guids[0]
        assert filtered_guids[1] == guids[1]
        assert filtered_guids[2] == guids[3]
Exemple #17
0
 def setUp(self):
     self.conf = Config()
Exemple #18
0
class TestConfig(TestCase):
    def setUp(self):
        self.conf = Config()

    def test_missing_config_file(self):
        with self.assertRaises(FileNotFoundError):
            self.conf.load_config("./missing.json")

    @patch.object(Config, 'current_schema', new_callable=PropertyMock)
    @patch.object(Config, 'env_file_name', new_callable=PropertyMock)
    @patch.object(Config, 'load_config')
    @patch('os.path.isfile')
    @unittest.skipIf(Path.cwd() == Path.home(),
                     'This test requires that working dir is different from'
                     'homedir.')
    def test_default_config_files(self, isfile, load_config, env, schema):
        # don't try to load custom schemas
        self.conf.schema_cwd_file_name = None
        self.conf.schema_home_file_name = None
        self.conf.schema_env_file_name = None
        schema.return_value = SCHEMA
        env.return_value = ENV_KEY
        isfile.return_value = True
        load_config.side_effect = partial(side_effect, GOOD_CONFIG_MAP)
        self.conf.defaults, self.defaults_schema = self.conf.load_default()
        config = self.conf.update_config()
        self.assertEqual(config, CONFIG)

    @patch.object(Config, 'current_schema', new_callable=PropertyMock)
    @patch.object(Config, 'env_file_name', new_callable=PropertyMock)
    @patch.object(Config, 'load_config')
    @patch('os.path.isfile')
    @unittest.skipIf(Path.cwd() == Path.home(),
                     'This test requires that working dir is different from'
                     'homedir.')
    def test_bad_config_files(self, isfile, load_config, env, schema):
        # don't try to load custom schemas
        self.conf.schema_cwd_file_name = None
        self.conf.schema_home_file_name = None
        self.conf.schema_env_file_name = None
        schema.return_value = SCHEMA
        env.return_value = ENV_KEY
        isfile.return_value = True
        load_config.side_effect = partial(side_effect, BAD_CONFIG_MAP)
        with self.assertRaises(jsonschema.exceptions.ValidationError):
            self.conf.defaults, self.defaults_schema = self.conf.load_default()
            self.conf.update_config()

    @patch.object(Config, 'current_schema', new_callable=PropertyMock)
    @patch.object(Config, 'env_file_name', new_callable=PropertyMock)
    @patch.object(Config, 'load_config')
    @patch('os.path.isfile')
    @patch("builtins.open", mock_open(read_data=USER_SCHEMA))
    @unittest.skipIf(Path.cwd() == Path.home(),
                     'This test requires that working dir is different from'
                     'homedir.')
    def test_user_schema(self, isfile, load_config, env, schema):
        schema.return_value = copy.deepcopy(SCHEMA)
        env.return_value = ENV_KEY
        isfile.return_value = True
        load_config.side_effect = partial(side_effect, GOOD_CONFIG_MAP)
        self.conf.defaults, self.defaults_schema = self.conf.load_default()
        config = self.conf.update_config()
        self.assertEqual(config, CONFIG)

    @patch.object(Config, 'current_schema', new_callable=PropertyMock)
    @patch.object(Config, 'env_file_name', new_callable=PropertyMock)
    @patch.object(Config, 'load_config')
    @patch('os.path.isfile')
    @patch("builtins.open", mock_open(read_data=USER_SCHEMA))
    def test_bad_user_schema(self, isfile, load_config, env, schema):
        schema.return_value = copy.deepcopy(SCHEMA)
        env.return_value = ENV_KEY
        isfile.return_value = True
        load_config.side_effect = partial(side_effect, BAD_CONFIG_MAP)
        with self.assertRaises(jsonschema.exceptions.ValidationError):
            self.conf.defaults, self.defaults_schema = self.conf.load_default()
            self.conf.update_config()

    @patch.object(Config, "current_config", new_callable=PropertyMock)
    def test_update_user_config(self, config):
        # deep copy because we mutate state
        config.return_value = copy.deepcopy(CONFIG)
        self.conf.add("foo", "bar")
        self.assertEqual(self.conf.current_config, UPDATED_CONFIG)

    @patch.object(Config, 'current_schema', new_callable=PropertyMock)
    @patch.object(Config, "current_config", new_callable=PropertyMock)
    def test_update_and_validate_user_config(self, config, schema):
        self.maxDiff = None
        schema.return_value = copy.deepcopy(SCHEMA)
        # deep copy because we mutate state
        config.return_value = copy.deepcopy(CONFIG)
        self.conf.add("foo", "bar", "string", "foo", "bar")
        self.assertEqual(self.conf.current_config, UPDATED_CONFIG)
        self.assertEqual(self.conf.current_schema, UPDATED_SCHEMA)