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.
Files changed (107) hide show
  1. {quapp_common-0.0.14.dev7/quapp_common.egg-info → quapp_common-0.0.14.dev9}/PKG-INFO +1 -1
  2. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/pyproject.toml +1 -1
  3. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/async_tasks/post_processing_task.py +3 -3
  4. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/dispatcher.py +0 -4
  5. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/model/device/custom_device.py +5 -5
  6. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9/quapp_common.egg-info}/PKG-INFO +1 -1
  7. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/tests/test_dispatcher_runner_error.py +3 -3
  8. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/tests/test_error_log_dedupe.py +8 -8
  9. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/tests/test_error_report.py +1 -1
  10. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/tests/test_language_dispatcher.py +2 -8
  11. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/tests/test_log_secret_leak.py +6 -5
  12. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/tests/test_no_sdk_dependency.py +4 -4
  13. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/tests/test_phase_coverage.py +27 -22
  14. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/LICENSE +0 -0
  15. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/README.md +0 -0
  16. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/__init__.py +0 -0
  17. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/async_tasks/__init__.py +0 -0
  18. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/async_tasks/async_invocation_task.py +0 -0
  19. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/async_tasks/async_task.py +0 -0
  20. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/async_tasks/export_circuit_task.py +0 -0
  21. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/__init__.py +0 -0
  22. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/backend/__init__.py +0 -0
  23. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/backend/invocation.py +0 -0
  24. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/backend/job_fetcher.py +0 -0
  25. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/backend/job_fetching.py +0 -0
  26. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/backend/job_heartbeat.py +0 -0
  27. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/backend/job_manager.py +0 -0
  28. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/bridge.py +0 -0
  29. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/callback/__init__.py +0 -0
  30. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/callback/update_job_metadata.py +0 -0
  31. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/circuit_adapter.py +0 -0
  32. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/device/__init__.py +0 -0
  33. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/device/device_selection.py +0 -0
  34. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/component/result_serializer.py +0 -0
  35. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/config/__init__.py +0 -0
  36. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/config/log_context.py +0 -0
  37. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/config/logging_config.py +0 -0
  38. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/config/thread_config.py +0 -0
  39. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/__init__.py +0 -0
  40. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/async_task/__init__.py +0 -0
  41. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/async_task/circuit_export/__init__.py +0 -0
  42. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/async_task/circuit_export/backend_holder.py +0 -0
  43. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/async_task/circuit_export/circuit_holder.py +0 -0
  44. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/backend/__init__.py +0 -0
  45. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/backend/backend_information.py +0 -0
  46. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/callback/__init__.py +0 -0
  47. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/callback/callback_url.py +0 -0
  48. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/device/__init__.py +0 -0
  49. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/device/circuit_running_option.py +0 -0
  50. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/promise/__init__.py +0 -0
  51. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/promise/post_processing_promise.py +0 -0
  52. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/promise/promise.py +0 -0
  53. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/request/__init__.py +0 -0
  54. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/request/invocation_request.py +0 -0
  55. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/request/job_fetching_request.py +0 -0
  56. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/request/request.py +0 -0
  57. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/response/__init__.py +0 -0
  58. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/response/authentication.py +0 -0
  59. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/response/custom_header.py +0 -0
  60. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/response/error_report.py +0 -0
  61. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/data/response/job_response.py +0 -0
  62. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/enum/__init__.py +0 -0
  63. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/enum/base_enum.py +0 -0
  64. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/enum/error_category.py +0 -0
  65. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/enum/http_header.py +0 -0
  66. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/enum/invocation_step.py +0 -0
  67. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/enum/language.py +0 -0
  68. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/enum/media_type.py +0 -0
  69. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/enum/processing_unit.py +0 -0
  70. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/enum/provider_tag.py +0 -0
  71. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/enum/runtime_phase.py +0 -0
  72. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/enum/sdk.py +0 -0
  73. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/enum/status/__init__.py +0 -0
  74. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/enum/status/job_status.py +0 -0
  75. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/enum/status/status_code.py +0 -0
  76. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/enum/token_type.py +0 -0
  77. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/factory/__init__.py +0 -0
  78. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/factory/device_factory.py +0 -0
  79. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/factory/handler_factory.py +0 -0
  80. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/factory/provider_factory.py +0 -0
  81. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/handler/__init__.py +0 -0
  82. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/handler/handler.py +0 -0
  83. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/model/__init__.py +0 -0
  84. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/model/device/__init__.py +0 -0
  85. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/model/device/device.py +0 -0
  86. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/model/invocation.py +0 -0
  87. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/model/provider/__init__.py +0 -0
  88. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/model/provider/provider.py +0 -0
  89. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/util/__init__.py +0 -0
  90. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/util/error_classifier.py +0 -0
  91. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/util/file_utils.py +0 -0
  92. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/util/http_utils.py +0 -0
  93. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/util/invocation_failure.py +0 -0
  94. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/util/json_parser_utils.py +0 -0
  95. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common/util/response_utils.py +0 -0
  96. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common.egg-info/SOURCES.txt +0 -0
  97. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common.egg-info/dependency_links.txt +0 -0
  98. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common.egg-info/requires.txt +0 -0
  99. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/quapp_common.egg-info/top_level.txt +0 -0
  100. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/setup.cfg +0 -0
  101. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/tests/test_circuit_adapter.py +0 -0
  102. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/tests/test_error_classifier.py +0 -0
  103. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/tests/test_invocation_failure.py +0 -0
  104. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/tests/test_job_heartbeat.py +0 -0
  105. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/tests/test_json_parser_utils.py +0 -0
  106. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/tests/test_logging_config.py +0 -0
  107. {quapp_common-0.0.14.dev7 → quapp_common-0.0.14.dev9}/tests/test_result_serializer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: quapp-common
