quapp-common 0.0.14.dev7__tar.gz → 0.0.14.dev9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {quapp_common-0.0.14.dev7/quapp_common.egg-info → quapp_common-0.0.14.dev9}/PKG-INFO +1 -1
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/pyproject.toml +1 -1
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/async_tasks/post_processing_task.py +3 -3
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/dispatcher.py +0 -4
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/model/device/custom_device.py +5 -5
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9/quapp_common.egg-info}/PKG-INFO +1 -1
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/tests/test_dispatcher_runner_error.py +3 -3
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/tests/test_error_log_dedupe.py +8 -8
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/tests/test_error_report.py +1 -1
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/tests/test_language_dispatcher.py +2 -8
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/tests/test_log_secret_leak.py +6 -5
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/tests/test_no_sdk_dependency.py +4 -4
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/tests/test_phase_coverage.py +27 -22
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/LICENSE +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/README.md +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/__init__.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/async_tasks/__init__.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/async_tasks/async_invocation_task.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/async_tasks/async_task.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/async_tasks/export_circuit_task.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/__init__.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/backend/__init__.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/backend/invocation.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/backend/job_fetcher.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/backend/job_fetching.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/backend/job_heartbeat.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/backend/job_manager.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/bridge.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/callback/__init__.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/callback/update_job_metadata.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/circuit_adapter.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/device/__init__.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/device/device_selection.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/result_serializer.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/config/__init__.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/config/log_context.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/config/logging_config.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/config/thread_config.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/__init__.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/async_task/__init__.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/async_task/circuit_export/__init__.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/async_task/circuit_export/backend_holder.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/async_task/circuit_export/circuit_holder.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/backend/__init__.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/backend/backend_information.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/callback/__init__.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/callback/callback_url.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/device/__init__.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/device/circuit_running_option.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/promise/__init__.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/promise/post_processing_promise.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/promise/promise.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/request/__init__.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/request/invocation_request.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/request/job_fetching_request.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/request/request.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/response/__init__.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/response/authentication.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/response/custom_header.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/response/error_report.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/response/job_response.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/enum/__init__.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/enum/base_enum.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/enum/error_category.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/enum/http_header.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/enum/invocation_step.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/enum/language.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/enum/media_type.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/enum/processing_unit.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/enum/provider_tag.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/enum/runtime_phase.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/enum/sdk.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/enum/status/__init__.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/enum/status/job_status.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/enum/status/status_code.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/enum/token_type.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/factory/__init__.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/factory/device_factory.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/factory/handler_factory.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/factory/provider_factory.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/handler/__init__.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/handler/handler.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/model/__init__.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/model/device/__init__.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/model/device/device.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/model/invocation.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/model/provider/__init__.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/model/provider/provider.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/util/__init__.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/util/error_classifier.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/util/file_utils.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/util/http_utils.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/util/invocation_failure.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/util/json_parser_utils.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/util/response_utils.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common.egg-info/SOURCES.txt +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common.egg-info/dependency_links.txt +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common.egg-info/requires.txt +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common.egg-info/top_level.txt +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/setup.cfg +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/tests/test_circuit_adapter.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/tests/test_error_classifier.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/tests/test_invocation_failure.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/tests/test_job_heartbeat.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/tests/test_json_parser_utils.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/tests/test_logging_config.py +0 -0
- {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/tests/test_result_serializer.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "quapp-common"
|
|
7
|
-
version = "0.0.14.
|
|
7
|
+
version = "0.0.14.dev9"
|
|
8
8
|
description = "Quapp common library supporting Quapp Platform for Quantum Computing"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
authors = [{ name = "CITYNOW Co. Ltd. ", email = "corp@citynow.vn" }]
|
|
@@ -33,9 +33,9 @@ class PostProcessingTask(AsyncTask):
|
|
|
33
33
|
job_response.content_type = MediaType.APPLICATION_JSON
|
|
34
34
|
|
|
35
35
|
try:
|
|
36
|
-
# RuntimePhase.POST_PROCESSING
|
|
37
|
-
#
|
|
38
|
-
#
|
|
36
|
+
# RuntimePhase.POST_PROCESSING was defined but never used anywhere,
|
|
37
|
+
# so user code running inside post_processing_fn had no phase, in
|
|
38
|
+
# the log or in the ErrorReport.
|
|
39
39
|
with phase(RuntimePhase.POST_PROCESSING):
|
|
40
40
|
self.logger.info("Execute post_processing ...")
|
|
41
41
|
job_result_post_processing = self.post_processing_fn(
|
{quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/model/device/custom_device.py
RENAMED
|
@@ -35,11 +35,11 @@ class CustomDevice(Device, ABC):
|
|
|
35
35
|
update_job_metadata(job_response, analysis_callback.on_start)
|
|
36
36
|
|
|
37
37
|
try:
|
|
38
|
-
# Device._on_analysis
|
|
39
|
-
#
|
|
40
|
-
#
|
|
41
|
-
#
|
|
42
|
-
# analysis
|
|
38
|
+
# Device._on_analysis has `with phase(...)`; this override did not
|
|
39
|
+
# -- and this is the version that actually runs, because
|
|
40
|
+
# QiskitDevice, OqcCloudDevice and the rest all inherit CustomDevice.
|
|
41
|
+
# Without it, analysis lines carry no `phase` field, Grafana cannot
|
|
42
|
+
# filter on it, and an error during analysis reports phase=None.
|
|
43
43
|
with phase(RuntimePhase.ANALYSIS):
|
|
44
44
|
self.logger.debug(
|
|
45
45
|
"Producing histogram data from original job result")
|
|
@@ -89,7 +89,7 @@ def test_structured_error_legacy_string_form(fake_run):
|
|
|
89
89
|
'status': 'error', 'error': 'invalid JSON on stdin'})))
|
|
90
90
|
|
|
91
91
|
with pytest.raises(HandlerRuntimeError) as info:
|
|
92
|
-
dispatch(Language.
|
|
92
|
+
dispatch(Language.QSHARP, REQUEST)
|
|
93
93
|
|
|
94
94
|
assert 'invalid JSON on stdin' in str(info.value)
|
|
95
95
|
|
|
@@ -97,11 +97,11 @@ def test_structured_error_legacy_string_form(fake_run):
|
|
|
97
97
|
# ------------------------------------------------------------- (3) killed by signal
|
|
98
98
|
|
|
99
99
|
def test_signal_is_detected(fake_run):
|
|
100
|
-
"""handler
|
|
100
|
+
"""A subprocess handler is killed by a signal: returncode = -11, stdout empty."""
|
|
101
101
|
fake_run(FakeCompletedProcess(returncode=-11, stdout=''))
|
|
102
102
|
|
|
103
103
|
with pytest.raises(HandlerRuntimeError) as info:
|
|
104
|
-
dispatch(Language.
|
|
104
|
+
dispatch(Language.QSHARP, REQUEST)
|
|
105
105
|
|
|
106
106
|
error = info.value
|
|
107
107
|
assert error.error_type == 'Signal'
|
|
@@ -70,7 +70,7 @@ def raise_and_catch(exception):
|
|
|
70
70
|
return caught
|
|
71
71
|
|
|
72
72
|
|
|
73
|
-
#
|
|
73
|
+
# ------------------------------------------------- one error = one line
|
|
74
74
|
|
|
75
75
|
def test_single_job_failed_line_per_error(captured):
|
|
76
76
|
bind_job('job_1')
|
|
@@ -80,7 +80,7 @@ def test_single_job_failed_line_per_error(captured):
|
|
|
80
80
|
phase=RuntimePhase.EXECUTION)
|
|
81
81
|
|
|
82
82
|
failed = [r for r in captured if r.get('event') == 'job_failed']
|
|
83
|
-
assert len(failed) == 1, f'
|
|
83
|
+
assert len(failed) == 1, f'expected 1 line, got {len(failed)}'
|
|
84
84
|
assert failed[0]['_level'] == 'ERROR'
|
|
85
85
|
|
|
86
86
|
|
|
@@ -111,7 +111,7 @@ def test_phase_failed_is_separate_and_single(captured):
|
|
|
111
111
|
assert events['job_failed'] == 0
|
|
112
112
|
|
|
113
113
|
|
|
114
|
-
#
|
|
114
|
+
# ------------------------------------------ no logging left at the call site
|
|
115
115
|
|
|
116
116
|
@pytest.mark.parametrize('relative', CALL_SITE_FILES)
|
|
117
117
|
def test_no_redundant_logger_exception_before_builder(relative):
|
|
@@ -126,11 +126,11 @@ def test_no_redundant_logger_exception_before_builder(relative):
|
|
|
126
126
|
re.MULTILINE)
|
|
127
127
|
|
|
128
128
|
assert not pattern.search(source), (
|
|
129
|
-
f'{relative}:
|
|
130
|
-
f'build_error_job_response --
|
|
129
|
+
f'{relative}: still logs the exception right before '
|
|
130
|
+
f'build_error_job_response -- that yields 2 ERROR lines for one error')
|
|
131
131
|
|
|
132
132
|
|
|
133
|
-
# ------------------------------------------------------------
|
|
133
|
+
# ------------------------------------------------------------ concurrency
|
|
134
134
|
|
|
135
135
|
def test_concurrent_jobs_do_not_duplicate_or_mix(captured):
|
|
136
136
|
"""4 concurrent jobs: each gets exactly its own lines, no context mixing."""
|
|
@@ -158,13 +158,13 @@ def test_concurrent_jobs_do_not_duplicate_or_mix(captured):
|
|
|
158
158
|
per_job = Counter(r.get('job_id') for r in captured)
|
|
159
159
|
assert set(per_job) == {'job_0', 'job_1', 'job_2', 'job_3'}
|
|
160
160
|
assert len(set(per_job.values())) == 1, \
|
|
161
|
-
f'
|
|
161
|
+
f'line counts differ between jobs: {dict(per_job)}'
|
|
162
162
|
|
|
163
163
|
# No line carries a job_id belonging to a job other than its own message.
|
|
164
164
|
mixed = [r for r in captured
|
|
165
165
|
if r.get('job_id') and 'job_' in r['_message']
|
|
166
166
|
and r['job_id'] not in r['_message']]
|
|
167
|
-
assert not mixed, f'{len(mixed)}
|
|
167
|
+
assert not mixed, f'{len(mixed)} lines mixed context between jobs'
|
|
168
168
|
|
|
169
169
|
|
|
170
170
|
def test_thread_pool_keeps_phase(captured):
|
|
@@ -346,7 +346,7 @@ def test_phase_emits_failed_and_reraises(captured):
|
|
|
346
346
|
if r['extra'].get('event') == 'phase_failed')
|
|
347
347
|
assert failed['extra']['phase'] == 'COMPILATION'
|
|
348
348
|
assert failed['level'].name == 'WARNING', \
|
|
349
|
-
'phase_failed
|
|
349
|
+
'phase_failed has to be visible at LOG_LEVEL=INFO'
|
|
350
350
|
assert 'duration_ms' in failed['extra']
|
|
351
351
|
|
|
352
352
|
|
|
@@ -10,14 +10,8 @@ class TestLanguageCEnum(unittest.TestCase):
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class TestRunnerMapLanguageC(unittest.TestCase):
|
|
13
|
-
def
|
|
14
|
-
self.
|
|
15
|
-
|
|
16
|
-
def test_command_is_compiled_binary(self):
|
|
17
|
-
self.assertEqual(RUNNER_MAP[Language.C]['command'], ['./handler_compiled'])
|
|
18
|
-
|
|
19
|
-
def test_timeout(self):
|
|
20
|
-
self.assertEqual(RUNNER_MAP[Language.C]['timeout'], 300)
|
|
13
|
+
def test_language_c_not_registered(self):
|
|
14
|
+
self.assertNotIn(Language.C, RUNNER_MAP)
|
|
21
15
|
|
|
22
16
|
|
|
23
17
|
class TestLanguageCppEnum(unittest.TestCase):
|
|
@@ -71,7 +71,7 @@ def _connect(api_token):
|
|
|
71
71
|
raise ConnectionError('provider refused the connection')
|
|
72
72
|
|
|
73
73
|
|
|
74
|
-
#
|
|
74
|
+
# ------------------------------------------- (1) the secret is in the message
|
|
75
75
|
|
|
76
76
|
def test_secret_in_message_is_redacted(real_sink):
|
|
77
77
|
bind_job('job_1')
|
|
@@ -104,7 +104,7 @@ def test_secret_in_exception_string_is_redacted(real_sink):
|
|
|
104
104
|
assert 'Traceback' in output
|
|
105
105
|
|
|
106
106
|
|
|
107
|
-
#
|
|
107
|
+
# ------------------------------ (2) the secret is in a local variable
|
|
108
108
|
|
|
109
109
|
def test_diagnose_true_would_leak_local_variables():
|
|
110
110
|
"""Pin loguru's behaviour so the test above means something: with
|
|
@@ -118,8 +118,9 @@ def test_diagnose_true_would_leak_local_variables():
|
|
|
118
118
|
except ConnectionError:
|
|
119
119
|
job_logger().exception('provider connection failed')
|
|
120
120
|
|
|
121
|
-
assert TOKEN in buffer.getvalue(),
|
|
122
|
-
'loguru
|
|
121
|
+
assert TOKEN in buffer.getvalue(), (
|
|
122
|
+
'loguru no longer prints local variable values -- recheck whether '
|
|
123
|
+
'diagnose=False is still needed')
|
|
123
124
|
|
|
124
125
|
|
|
125
126
|
def test_diagnose_false_does_not_leak_local_variables():
|
|
@@ -136,7 +137,7 @@ def test_diagnose_false_does_not_leak_local_variables():
|
|
|
136
137
|
|
|
137
138
|
|
|
138
139
|
|
|
139
|
-
#
|
|
140
|
+
# ------------------------------ the json sink uses a clean traceback
|
|
140
141
|
|
|
141
142
|
def test_json_stack_trace_has_no_variable_values():
|
|
142
143
|
"""stackTrace in JSON comes from traceback.format_exception (the standard
|
|
@@ -71,7 +71,7 @@ def module_level_imports(path: Path):
|
|
|
71
71
|
|
|
72
72
|
|
|
73
73
|
def test_package_has_python_files():
|
|
74
|
-
assert python_files(), '
|
|
74
|
+
assert python_files(), 'found no .py files at all'
|
|
75
75
|
|
|
76
76
|
|
|
77
77
|
@pytest.mark.parametrize('path', python_files(), ids=lambda p: p.name)
|
|
@@ -79,7 +79,7 @@ def test_no_module_level_sdk_import(path):
|
|
|
79
79
|
offenders = module_level_imports(path) & SDK_MODULES
|
|
80
80
|
assert not offenders, (
|
|
81
81
|
f'{path.relative_to(PACKAGE_ROOT)} import SDK o module level: '
|
|
82
|
-
f'{sorted(offenders)}.
|
|
82
|
+
f'{sorted(offenders)}. Move it inside the function (see _require() '
|
|
83
83
|
f'trong circuit_adapter.py).')
|
|
84
84
|
|
|
85
85
|
|
|
@@ -94,8 +94,8 @@ def test_pyproject_declares_no_sdk():
|
|
|
94
94
|
in SDK_MODULES]
|
|
95
95
|
|
|
96
96
|
assert not offenders, (
|
|
97
|
-
f'pyproject
|
|
98
|
-
f'
|
|
97
|
+
f'pyproject declares an SDK in dependencies: {offenders}. '
|
|
98
|
+
f'SDKs belong to the child libs.')
|
|
99
99
|
|
|
100
100
|
|
|
101
101
|
def test_circuit_adapter_uses_require_helper():
|
|
@@ -76,35 +76,38 @@ def phases_wrapped_in(relative_path):
|
|
|
76
76
|
return found
|
|
77
77
|
|
|
78
78
|
|
|
79
|
-
#
|
|
79
|
+
# ----------------------------------- (1) CustomDevice must open ANALYSIS
|
|
80
80
|
|
|
81
81
|
def test_custom_device_analysis_is_wrapped():
|
|
82
|
-
"""
|
|
82
|
+
"""The override is the version that runs, so it must open the same phase as
|
|
83
|
+
the original."""
|
|
83
84
|
assert 'ANALYSIS' in phases_wrapped_in('model/device/custom_device.py'), (
|
|
84
|
-
'CustomDevice._on_analysis
|
|
85
|
-
'
|
|
85
|
+
'CustomDevice._on_analysis has no `with phase(RuntimePhase.ANALYSIS)`; '
|
|
86
|
+
'every Qiskit device uses this version, so analysis lines would lose '
|
|
87
|
+
'their phase field')
|
|
86
88
|
|
|
87
89
|
|
|
88
90
|
def test_base_device_still_wraps_its_phases():
|
|
89
|
-
"""
|
|
91
|
+
"""Fixing the override must not break the original."""
|
|
90
92
|
wrapped = phases_wrapped_in('model/device/device.py')
|
|
91
93
|
assert {'COMPILATION', 'EXECUTION', 'ANALYSIS'} <= wrapped
|
|
92
94
|
|
|
93
95
|
|
|
94
|
-
#
|
|
96
|
+
# -------------------------- (2) post_processing must open POST_PROCESSING
|
|
95
97
|
|
|
96
98
|
def test_post_processing_task_is_wrapped():
|
|
97
99
|
wrapped = phases_wrapped_in('async_tasks/post_processing_task.py')
|
|
98
100
|
assert 'POST_PROCESSING' in wrapped, (
|
|
99
|
-
'post_processing_fn (code
|
|
100
|
-
'
|
|
101
|
+
'post_processing_fn (user code) runs outside every phase, so an error '
|
|
102
|
+
'in it belongs to no known stage')
|
|
101
103
|
|
|
102
104
|
|
|
103
105
|
def test_every_declared_phase_is_actually_used():
|
|
104
|
-
"""
|
|
106
|
+
"""A declared RuntimePhase must be opened somewhere -- except CALLBACK and
|
|
107
|
+
POLLING.
|
|
105
108
|
|
|
106
|
-
CALLBACK
|
|
107
|
-
|
|
109
|
+
CALLBACK and POLLING are set through build_error_job_response's `phase=`
|
|
110
|
+
argument rather than `with phase(...)`, so they do not count here.
|
|
108
111
|
"""
|
|
109
112
|
used = set()
|
|
110
113
|
for path in PACKAGE_ROOT.rglob('*.py'):
|
|
@@ -113,13 +116,13 @@ def test_every_declared_phase_is_actually_used():
|
|
|
113
116
|
declared = {member.name for member in RuntimePhase}
|
|
114
117
|
never_opened = declared - used - {'CALLBACK', 'POLLING'}
|
|
115
118
|
assert not never_opened, (
|
|
116
|
-
f'RuntimePhase
|
|
119
|
+
f'RuntimePhase never opened anywhere: {sorted(never_opened)}')
|
|
117
120
|
|
|
118
121
|
|
|
119
|
-
#
|
|
122
|
+
# ------------------------------------------------------ behaviour at runtime
|
|
120
123
|
|
|
121
124
|
def test_analysis_phase_reaches_the_log_record(captured):
|
|
122
|
-
"""
|
|
125
|
+
"""Inside `with phase(ANALYSIS)`, a log line must carry phase=ANALYSIS."""
|
|
123
126
|
from quapp_common.config.log_context import phase
|
|
124
127
|
|
|
125
128
|
bind_job('job_A', sdk='qiskit')
|
|
@@ -132,8 +135,8 @@ def test_analysis_phase_reaches_the_log_record(captured):
|
|
|
132
135
|
|
|
133
136
|
|
|
134
137
|
def test_failure_inside_analysis_keeps_the_phase():
|
|
135
|
-
"""`phase()`
|
|
136
|
-
phase
|
|
138
|
+
"""`phase()` resets the contextvar in finally, so ErrorReport has to read the
|
|
139
|
+
failed phase through _FAILED_PHASE."""
|
|
137
140
|
from quapp_common.config.log_context import phase
|
|
138
141
|
|
|
139
142
|
bind_job('job_B')
|
|
@@ -155,19 +158,21 @@ def test_failure_inside_post_processing_keeps_the_phase():
|
|
|
155
158
|
assert effective_phase() is RuntimePhase.POST_PROCESSING
|
|
156
159
|
|
|
157
160
|
|
|
158
|
-
# ------------------------------------------------- (3) trace_id
|
|
161
|
+
# ------------------------------------------------- (3) trace_id is not split
|
|
159
162
|
|
|
160
163
|
def test_rebinding_same_job_keeps_one_trace_id():
|
|
161
|
-
"""AsyncInvocationTask
|
|
164
|
+
"""AsyncInvocationTask binds, then Handler.__init__ binds again -- still one
|
|
165
|
+
trace."""
|
|
162
166
|
bind_job('job_SAME')
|
|
163
167
|
first = trace_id()
|
|
164
168
|
|
|
165
169
|
bind_job('job_SAME', sdk='qiskit', provider='QUAO_QUANTUM_SIMULATOR')
|
|
166
|
-
assert trace_id() == first, '
|
|
170
|
+
assert trace_id() == first, 'one job ended up with two traceIds'
|
|
167
171
|
|
|
168
172
|
|
|
169
173
|
def test_binding_without_job_id_then_with_it_keeps_the_trace():
|
|
170
|
-
"""
|
|
174
|
+
"""The HTTP entry point binds before the job_id is known; the trace has to
|
|
175
|
+
carry over."""
|
|
171
176
|
bind_job(None)
|
|
172
177
|
first = trace_id()
|
|
173
178
|
|
|
@@ -176,7 +181,7 @@ def test_binding_without_job_id_then_with_it_keeps_the_trace():
|
|
|
176
181
|
|
|
177
182
|
|
|
178
183
|
def test_different_job_gets_a_fresh_trace_id():
|
|
179
|
-
"""
|
|
184
|
+
"""Traces must never be mixed between two different jobs."""
|
|
180
185
|
bind_job('job_ONE')
|
|
181
186
|
first = trace_id()
|
|
182
187
|
|
|
@@ -192,6 +197,6 @@ def test_explicit_trace_id_always_wins():
|
|
|
192
197
|
|
|
193
198
|
def test_trace_id_is_present_on_every_record(captured):
|
|
194
199
|
bind_job('job_T')
|
|
195
|
-
logger.bind(**log_context.job_context()).info('
|
|
200
|
+
logger.bind(**log_context.job_context()).info('any line at all')
|
|
196
201
|
|
|
197
202
|
assert captured[-1].get(TRACE_ID)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/async_tasks/async_task.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/backend/__init__.py
RENAMED
|
File without changes
|
{quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/backend/invocation.py
RENAMED
|
File without changes
|
{quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/backend/job_fetcher.py
RENAMED
|
File without changes
|
{quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/backend/job_fetching.py
RENAMED
|
File without changes
|
|
File without changes
|
{quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/backend/job_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
{quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/callback/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/circuit_adapter.py
RENAMED
|
File without changes
|
{quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/device/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/result_serializer.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/async_task/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/callback/__init__.py
RENAMED
|
File without changes
|
{quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/callback/callback_url.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/response/__init__.py
RENAMED
|
File without changes
|
{quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/response/authentication.py
RENAMED
|
File without changes
|
{quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/response/custom_header.py
RENAMED
|
File without changes
|
{quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/response/error_report.py
RENAMED
|
File without changes
|
{quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/response/job_response.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/enum/status/job_status.py
RENAMED
|
File without changes
|
{quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/enum/status/status_code.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/factory/device_factory.py
RENAMED
|
File without changes
|
{quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/factory/handler_factory.py
RENAMED
|
File without changes
|
{quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/factory/provider_factory.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/model/provider/__init__.py
RENAMED
|
File without changes
|
{quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/model/provider/provider.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/util/invocation_failure.py
RENAMED
|
File without changes
|
{quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/util/json_parser_utils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|