Skip to content

Commit 0fe2844

Browse files
committed
Remove most of qiskit.test
This removes large tracts of `qiskit.test` that Qiskit itself is no longer using, or inlines a couple of components that were either exceptionally simple or used only once. A few tests that made heavier use of the removed features have been removed rather than replacing the functionality, since those had not actually been running due to dependencies on IBMQ that have not been fulfilled for a long time. This prepares for a more complete removal of `qiskit.test`, if we choose to, but such a change raises the possibility of rather more merge conflicts (due to the need to touch every test file), so is best done separately.
1 parent b145420 commit 0fe2844

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+119
-2726
lines changed

qiskit/test/__init__.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,4 @@
1313
"""Functionality and helpers for testing Qiskit."""
1414

1515
from .base import QiskitTestCase
16-
from .decorators import requires_aer_provider, online_test, slow_test
17-
from .reference_circuits import ReferenceCircuits
18-
from .utils import Path
16+
from .decorators import slow_test

qiskit/test/base.py

+18-19
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
from qiskit.utils import optionals as _optionals
3333
from qiskit.circuit import QuantumCircuit
3434
from .decorators import enforce_subclasses_call
35-
from .utils import Path, setup_test_logging
3635

3736

3837
__unittest = True # Allows shorter stack trace for .assertDictAlmostEqual
@@ -99,19 +98,6 @@ def tearDown(self):
9998
)
10099
self.__teardown_called = True
101100

102-
@staticmethod
103-
def _get_resource_path(filename, path=Path.TEST):
104-
"""Get the absolute path to a resource.
105-
106-
Args:
107-
filename (string): filename or relative path to the resource.
108-
path (Path): path used as relative to the filename.
109-
110-
Returns:
111-
str: the absolute path to the resource.
112-
"""
113-
return os.path.normpath(os.path.join(path.value, filename))
114-
115101
def assertQuantumCircuitEqual(self, qc1, qc2, msg=None):
116102
"""Extra assertion method to give a better error message when two circuits are unequal."""
117103
if qc1 == qc2:
@@ -192,13 +178,26 @@ def tearDown(self):
192178
@classmethod
193179
def setUpClass(cls):
194180
super().setUpClass()
195-
# Determines if the TestCase is using IBMQ credentials.
196-
cls.using_ibmq_credentials = False
197181
# Set logging to file and stdout if the LOG_LEVEL envar is set.
198182
cls.log = logging.getLogger(cls.__name__)
199-
if os.getenv("LOG_LEVEL"):
200-
filename = "%s.log" % os.path.splitext(inspect.getfile(cls))[0]
201-
setup_test_logging(cls.log, os.getenv("LOG_LEVEL"), filename)
183+
184+
if log_level := os.getenv("LOG_LEVEL"):
185+
log_fmt = f"{cls.log.name}.%(funcName)s:%(levelname)s:%(asctime)s: %(message)s"
186+
formatter = logging.Formatter(log_fmt)
187+
file_handler = logging.FileHandler(f"{os.path.splitext(inspect.getfile(cls))[0]}.log")
188+
file_handler.setFormatter(formatter)
189+
cls.log.addHandler(file_handler)
190+
191+
if os.getenv("STREAM_LOG"):
192+
# Set up the stream handler.
193+
stream_handler = logging.StreamHandler()
194+
stream_handler.setFormatter(formatter)
195+
cls.log.addHandler(stream_handler)
196+
197+
# Set the logging level from the environment variable, defaulting
198+
# to INFO if it is not a valid level.
199+
level = logging._nameToLevel.get(log_level, logging.INFO)
200+
cls.log.setLevel(level)
202201

203202
warnings.filterwarnings("error", category=DeprecationWarning)
204203
allow_DeprecationWarning_modules = [

qiskit/test/decorators.py

+2-174
Original file line numberDiff line numberDiff line change
@@ -13,69 +13,12 @@
1313

1414
"""Decorator for using with Qiskit unit tests."""
1515

16-
import collections.abc
1716
import functools
1817
import os
19-
import socket
20-
import sys
21-
from typing import Union, Callable, Type, Iterable
2218
import unittest
19+
from typing import Union, Callable, Type, Iterable
2320

2421
from qiskit.utils import wrap_method
25-
from .testing_options import get_test_options
26-
27-
HAS_NET_CONNECTION = None
28-
29-
30-
def _has_connection(hostname, port):
31-
"""Checks if internet connection exists to host via specified port.
32-
33-
If any exception is raised while trying to open a socket this will return
34-
false.
35-
36-
Args:
37-
hostname (str): Hostname to connect to.
38-
port (int): Port to connect to
39-
40-
Returns:
41-
bool: Has connection or not
42-
43-
"""
44-
try:
45-
host = socket.gethostbyname(hostname)
46-
socket.create_connection((host, port), 2).close()
47-
return True
48-
except Exception: # pylint: disable=broad-except
49-
return False
50-
51-
52-
def is_aer_provider_available():
53-
"""Check if the C++ simulator can be instantiated.
54-
55-
Returns:
56-
bool: True if simulator executable is available
57-
"""
58-
# TODO: HACK FROM THE DEPTHS OF DESPAIR AS AER DOES NOT WORK ON MAC
59-
if sys.platform == "darwin":
60-
return False
61-
try:
62-
import qiskit.providers.aer # pylint: disable=unused-import
63-
except ImportError:
64-
return False
65-
return True
66-
67-
68-
def requires_aer_provider(test_item):
69-
"""Decorator that skips test if qiskit aer provider is not available
70-
71-
Args:
72-
test_item (callable): function or class to be decorated.
73-
74-
Returns:
75-
callable: the decorated function.
76-
"""
77-
reason = "Aer provider not found, skipping test"
78-
return unittest.skipIf(not is_aer_provider_available(), reason)(test_item)
7922

8023

8124
def slow_test(func):
@@ -90,100 +33,13 @@ def slow_test(func):
9033

9134
@functools.wraps(func)
9235
def _wrapper(*args, **kwargs):
93-
skip_slow = not TEST_OPTIONS["run_slow"]
94-
if skip_slow:
36+
if "run_slow" in os.environ.get("QISKIT_TESTS", ""):
9537
raise unittest.SkipTest("Skipping slow tests")
96-
9738
return func(*args, **kwargs)
9839

9940
return _wrapper
10041

10142

102-
def _get_credentials():
103-
"""Finds the credentials for a specific test and options.
104-
105-
Returns:
106-
Credentials: set of credentials
107-
108-
Raises:
109-
SkipTest: when credentials can't be found
110-
"""
111-
try:
112-
from qiskit.providers.ibmq.credentials import Credentials, discover_credentials
113-
except ImportError as ex:
114-
raise unittest.SkipTest(
115-
"qiskit-ibmq-provider could not be found, "
116-
"and is required for executing online tests. "
117-
'To install, run "pip install qiskit-ibmq-provider" '
118-
"or check your installation."
119-
) from ex
120-
121-
if os.getenv("IBMQ_TOKEN") and os.getenv("IBMQ_URL"):
122-
return Credentials(os.getenv("IBMQ_TOKEN"), os.getenv("IBMQ_URL"))
123-
elif os.getenv("QISKIT_TESTS_USE_CREDENTIALS_FILE"):
124-
# Attempt to read the standard credentials.
125-
discovered_credentials = discover_credentials()
126-
127-
if discovered_credentials:
128-
# Decide which credentials to use for testing.
129-
if len(discovered_credentials) > 1:
130-
raise unittest.SkipTest(
131-
"More than 1 credential set found, use: "
132-
"IBMQ_TOKEN and IBMQ_URL env variables to "
133-
"set credentials explicitly"
134-
)
135-
136-
# Use the first available credentials.
137-
return list(discovered_credentials.values())[0]
138-
raise unittest.SkipTest(
139-
"No IBMQ credentials found for running the test. This is required for running online tests."
140-
)
141-
142-
143-
def online_test(func):
144-
"""Decorator that signals that the test uses the network (and the online API):
145-
146-
It involves:
147-
* determines if the test should be skipped by checking environment
148-
variables.
149-
* if the `USE_ALTERNATE_ENV_CREDENTIALS` environment variable is
150-
set, it reads the credentials from an alternative set of environment
151-
variables.
152-
* if the test is not skipped, it reads `qe_token` and `qe_url` from
153-
`Qconfig.py`, environment variables or qiskitrc.
154-
* if the test is not skipped, it appends `qe_token` and `qe_url` as
155-
arguments to the test function.
156-
157-
Args:
158-
func (callable): test function to be decorated.
159-
160-
Returns:
161-
callable: the decorated function.
162-
"""
163-
164-
@functools.wraps(func)
165-
def _wrapper(self, *args, **kwargs):
166-
# To avoid checking the connection in each test
167-
global HAS_NET_CONNECTION # pylint: disable=global-statement
168-
169-
if TEST_OPTIONS["skip_online"]:
170-
raise unittest.SkipTest("Skipping online tests")
171-
172-
if HAS_NET_CONNECTION is None:
173-
HAS_NET_CONNECTION = _has_connection("qiskit.org", 443)
174-
175-
if not HAS_NET_CONNECTION:
176-
raise unittest.SkipTest("Test requires internet connection.")
177-
178-
credentials = _get_credentials()
179-
self.using_ibmq_credentials = credentials.is_ibmq()
180-
kwargs.update({"qe_token": credentials.token, "qe_url": credentials.url})
181-
182-
return func(self, *args, **kwargs)
183-
184-
return _wrapper
185-
186-
18743
def enforce_subclasses_call(
18844
methods: Union[str, Iterable[str]], attr: str = "_enforce_subclasses_call_cache"
18945
) -> Callable[[Type], Type]:
@@ -278,31 +134,3 @@ def decorator(cls):
278134
return cls
279135

280136
return decorator
281-
282-
283-
class _TestOptions(collections.abc.Mapping):
284-
"""Lazy-loading view onto the test options retrieved from the environment."""
285-
286-
__slots__ = ("_options",)
287-
288-
def __init__(self):
289-
self._options = None
290-
291-
def _load(self):
292-
if self._options is None:
293-
self._options = get_test_options()
294-
295-
def __getitem__(self, key):
296-
self._load()
297-
return self._options[key]
298-
299-
def __iter__(self):
300-
self._load()
301-
return iter(self._options)
302-
303-
def __len__(self):
304-
self._load()
305-
return len(self._options)
306-
307-
308-
TEST_OPTIONS = _TestOptions()

qiskit/test/ibmq_mock.py

-45
This file was deleted.

qiskit/test/mock/__init__.py

-40
This file was deleted.

qiskit/test/mock/backends/__init__.py

-32
This file was deleted.

0 commit comments

Comments
 (0)