Skip to content
This repository was archived by the owner on Jul 28, 2023. It is now read-only.

Commit 15a786d

Browse files
authored
Allow non default provider in test (#461)
* allow use of non default provider in test * remove unused import * rename decorator * slow_test to slow_test_on_device * test need not be slow * bump version * separate try blocks
1 parent 0285186 commit 15a786d

File tree

6 files changed

+65
-41
lines changed

6 files changed

+65
-41
lines changed

qiskit/providers/ibmq/VERSION.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.4.3
1+
0.4.4rc1

test/decorators.py

+15-3
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ def _wrapper(*args, **kwargs):
124124
return _wrapper
125125

126126

127-
def run_on_device(func):
127+
def slow_test_on_device(func):
128128
"""Decorator that signals that the test should run on a real or semi-real device.
129129
130130
It involves:
@@ -164,9 +164,21 @@ def _wrapper(obj, *args, **kwargs):
164164
obj.using_ibmq_credentials = credentials.is_ibmq()
165165
ibmq_factory = IBMQFactory()
166166
provider = ibmq_factory.enable_account(credentials.token, credentials.url)
167+
168+
_backend = None
169+
if backend_name:
170+
for provider in ibmq_factory.providers():
171+
backends = provider.backends(name=backend_name)
172+
if backends:
173+
_backend = backends[0]
174+
break
175+
else:
176+
_backend = least_busy(provider.backends(simulator=False))
177+
178+
if not _backend:
179+
raise Exception("Unable to find suitable backend.")
180+
167181
kwargs.update({'provider': provider})
168-
_backend = provider.get_backend(backend_name) if backend_name else \
169-
least_busy(provider.backends(simulator=False))
170182
kwargs.update({'backend': _backend})
171183

172184
return func(obj, *args, **kwargs)

test/ibmq/test_ibmq_job.py

+33-22
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import time
1818
from concurrent import futures
1919
from datetime import datetime, timedelta
20+
from unittest import SkipTest
2021

2122
import numpy
2223
from scipy.stats import chi2_contingency
@@ -28,14 +29,14 @@
2829
from qiskit.providers.ibmq.exceptions import IBMQBackendError
2930
from qiskit.providers.ibmq.ibmqfactory import IBMQFactory
3031
from qiskit.providers.ibmq.job.ibmqjob import IBMQJob
31-
from qiskit.providers.ibmq.job.exceptions import IBMQJobInvalidStateError
32+
from qiskit.providers.ibmq.job.exceptions import IBMQJobInvalidStateError, JobError
3233
from qiskit.test import slow_test
3334
from qiskit.compiler import assemble, transpile
3435
from qiskit.result import Result
3536

3637
from ..jobtestcase import JobTestCase
3738
from ..decorators import (requires_provider, requires_qe_access,
38-
run_on_device, requires_device)
39+
slow_test_on_device, requires_device)
3940

4041

4142
class TestIBMQJob(JobTestCase):
@@ -81,9 +82,8 @@ def test_run_simulator(self, provider):
8182
self.assertGreater(contingency1[1], 0.01)
8283
self.assertGreater(contingency2[1], 0.01)
8384

84-
@slow_test
85-
@requires_device
86-
def test_run_device(self, backend):
85+
@slow_test_on_device
86+
def test_run_device(self, provider, backend): # pylint: disable=unused-argument
8787
"""Test running in a real device."""
8888
qobj = assemble(transpile(self._qc, backend=backend), backend=backend)
8989
shots = qobj.config.shots
@@ -152,7 +152,7 @@ def test_run_async_simulator(self, provider):
152152
job_ids = [job.job_id() for job in job_array]
153153
self.assertEqual(sorted(job_ids), sorted(list(set(job_ids))))
154154

155-
@run_on_device
155+
@slow_test_on_device
156156
def test_run_async_device(self, provider, backend): # pylint: disable=unused-argument
157157
"""Test running in a real device asynchronously."""
158158
self.log.info('submitting to backend %s', backend.name())
@@ -208,7 +208,6 @@ def test_cancel(self, provider):
208208

209209
qobj = assemble(transpile(self._qc, backend=backend), backend=backend)
210210
job = backend.run(qobj)
211-
self.wait_for_initialization(job, timeout=5)
212211
can_cancel = job.cancel()
213212
self.assertTrue(can_cancel)
214213
self.assertTrue(job.status() is JobStatus.CANCELLED)
@@ -234,38 +233,50 @@ def test_retrieve_job(self, provider):
234233
self.assertEqual(job.result().get_counts(), retrieved_job.result().get_counts())
235234
self.assertEqual(job.qobj().to_dict(), qobj.to_dict())
236235

237-
@slow_test
238236
@requires_device
239237
@requires_provider
240238
def test_retrieve_job_uses_appropriate_backend(self, backend, provider):
241239
"""Test that retrieved jobs come from their appropriate backend."""
242-
simulator_backend = provider.get_backend('ibmq_qasm_simulator')
243-
real_backend = backend
240+
backend_1 = backend
241+
# Get a second backend.
242+
backend_2 = None
243+
for backend_2 in provider.backends():
244+
if backend_2.status().operational and backend_2.name() != backend_1.name():
245+
break
246+
if not backend_2:
247+
raise SkipTest('Skipping test that requires multiple backends')
244248

245-
qobj_sim = assemble(
246-
transpile(self._qc, backend=simulator_backend), backend=simulator_backend)
247-
job_sim = simulator_backend.run(qobj_sim)
249+
qobj_1 = assemble(
250+
transpile(self._qc, backend=backend_1), backend=backend_1)
251+
job_1 = backend_1.run(qobj_1)
248252

249-
qobj_real = assemble(
250-
transpile(self._qc, backend=real_backend), backend=real_backend)
251-
job_real = real_backend.run(qobj_real)
253+
qobj_2 = assemble(
254+
transpile(self._qc, backend=backend_2), backend=backend_2)
255+
job_2 = backend_2.run(qobj_2)
252256

253257
# test a retrieved job's backend is the same as the queried backend
254-
self.assertEqual(simulator_backend.retrieve_job(job_sim.job_id()).backend().name(),
255-
simulator_backend.name())
256-
self.assertEqual(real_backend.retrieve_job(job_real.job_id()).backend().name(),
257-
real_backend.name())
258+
self.assertEqual(backend_1.retrieve_job(job_1.job_id()).backend().name(),
259+
backend_1.name())
260+
self.assertEqual(backend_2.retrieve_job(job_2.job_id()).backend().name(),
261+
backend_2.name())
258262

259263
# test retrieve requests for jobs that exist on other backends throw errors
260264
with self.assertWarns(Warning) as context_manager:
261265
self.assertRaises(IBMQBackendError,
262-
simulator_backend.retrieve_job, job_real.job_id())
266+
backend_1.retrieve_job, job_2.job_id())
263267
self.assertIn('belongs to', str(context_manager.warning))
264268
with self.assertWarns(Warning) as context_manager:
265269
self.assertRaises(IBMQBackendError,
266-
real_backend.retrieve_job, job_sim.job_id())
270+
backend_2.retrieve_job, job_1.job_id())
267271
self.assertIn('belongs to', str(context_manager.warning))
268272

273+
# Cleanup
274+
for job in [job_1, job_2]:
275+
try:
276+
job.cancel()
277+
except JobError:
278+
pass
279+
269280
@requires_provider
270281
def test_retrieve_job_error(self, provider):
271282
"""Test retrieving an invalid job."""

test/ibmq/test_ibmq_job_attributes.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
from qiskit.compiler import assemble, transpile
2727

2828
from ..jobtestcase import JobTestCase
29-
from ..decorators import requires_provider, run_on_device
29+
from ..decorators import requires_provider, slow_test_on_device
3030

3131

3232
class TestIBMQJobAttributes(JobTestCase):
@@ -55,7 +55,7 @@ def test_get_backend_name(self, provider):
5555
job = backend.run(qobj)
5656
self.assertTrue(job.backend().name() == backend.name())
5757

58-
@run_on_device
58+
@slow_test_on_device
5959
def test_running_job_properties(self, provider, backend): # pylint: disable=unused-argument
6060
"""Test fetching properties of a running job."""
6161
qobj = assemble(transpile(self._qc, backend=backend), backend=backend)
@@ -110,7 +110,7 @@ def test_duplicate_job_name(self, provider):
110110
for job in retrieved_jobs:
111111
self.assertEqual(job.name(), job_name)
112112

113-
@run_on_device
113+
@slow_test_on_device
114114
def test_error_message_device(self, provider, backend): # pylint: disable=unused-argument
115115
"""Test retrieving job error messages from a device backend."""
116116
qc_new = transpile(self._qc, backend)

test/ibmq/test_ibmq_provider.py

+11-10
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@
2323
from qiskit.providers.ibmq.ibmqfactory import IBMQFactory
2424
from qiskit.providers.ibmq.ibmqbackend import IBMQSimulator, IBMQBackend
2525
from qiskit.qobj import QobjHeader
26-
from qiskit.test import slow_test, providers
26+
from qiskit.test import providers
2727
from qiskit.compiler import assemble, transpile
2828
from qiskit.providers.models.backendproperties import BackendProperties
2929

30-
from ..decorators import requires_qe_access
30+
from ..decorators import requires_qe_access, slow_test_on_device
3131
from ..ibmqtestcase import IBMQTestCase
3232

3333

@@ -119,24 +119,25 @@ def test_qobj_headers_in_result_sims(self):
119119
self.assertEqual(result.results[0].header.some_field,
120120
'extra info')
121121

122-
@slow_test
123-
def test_qobj_headers_in_result_devices(self):
122+
@slow_test_on_device
123+
def test_qobj_headers_in_result_devices(self, provider, backend):
124124
"""Test that the qobj headers are passed onto the results for devices."""
125-
backends = self.provider.backends(simulator=False)
125+
# pylint: disable=unused-argument
126+
backends = provider.backends(simulator=False, filters=lambda b: b.status().operational)
126127

127128
custom_qobj_header = {'x': 1, 'y': [1, 2, 3], 'z': {'a': 4}}
128129

129-
for backend in backends:
130-
with self.subTest(backend=backend):
131-
circuits = transpile(self.qc1, backend=backend)
130+
for backend_ in backends:
131+
with self.subTest(backend=backend_):
132+
circuits = transpile(self.qc1, backend=backend_)
132133

133-
qobj = assemble(circuits, backend=backend)
134+
qobj = assemble(circuits, backend=backend_)
134135
# Update the Qobj header.
135136
qobj.header = QobjHeader.from_dict(custom_qobj_header)
136137
# Update the Qobj.experiment header.
137138
qobj.experiments[0].header.some_field = 'extra info'
138139

139-
result = backend.run(qobj).result()
140+
result = backend_.run(qobj).result()
140141
self.assertEqual(result.header.to_dict(), custom_qobj_header)
141142
self.assertEqual(result.results[0].header.some_field,
142143
'extra info')

test/ibmq/websocket/test_websocket_integration.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
from qiskit.providers.jobstatus import JobStatus
2929

3030
from ...ibmqtestcase import IBMQTestCase
31-
from ...decorators import requires_qe_access, run_on_device
31+
from ...decorators import requires_qe_access, slow_test_on_device
3232

3333

3434
class TestWebsocketIntegration(IBMQTestCase):
@@ -66,7 +66,7 @@ def test_websockets_simulator(self):
6666

6767
self.assertEqual(result.status, 'COMPLETED')
6868

69-
@run_on_device
69+
@slow_test_on_device
7070
def test_websockets_device(self, provider, backend): # pylint: disable=unused-argument
7171
"""Test checking status of a job via websockets for a device."""
7272
qc = transpile(self.qc1, backend=backend)

0 commit comments

Comments
 (0)