diff --git a/tests/dataset/test_export_datasets_and_create_metadata_db.py b/tests/dataset/test_export_datasets_and_create_metadata_db.py index f15806b2459..3a2df9236c4 100644 --- a/tests/dataset/test_export_datasets_and_create_metadata_db.py +++ b/tests/dataset/test_export_datasets_and_create_metadata_db.py @@ -172,10 +172,6 @@ def test_export_datasets_preserve_experiment_structure( # TODO: assert netcdf files, and result statuses -@pytest.mark.xfail( - run=True, - reason="For incomplete datasets, this should not fail but either succeed or copy as is", -) def test_export_datasets_with_incomplete_dataset( tmp_path: "Path", request: pytest.FixtureRequest ) -> None: @@ -226,7 +222,7 @@ def test_export_datasets_with_incomplete_dataset( # Incomplete dataset should be copied as-is assert result[dataset1.run_id] == "exported" - assert result[dataset2.run_id] == "failed" + assert result[dataset2.run_id] == "exported" def test_export_datasets_empty_database(tmp_path: "Path") -> None: diff --git a/tests/drivers/test_keysight_34465a.py b/tests/drivers/test_keysight_34465a.py index 676ea1439af..e7beb972ea2 100644 --- a/tests/drivers/test_keysight_34465a.py +++ b/tests/drivers/test_keysight_34465a.py @@ -1,3 +1,5 @@ +from typing import TYPE_CHECKING + import numpy as np import pytest @@ -5,9 +7,12 @@ Keysight34465A, ) +if TYPE_CHECKING: + from collections.abc import Generator + @pytest.fixture(scope="function") -def driver(): +def driver() -> "Generator[Keysight34465A, None, None]": keysight_sim = Keysight34465A( "keysight_34465A_sim", address="GPIB::1::INSTR", @@ -21,7 +26,9 @@ def driver(): @pytest.fixture(scope="function") -def driver_with_read_and_fetch_mocked(val_volt): +def driver_with_read_and_fetch_mocked( + val_volt, +) -> "Generator[Keysight34465A, None, None]": keysight_sim = Keysight34465A( "keysight_34465A_sim", address="GPIB::1::INSTR", @@ -44,21 +51,21 @@ def ask_with_read_mock(cmd: str) -> str: Keysight34465A.close_all() -def test_init(driver) -> None: +def test_init(driver: Keysight34465A) -> None: idn = driver.IDN() assert idn["vendor"] == "Keysight" assert idn["model"] == "34465A" -def test_has_dig_option(driver) -> None: +def test_has_dig_option(driver: Keysight34465A) -> None: assert True is driver.has_DIG -def test_model_flag(driver) -> None: +def test_model_flag(driver: Keysight34465A) -> None: assert True is driver.is_34465A_34470A -def test_reset(driver) -> None: +def test_reset(driver: Keysight34465A) -> None: driver.reset() @@ -70,39 +77,40 @@ def test_NPLC(driver) -> None: @pytest.mark.parametrize("val_volt", ["100.0"]) -def test_get_voltage(driver_with_read_and_fetch_mocked, val_volt) -> None: +def test_get_voltage( + driver_with_read_and_fetch_mocked: Keysight34465A, val_volt: float +) -> None: voltage = driver_with_read_and_fetch_mocked.volt.get() assert voltage == 100.0 @pytest.mark.parametrize("val_volt", ["9.9e37"]) -def test_get_voltage_plus_inf(driver_with_read_and_fetch_mocked, val_volt) -> None: +def test_get_voltage_plus_inf( + driver_with_read_and_fetch_mocked: Keysight34465A, val_volt: float +) -> None: voltage = driver_with_read_and_fetch_mocked.volt.get() assert voltage == np.inf @pytest.mark.parametrize("val_volt", ["-9.9e37"]) -def test_get_voltage_minus_inf(driver_with_read_and_fetch_mocked, val_volt) -> None: +def test_get_voltage_minus_inf( + driver_with_read_and_fetch_mocked: Keysight34465A, val_volt: float +) -> None: voltage = driver_with_read_and_fetch_mocked.volt.get() assert voltage == -np.inf -@pytest.mark.xfail( - run=False, - reason="If the test is run, it will pass " - "but all tests after this one will " - "fail. The problem is coming from " - "timetrace().", -) @pytest.mark.parametrize("val_volt", ["10, 9.9e37, -9.9e37"]) -def test_get_timetrace(driver_with_read_and_fetch_mocked, val_volt) -> None: +def test_get_timetrace( + driver_with_read_and_fetch_mocked: Keysight34465A, val_volt: float +) -> None: driver_with_read_and_fetch_mocked.timetrace_npts(3) assert driver_with_read_and_fetch_mocked.timetrace_npts() == 3 voltage = driver_with_read_and_fetch_mocked.timetrace() assert (voltage == np.array([10.0, np.inf, -np.inf])).all() -def test_set_get_autorange(driver) -> None: +def test_set_get_autorange(driver: Keysight34465A) -> None: ar = driver.autorange.get() assert ar == "OFF" driver.autorange.set("ON") @@ -113,7 +121,7 @@ def test_set_get_autorange(driver) -> None: assert ar == "OFF" -def test_increase_decrease_range(driver) -> None: +def test_increase_decrease_range(driver: Keysight34465A) -> None: driver_range_user = driver.ranges[2] driver.increase_range(driver_range_user) assert driver.range() == driver.ranges[3] @@ -128,7 +136,7 @@ def test_increase_decrease_range(driver) -> None: assert driver.range() == driver.ranges[1] -def test_display_text(driver) -> None: +def test_display_text(driver: Keysight34465A) -> None: original_text = driver.display.text() assert original_text == "" diff --git a/tests/drivers/test_tektronix_dpo7200xx.py b/tests/drivers/test_tektronix_dpo7200xx.py index 8d6eef682d5..17208ce87be 100644 --- a/tests/drivers/test_tektronix_dpo7200xx.py +++ b/tests/drivers/test_tektronix_dpo7200xx.py @@ -1,5 +1,3 @@ -import sys -import timeit from typing import TYPE_CHECKING import pytest @@ -9,6 +7,8 @@ if TYPE_CHECKING: from collections.abc import Generator + from pytest_mock import MockerFixture + @pytest.fixture(scope="function") def tektronix_dpo() -> "Generator[TektronixDPO7000xx, None, None]": @@ -25,37 +25,43 @@ def tektronix_dpo() -> "Generator[TektronixDPO7000xx, None, None]": driver.close() -@pytest.mark.xfail( - condition=sys.platform == "win32", reason="Time resolution is too low on windows" -) -def test_adjust_timer(tektronix_dpo: TektronixDPO7000xx) -> None: +def test_adjust_timer( + tektronix_dpo: TektronixDPO7000xx, mocker: "MockerFixture" +) -> None: """ After adjusting the type of the measurement or the source of the measurement, we need wait at least 0.1 seconds ('minimum_adjustment_time') before a measurement value can be retrieved. Test this. """ + measurement = tektronix_dpo.measurement[0] + min_time = measurement._minimum_adjustment_time - timer = timeit.Timer( - 'tektronix_dpo.measurement[0].source1("CH1"),' - "tektronix_dpo.measurement[0].amplitude()", - globals=locals(), - ) - min_time = tektronix_dpo.measurement[0]._minimum_adjustment_time - repeats = timer.repeat(repeat=10, number=1) - - # The minimum time should be at least 95% of the 'minimum_adjustment_time' - assert all(t > min_time * 0.95 for t in repeats) - # To see why this fudge factor is necessary, try the following: - # >>> import time - # >>> import timeit - # >>> timer = timeit.Timer("time.sleep(1E-3)") - # >>> print(any(t < 1E-3 for t in timer.repeat(repeat=100, number=1))) - # ... True - # Conclusion: the command 'time.sleep(1E-3)' sometimes takes less - # than 1E-3 seconds to return. Since the sleep time is not critical - # to the microsecond, we don't care that we sometimes retrieve - # measurements slightly sooner then 'minimum_adjustment_time' + mock_time = mocker.patch("qcodes.instrument_drivers.tektronix.DPO7200xx.time") + + # Simulate: source was set at t=1.0, measurement read at t=1.05 + # (only 0.05s elapsed, less than the 0.1s minimum) + mock_time.perf_counter.return_value = 1.05 + measurement._adjustment_time = 1.0 + measurement.wait_adjustment_time() + mock_time.sleep.assert_called_once_with(pytest.approx(min_time - 0.05)) + + # Simulate: enough time has passed (0.2s > 0.1s minimum) + mock_time.reset_mock() + mock_time.perf_counter.return_value = 1.2 + measurement._adjustment_time = 1.0 + measurement.wait_adjustment_time() + mock_time.sleep.assert_not_called() + + # Verify _set_source records the adjustment time + mock_time.perf_counter.return_value = 5.0 + measurement._set_source(1, "CH1") + assert measurement._adjustment_time == 5.0 + + # Verify _set_measurement_type records the adjustment time + mock_time.perf_counter.return_value = 6.0 + measurement._set_measurement_type("AMPlitude") + assert measurement._adjustment_time == 6.0 def test_measurements_return_float(tektronix_dpo: TektronixDPO7000xx) -> None: