Пример #1
0
def test_load_by_X_functions(two_empty_temp_db_connections, some_interdeps):
    """
    Test some different loading functions
    """
    source_conn, target_conn = two_empty_temp_db_connections

    source_path = path_to_dbfile(source_conn)
    target_path = path_to_dbfile(target_conn)

    source_exp1 = Experiment(conn=source_conn)
    source_ds_1_1 = DataSet(conn=source_conn, exp_id=source_exp1.exp_id)

    source_exp2 = Experiment(conn=source_conn)
    source_ds_2_1 = DataSet(conn=source_conn, exp_id=source_exp2.exp_id)

    source_ds_2_2 = DataSet(conn=source_conn,
                            exp_id=source_exp2.exp_id,
                            name="customname")

    for ds in (source_ds_1_1, source_ds_2_1, source_ds_2_2):
        ds.set_interdependencies(some_interdeps[1])
        ds.mark_started()
        ds.add_result({name: 0.0 for name in some_interdeps[1].names})
        ds.mark_completed()

    extract_runs_into_db(source_path, target_path, source_ds_2_2.run_id)

    test_ds = load_by_guid(source_ds_2_2.guid, target_conn)
    assert source_ds_2_2.the_same_dataset_as(test_ds)

    test_ds = load_by_id(1, target_conn)
    assert source_ds_2_2.the_same_dataset_as(test_ds)

    test_ds = load_by_counter(1, 1, target_conn)
    assert source_ds_2_2.the_same_dataset_as(test_ds)
Пример #2
0
def test_load_experiment_by_name_duplicate_name(empty_temp_db):
    exp1 = Experiment(exp_id=None, name="exp")
    exp2 = Experiment(exp_id=None, name="exp")

    repr_str_1_2 = (f"Many experiments matching your request found:\n"
                    f"exp_id:{exp1.exp_id} ({exp1.name}-{exp1.sample_name}) "
                    f"started at ({exp1.started_at})\n"
                    f"exp_id:{exp2.exp_id} ({exp2.name}-{exp2.sample_name}) "
                    f"started at ({exp2.started_at})")
    repr_str_1_2_regex = re.escape(repr_str_1_2)
    with pytest.raises(ValueError, match=repr_str_1_2_regex):
        load_experiment_by_name("exp", "some_sample")

    last_exp = load_experiment_by_name("exp", load_last_duplicate=True)
    assert last_exp.name == "exp"
    assert last_exp.sample_name == "some_sample"
    assert last_exp.exp_id == 2

    exp3 = Experiment(exp_id=None, name="exp", sample_name="my_sample")
    repr_str_1_2_3 = (repr_str_1_2 + "\n" +
                      f"exp_id:{exp3.exp_id} ({exp3.name}-{exp3.sample_name}) "
                      f"started at ({exp3.started_at})")
    repr_str_1_2_3_regex = re.escape(repr_str_1_2_3)
    with pytest.raises(ValueError, match=repr_str_1_2_3_regex):
        load_experiment_by_name("exp")
    last_exp = load_experiment_by_name("exp", load_last_duplicate=True)
    assert last_exp.name == "exp"
    assert last_exp.sample_name == "my_sample"
    assert last_exp.exp_id == 3

    exp3_loaded = load_experiment_by_name('exp', 'my_sample')
    assert_experiments_equal(exp3, exp3_loaded)
def test_has_attributes_after_init():
    """
    Ensure that all attributes are populated after __init__ in BOTH cases
    (exp_id is None / exp_id is not None)
    """

    attrs = [
        'name', 'sample_name', 'last_counter', 'path_to_db', 'conn',
        'started_at', 'finished_at'
    ]

    # This creates an experiment in the db
    exp1 = Experiment(exp_id=None)

    # This loads the experiment that we just created
    exp2 = Experiment(exp_id=1)

    # This tries to load an experiment that we don't have
    with pytest.raises(ValueError, match='No such experiment in the database'):
        Experiment(exp_id=2)

    for exp in (exp1, exp2):
        for attr in attrs:
            assert hasattr(exp, attr)
            getattr(exp, attr)
Пример #4
0
def test_runs_from_different_experiments_raises(two_empty_temp_db_connections,
                                                some_paramspecs):
    """
    Test that inserting runs from multiple experiments raises
    """
    source_conn, target_conn = two_empty_temp_db_connections

    source_path = path_to_dbfile(source_conn)
    target_path = path_to_dbfile(target_conn)

    source_exp_1 = Experiment(conn=source_conn)
    source_exp_2 = Experiment(conn=source_conn)

    # make 5 runs in first experiment

    exp_1_run_ids = []
    for _ in range(5):

        source_dataset = DataSet(conn=source_conn, exp_id=source_exp_1.exp_id)
        exp_1_run_ids.append(source_dataset.run_id)

        for ps in some_paramspecs[2].values():
            source_dataset.add_parameter(ps)

        source_dataset.mark_started()

        for val in range(10):
            source_dataset.add_result(
                {ps.name: val
                 for ps in some_paramspecs[2].values()})
        source_dataset.mark_completed()

    # make 5 runs in second experiment

    exp_2_run_ids = []
    for _ in range(5):

        source_dataset = DataSet(conn=source_conn, exp_id=source_exp_2.exp_id)
        exp_2_run_ids.append(source_dataset.run_id)

        for ps in some_paramspecs[2].values():
            source_dataset.add_parameter(ps)

        source_dataset.mark_started()

        for val in range(10):
            source_dataset.add_result(
                {ps.name: val
                 for ps in some_paramspecs[2].values()})
        source_dataset.mark_completed()

    run_ids = exp_1_run_ids + exp_2_run_ids
    source_exp_ids = np.unique([1, 2])
    matchstring = ('Did not receive runs from a single experiment\\. '
                   f'Got runs from experiments {source_exp_ids}')
    # make the matchstring safe to use as a regexp
    matchstring = matchstring.replace('[', '\\[').replace(']', '\\]')
    with pytest.raises(ValueError, match=matchstring):
        extract_runs_into_db(source_path, target_path, *run_ids)
Пример #5
0
def generate_DB_file_with_some_runs():
    """
    Generate a .db-file with a handful of runs with some interdependent
    parameters
    """

    # This function will run often on CI and re-generate the .db-files
    # That should ideally be a deterministic action
    # (although this hopefully plays no role)
    np.random.seed(0)

    v2fixturepath = os.path.join(fixturepath, 'version2')
    os.makedirs(v2fixturepath, exist_ok=True)
    path = os.path.join(v2fixturepath, 'some_runs.db')

    if os.path.exists(path):
        os.remove(path)

    from qcodes.dataset.sqlite_base import connect, new_experiment
    from qcodes.dataset.measurements import Measurement
    from qcodes.dataset.experiment_container import Experiment
    from qcodes import Parameter

    conn = connect(path)
    exp = Experiment(path)
    exp._new(name='experiment_1', sample_name='no_sample_1')

    # Now make some parameters to use in measurements
    params = []
    for n in range(5):
        params.append(
            Parameter(f'p{n}',
                      label=f'Parameter {n}',
                      unit=f'unit {n}',
                      set_cmd=None,
                      get_cmd=None))

    # Set up an experiment

    meas = Measurement(exp)
    meas.register_parameter(params[0])
    meas.register_parameter(params[1])
    meas.register_parameter(params[2], basis=(params[0], ))
    meas.register_parameter(params[3], basis=(params[1], ))
    meas.register_parameter(params[4], setpoints=(params[2], params[3]))

    # Make a number of identical runs

    for _ in range(10):

        with meas.run() as datasaver:

            for x in np.random.rand(10):
                for y in np.random.rand(10):
                    z = np.random.rand()
                    datasaver.add_result((params[2], x), (params[3], y),
                                         (params[4], z))
Пример #6
0
def test_experiments_with_NULL_sample_name(two_empty_temp_db_connections,
                                           some_paramspecs):
    """
    In older API versions (corresponding to DB version 3),
    users could get away with setting the sample name to None

    This test checks that such an experiment gets correctly recognised and
    is thus not ever re-inserted into the target DB
    """
    source_conn, target_conn = two_empty_temp_db_connections
    source_exp_1 = Experiment(conn=source_conn, name='null_sample_name')

    source_path = path_to_dbfile(source_conn)
    target_path = path_to_dbfile(target_conn)

    # make 5 runs in experiment

    exp_1_run_ids = []
    for _ in range(5):

        source_dataset = DataSet(conn=source_conn, exp_id=source_exp_1.exp_id)
        exp_1_run_ids.append(source_dataset.run_id)

        for ps in some_paramspecs[2].values():
            source_dataset.add_parameter(ps)
        source_dataset.mark_started()

        for val in range(10):
            source_dataset.add_result(
                {ps.name: val
                 for ps in some_paramspecs[2].values()})
        source_dataset.mark_completed()

    sql = """
          UPDATE experiments
          SET sample_name = NULL
          WHERE exp_id = 1
          """
    source_conn.execute(sql)
    source_conn.commit()

    assert source_exp_1.sample_name is None

    extract_runs_into_db(source_path, target_path, 1, 2, 3, 4, 5)

    assert len(get_experiments(target_conn)) == 1

    extract_runs_into_db(source_path, target_path, 1, 2, 3, 4, 5)

    assert len(get_experiments(target_conn)) == 1

    assert len(Experiment(exp_id=1, conn=target_conn)) == 5
def test_load_by_X_functions(two_empty_temp_db_connections,
                             some_interdeps):
    """
    Test some different loading functions
    """
    source_conn, target_conn = two_empty_temp_db_connections

    source_path = path_to_dbfile(source_conn)
    target_path = path_to_dbfile(target_conn)

    source_exp1 = Experiment(conn=source_conn)
    source_ds_1_1 = DataSet(conn=source_conn, exp_id=source_exp1.exp_id)

    source_exp2 = Experiment(conn=source_conn)
    source_ds_2_1 = DataSet(conn=source_conn, exp_id=source_exp2.exp_id)

    source_ds_2_2 = DataSet(conn=source_conn,
                            exp_id=source_exp2.exp_id,
                            name="customname")

    for ds in (source_ds_1_1, source_ds_2_1, source_ds_2_2):
        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()

    extract_runs_into_db(source_path, target_path, source_ds_2_2.run_id)
    extract_runs_into_db(source_path, target_path, source_ds_2_1.run_id)
    extract_runs_into_db(source_path, target_path, source_ds_1_1.run_id)

    test_ds = load_by_guid(source_ds_2_2.guid, target_conn)
    assert source_ds_2_2.the_same_dataset_as(test_ds)

    test_ds = load_by_id(1, target_conn)
    assert source_ds_2_2.the_same_dataset_as(test_ds)

    test_ds = load_by_run_spec(captured_run_id=source_ds_2_2.captured_run_id,
                               conn=target_conn)
    assert source_ds_2_2.the_same_dataset_as(test_ds)

    assert source_exp2.exp_id == 2

    # this is now the first run in the db so run_id is 1
    target_run_id = 1
    # and the experiment ids will be interchanged.
    target_exp_id = 1

    test_ds = load_by_counter(target_run_id, target_exp_id, target_conn)
    assert source_ds_2_2.the_same_dataset_as(test_ds)
Пример #8
0
def generate_DB_file_with_empty_runs():
    """
    Generate a DB file that holds empty runs and runs with no interdependencies
    """

    v2fixturepath = os.path.join(fixturepath, 'version2')
    os.makedirs(v2fixturepath, exist_ok=True)
    path = os.path.join(v2fixturepath, 'empty_runs.db')

    if os.path.exists(path):
        os.remove(path)

    from qcodes.dataset.sqlite_base import connect
    from qcodes.dataset.measurements import Measurement
    from qcodes.dataset.experiment_container import Experiment
    from qcodes import Parameter
    from qcodes.dataset.data_set import DataSet

    conn = connect(path)
    exp = Experiment(path)
    exp._new(name='experiment_1', sample_name='no_sample_1')

    # Now make some parameters to use in measurements
    params = []
    for n in range(5):
        params.append(Parameter(f'p{n}', label=f'Parameter {n}',
                                unit=f'unit {n}', set_cmd=None, get_cmd=None))

    # truly empty run, no layouts table, no nothing
    dataset = DataSet(path, conn=conn)
    dataset._new('empty_dataset', exp_id=exp.exp_id)

    # empty run
    meas = Measurement(exp)
    with meas.run() as datasaver:
        pass

    # run with no interdeps
    meas = Measurement(exp)
    for param in params:
        meas.register_parameter(param)

    with meas.run() as datasaver:
        pass

    with meas.run() as datasaver:
        for _ in range(10):
            res = tuple((p, 0.0) for p in params)
            datasaver.add_result(*res)
Пример #9
0
def test_load_by_X_functions(two_empty_temp_db_connections, some_paramspecs):
    """
    Test some different loading functions
    """
    source_conn, target_conn = two_empty_temp_db_connections

    source_path = path_to_dbfile(source_conn)
    target_path = path_to_dbfile(target_conn)

    source_exp1 = Experiment(conn=source_conn)
    source_ds_1_1 = DataSet(conn=source_conn, exp_id=source_exp1.exp_id)
    for ps in some_paramspecs[2].values():
        source_ds_1_1.add_parameter(ps)
    source_ds_1_1.mark_started()
    source_ds_1_1.add_result(
        {ps.name: 0.0
         for ps in some_paramspecs[2].values()})
    source_ds_1_1.mark_completed()

    source_exp2 = Experiment(conn=source_conn)
    source_ds_2_1 = DataSet(conn=source_conn, exp_id=source_exp2.exp_id)
    for ps in some_paramspecs[2].values():
        source_ds_2_1.add_parameter(ps)
    source_ds_2_1.mark_started()
    source_ds_2_1.add_result(
        {ps.name: 0.0
         for ps in some_paramspecs[2].values()})
    source_ds_2_1.mark_completed()
    source_ds_2_2 = DataSet(conn=source_conn,
                            exp_id=source_exp2.exp_id,
                            name="customname")
    for ps in some_paramspecs[2].values():
        source_ds_2_2.add_parameter(ps)
    source_ds_2_2.mark_started()
    source_ds_2_2.add_result(
        {ps.name: 0.0
         for ps in some_paramspecs[2].values()})
    source_ds_2_2.mark_completed()

    extract_runs_into_db(source_path, target_path, source_ds_2_2.run_id)

    test_ds = load_by_guid(source_ds_2_2.guid, target_conn)
    assert source_ds_2_2.the_same_dataset_as(test_ds)

    test_ds = load_by_id(1, target_conn)
    assert source_ds_2_2.the_same_dataset_as(test_ds)

    test_ds = load_by_counter(1, 1, target_conn)
    assert source_ds_2_2.the_same_dataset_as(test_ds)