3
- Version: 0.0.14.dev7
3
+ Version: 0.0.14.dev9
4
4
  Summary: Quapp common library supporting Quapp Platform for Quantum Computing
5
5
  Author-email: "CITYNOW Co. Ltd. " <corp@citynow.vn>
6
6
  License: The MIT License (MIT)
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "quapp-common"
7
- version = "0.0.14.dev7"
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 duoc dinh nghia nhung truoc day khong
37
- # noi nao dung, nen code user chay trong post_processing_fn khong he
38
- # co phase trong log lan trong ErrorReport.
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(
@@ -46,10 +46,6 @@ RUNNER_MAP = {
46
46
  'command': [_QSHARP_BINARY],
47
47
  'timeout': 300,
48
48
  },
49
- Language.C: {
50
- 'command': ['./handler_compiled'],
51
- 'timeout': 300,
52
- },
53
49
  }
54
50
 
55
51
  # Cap the stack/stderr length carried on the exception so job_result stays small.
@@ -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 co `with phase(...)`, ban override nay khong --
39
- # va day moi la ban thuc su chay: QiskitDevice, OqcCloudDevice...
40
- # deu ke thua CustomDevice. Thieu no thi log cua analysis khong co
41
- # field `phase`, Grafana khong loc duoc va ErrorReport cua loi trong
42
- # analysis ra phase=None.
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")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: quapp-common
3
- Version: 0.0.14.dev7
3
+ Version: 0.0.14.dev9
4
4
  Summary: Quapp common library supporting Quapp Platform for Quantum Computing
5
5
  Author-email: "CITYNOW Co. Ltd. " <corp@citynow.vn>
6
6
  License: The MIT License (MIT)
@@ -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.C, REQUEST)
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.c segfaults: returncode = -11, stdout empty."""
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.C, REQUEST)
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
- # ------------------------------------------------------- mot loi = mot dong
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'mong doi 1 dong, nhan {len(failed)}'
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
- # --------------------------------------------------- khong con log o call-site
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}: con log exception ngay truoc '
130
- f'build_error_job_response -- se ra 2 dong ERROR cho mot loi')
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
- # ------------------------------------------------------------ dong thoi
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'so dong khong deu giua cac job: {dict(per_job)}'
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)} dong lan context giua cac job'
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 phai thay duoc o LOG_LEVEL=INFO'
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 test_language_c_registered(self):
14
- self.assertIn(Language.C, RUNNER_MAP)
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
- # ------------------------------------------------- (1) secret trong message
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
- # --------------------------------------- (2) secret trong bien cuc bo
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 khong con in gia tri bien cuc bo -- xem lai co can diagnose=False'
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
- # ------------------------------------------------- json sink dung traceback sach
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(), 'khong tim thay file .py nao'
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)}. Chuyen vao trong function (xem _require() '
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 khai bao SDK trong dependencies: {offenders}. '
98
- f'SDK thuoc ve lib con.')
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
- # ------------------------------------------- (1) CustomDevice phai co ANALYSIS
79
+ # ----------------------------------- (1) CustomDevice must open ANALYSIS
80
80
 
81
81
  def test_custom_device_analysis_is_wrapped():
82
- """Ban override moi la ban chay that, no phai mo phase nhu ban goc."""
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 khong co `with phase(RuntimePhase.ANALYSIS)`; '
85
- 'moi device Qiskit dung ban nay nen log analysis se mat field phase')
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
- """Khong duoc lam hong ban goc khi sua ban override."""
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
- # ------------------------------------ (2) post_processing phai co POST_PROCESSING
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 cua user) chay ngoai moi phase, nen loi trong '
100
- 'do khong biet thuoc giai doan nao')
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
- """RuntimePhase khai bao ra thi phai co noi mo -- tru CALLBACK/POLLING.
106
+ """A declared RuntimePhase must be opened somewhere -- except CALLBACK and
107
+ POLLING.
105
108
 
106
- CALLBACK va POLLING duoc dat qua `phase=` cua build_error_job_response chu
107
- khong qua `with phase(...)`, nen khong tinh o day.
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 khong bao gio duoc mo: {sorted(never_opened)}')
119
+ f'RuntimePhase never opened anywhere: {sorted(never_opened)}')
117
120
 
118
121
 
119
- # --------------------------------------------------- hanh vi khi chay that
122
+ # ------------------------------------------------------ behaviour at runtime
120
123
 
121
124
  def test_analysis_phase_reaches_the_log_record(captured):
122
- """Trong `with phase(ANALYSIS)`, dong log phai mang phase=ANALYSIS."""
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()` reset contextvar trong finally, nen ErrorReport phai doc duoc
136
- phase da that bai qua _FAILED_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 khong bi tach
161
+ # ------------------------------------------------- (3) trace_id is not split
159
162
 
160
163
  def test_rebinding_same_job_keeps_one_trace_id():
161
- """AsyncInvocationTask bind roi Handler.__init__ bind lai -- van mot trace."""
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, 'cung mot job ma co hai traceId'
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
- """Cua vao HTTP bind truoc khi biet job_id; trace phai duoc mang theo."""
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
- """Khong duoc tron trace giua hai job khac nhau."""
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('mot dong bat ky')
200
+ logger.bind(**log_context.job_context()).info('any line at all')
196
201
 
197
202
  assert captured[-1].get(TRACE_ID)