def test_perform_actual_upgrade_2_to_3_empty(): v2fixpath = os.path.join(fixturepath, 'db_files', 'version2') dbname_old = os.path.join(v2fixpath, 'empty.db') if not os.path.exists(dbname_old): pytest.skip("No db-file fixtures found. You can generate test db-files" " using the scripts in the " "https://github.com/QCoDeS/qcodes_generate_test_db/ repo") with temporarily_copied_DB(dbname_old, debug=False, version=2) as conn: assert get_user_version(conn) == 2 desc_query = 'SELECT run_description FROM runs' with pytest.raises(RuntimeError) as excinfo: atomic_transaction(conn, desc_query) assert error_caused_by(excinfo, 'no such column: run_description') perform_db_upgrade_2_to_3(conn) assert get_user_version(conn) == 3 c = atomic_transaction(conn, desc_query) assert len(c.fetchall()) == 0
def test_perform_actual_upgrade_5_to_6(): fixpath = os.path.join(fixturepath, 'db_files', 'version5') db_file = 'empty.db' dbname_old = os.path.join(fixpath, db_file) if not os.path.exists(dbname_old): pytest.skip("No db-file fixtures found. You can generate test db-files" " using the scripts in the " "https://github.com/QCoDeS/qcodes_generate_test_db/ repo") with temporarily_copied_DB(dbname_old, debug=False, version=5) as conn: perform_db_upgrade_5_to_6(conn) assert get_user_version(conn) == 6 db_file = 'some_runs.db' dbname_old = os.path.join(fixpath, db_file) with temporarily_copied_DB(dbname_old, debug=False, version=5) as conn: perform_db_upgrade_5_to_6(conn) assert get_user_version(conn) == 6 no_of_runs_query = "SELECT max(run_id) FROM runs" no_of_runs = one( atomic_transaction(conn, no_of_runs_query), 'max(run_id)') assert no_of_runs == 10 for run_id in range(1, no_of_runs + 1): json_str = get_run_description(conn, run_id) deser = json.loads(json_str) assert deser['version'] == 0 desc = serial.from_json_to_current(json_str) assert desc._version == 1
def test_perform_actual_upgrade_0_to_1(): # we cannot use the empty_temp_db, since that has already called connect # and is therefore latest version already v0fixpath = os.path.join(fixturepath, 'db_files', 'version0') dbname_old = os.path.join(v0fixpath, 'empty.db') if not os.path.exists(dbname_old): pytest.skip("No db-file fixtures found. You can generate test db-files" " using the scripts in the " "https://github.com/QCoDeS/qcodes_generate_test_db/ repo") with temporarily_copied_DB(dbname_old, debug=False, version=0) as conn: assert get_user_version(conn) == 0 guid_table_query = "SELECT guid FROM runs" with pytest.raises(RuntimeError) as excinfo: atomic_transaction(conn, guid_table_query) assert error_caused_by(excinfo, 'no such column: guid') perform_db_upgrade_0_to_1(conn) assert get_user_version(conn) == 1 c = atomic_transaction(conn, guid_table_query) assert len(c.fetchall()) == 0
def fix_version_4a_run_description_bug(conn: ConnectionPlus) -> Dict[str, int]: """ Fix function to fix a bug where the RunDescriber accidentally wrote itself to string using the (new) InterDependencies_ object instead of the (old) InterDependencies object. After the first call, this function should be idempotent. Args: conn: the connection to the database Returns: A dict with the fix results ('runs_inspected', 'runs_fixed') """ user_version = get_user_version(conn) if not user_version == 4: raise RuntimeError('Database of wrong version. Will not apply fix. ' 'Expected version 4, found version {user_version}') no_of_runs_query = "SELECT max(run_id) FROM runs" no_of_runs = one(atomic_transaction(conn, no_of_runs_query), 'max(run_id)') no_of_runs = no_of_runs or 0 with atomic(conn) as conn: pbar = tqdm(range(1, no_of_runs+1)) pbar.set_description("Fixing database") # collect some metrics runs_inspected = 0 runs_fixed = 0 old_style_keys = ['paramspecs'] new_style_keys = ['parameters', 'dependencies', 'inferences', 'standalones'] for run_id in pbar: desc_str = get_run_description(conn, run_id) desc_ser = json.loads(desc_str) idps_ser = desc_ser['interdependencies'] if list(idps_ser.keys()) == old_style_keys: pass elif list(idps_ser.keys()) == new_style_keys: old_desc_ser = \ _convert_run_describer_v1_like_dict_to_v0_like_dict( desc_ser) json_str = json.dumps(old_desc_ser) _update_run_description(conn, run_id, json_str) runs_fixed += 1 else: raise RuntimeError(f'Invalid runs_description for run_id: ' f'{run_id}') runs_inspected += 1 return {'runs_inspected': runs_inspected, 'runs_fixed': runs_fixed}
def test_perform_actual_upgrade_1_to_2(): v1fixpath = os.path.join(fixturepath, 'db_files', 'version1') dbname_old = os.path.join(v1fixpath, 'empty.db') if not os.path.exists(dbname_old): pytest.skip("No db-file fixtures found. You can generate test db-files" " using the scripts in the legacy_DB_generation folder") with temporarily_copied_DB(dbname_old, debug=False, version=1) as conn: assert get_user_version(conn) == 1 guid_table_query = "SELECT guid FROM runs" c = atomic_transaction(conn, guid_table_query) assert len(c.fetchall()) == 0 index_query = "PRAGMA index_list(runs)" c = atomic_transaction(conn, index_query) assert len(c.fetchall()) == 0 perform_db_upgrade_1_to_2(conn) c = atomic_transaction(conn, index_query) assert len(c.fetchall()) == 2
def test_fix_wrong_run_descriptions(): v3fixpath = os.path.join(fixturepath, 'db_files', 'version3') dbname_old = os.path.join(v3fixpath, 'some_runs_without_run_description.db') if not os.path.exists(dbname_old): pytest.skip( "No db-file fixtures found. You can generate test db-files" " using the scripts in the legacy_DB_generation folder") with temporarily_copied_DB(dbname_old, debug=False, version=3) as conn: assert get_user_version(conn) == 3 ds1 = DataSet(conn=conn, run_id=1) expected_description = ds1.description empty_description = RunDescriber(InterDependencies_()) fix_wrong_run_descriptions(conn, [1, 2, 3, 4]) ds2 = DataSet(conn=conn, run_id=2) assert expected_description == ds2.description ds3 = DataSet(conn=conn, run_id=3) assert expected_description == ds3.description ds4 = DataSet(conn=conn, run_id=4) assert empty_description == ds4.description
def connect(name: Union[str, Path], debug: bool = False, version: int = -1) -> ConnectionPlus: """ Connect or create database. If debug the queries will be echoed back. This function takes care of registering the numpy/sqlite type converters that we need. Args: name: name or path to the sqlite file debug: whether or not to turn on tracing version: which version to create. We count from 0. -1 means 'latest'. Should always be left at -1 except when testing. Returns: conn: connection object to the database (note, it is `ConnectionPlus`, not `sqlite3.Connection` """ # register numpy->binary(TEXT) adapter sqlite3.register_adapter(np.ndarray, _adapt_array) # register binary(TEXT) -> numpy converter sqlite3.register_converter("array", _convert_array) sqlite3_conn = sqlite3.connect(name, detect_types=sqlite3.PARSE_DECLTYPES, check_same_thread=True) conn = ConnectionPlus(sqlite3_conn) latest_supported_version = _latest_available_version() db_version = get_user_version(conn) if db_version > latest_supported_version: raise RuntimeError(f"Database {name} is version {db_version} but this " f"version of QCoDeS supports up to " f"version {latest_supported_version}") # sqlite3 options conn.row_factory = sqlite3.Row # Make sure numpy ints and floats types are inserted properly for numpy_int in numpy_ints: sqlite3.register_adapter(numpy_int, int) sqlite3.register_converter("numeric", _convert_numeric) for numpy_float in (float,) + numpy_floats: sqlite3.register_adapter(numpy_float, _adapt_float) for complex_type in complex_types: sqlite3.register_adapter(complex_type, _adapt_complex) sqlite3.register_converter("complex", _convert_complex) if debug: conn.set_trace_callback(print) init_db(conn) perform_db_upgrade(conn, version=version) return conn
def test_cannot_connect_to_newer_db(): conn = connect(qc.config["core"]["db_location"], qc.config["core"]["db_debug"]) current_version = get_user_version(conn) set_user_version(conn, current_version+1) conn.close() err_msg = f'is version {current_version + 1} but this version of QCoDeS ' \ f'supports up to version {current_version}' with pytest.raises(RuntimeError, match=err_msg): conn = connect(qc.config["core"]["db_location"], qc.config["core"]["db_debug"])
def fix_version_4a_run_description_bug(conn: ConnectionPlus) -> Dict[str, int]: """ Fix function to fix a bug where the RunDescriber accidentally wrote itself to string using the (new) InterDependencies_ object instead of the (old) InterDependencies object. After the first run, this function should be idempotent. Args: conn: the connection to the database Returns: A dict with the fix results ('runs_inspected', 'runs_fixed') """ user_version = get_user_version(conn) if not user_version == 4: raise RuntimeError('Database of wrong version. Will not apply fix. ' 'Expected version 4, found version {user_version}') no_of_runs_query = "SELECT max(run_id) FROM runs" no_of_runs = one(atomic_transaction(conn, no_of_runs_query), 'max(run_id)') no_of_runs = no_of_runs or 0 with atomic(conn) as conn: pbar = tqdm(range(1, no_of_runs + 1)) pbar.set_description("Fixing database") # collect some metrics runs_inspected = 0 runs_fixed = 0 for run_id in pbar: desc_str = get_run_description(conn, run_id) desc_ser = json.loads(desc_str) idps_ser = desc_ser['interdependencies'] if RunDescriber._is_description_old_style(idps_ser): pass else: new_desc = RunDescriber.from_json(desc_str) update_run_description(conn, run_id, new_desc.to_json()) runs_fixed += 1 runs_inspected += 1 return {'runs_inspected': runs_inspected, 'runs_fixed': runs_fixed}
def test_perform_actual_upgrade_6_to_7(): fixpath = os.path.join(fixturepath, 'db_files', 'version6') db_file = 'some_runs.db' dbname_old = os.path.join(fixpath, db_file) if not os.path.exists(dbname_old): pytest.skip("No db-file fixtures found. You can generate test db-files" " using the scripts in the " "https://github.com/QCoDeS/qcodes_generate_test_db/ repo") with temporarily_copied_DB(dbname_old, debug=False, version=6) as conn: assert isinstance(conn, ConnectionPlus) perform_db_upgrade_6_to_7(conn) assert get_user_version(conn) == 7 no_of_runs_query = "SELECT max(run_id) FROM runs" no_of_runs = one(atomic_transaction(conn, no_of_runs_query), 'max(run_id)') assert no_of_runs == 10 columns = atomic_transaction(conn, "PRAGMA table_info(runs)").fetchall() col_names = [col['name'] for col in columns] assert 'captured_run_id' in col_names assert 'captured_counter' in col_names for run_id in range(1, no_of_runs + 1): ds1 = load_by_id(run_id, conn) ds2 = load_by_run_spec(captured_run_id=run_id, conn=conn) assert ds1.the_same_dataset_as(ds2) assert ds1.run_id == run_id assert ds1.run_id == ds1.captured_run_id assert ds2.run_id == run_id assert ds2.run_id == ds2.captured_run_id exp_id = 1 for counter in range(1, no_of_runs + 1): ds1 = load_by_counter(counter, exp_id, conn) ds2 = load_by_run_spec(captured_counter=counter, conn=conn) assert ds1.the_same_dataset_as(ds2) assert ds1.counter == counter assert ds1.counter == ds1.captured_counter assert ds2.counter == counter assert ds2.counter == ds2.captured_counter
def test_perform_upgrade_6_7(): fixpath = os.path.join(fixturepath, 'db_files', 'version6') db_file = 'empty.db' dbname_old = os.path.join(fixpath, db_file) if not os.path.exists(dbname_old): pytest.skip("No db-file fixtures found. You can generate test db-files" " using the scripts in the " "https://github.com/QCoDeS/qcodes_generate_test_db/ repo") with temporarily_copied_DB(dbname_old, debug=False, version=6) as conn: perform_db_upgrade_6_to_7(conn) assert get_user_version(conn) == 7
def get_db_version_and_newest_available_version( path_to_db: str) -> Tuple[int, int]: """ Connect to a DB without performing any upgrades and get the version of that database file along with the newest available version (the one that a normal "connect" will automatically upgrade to) Args: path_to_db: the absolute path to the DB file Returns: A tuple of (db_version, latest_available_version) """ conn = connect(path_to_db, version=0) db_version = get_user_version(conn) return db_version, _latest_available_version()
def test_fix_wrong_run_descriptions(): v3fixpath = os.path.join(fixturepath, 'db_files', 'version3') dbname_old = os.path.join(v3fixpath, 'some_runs_without_run_description.db') if not os.path.exists(dbname_old): pytest.skip("No db-file fixtures found. You can generate test db-files" " using the scripts in the legacy_DB_generation folder") def make_ps(n): ps = ParamSpec(f'p{n}', label=f'Parameter {n}', unit=f'unit {n}', paramtype='numeric') return ps paramspecs = [make_ps(n) for n in range(6)] paramspecs[2]._inferred_from = ['p0'] paramspecs[3]._inferred_from = ['p1', 'p0'] paramspecs[4]._depends_on = ['p2', 'p3'] paramspecs[5]._inferred_from = ['p0'] with temporarily_copied_DB(dbname_old, debug=False, version=3) as conn: assert get_user_version(conn) == 3 expected_description = v0.RunDescriber( v0.InterDependencies(*paramspecs)) empty_description = v0.RunDescriber(v0.InterDependencies()) fix_wrong_run_descriptions(conn, [1, 2, 3, 4]) for run_id in [1, 2, 3]: desc_str = get_run_description(conn, run_id) desc = serial.from_json_to_native(desc_str) assert desc == expected_description desc_str = get_run_description(conn, run_id=4) desc = serial.from_json_to_native(desc_str) assert desc == empty_description
def fix_wrong_run_descriptions(conn: ConnectionPlus, run_ids: Sequence[int]) -> None: """ NB: This is a FIX function. Do not use it unless your database has been diagnosed with the problem that this function fixes. Overwrite faulty run_descriptions by using information from the layouts and dependencies tables. If a correct description is found for a run, that run is left untouched. Args: conn: The connection to the database run_ids: The runs to (potentially) fix """ user_version = get_user_version(conn) if not user_version == 3: raise RuntimeError('Database of wrong version. Will not apply fix. ' 'Expected version 3, found version {user_version}') log.info('[*] Fixing run descriptions...') for run_id in run_ids: trusted_paramspecs = _get_parameters(conn, run_id) trusted_desc = v0.RunDescriber( v0.InterDependencies(*trusted_paramspecs)) actual_desc_str = select_one_where(conn, "runs", "run_description", "run_id", run_id) trusted_json = serial.to_json_as_version(trusted_desc, 0) if actual_desc_str == trusted_json: log.info(f'[+] Run id: {run_id} had an OK description') else: log.info(f'[-] Run id: {run_id} had a broken description. ' f'Description found: {actual_desc_str}') update_run_description(conn, run_id, trusted_json) log.info(f' Run id: {run_id} has been updated.')
def test_perform_actual_upgrade_2_to_3_some_runs(): v2fixpath = os.path.join(fixturepath, 'db_files', 'version2') dbname_old = os.path.join(v2fixpath, 'some_runs.db') if not os.path.exists(dbname_old): pytest.skip("No db-file fixtures found. You can generate test db-files" " using the scripts in the" "https://github.com/QCoDeS/qcodes_generate_test_db/ repo") with temporarily_copied_DB(dbname_old, debug=False, version=2) as conn: assert get_user_version(conn) == 2 perform_db_upgrade_2_to_3(conn) desc_query = 'SELECT run_description FROM runs' c = atomic_transaction(conn, desc_query) assert len(c.fetchall()) == 10 # retrieve the json string and recreate the object sql = f""" SELECT run_description FROM runs WHERE run_id == 1 """ c = atomic_transaction(conn, sql) json_str = one(c, 'run_description') unversioned_dict = json.loads(json_str) idp = InterDependencies._from_dict( unversioned_dict['interdependencies']) assert isinstance(idp, InterDependencies) # here we verify that the dependencies encoded in # tests/dataset/legacy_DB_generation/generate_version_2.py # are recovered p0 = [p for p in idp.paramspecs if p.name == 'p0'][0] assert p0.depends_on == '' assert p0.depends_on_ == [] assert p0.inferred_from == '' assert p0.inferred_from_ == [] assert p0.label == "Parameter 0" assert p0.unit == "unit 0" p1 = [p for p in idp.paramspecs if p.name == 'p1'][0] assert p1.depends_on == '' assert p1.depends_on_ == [] assert p1.inferred_from == '' assert p1.inferred_from_ == [] assert p1.label == "Parameter 1" assert p1.unit == "unit 1" p2 = [p for p in idp.paramspecs if p.name == 'p2'][0] assert p2.depends_on == '' assert p2.depends_on_ == [] assert p2.inferred_from == 'p0' assert p2.inferred_from_ == ['p0'] assert p2.label == "Parameter 2" assert p2.unit == "unit 2" p3 = [p for p in idp.paramspecs if p.name == 'p3'][0] assert p3.depends_on == '' assert p3.depends_on_ == [] assert p3.inferred_from == 'p1, p0' assert p3.inferred_from_ == ['p1', 'p0'] assert p3.label == "Parameter 3" assert p3.unit == "unit 3" p4 = [p for p in idp.paramspecs if p.name == 'p4'][0] assert p4.depends_on == 'p2, p3' assert p4.depends_on_ == ['p2', 'p3'] assert p4.inferred_from == '' assert p4.inferred_from_ == [] assert p4.label == "Parameter 4" assert p4.unit == "unit 4" p5 = [p for p in idp.paramspecs if p.name == 'p5'][0] assert p5.depends_on == '' assert p5.depends_on_ == [] assert p5.inferred_from == 'p0' assert p5.inferred_from_ == ['p0'] assert p5.label == "Parameter 5" assert p5.unit == "unit 5"
def connect(name: str, debug: bool = False, version: int = -1) -> ConnectionPlus: """ Connect or create database. If debug the queries will be echoed back. This function takes care of registering the numpy/sqlite type converters that we need. Args: name: name or path to the sqlite file debug: whether or not to turn on tracing version: which version to create. We count from 0. -1 means 'latest'. Should always be left at -1 except when testing. Returns: conn: connection object to the database (note, it is `ConnectionPlus`, not `sqlite3.Connection` """ # register numpy->binary(TEXT) adapter # the typing here is ignored due to what we think is a flaw in typeshed # see https://github.com/python/typeshed/issues/2429 sqlite3.register_adapter(np.ndarray, _adapt_array) # type: ignore # register binary(TEXT) -> numpy converter # for some reasons mypy complains about this sqlite3.register_converter("array", _convert_array) sqlite3_conn = sqlite3.connect(name, detect_types=sqlite3.PARSE_DECLTYPES) conn = ConnectionPlus(sqlite3_conn) latest_supported_version = _latest_available_version() db_version = get_user_version(conn) if db_version > latest_supported_version: raise RuntimeError(f"Database {name} is version {db_version} but this " f"version of QCoDeS supports up to " f"version {latest_supported_version}") # sqlite3 options conn.row_factory = sqlite3.Row # Make sure numpy ints and floats types are inserted properly for numpy_int in [ np.int, np.int8, np.int16, np.int32, np.int64, np.uint, np.uint8, np.uint16, np.uint32, np.uint64 ]: sqlite3.register_adapter(numpy_int, int) sqlite3.register_converter("numeric", _convert_numeric) for numpy_float in [np.float, np.float16, np.float32, np.float64]: sqlite3.register_adapter(numpy_float, _adapt_float) for complex_type in complex_types: sqlite3.register_adapter(complex_type, _adapt_complex) # type: ignore sqlite3.register_converter("complex", _convert_complex) if debug: conn.set_trace_callback(print) init_db(conn) perform_db_upgrade(conn, version=version) return conn
def test_perform_upgrade_v2_v3_to_v4_fixes(): """ Test that a db that was upgraded from v2 to v3 with a buggy version will be corrected when upgraded to v4. """ v3fixpath = os.path.join(fixturepath, 'db_files', 'version3') dbname_old = os.path.join(v3fixpath, 'some_runs_upgraded_2.db') if not os.path.exists(dbname_old): pytest.skip("No db-file fixtures found. You can generate test db-files" " using the scripts in the" " https://github.com/QCoDeS/qcodes_generate_test_db/ repo") with temporarily_copied_DB(dbname_old, debug=False, version=3) as conn: assert get_user_version(conn) == 3 sql = f""" SELECT run_description FROM runs WHERE run_id == 1 """ c = atomic_transaction(conn, sql) json_str = one(c, 'run_description') desc = RunDescriber.from_json(json_str) idp = desc.interdeps assert isinstance(idp, InterDependencies) p0 = [p for p in idp.paramspecs if p.name == 'p0'][0] assert p0.depends_on == '' assert p0.depends_on_ == [] assert p0.inferred_from == '' assert p0.inferred_from_ == [] assert p0.label == "Parameter 0" assert p0.unit == "unit 0" p1 = [p for p in idp.paramspecs if p.name == 'p1'][0] assert p1.depends_on == '' assert p1.depends_on_ == [] assert p1.inferred_from == '' assert p1.inferred_from_ == [] assert p1.label == "Parameter 1" assert p1.unit == "unit 1" p2 = [p for p in idp.paramspecs if p.name == 'p2'][0] assert p2.depends_on == '' assert p2.depends_on_ == [] # the 2 lines below are wrong due to the incorrect upgrade from # db version 2 to 3 assert p2.inferred_from == 'p, 0' assert p2.inferred_from_ == ['p', '0'] assert p2.label == "Parameter 2" assert p2.unit == "unit 2" p3 = [p for p in idp.paramspecs if p.name == 'p3'][0] assert p3.depends_on == '' assert p3.depends_on_ == [] # the 2 lines below are wrong due to the incorrect upgrade from # db version 2 to 3 assert p3.inferred_from == 'p, 1, ,, , p, 0' assert p3.inferred_from_ == ['p', '1', ',', ' ', 'p', '0'] assert p3.label == "Parameter 3" assert p3.unit == "unit 3" p4 = [p for p in idp.paramspecs if p.name == 'p4'][0] assert p4.depends_on == 'p2, p3' assert p4.depends_on_ == ['p2', 'p3'] assert p4.inferred_from == '' assert p4.inferred_from_ == [] assert p4.label == "Parameter 4" assert p4.unit == "unit 4" p5 = [p for p in idp.paramspecs if p.name == 'p5'][0] assert p5.depends_on == '' assert p5.depends_on_ == [] # the 2 lines below are wrong due to the incorrect upgrade from # db version 2 to 3. Here the interdep is missing assert p5.inferred_from == '' assert p5.inferred_from_ == [] assert p5.label == "Parameter 5" assert p5.unit == "unit 5" perform_db_upgrade_3_to_4(conn) c = atomic_transaction(conn, sql) json_str = one(c, 'run_description') desc = RunDescriber.from_json(json_str) idp = desc.interdeps assert isinstance(idp, InterDependencies) p0 = [p for p in idp.paramspecs if p.name == 'p0'][0] assert p0.depends_on == '' assert p0.depends_on_ == [] assert p0.inferred_from == '' assert p0.inferred_from_ == [] assert p0.label == "Parameter 0" assert p0.unit == "unit 0" p1 = [p for p in idp.paramspecs if p.name == 'p1'][0] assert p1.depends_on == '' assert p1.depends_on_ == [] assert p1.inferred_from == '' assert p1.inferred_from_ == [] assert p1.label == "Parameter 1" assert p1.unit == "unit 1" p2 = [p for p in idp.paramspecs if p.name == 'p2'][0] assert p2.depends_on == '' assert p2.depends_on_ == [] assert p2.inferred_from == 'p0' assert p2.inferred_from_ == ['p0'] assert p2.label == "Parameter 2" assert p2.unit == "unit 2" p3 = [p for p in idp.paramspecs if p.name == 'p3'][0] assert p3.depends_on == '' assert p3.depends_on_ == [] assert p3.inferred_from == 'p1, p0' assert p3.inferred_from_ == ['p1', 'p0'] assert p3.label == "Parameter 3" assert p3.unit == "unit 3" p4 = [p for p in idp.paramspecs if p.name == 'p4'][0] assert p4.depends_on == 'p2, p3' assert p4.depends_on_ == ['p2', 'p3'] assert p4.inferred_from == '' assert p4.inferred_from_ == [] assert p4.label == "Parameter 4" assert p4.unit == "unit 4" p5 = [p for p in idp.paramspecs if p.name == 'p5'][0] assert p5.depends_on == '' assert p5.depends_on_ == [] assert p5.inferred_from == 'p0' assert p5.inferred_from_ == ['p0'] assert p5.label == "Parameter 5" assert p5.unit == "unit 5"
def test_perform_upgrade_v3_to_v4(): """ Test that a db upgrade from v2 to v4 works correctly. """ v3fixpath = os.path.join(fixturepath, 'db_files', 'version3') dbname_old = os.path.join(v3fixpath, 'some_runs_upgraded_2.db') if not os.path.exists(dbname_old): pytest.skip("No db-file fixtures found. You can generate test db-files" " using the scripts in the " "https://github.com/QCoDeS/qcodes_generate_test_db/ repo") with temporarily_copied_DB(dbname_old, debug=False, version=3) as conn: assert get_user_version(conn) == 3 sql = f""" SELECT run_description FROM runs WHERE run_id == 1 """ perform_db_upgrade_3_to_4(conn) c = atomic_transaction(conn, sql) json_str = one(c, 'run_description') unversioned_dict = json.loads(json_str) idp = InterDependencies._from_dict( unversioned_dict['interdependencies']) assert isinstance(idp, InterDependencies) p0 = [p for p in idp.paramspecs if p.name == 'p0'][0] assert p0.depends_on == '' assert p0.depends_on_ == [] assert p0.inferred_from == '' assert p0.inferred_from_ == [] assert p0.label == "Parameter 0" assert p0.unit == "unit 0" p1 = [p for p in idp.paramspecs if p.name == 'p1'][0] assert p1.depends_on == '' assert p1.depends_on_ == [] assert p1.inferred_from == '' assert p1.inferred_from_ == [] assert p1.label == "Parameter 1" assert p1.unit == "unit 1" p2 = [p for p in idp.paramspecs if p.name == 'p2'][0] assert p2.depends_on == '' assert p2.depends_on_ == [] assert p2.inferred_from == 'p0' assert p2.inferred_from_ == ['p0'] assert p2.label == "Parameter 2" assert p2.unit == "unit 2" p3 = [p for p in idp.paramspecs if p.name == 'p3'][0] assert p3.depends_on == '' assert p3.depends_on_ == [] assert p3.inferred_from == 'p1, p0' assert p3.inferred_from_ == ['p1', 'p0'] assert p3.label == "Parameter 3" assert p3.unit == "unit 3" p4 = [p for p in idp.paramspecs if p.name == 'p4'][0] assert p4.depends_on == 'p2, p3' assert p4.depends_on_ == ['p2', 'p3'] assert p4.inferred_from == '' assert p4.inferred_from_ == [] assert p4.label == "Parameter 4" assert p4.unit == "unit 4" p5 = [p for p in idp.paramspecs if p.name == 'p5'][0] assert p5.depends_on == '' assert p5.depends_on_ == [] assert p5.inferred_from == 'p0' assert p5.inferred_from_ == ['p0'] assert p5.label == "Parameter 5" assert p5.unit == "unit 5"
def test_perform_actual_upgrade_6_to_newest_add_new_data(): """ Insert new runs on top of existing runs upgraded and verify that they get the correct captured_run_id and captured_counter """ from qcodes.dataset.measurements import Measurement from qcodes.instrument.parameter import Parameter import numpy as np fixpath = os.path.join(fixturepath, 'db_files', 'version6') db_file = 'some_runs.db' dbname_old = os.path.join(fixpath, db_file) if not os.path.exists(dbname_old): pytest.skip("No db-file fixtures found. You can generate test db-files" " using the scripts in the " "https://github.com/QCoDeS/qcodes_generate_test_db/ repo") with temporarily_copied_DB(dbname_old, debug=False, version=6) as conn: assert isinstance(conn, ConnectionPlus) perform_db_upgrade(conn) assert get_user_version(conn) >= 7 no_of_runs_query = "SELECT max(run_id) FROM runs" no_of_runs = one( atomic_transaction(conn, no_of_runs_query), 'max(run_id)') # Now let's insert new runs and ensure that they also get # captured_run_id assigned. 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 exp = new_experiment('some-exp', 'some-sample', conn=conn) meas = Measurement(exp=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[0], 0), (params[1], 1), (params[2], x), (params[3], y), (params[4], z)) no_of_runs_new = one( atomic_transaction(conn, no_of_runs_query), 'max(run_id)') assert no_of_runs_new == 20 # check that run_id is equivalent to captured_run_id for new # runs for run_id in range(no_of_runs, no_of_runs_new + 1): ds1 = load_by_id(run_id, conn) ds2 = load_by_run_spec(captured_run_id=run_id, conn=conn) assert ds1.the_same_dataset_as(ds2) assert ds1.run_id == run_id assert ds1.run_id == ds1.captured_run_id assert ds2.run_id == run_id assert ds2.run_id == ds2.captured_run_id # we are creating a new experiment into a db with one exp so: exp_id = 2 # check that counter is equivalent to captured_counter for new # runs for counter in range(1, no_of_runs_new - no_of_runs + 1): ds1 = load_by_counter(counter, exp_id, conn) # giving only the counter is not unique since we have 2 experiments with pytest.raises(NameError, match="More than one" " matching dataset"): load_by_run_spec(captured_counter=counter, conn=conn) # however we can supply counter and experiment ds2 = load_by_run_spec(captured_counter=counter, experiment_name='some-exp', conn=conn) assert ds1.the_same_dataset_as(ds2) assert ds1.counter == counter assert ds1.counter == ds1.captured_counter assert ds2.counter == counter assert ds2.counter == ds2.captured_counter
def test_connect_upgrades_user_version(ver): expected_version = ver if ver != LATEST_VERSION_ARG else LATEST_VERSION conn = connect(':memory:', version=ver) assert expected_version == get_user_version(conn)