Пример #10
0
def test_result_table_naming_and_run_id(two_empty_temp_db_connections,
                                        some_paramspecs):
    """
    Check that a correct result table name is given and that a correct run_id
    is assigned
    """
    source_conn, target_conn = two_empty_temp_db_connections

    source_path = path_to_dbfile(source_conn)
    target_path = path_to_dbfile(target_conn)

    source_exp1 = Experiment(conn=source_conn)
    source_ds_1_1 = DataSet(conn=source_conn, exp_id=source_exp1.exp_id)
    for ps in some_paramspecs[2].values():
        source_ds_1_1.add_parameter(ps)
    source_ds_1_1.mark_started()
    source_ds_1_1.add_result(
        {ps.name: 0.0
         for ps in some_paramspecs[2].values()})
    source_ds_1_1.mark_completed()

    source_exp2 = Experiment(conn=source_conn)
    source_ds_2_1 = DataSet(conn=source_conn, exp_id=source_exp2.exp_id)
    for ps in some_paramspecs[2].values():
        source_ds_2_1.add_parameter(ps)
    source_ds_2_1.mark_started()
    source_ds_2_1.add_result(
        {ps.name: 0.0
         for ps in some_paramspecs[2].values()})
    source_ds_2_1.mark_completed()
    source_ds_2_2 = DataSet(conn=source_conn,
                            exp_id=source_exp2.exp_id,
                            name="customname")
    for ps in some_paramspecs[2].values():
        source_ds_2_2.add_parameter(ps)
    source_ds_2_2.mark_started()
    source_ds_2_2.add_result(
        {ps.name: 0.0
         for ps in some_paramspecs[2].values()})
    source_ds_2_2.mark_completed()

    extract_runs_into_db(source_path, target_path, source_ds_2_2.run_id)

    # The target ds ought to have a runs table "customname-1-1"
    # and ought to be the same dataset as its "ancestor"
    target_ds = DataSet(conn=target_conn, run_id=1)

    assert target_ds.table_name == "customname-1-1"
    assert target_ds.the_same_dataset_as(source_ds_2_2)
Пример #11
0
def test_load_experiment_by_name_duplicate_sample_name(empty_temp_db):
    exp1 = Experiment(exp_id=None, name='exp1', sample_name='sss')
    exp2 = Experiment(exp_id=None, name='exp2', sample_name='sss')

    exp1_loaded = load_experiment_by_name('exp1')
    assert_experiments_equal(exp1, exp1_loaded)

    exp2_loaded = load_experiment_by_name('exp2')
    assert_experiments_equal(exp2, exp2_loaded)

    exp1_loaded_with_sample = load_experiment_by_name('exp1', 'sss')
    assert_experiments_equal(exp1, exp1_loaded_with_sample)

    exp2_loaded_with_sample = load_experiment_by_name('exp2', 'sss')
    assert_experiments_equal(exp2, exp2_loaded_with_sample)
Пример #12
0
def test_integration_station_and_measurement(two_empty_temp_db_connections,
                                             inst):
    """
    An integration test where the runs in the source DB file are produced
    with the Measurement object and there is a Station as well
    """
    source_conn, target_conn = two_empty_temp_db_connections
    source_path = path_to_dbfile(source_conn)
    target_path = path_to_dbfile(target_conn)

    source_exp = Experiment(conn=source_conn)

    # Set up measurement scenario
    station = Station(inst)

    meas = Measurement(exp=source_exp, station=station)
    meas.register_parameter(inst.back)
    meas.register_parameter(inst.plunger)
    meas.register_parameter(inst.cutter, setpoints=(inst.back, inst.plunger))

    with meas.run() as datasaver:
        for back_v in [1, 2, 3]:
            for plung_v in [-3, -2.5, 0]:
                datasaver.add_result((inst.back, back_v),
                                     (inst.plunger, plung_v),
                                     (inst.cutter, back_v+plung_v))

    extract_runs_into_db(source_path, target_path, 1)

    target_ds = DataSet(conn=target_conn, run_id=1)

    assert datasaver.dataset.the_same_dataset_as(target_ds)
Пример #13
0
def test_format_string(empty_temp_db):
    # default format string
    exp1 = Experiment(exp_id=None)
    assert "{}-{}-{}" == exp1.format_string

    # custom format string
    fmt_str = "name_{}__id_{}__run_cnt_{}"
    exp2 = Experiment(exp_id=None, format_string=fmt_str)
    assert fmt_str == exp2.format_string

    # invalid format string
    fmt_str = "name_{}__id_{}__{}__{}"
    with pytest.raises(ValueError, match=r"Invalid format string. Can not "
                                         r"format \(name, exp_id, "
                                         r"run_counter\)"):
        _ = Experiment(exp_id=None, format_string=fmt_str)
Пример #14
0
def test_atomicity(two_empty_temp_db_connections, some_interdeps):
    """
    Test the atomicity of the transaction by extracting and inserting two
    runs where the second one is not completed. The not completed error must
    roll back any changes to the target
    """
    source_conn, target_conn = two_empty_temp_db_connections

    source_path = path_to_dbfile(source_conn)
    target_path = path_to_dbfile(target_conn)

    # The target file must exist for us to be able to see whether it has
    # changed
    Path(target_path).touch()

    source_exp = Experiment(conn=source_conn)
    source_ds_1 = DataSet(conn=source_conn, exp_id=source_exp.exp_id)
    source_ds_2 = DataSet(conn=source_conn, exp_id=source_exp.exp_id)

    for ds in (source_ds_1, source_ds_2):
        ds.set_interdependencies(some_interdeps[1])
        ds.mark_started()
        ds.add_result({name: 2.1 for name in some_interdeps[1].names})

    # importantly, source_ds_2 is NOT marked as completed
    source_ds_1.mark_completed()

    # now check that the target file is untouched
    with raise_if_file_changed(target_path):
        # although the not completed error is a ValueError, we get the
        # RuntimeError from SQLite
        with pytest.raises(RuntimeError):
            extract_runs_into_db(source_path, target_path, 1, 2)
Пример #15
0
def test_load_experiment_by_name(empty_temp_db):
    exp1 = Experiment(exp_id=None, name='myname')

    exp2 = load_experiment_by_name('myname')
    assert_experiments_equal(exp1, exp2)

    exp3 = load_experiment_by_name('myname', 'some_sample')
    assert_experiments_equal(exp1, exp3)

    exp4 = Experiment(exp_id=None, name='with_sample', sample_name='mysample')

    exp5 = load_experiment_by_name('with_sample')
    assert_experiments_equal(exp4, exp5)

    exp6 = load_experiment_by_name('with_sample', 'mysample')
    assert_experiments_equal(exp4, exp6)
Пример #16
0
def test_load_experiment_by_name_duplicate_name_and_sample_name(empty_temp_db):
    exp1 = Experiment(exp_id=None, name='exp', sample_name='sss')
    exp2 = Experiment(exp_id=None, name='exp', sample_name='sss')

    repr_str = f"Many experiments matching your request found:\n" \
               f"exp_id:{exp1.exp_id} ({exp1.name}-{exp1.sample_name}) " \
               f"started at ({exp1.started_at})\n" \
               f"exp_id:{exp2.exp_id} ({exp2.name}-{exp2.sample_name}) " \
               f"started at ({exp2.started_at})"
    repr_str_regex = re.escape(repr_str)

    with pytest.raises(ValueError, match=repr_str_regex):
        load_experiment_by_name('exp')

    with pytest.raises(ValueError, match=repr_str_regex):
        load_experiment_by_name('exp', 'sss')
Пример #17
0
def test_load_last_experiment(empty_temp_db):
    # test in case of no experiments
    with pytest.raises(ValueError, match='There are no experiments in the '
                                         'database file'):
        _ = load_last_experiment()

    # create 2 experiments
    exp1 = Experiment(exp_id=None)
    exp2 = Experiment(exp_id=None)
    assert get_DB_location() == exp1.path_to_db
    assert get_DB_location() == exp2.path_to_db

    # load last and assert that its the 2nd one that was created
    last_exp = load_last_experiment()
    assert last_exp.exp_id == exp2.exp_id
    assert last_exp.exp_id != exp1.exp_id
    assert last_exp.path_to_db == exp2.path_to_db
Пример #18
0
def test_load_experiment_by_name_defaults(empty_temp_db):
    exp1 = Experiment(exp_id=None)

    exp2 = load_experiment_by_name('experiment_1')
    assert_experiments_equal(exp1, exp2)

    exp3 = load_experiment_by_name('experiment_1', 'some_sample')
    assert_experiments_equal(exp1, exp3)
Пример #19
0
def test_column_mismatch(two_empty_temp_db_connections, some_interdeps, inst):
    """
    Test insertion of runs with no metadata and no snapshot into a DB already
    containing a run that has both
    """

    source_conn, target_conn = two_empty_temp_db_connections
    source_path = path_to_dbfile(source_conn)
    target_path = path_to_dbfile(target_conn)

    target_exp = Experiment(conn=target_conn)

    # Set up measurement scenario
    station = Station(inst)

    meas = Measurement(exp=target_exp, station=station)
    meas.register_parameter(inst.back)
    meas.register_parameter(inst.plunger)
    meas.register_parameter(inst.cutter, setpoints=(inst.back, inst.plunger))

    with meas.run() as datasaver:
        for back_v in [1, 2, 3]:
            for plung_v in [-3, -2.5, 0]:
                datasaver.add_result((inst.back, back_v),
                                     (inst.plunger, plung_v),
                                     (inst.cutter, back_v+plung_v))
    datasaver.dataset.add_metadata('meta_tag', 'meta_value')

    Experiment(conn=source_conn)
    source_ds = DataSet(conn=source_conn)
    source_ds.set_interdependencies(some_interdeps[1])

    source_ds.mark_started()
    source_ds.add_results([{name: 2.1
                            for name in some_interdeps[1].names}])
    source_ds.mark_completed()

    extract_runs_into_db(source_path, target_path, 1)

    # compare
    target_copied_ds = DataSet(conn=target_conn, run_id=2)

    assert target_copied_ds.the_same_dataset_as(source_ds)
Пример #20
0
def test_has_attributes_after_init():
    """
    Ensure that all attributes are populated after __init__ in BOTH cases
    (exp_id is None / exp_id is not None)
    """

    attrs = ['name', 'exp_id', '_exp_id', 'sample_name', 'last_counter',
             'path_to_db', 'conn', 'started_at',
             'finished_at', 'format_string']

    # This creates an experiment in the db
    exp1 = Experiment(exp_id=None)

    # This loads the experiment that we just created
    exp2 = Experiment(exp_id=1)

    for exp in (exp1, exp2):
        for attr in attrs:
            assert hasattr(exp, attr)
            getattr(exp, attr)
Пример #21
0
def test_load_experiment_by_name_bad_sample_name(empty_temp_db):
    Experiment(exp_id=None, sample_name='mysample')

    with pytest.raises(ValueError, match='Experiment not found'):
        _ = load_experiment_by_name('experiment_1', 'mysample__')

    with pytest.raises(ValueError, match='Experiment not found'):
        _ = load_experiment_by_name('experiment_1__', 'mysample')

    with pytest.raises(ValueError, match='Experiment not found'):
        _ = load_experiment_by_name('experiment_1__', 'mysample__')
