Skip to content

Commit

Permalink
Merge branch 'main' into enable-test-jupyter
Browse files Browse the repository at this point in the history
  • Loading branch information
kt474 committed Mar 29, 2022
2 parents 45d6683 + 1ecfc53 commit 6222e0c
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 89 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,7 @@ Qconfig.py
.DS_Store

/docs/stubs/


# Pycharm
.idea
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ integration-test:
# TODO: enable all tests in "test/integration" directory
python -m unittest -v test/integration/test_backend.py test/integration/test_account_client.py test/integration/test_filter_backends.py \
test/integration/test_serialization.py test/integration/test_ibm_job_attributes.py test/integration/test_basic_server_paths.py \
test/integration/test_jupyter.py

test/integration/test_ibm_integration.py test/integration/test_ibm_job.py test/integration/test_ibm_qasm_simulator.py \
test/integration/test_jupyter.py

black:
black qiskit_ibm_provider test setup.py docs/tutorials
7 changes: 6 additions & 1 deletion qiskit_ibm_provider/ibm_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,12 @@ def get_backend(
`project` are specified.
"""
# pylint: disable=arguments-differ
backends = self.backends(name, hub=hub, group=group, project=project, **kwargs)
instance = (
to_instance_format(hub, group, project)
if all([hub, group, project])
else None
)
backends = self.backends(name, instance=instance, **kwargs)
if len(backends) > 1:
raise QiskitBackendNotFoundError(
"More than one backend matches the criteria"
Expand Down
9 changes: 6 additions & 3 deletions test/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,13 @@ def _wrapper(self, *args, **kwargs):


def _get_integration_test_config():
token, url, instance = (
token, url, instance, instance_private = (
os.getenv("QISKIT_IBM_TOKEN"),
os.getenv("QISKIT_IBM_URL"),
os.getenv("QISKIT_IBM_INSTANCE"),
os.getenv("QISKIT_IBM_INSTANCE_PRIVATE"),
)
return token, url, instance
return token, url, instance, instance_private


def integration_test_setup_with_backend(
Expand Down Expand Up @@ -101,7 +102,7 @@ def integration_test_setup(
def _decorator(func):
@wraps(func)
def _wrapper(self, *args, **kwargs):
token, url, instance = _get_integration_test_config()
token, url, instance, instance_private = _get_integration_test_config()
if not all([token, url]):
raise Exception("Configuration Issue. Token and URL must be set.")

Expand All @@ -112,6 +113,7 @@ def _wrapper(self, *args, **kwargs):
token=token,
url=url,
instance=instance,
instance_private=instance_private,
provider=provider,
)
kwargs["dependencies"] = dependencies
Expand All @@ -128,5 +130,6 @@ class IntegrationTestDependencies:

provider: IBMProvider
instance: Optional[str]
instance_private: Optional[str]
token: str
url: str
51 changes: 28 additions & 23 deletions test/integration/test_ibm_integration.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
# pylint: disable-all
# type: ignore
# TODO: Reenable and fix integration tests.

# This code is part of Qiskit.
#
# (C) Copyright IBM 2021.
Expand All @@ -23,8 +19,13 @@
from qiskit.result import Result
from qiskit.test.reference_circuits import ReferenceCircuits

from qiskit_ibm_provider import IBMBackend
from qiskit_ibm_provider.hub_group_project import from_instance_format
from qiskit_ibm_provider.job.exceptions import IBMJobApiError
from ..decorators import requires_provider, requires_device, requires_private_provider
from ..decorators import (
IntegrationTestDependencies,
integration_test_setup_with_backend,
)
from ..ibm_test_case import IBMTestCase


Expand All @@ -34,18 +35,19 @@ class TestIBMIntegration(IBMTestCase):
seed = 42

@classmethod
@requires_provider
def setUpClass(cls, provider, hub, group, project):
@integration_test_setup_with_backend(simulator=False)
def setUpClass(
cls, backend: IBMBackend, dependencies: IntegrationTestDependencies
) -> None:
"""Initial class level setup."""
# pylint: disable=arguments-differ
super().setUpClass()
cls.provider = provider
cls.hub = hub
cls.group = group
cls.project = project
cls.sim_backend = provider.get_backend(
"ibmq_qasm_simulator", hub=cls.hub, group=cls.group, project=cls.project
hub, group, project = from_instance_format(dependencies.instance)
cls.sim_backend = dependencies.provider.get_backend(
"ibmq_qasm_simulator", hub=hub, group=group, project=project
)
cls.real_device_backend = backend
cls.dependencies = dependencies

def setUp(self):
super().setUp()
Expand All @@ -66,8 +68,7 @@ def test_ibm_result_fields(self):
self.assertEqual(remote_result.status, "COMPLETED")
self.assertEqual(remote_result.results[0].status, "DONE")

@requires_device
def test_compile_remote(self, backend):
def test_compile_remote(self):
"""Test transpile with a remote backend."""
qubit_reg = QuantumRegister(2, name="q")
clbit_reg = ClassicalRegister(2, name="c")
Expand All @@ -76,11 +77,10 @@ def test_compile_remote(self, backend):
quantum_circuit.cx(qubit_reg[0], qubit_reg[1])
quantum_circuit.measure(qubit_reg, clbit_reg)

circuits = transpile(quantum_circuit, backend=backend)
circuits = transpile(quantum_circuit, backend=self.real_device_backend)
self.assertIsInstance(circuits, QuantumCircuit)

@requires_device
def test_compile_two_remote(self, backend):
def test_compile_two_remote(self):
"""Test transpile with a remote backend on two circuits."""
qubit_reg = QuantumRegister(2, name="q")
clbit_reg = ClassicalRegister(2, name="c")
Expand All @@ -90,7 +90,7 @@ def test_compile_two_remote(self, backend):
quantum_circuit.measure(qubit_reg, clbit_reg)
qc_extra = QuantumCircuit(qubit_reg, clbit_reg, name="extra")
qc_extra.measure(qubit_reg, clbit_reg)
circuits = transpile([quantum_circuit, qc_extra], backend)
circuits = transpile([quantum_circuit, qc_extra], self.real_device_backend)
self.assertIsInstance(circuits[0], QuantumCircuit)
self.assertIsInstance(circuits[1], QuantumCircuit)

Expand Down Expand Up @@ -124,18 +124,23 @@ def test_execute_two_remote(self):
results = job.result()
self.assertIsInstance(results, Result)

@requires_private_provider
def test_private_job(self, provider, hub, group, project):
def test_private_job(self):
"""Test a private job."""
backend = provider.get_backend("ibmq_qasm_simulator", hub, group, project)
if not self.dependencies.instance_private:
print(self.skipTest("Skip test because no private instance is configured"))

hub, group, project = from_instance_format(self.dependencies.instance_private)
backend = self.dependencies.provider.get_backend(
"ibmq_qasm_simulator", hub, group, project
)
quantum_circuit = ReferenceCircuits.bell()
job = execute(quantum_circuit, backend=backend)
self.assertIsNotNone(job.circuits())
self.assertIsNotNone(job.result())

# Wait a bit for databases to update.
time.sleep(2)
rjob = provider.backend.job(job.job_id())
rjob = self.dependencies.provider.backend.job(job.job_id())

with self.assertRaises(IBMJobApiError) as err_cm:
rjob.circuits()
Expand Down
71 changes: 35 additions & 36 deletions test/integration/test_ibm_job.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
# pylint: disable-all
# type: ignore
# TODO: Reenable and fix integration tests.

# This code is part of Qiskit.
#
# (C) Copyright IBM 2021.
Expand All @@ -15,12 +11,12 @@
# that they have been altered from the originals.

"""IBMJob Test."""

import copy
import time
from datetime import datetime, timedelta
from threading import Thread, Event
from unittest import SkipTest, mock
from unittest import skip

from dateutil import tz
from qiskit import ClassicalRegister, QuantumCircuit, QuantumRegister
Expand All @@ -30,15 +26,19 @@
from qiskit.test import slow_test
from qiskit.test.reference_circuits import ReferenceCircuits

from qiskit_ibm_provider import least_busy
from qiskit_ibm_provider import IBMBackend, least_busy
from qiskit_ibm_provider.api.exceptions import RequestsApiError
from qiskit_ibm_provider.api.rest.job import Job as RestJob
from qiskit_ibm_provider.apiconstants import ApiJobStatus, API_JOB_FINAL_STATES
from qiskit_ibm_provider.exceptions import IBMBackendApiError
from qiskit_ibm_provider.hub_group_project import from_instance_format
from qiskit_ibm_provider.ibm_backend import IBMRetiredBackend
from qiskit_ibm_provider.job.exceptions import IBMJobTimeoutError, IBMJobNotFoundError
from qiskit_ibm_provider.utils.utils import api_status_to_job_status
from ..decorators import requires_provider, requires_device
from ..decorators import (
IntegrationTestDependencies,
integration_test_setup_with_backend,
)
from ..fake_account_client import BaseFakeAccountClient, CancelableFakeJob
from ..ibm_test_case import IBMTestCase
from ..utils import (
Expand All @@ -54,29 +54,32 @@ class TestIBMJob(IBMTestCase):
"""Test ibm_job module."""

@classmethod
@requires_provider
def setUpClass(cls, provider, hub, group, project):
@integration_test_setup_with_backend(simulator=False)
def setUpClass(
cls, backend: IBMBackend, dependencies: IntegrationTestDependencies
) -> None:
"""Initial class level setup."""
# pylint: disable=arguments-differ
super().setUpClass()
cls.provider = provider
cls.hub = hub
cls.group = group
cls.project = project
cls.sim_backend = provider.get_backend(
"ibmq_qasm_simulator", hub=cls.hub, group=cls.group, project=cls.project

cls.provider = dependencies.provider
hub, group, project = from_instance_format(dependencies.instance)
cls.sim_backend = dependencies.provider.get_backend(
"ibmq_qasm_simulator", hub=hub, group=group, project=project
)
cls.real_device_backend = backend
cls.dependencies = dependencies
cls.bell = transpile(ReferenceCircuits.bell(), cls.sim_backend)
cls.sim_job = cls.sim_backend.run(cls.bell)
cls.last_month = datetime.now() - timedelta(days=30)

@slow_test
@requires_device
def test_run_device(self, backend):
def test_run_device(self):
"""Test running in a real device."""
shots = 8192
job = backend.run(
transpile(ReferenceCircuits.bell(), backend=backend), shots=shots
job = self.real_device_backend.run(
transpile(ReferenceCircuits.bell(), backend=self.real_device_backend),
shots=shots,
)

job.wait_for_final_state(wait=300, callback=self.simple_job_callback)
Expand Down Expand Up @@ -146,7 +149,6 @@ def test_run_multiple_simulator(self):
self.assertEqual(sorted(job_ids), sorted(list(set(job_ids))))

@slow_test
@requires_device
def test_run_multiple_device(self, backend):
"""Test running multiple jobs in a real device."""
num_qubits = 5
Expand Down Expand Up @@ -193,9 +195,7 @@ def test_run_multiple_device(self, backend):
def test_cancel(self):
"""Test job cancellation."""
# Find the most busy backend
backend = most_busy_backend(
self.provider, hub=self.hub, group=self.group, project=self.project
)
backend = most_busy_backend(self.provider, instance=self.dependencies.instance)
submit_and_cancel(backend)

def test_retrieve_jobs(self):
Expand All @@ -220,13 +220,12 @@ def test_retrieve_job(self):
self.sim_job.result().get_counts(), retrieved_job.result().get_counts()
)

@requires_device
def test_retrieve_job_uses_appropriate_backend(self, backend):
def test_retrieve_job_uses_appropriate_backend(self):
"""Test that retrieved jobs come from their appropriate backend."""
backend_1 = backend
backend_1 = self.real_device_backend
# Get a second backend.
backend_2 = None
provider = backend.provider()
provider = self.real_device_backend.provider()
for my_backend in provider.backends():
if (
my_backend.status().operational
Expand Down Expand Up @@ -316,9 +315,7 @@ def test_retrieve_multiple_job_statuses(self):

def test_retrieve_active_jobs(self):
"""Test retrieving jobs that are currently unfinished."""
backend = most_busy_backend(
self.provider, hub=self.hub, group=self.group, project=self.project
)
backend = most_busy_backend(self.provider, instance=self.dependencies.instance)
active_job_statuses = {
api_status_to_job_status(status)
for status in ApiJobStatus
Expand Down Expand Up @@ -346,9 +343,8 @@ def test_retrieve_active_jobs(self):

def test_retrieve_jobs_queued(self):
"""Test retrieving jobs that are queued."""
backend = most_busy_backend(
self.provider, hub=self.hub, group=self.group, project=self.project
)
backend = most_busy_backend(self.provider, instance=self.dependencies.instance)

job = backend.run(transpile(ReferenceCircuits.bell(), backend))
provider = backend.provider()

Expand Down Expand Up @@ -507,6 +503,11 @@ def test_retrieve_jobs_order(self):
)
self.assertNotIn(job.job_id(), [rjob.job_id() for rjob in oldest_jobs])

# TODO: check why test case still fails
@skip(
"Ported from qiskit-ibmq-provider. Test case still skipped even though aer issue 1214 is fixed. "
"Needs further investigation"
)
def test_retrieve_failed_job_simulator_partial(self):
"""Test retrieving partial results from a simulator backend."""
job = submit_job_one_bad_instr(self.sim_backend)
Expand Down Expand Up @@ -652,9 +653,7 @@ def job_canceller(job_, exit_event, wait):

def test_wait_for_final_state_timeout(self):
"""Test waiting for job to reach final state times out."""
backend = most_busy_backend(
self.provider, hub=self.hub, group=self.group, project=self.project
)
backend = most_busy_backend(self.provider, instance=self.dependencies.instance)
job = backend.run(transpile(ReferenceCircuits.bell(), backend=backend))
try:
self.assertRaises(IBMJobTimeoutError, job.wait_for_final_state, timeout=0.1)
Expand Down
Loading

0 comments on commit 6222e0c

Please sign in to comment.