Пример #22
0
def test_old_versions_not_touched(two_empty_temp_db_connections,
                                  some_interdeps):

    source_conn, target_conn = two_empty_temp_db_connections

    target_path = path_to_dbfile(target_conn)
    source_path = path_to_dbfile(source_conn)

    _, new_v = get_db_version_and_newest_available_version(source_path)

    fixturepath = os.sep.join(qcodes.tests.dataset.__file__.split(os.sep)[:-1])
    fixturepath = os.path.join(fixturepath,
                               'fixtures', 'db_files', 'version2',
                               'some_runs.db')
    if not os.path.exists(fixturepath):
        pytest.skip("No db-file fixtures found. You can generate test db-files"
                    " using the scripts in the legacy_DB_generation folder")

    # First test that we cannot use an old version as source

    with raise_if_file_changed(fixturepath):
        with pytest.warns(UserWarning) as warning:
            extract_runs_into_db(fixturepath, target_path, 1)
            expected_mssg = ('Source DB version is 2, but this '
                             f'function needs it to be in version {new_v}. '
                             'Run this function again with '
                             'upgrade_source_db=True to auto-upgrade '
                             'the source DB file.')
            assert warning[0].message.args[0] == expected_mssg

    # Then test that we cannot use an old version as target

    # first create a run in the new version source
    source_exp = Experiment(conn=source_conn)
    source_ds = DataSet(conn=source_conn, exp_id=source_exp.exp_id)

    source_ds.set_interdependencies(some_interdeps[1])

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

    with raise_if_file_changed(fixturepath):
        with pytest.warns(UserWarning) as warning:
            extract_runs_into_db(source_path, fixturepath, 1)
            expected_mssg = ('Target DB version is 2, but this '
                             f'function needs it to be in version {new_v}. '
                             'Run this function again with '
                             'upgrade_target_db=True to auto-upgrade '
                             'the target DB file.')
            assert warning[0].message.args[0] == expected_mssg
Пример #23
0
def test_load_experiment_by_name_duplicate_name(empty_temp_db):
    exp1 = Experiment(exp_id=None, name='exp')
    exp2 = Experiment(exp_id=None, name='exp')
    exp3 = Experiment(exp_id=None, name='exp', sample_name='my_sample')

    repr_str_1_2 = f"Many experiments matching your request found:\n" \
                   f"exp_id:{exp1.exp_id} ({exp1.name}-{exp1.sample_name}) " \
                   f"started at ({exp1.started_at})\n" \
                   f"exp_id:{exp2.exp_id} ({exp2.name}-{exp2.sample_name}) " \
                   f"started at ({exp2.started_at})"
    repr_str_1_2_3 = repr_str_1_2 + "\n" + \
        f"exp_id:{exp3.exp_id} ({exp3.name}-{exp3.sample_name}) " \
        f"started at ({exp3.started_at})"
    repr_str_1_2_regex = re.escape(repr_str_1_2)
    repr_str_1_2_3_regex = re.escape(repr_str_1_2_3)

    with pytest.raises(ValueError, match=repr_str_1_2_3_regex):
        load_experiment_by_name('exp')

    with pytest.raises(ValueError, match=repr_str_1_2_regex):
        load_experiment_by_name('exp', 'some_sample')

    exp3_loaded = load_experiment_by_name('exp', 'my_sample')
    assert_experiments_equal(exp3, exp3_loaded)
Пример #24
0
def test_extracting_dataless_run(two_empty_temp_db_connections):
    """
    Although contrived, it could happen that a run with no data is extracted
    """
    source_conn, target_conn = two_empty_temp_db_connections

    source_path = path_to_dbfile(source_conn)
    target_path = path_to_dbfile(target_conn)

    Experiment(conn=source_conn)

    source_ds = DataSet(conn=source_conn)
    source_ds.mark_started()
    source_ds.mark_completed()

    extract_runs_into_db(source_path, target_path, source_ds.run_id)

    loaded_ds = DataSet(conn=target_conn, run_id=1)

    assert loaded_ds.the_same_dataset_as(source_ds)
Пример #25
0
def test_missing_runs_raises(two_empty_temp_db_connections, some_paramspecs):
    """
    Test that an error is raised if we attempt to extract a run not present in
    the source DB
    """
    source_conn, target_conn = two_empty_temp_db_connections

    source_exp_1 = Experiment(conn=source_conn)

    # make 5 runs in first experiment

    exp_1_run_ids = []
    for _ in range(5):

        source_dataset = DataSet(conn=source_conn, exp_id=source_exp_1.exp_id)
        exp_1_run_ids.append(source_dataset.run_id)

        for ps in some_paramspecs[2].values():
            source_dataset.add_parameter(ps)

        source_dataset.mark_started()

        for val in range(10):
            source_dataset.add_result(
                {ps.name: val
                 for ps in some_paramspecs[2].values()})
        source_dataset.mark_completed()

    source_path = path_to_dbfile(source_conn)
    target_path = path_to_dbfile(target_conn)

    run_ids = [1, 8, 5, 3, 2, 4, 4, 4, 7, 8]
    wrong_ids = [8, 7, 8]

    expected_err = ("Error: not all run_ids exist in the source database. "
                    "The following run(s) is/are not present: "
                    f"{wrong_ids}")

    with pytest.raises(ValueError, match=re.escape(expected_err)):
        extract_runs_into_db(source_path, target_path, *run_ids)
Пример #26
0
def test_atomicity(two_empty_temp_db_connections, some_paramspecs):
    """
    Test the atomicity of the transaction by extracting and inserting two
    runs where the second one is not completed. The not completed error must
    roll back any changes to the target
    """
    source_conn, target_conn = two_empty_temp_db_connections

    source_path = path_to_dbfile(source_conn)
    target_path = path_to_dbfile(target_conn)

    # The target file must exist for us to be able to see whether it has
    # changed
    Path(target_path).touch()

    source_exp = Experiment(conn=source_conn)
    source_ds_1 = DataSet(conn=source_conn, exp_id=source_exp.exp_id)
    for ps in some_paramspecs[2].values():
        source_ds_1.add_parameter(ps)
    source_ds_1.mark_started()
    source_ds_1.add_result(
        {ps.name: 2.1
         for ps in some_paramspecs[2].values()})
    source_ds_1.mark_completed()

    source_ds_2 = DataSet(conn=source_conn, exp_id=source_exp.exp_id)
    for ps in some_paramspecs[2].values():
        source_ds_2.add_parameter(ps)
    source_ds_2.mark_started()
    source_ds_2.add_result(
        {ps.name: 2.1
         for ps in some_paramspecs[2].values()})
    # This dataset is NOT marked as completed

    # now check that the target file is untouched
    with raise_if_file_changed(target_path):
        # although the not completed error is a ValueError, we get the
        # RuntimeError from SQLite
        with pytest.raises(RuntimeError):
            extract_runs_into_db(source_path, target_path, 1, 2)
Пример #27
0
def test_correct_experiment_routing(two_empty_temp_db_connections,
                                    some_paramspecs):
    """
    Test that existing experiments are correctly identified AND that multiple
    insertions of the same runs don't matter (run insertion is idempotent)
    """
    source_conn, target_conn = two_empty_temp_db_connections

    source_exp_1 = Experiment(conn=source_conn)

    # make 5 runs in first experiment

    exp_1_run_ids = []
    for _ in range(5):

        source_dataset = DataSet(conn=source_conn, exp_id=source_exp_1.exp_id)
        exp_1_run_ids.append(source_dataset.run_id)

        for ps in some_paramspecs[2].values():
            source_dataset.add_parameter(ps)

        for val in range(10):
            source_dataset.add_result({ps.name: val
                                       for ps in some_paramspecs[2].values()})
        source_dataset.mark_complete()

    # make a new experiment with 1 run

    source_exp_2 = Experiment(conn=source_conn)
    ds = DataSet(conn=source_conn, exp_id=source_exp_2.exp_id, name="lala")
    exp_2_run_ids = [ds.run_id]

    for ps in some_paramspecs[2].values():
        ds.add_parameter(ps)

    for val in range(10):
        ds.add_result({ps.name: val for ps in some_paramspecs[2].values()})

    ds.mark_complete()

    source_path = path_to_dbfile(source_conn)
    target_path = path_to_dbfile(target_conn)

    # now copy 2 runs
    extract_runs_into_db(source_path, target_path, *exp_1_run_ids[:2])

    target_exp1 = Experiment(conn=target_conn, exp_id=1)

    assert len(target_exp1) == 2

    # copy two other runs, one of them already in
    extract_runs_into_db(source_path, target_path, *exp_1_run_ids[1:3])

    assert len(target_exp1) == 3

    # insert run from different experiment
    extract_runs_into_db(source_path, target_path, ds.run_id)

    assert len(target_exp1) == 3

    target_exp2 = Experiment(conn=target_conn, exp_id=2)

    assert len(target_exp2) == 1

    # finally insert every single run from experiment 1

    extract_runs_into_db(source_path, target_path, *exp_1_run_ids)

    # check for idempotency once more by inserting all the runs but in another
    # order
    with raise_if_file_changed(target_path):
        extract_runs_into_db(source_path, target_path, *exp_1_run_ids[::-1])

    target_exps = get_experiments(target_conn)

    assert len(target_exps) == 2
    assert len(target_exp1) == 5
    assert len(target_exp2) == 1

    # check that all the datasets match up
    for run_id in exp_1_run_ids + exp_2_run_ids:
        source_ds = DataSet(conn=source_conn, run_id=run_id)
        target_ds = load_by_guid(guid=source_ds.guid, conn=target_conn)

        assert source_ds.the_same_dataset_as(target_ds)

        source_data = source_ds.get_data(*source_ds.parameters.split(','))
        target_data = target_ds.get_data(*target_ds.parameters.split(','))

        assert source_data == target_data
Пример #28
0
def test_create_experiment_from_non_existing_id(non_existing_id):
    with pytest.raises(ValueError, match="No such experiment in the database"):
        _ = Experiment(exp_id=non_existing_id)
Пример #29
0
def generate_DB_file_with_some_runs_having_not_run_descriptions():
    """
    Generate a .db-file with a handful of runs some of which lack run
    description or have it as empty object (based on a real case).

    Generated runs:
        #1: run with parameters and correct run description
        #2: run with parameters but run description is NULL
        #3: run with parameters but run description is empty RunDescriber
        #4: run without parameters but run description is NULL
    """
    v3fixturepath = os.path.join(fixturepath, 'version3')
    os.makedirs(v3fixturepath, exist_ok=True)
    path = os.path.join(v3fixturepath, 'some_runs_without_run_description.db')

    if os.path.exists(path):
        os.remove(path)

    from qcodes.dataset.measurements import Measurement
    from qcodes.dataset.experiment_container import Experiment
    from qcodes import Parameter
    from qcodes.dataset.descriptions import RunDescriber
    from qcodes.dataset.dependencies import InterDependencies

    exp = Experiment(path_to_db=path,
                     name='experiment_1',
                     sample_name='no_sample_1')
    conn = exp.conn

    # Now make some parameters to use in measurements
    params = []
    for n in range(5):
        params.append(
            Parameter(f'p{n}',
                      label=f'Parameter {n}',
                      unit=f'unit {n}',
                      set_cmd=None,
                      get_cmd=None))

    # Set up a measurement

    meas = Measurement(exp)
    meas.register_parameter(params[0])
    meas.register_parameter(params[1])
    meas.register_parameter(params[2], basis=(params[0], ))
    meas.register_parameter(params[3], basis=(params[1], ))
    meas.register_parameter(params[4], setpoints=(params[2], params[3]))

    # Initially make 3 correct runs

    run_ids = []

    for _ in range(3):

        with meas.run() as datasaver:

            for x in np.random.rand(10):
                for y in np.random.rand(10):
                    z = np.random.rand()
                    datasaver.add_result((params[2], x), (params[3], y),
                                         (params[4], z))

        run_ids.append(datasaver.run_id)

    assert [1, 2, 3] == run_ids, 'Run ids of generated runs are not as ' \
                                 'expected after generating runs #1-3'

    # Formulate SQL query for adjusting run_description column

    set_run_description_sql = f"""
               UPDATE runs
               SET run_description = ?
               WHERE run_id == ?
               """

    # Make run_description of run #2 NULL

    conn.execute(set_run_description_sql, (None, run_ids[1]))
    conn.commit()  # just to be sure

    # Make run_description of run #3 equivalent to an empty RunDescriber

    empty_run_description = RunDescriber(InterDependencies()).to_json()
    conn.execute(set_run_description_sql, (empty_run_description, run_ids[2]))
    conn.commit()  # just to be sure

    # Set up a measurement without parameters, and create run #4 out of it

    meas_no_params = Measurement(exp)

    with meas_no_params.run() as datasaver:
        pass

    run_ids.append(datasaver.run_id)

    assert [1, 2, 3, 4] == run_ids, 'Run ids of generated runs are not as ' \
                                    'expected after generating run #4'

    # Make run_description of run #4 NULL

    conn.execute(set_run_description_sql, (None, run_ids[3]))
    conn.commit()  # just to be sure
Пример #30
0
def test_basic_extraction(two_empty_temp_db_connections, some_paramspecs):
    source_conn, target_conn = two_empty_temp_db_connections

    source_path = path_to_dbfile(source_conn)
    target_path = path_to_dbfile(target_conn)

    type_casters = {'numeric': float,
                    'array': (lambda x: np.array(x) if hasattr(x, '__iter__')
                              else np.array([x])),
                    'text': str}

    source_exp = Experiment(conn=source_conn)
    source_dataset = DataSet(conn=source_conn, name="basic_copy_paste_name")

    with pytest.raises(RuntimeError) as excinfo:
        extract_runs_into_db(source_path, target_path, source_dataset.run_id)

    assert error_caused_by(excinfo, ('Dataset not completed. An incomplete '
                                     'dataset can not be copied. The '
                                     'incomplete dataset has GUID: '
                                     f'{source_dataset.guid} and run_id: '
                                     f'{source_dataset.run_id}'))

    for ps in some_paramspecs[1].values():
        source_dataset.add_parameter(ps)

    for value in range(10):
        result = {ps.name: type_casters[ps.type](value)
                  for ps in some_paramspecs[1].values()}
        source_dataset.add_result(result)

    source_dataset.add_metadata('goodness', 'fair')
    source_dataset.add_metadata('test', True)

    source_dataset.mark_complete()

    extract_runs_into_db(source_path, target_path, source_dataset.run_id)

    target_exp = Experiment(conn=target_conn, exp_id=1)

    length1 = len(target_exp)
    assert length1 == 1

    # trying to insert the same run again should be a NOOP
    with raise_if_file_changed(target_path):
        extract_runs_into_db(source_path, target_path, source_dataset.run_id)

    assert len(target_exp) == length1

    target_dataset = DataSet(conn=target_conn, run_id=1)

    # Now make the interesting comparisons: are the target objects the same as
    # the source objects?

    assert source_dataset.the_same_dataset_as(target_dataset)

    source_data = source_dataset.get_data(*source_dataset.parameters.split(','))
    target_data = target_dataset.get_data(*target_dataset.parameters.split(','))

    assert source_data == target_data

    exp_attrs = ['name', 'sample_name', 'format_string', 'started_at',
                 'finished_at']

    for exp_attr in exp_attrs:
        assert getattr(source_exp, exp_attr) == getattr(target_exp, exp_attr)

    # trying to insert the same run again should be a NOOP
    with raise_if_file_changed(target_path):
        extract_runs_into_db(source_path, target_path, source_dataset.run_id)