schemathesis 3.39.16__py3-none-any.whl → 4.0.0__py3-none-any.whl

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 (255) hide show
  1. schemathesis/__init__.py +41 -79
  2. schemathesis/auths.py +111 -122
  3. schemathesis/checks.py +169 -60
  4. schemathesis/cli/__init__.py +15 -2117
  5. schemathesis/cli/commands/__init__.py +85 -0
  6. schemathesis/cli/commands/data.py +10 -0
  7. schemathesis/cli/commands/run/__init__.py +590 -0
  8. schemathesis/cli/commands/run/context.py +204 -0
  9. schemathesis/cli/commands/run/events.py +60 -0
  10. schemathesis/cli/commands/run/executor.py +157 -0
  11. schemathesis/cli/commands/run/filters.py +53 -0
  12. schemathesis/cli/commands/run/handlers/__init__.py +46 -0
  13. schemathesis/cli/commands/run/handlers/base.py +18 -0
  14. schemathesis/cli/commands/run/handlers/cassettes.py +474 -0
  15. schemathesis/cli/commands/run/handlers/junitxml.py +55 -0
  16. schemathesis/cli/commands/run/handlers/output.py +1628 -0
  17. schemathesis/cli/commands/run/loaders.py +114 -0
  18. schemathesis/cli/commands/run/validation.py +246 -0
  19. schemathesis/cli/constants.py +5 -58
  20. schemathesis/cli/core.py +19 -0
  21. schemathesis/cli/ext/fs.py +16 -0
  22. schemathesis/cli/ext/groups.py +84 -0
  23. schemathesis/cli/{options.py → ext/options.py} +36 -34
  24. schemathesis/config/__init__.py +189 -0
  25. schemathesis/config/_auth.py +51 -0
  26. schemathesis/config/_checks.py +268 -0
  27. schemathesis/config/_diff_base.py +99 -0
  28. schemathesis/config/_env.py +21 -0
  29. schemathesis/config/_error.py +156 -0
  30. schemathesis/config/_generation.py +149 -0
  31. schemathesis/config/_health_check.py +24 -0
  32. schemathesis/config/_operations.py +327 -0
  33. schemathesis/config/_output.py +171 -0
  34. schemathesis/config/_parameters.py +19 -0
  35. schemathesis/config/_phases.py +187 -0
  36. schemathesis/config/_projects.py +527 -0
  37. schemathesis/config/_rate_limit.py +17 -0
  38. schemathesis/config/_report.py +120 -0
  39. schemathesis/config/_validator.py +9 -0
  40. schemathesis/config/_warnings.py +25 -0
  41. schemathesis/config/schema.json +885 -0
  42. schemathesis/core/__init__.py +67 -0
  43. schemathesis/core/compat.py +32 -0
  44. schemathesis/core/control.py +2 -0
  45. schemathesis/core/curl.py +58 -0
  46. schemathesis/core/deserialization.py +65 -0
  47. schemathesis/core/errors.py +459 -0
  48. schemathesis/core/failures.py +315 -0
  49. schemathesis/core/fs.py +19 -0
  50. schemathesis/core/hooks.py +20 -0
  51. schemathesis/core/loaders.py +104 -0
  52. schemathesis/core/marks.py +66 -0
  53. schemathesis/{transports/content_types.py → core/media_types.py} +14 -12
  54. schemathesis/core/output/__init__.py +46 -0
  55. schemathesis/core/output/sanitization.py +54 -0
  56. schemathesis/{throttling.py → core/rate_limit.py} +16 -17
  57. schemathesis/core/registries.py +31 -0
  58. schemathesis/core/transforms.py +113 -0
  59. schemathesis/core/transport.py +223 -0
  60. schemathesis/core/validation.py +54 -0
  61. schemathesis/core/version.py +7 -0
  62. schemathesis/engine/__init__.py +28 -0
  63. schemathesis/engine/context.py +118 -0
  64. schemathesis/engine/control.py +36 -0
  65. schemathesis/engine/core.py +169 -0
  66. schemathesis/engine/errors.py +464 -0
  67. schemathesis/engine/events.py +258 -0
  68. schemathesis/engine/phases/__init__.py +88 -0
  69. schemathesis/{runner → engine/phases}/probes.py +52 -68
  70. schemathesis/engine/phases/stateful/__init__.py +68 -0
  71. schemathesis/engine/phases/stateful/_executor.py +356 -0
  72. schemathesis/engine/phases/stateful/context.py +85 -0
  73. schemathesis/engine/phases/unit/__init__.py +212 -0
  74. schemathesis/engine/phases/unit/_executor.py +416 -0
  75. schemathesis/engine/phases/unit/_pool.py +82 -0
  76. schemathesis/engine/recorder.py +247 -0
  77. schemathesis/errors.py +43 -0
  78. schemathesis/filters.py +17 -98
  79. schemathesis/generation/__init__.py +5 -33
  80. schemathesis/generation/case.py +317 -0
  81. schemathesis/generation/coverage.py +282 -175
  82. schemathesis/generation/hypothesis/__init__.py +36 -0
  83. schemathesis/generation/hypothesis/builder.py +800 -0
  84. schemathesis/generation/{_hypothesis.py → hypothesis/examples.py} +2 -11
  85. schemathesis/generation/hypothesis/given.py +66 -0
  86. schemathesis/generation/hypothesis/reporting.py +14 -0
  87. schemathesis/generation/hypothesis/strategies.py +16 -0
  88. schemathesis/generation/meta.py +115 -0
  89. schemathesis/generation/metrics.py +93 -0
  90. schemathesis/generation/modes.py +20 -0
  91. schemathesis/generation/overrides.py +116 -0
  92. schemathesis/generation/stateful/__init__.py +37 -0
  93. schemathesis/generation/stateful/state_machine.py +278 -0
  94. schemathesis/graphql/__init__.py +15 -0
  95. schemathesis/graphql/checks.py +109 -0
  96. schemathesis/graphql/loaders.py +284 -0
  97. schemathesis/hooks.py +80 -101
  98. schemathesis/openapi/__init__.py +13 -0
  99. schemathesis/openapi/checks.py +455 -0
  100. schemathesis/openapi/generation/__init__.py +0 -0
  101. schemathesis/openapi/generation/filters.py +72 -0
  102. schemathesis/openapi/loaders.py +313 -0
  103. schemathesis/pytest/__init__.py +5 -0
  104. schemathesis/pytest/control_flow.py +7 -0
  105. schemathesis/pytest/lazy.py +281 -0
  106. schemathesis/pytest/loaders.py +36 -0
  107. schemathesis/{extra/pytest_plugin.py → pytest/plugin.py} +128 -108
  108. schemathesis/python/__init__.py +0 -0
  109. schemathesis/python/asgi.py +12 -0
  110. schemathesis/python/wsgi.py +12 -0
  111. schemathesis/schemas.py +537 -273
  112. schemathesis/specs/graphql/__init__.py +0 -1
  113. schemathesis/specs/graphql/_cache.py +1 -2
  114. schemathesis/specs/graphql/scalars.py +42 -6
  115. schemathesis/specs/graphql/schemas.py +141 -137
  116. schemathesis/specs/graphql/validation.py +11 -17
  117. schemathesis/specs/openapi/__init__.py +6 -1
  118. schemathesis/specs/openapi/_cache.py +1 -2
  119. schemathesis/specs/openapi/_hypothesis.py +142 -156
  120. schemathesis/specs/openapi/checks.py +368 -257
  121. schemathesis/specs/openapi/converter.py +4 -4
  122. schemathesis/specs/openapi/definitions.py +1 -1
  123. schemathesis/specs/openapi/examples.py +23 -21
  124. schemathesis/specs/openapi/expressions/__init__.py +31 -19
  125. schemathesis/specs/openapi/expressions/extractors.py +1 -4
  126. schemathesis/specs/openapi/expressions/lexer.py +1 -1
  127. schemathesis/specs/openapi/expressions/nodes.py +36 -41
  128. schemathesis/specs/openapi/expressions/parser.py +1 -1
  129. schemathesis/specs/openapi/formats.py +35 -7
  130. schemathesis/specs/openapi/media_types.py +53 -12
  131. schemathesis/specs/openapi/negative/__init__.py +7 -4
  132. schemathesis/specs/openapi/negative/mutations.py +6 -5
  133. schemathesis/specs/openapi/parameters.py +7 -10
  134. schemathesis/specs/openapi/patterns.py +94 -31
  135. schemathesis/specs/openapi/references.py +12 -53
  136. schemathesis/specs/openapi/schemas.py +233 -307
  137. schemathesis/specs/openapi/security.py +1 -1
  138. schemathesis/specs/openapi/serialization.py +12 -6
  139. schemathesis/specs/openapi/stateful/__init__.py +268 -133
  140. schemathesis/specs/openapi/stateful/control.py +87 -0
  141. schemathesis/specs/openapi/stateful/links.py +209 -0
  142. schemathesis/transport/__init__.py +142 -0
  143. schemathesis/transport/asgi.py +26 -0
  144. schemathesis/transport/prepare.py +124 -0
  145. schemathesis/transport/requests.py +244 -0
  146. schemathesis/{_xml.py → transport/serialization.py} +69 -11
  147. schemathesis/transport/wsgi.py +171 -0
  148. schemathesis-4.0.0.dist-info/METADATA +204 -0
  149. schemathesis-4.0.0.dist-info/RECORD +164 -0
  150. {schemathesis-3.39.16.dist-info → schemathesis-4.0.0.dist-info}/entry_points.txt +1 -1
  151. {schemathesis-3.39.16.dist-info → schemathesis-4.0.0.dist-info}/licenses/LICENSE +1 -1
  152. schemathesis/_compat.py +0 -74
  153. schemathesis/_dependency_versions.py +0 -19
  154. schemathesis/_hypothesis.py +0 -717
  155. schemathesis/_override.py +0 -50
  156. schemathesis/_patches.py +0 -21
  157. schemathesis/_rate_limiter.py +0 -7
  158. schemathesis/cli/callbacks.py +0 -466
  159. schemathesis/cli/cassettes.py +0 -561
  160. schemathesis/cli/context.py +0 -75
  161. schemathesis/cli/debug.py +0 -27
  162. schemathesis/cli/handlers.py +0 -19
  163. schemathesis/cli/junitxml.py +0 -124
  164. schemathesis/cli/output/__init__.py +0 -1
  165. schemathesis/cli/output/default.py +0 -920
  166. schemathesis/cli/output/short.py +0 -59
  167. schemathesis/cli/reporting.py +0 -79
  168. schemathesis/cli/sanitization.py +0 -26
  169. schemathesis/code_samples.py +0 -151
  170. schemathesis/constants.py +0 -54
  171. schemathesis/contrib/__init__.py +0 -11
  172. schemathesis/contrib/openapi/__init__.py +0 -11
  173. schemathesis/contrib/openapi/fill_missing_examples.py +0 -24
  174. schemathesis/contrib/openapi/formats/__init__.py +0 -9
  175. schemathesis/contrib/openapi/formats/uuid.py +0 -16
  176. schemathesis/contrib/unique_data.py +0 -41
  177. schemathesis/exceptions.py +0 -571
  178. schemathesis/experimental/__init__.py +0 -109
  179. schemathesis/extra/_aiohttp.py +0 -28
  180. schemathesis/extra/_flask.py +0 -13
  181. schemathesis/extra/_server.py +0 -18
  182. schemathesis/failures.py +0 -284
  183. schemathesis/fixups/__init__.py +0 -37
  184. schemathesis/fixups/fast_api.py +0 -41
  185. schemathesis/fixups/utf8_bom.py +0 -28
  186. schemathesis/generation/_methods.py +0 -44
  187. schemathesis/graphql.py +0 -3
  188. schemathesis/internal/__init__.py +0 -7
  189. schemathesis/internal/checks.py +0 -86
  190. schemathesis/internal/copy.py +0 -32
  191. schemathesis/internal/datetime.py +0 -5
  192. schemathesis/internal/deprecation.py +0 -37
  193. schemathesis/internal/diff.py +0 -15
  194. schemathesis/internal/extensions.py +0 -27
  195. schemathesis/internal/jsonschema.py +0 -36
  196. schemathesis/internal/output.py +0 -68
  197. schemathesis/internal/transformation.py +0 -26
  198. schemathesis/internal/validation.py +0 -34
  199. schemathesis/lazy.py +0 -474
  200. schemathesis/loaders.py +0 -122
  201. schemathesis/models.py +0 -1341
  202. schemathesis/parameters.py +0 -90
  203. schemathesis/runner/__init__.py +0 -605
  204. schemathesis/runner/events.py +0 -389
  205. schemathesis/runner/impl/__init__.py +0 -3
  206. schemathesis/runner/impl/context.py +0 -88
  207. schemathesis/runner/impl/core.py +0 -1280
  208. schemathesis/runner/impl/solo.py +0 -80
  209. schemathesis/runner/impl/threadpool.py +0 -391
  210. schemathesis/runner/serialization.py +0 -544
  211. schemathesis/sanitization.py +0 -252
  212. schemathesis/serializers.py +0 -328
  213. schemathesis/service/__init__.py +0 -18
  214. schemathesis/service/auth.py +0 -11
  215. schemathesis/service/ci.py +0 -202
  216. schemathesis/service/client.py +0 -133
  217. schemathesis/service/constants.py +0 -38
  218. schemathesis/service/events.py +0 -61
  219. schemathesis/service/extensions.py +0 -224
  220. schemathesis/service/hosts.py +0 -111
  221. schemathesis/service/metadata.py +0 -71
  222. schemathesis/service/models.py +0 -258
  223. schemathesis/service/report.py +0 -255
  224. schemathesis/service/serialization.py +0 -173
  225. schemathesis/service/usage.py +0 -66
  226. schemathesis/specs/graphql/loaders.py +0 -364
  227. schemathesis/specs/openapi/expressions/context.py +0 -16
  228. schemathesis/specs/openapi/links.py +0 -389
  229. schemathesis/specs/openapi/loaders.py +0 -707
  230. schemathesis/specs/openapi/stateful/statistic.py +0 -198
  231. schemathesis/specs/openapi/stateful/types.py +0 -14
  232. schemathesis/specs/openapi/validation.py +0 -26
  233. schemathesis/stateful/__init__.py +0 -147
  234. schemathesis/stateful/config.py +0 -97
  235. schemathesis/stateful/context.py +0 -135
  236. schemathesis/stateful/events.py +0 -274
  237. schemathesis/stateful/runner.py +0 -309
  238. schemathesis/stateful/sink.py +0 -68
  239. schemathesis/stateful/state_machine.py +0 -328
  240. schemathesis/stateful/statistic.py +0 -22
  241. schemathesis/stateful/validation.py +0 -100
  242. schemathesis/targets.py +0 -77
  243. schemathesis/transports/__init__.py +0 -369
  244. schemathesis/transports/asgi.py +0 -7
  245. schemathesis/transports/auth.py +0 -38
  246. schemathesis/transports/headers.py +0 -36
  247. schemathesis/transports/responses.py +0 -57
  248. schemathesis/types.py +0 -44
  249. schemathesis/utils.py +0 -164
  250. schemathesis-3.39.16.dist-info/METADATA +0 -293
  251. schemathesis-3.39.16.dist-info/RECORD +0 -160
  252. /schemathesis/{extra → cli/ext}/__init__.py +0 -0
  253. /schemathesis/{_lazy_import.py → core/lazy_import.py} +0 -0
  254. /schemathesis/{internal → core}/result.py +0 -0
  255. {schemathesis-3.39.16.dist-info → schemathesis-4.0.0.dist-info}/WHEEL +0 -0
@@ -1,389 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import enum
4
- import threading
5
- import time
6
- from dataclasses import asdict, dataclass, field
7
- from typing import TYPE_CHECKING, Any
8
-
9
- from ..exceptions import RuntimeErrorType, SchemaError, SchemaErrorType, format_exception
10
- from ..internal.datetime import current_datetime
11
- from ..internal.result import Err, Ok, Result
12
- from .serialization import SerializedError, SerializedTestResult
13
-
14
- if TYPE_CHECKING:
15
- from ..generation import DataGenerationMethod
16
- from ..models import APIOperation, Status, TestResult, TestResultSet
17
- from ..schemas import BaseSchema, Specification
18
- from ..service.models import AnalysisResult
19
- from ..stateful import events
20
- from . import probes
21
-
22
-
23
- @dataclass
24
- class ExecutionEvent:
25
- """Generic execution event."""
26
-
27
- # Whether this event is expected to be the last one in the event stream
28
- is_terminal = False
29
-
30
- def asdict(self, **kwargs: Any) -> dict[str, Any]:
31
- data = asdict(self, **kwargs)
32
- # An internal tag for simpler type identification
33
- data["event_type"] = self.__class__.__name__
34
- return data
35
-
36
-
37
- @dataclass
38
- class Initialized(ExecutionEvent):
39
- """Runner is initialized, settings are prepared, requests session is ready."""
40
-
41
- schema: dict[str, Any]
42
- specification: Specification
43
- # Total number of operations in the schema
44
- operations_count: int | None
45
- # Total number of links in the schema
46
- links_count: int | None
47
- # The place, where the API schema is located
48
- location: str | None
49
- seed: int | None
50
- # The base URL against which the tests are running
51
- base_url: str
52
- # The base path part of every operation
53
- base_path: str
54
- # API schema specification name
55
- specification_name: str
56
- # Monotonic clock value when the test run started. Used to properly calculate run duration, since this clock
57
- # can't go backwards.
58
- start_time: float = field(default_factory=time.monotonic)
59
- # Datetime of the test run start
60
- started_at: str = field(default_factory=current_datetime)
61
- thread_id: int = field(default_factory=threading.get_ident)
62
-
63
- @classmethod
64
- def from_schema(
65
- cls,
66
- *,
67
- schema: BaseSchema,
68
- count_operations: bool = True,
69
- count_links: bool = True,
70
- start_time: float | None = None,
71
- started_at: str | None = None,
72
- seed: int | None,
73
- ) -> Initialized:
74
- """Computes all needed data from a schema instance."""
75
- return cls(
76
- schema=schema.raw_schema,
77
- specification=schema.specification,
78
- operations_count=schema.operations_count if count_operations else None,
79
- links_count=schema.links_count if count_links else None,
80
- location=schema.location,
81
- base_url=schema.get_base_url(),
82
- base_path=schema.base_path,
83
- start_time=start_time or time.monotonic(),
84
- started_at=started_at or current_datetime(),
85
- specification_name=schema.verbose_name,
86
- seed=seed,
87
- )
88
-
89
-
90
- @dataclass
91
- class BeforeProbing(ExecutionEvent):
92
- pass
93
-
94
-
95
- @dataclass
96
- class AfterProbing(ExecutionEvent):
97
- probes: list[probes.ProbeRun] | None
98
-
99
- def asdict(self, **kwargs: Any) -> dict[str, Any]:
100
- probes = self.probes or []
101
- return {"probes": [probe.serialize() for probe in probes], "events_type": self.__class__.__name__}
102
-
103
-
104
- @dataclass
105
- class BeforeAnalysis(ExecutionEvent):
106
- pass
107
-
108
-
109
- @dataclass
110
- class AfterAnalysis(ExecutionEvent):
111
- analysis: Result[AnalysisResult, Exception] | None
112
-
113
- def _serialize(self) -> dict[str, Any]:
114
- from ..service.models import AnalysisSuccess
115
-
116
- data = {}
117
- if isinstance(self.analysis, Ok):
118
- result = self.analysis.ok()
119
- if isinstance(result, AnalysisSuccess):
120
- data["analysis_id"] = result.id
121
- else:
122
- data["error"] = result.message
123
- elif isinstance(self.analysis, Err):
124
- data["error"] = format_exception(self.analysis.err())
125
- return data
126
-
127
- def asdict(self, **kwargs: Any) -> dict[str, Any]:
128
- data = self._serialize()
129
- data["event_type"] = self.__class__.__name__
130
- return data
131
-
132
-
133
- class CurrentOperationMixin:
134
- method: str
135
- path: str
136
-
137
- @property
138
- def current_operation(self) -> str:
139
- return f"{self.method} {self.path}"
140
-
141
-
142
- @dataclass
143
- class BeforeExecution(CurrentOperationMixin, ExecutionEvent):
144
- """Happens before each tested API operation.
145
-
146
- It happens before a single hypothesis test, that may contain many examples inside.
147
- """
148
-
149
- # HTTP method
150
- method: str
151
- # Full path, including the base path
152
- path: str
153
- # Specification-specific operation name
154
- verbose_name: str
155
- # Path without the base path
156
- relative_path: str
157
- # The current level of recursion during stateful testing
158
- recursion_level: int
159
- # The way data will be generated
160
- data_generation_method: list[DataGenerationMethod]
161
- # A unique ID which connects events that happen during testing of the same API operation
162
- # It may be useful when multiple threads are involved where incoming events are not ordered
163
- correlation_id: str
164
- thread_id: int = field(default_factory=threading.get_ident)
165
-
166
- @classmethod
167
- def from_operation(
168
- cls,
169
- operation: APIOperation,
170
- recursion_level: int,
171
- data_generation_method: list[DataGenerationMethod],
172
- correlation_id: str,
173
- ) -> BeforeExecution:
174
- return cls(
175
- method=operation.method.upper(),
176
- path=operation.full_path,
177
- verbose_name=operation.verbose_name,
178
- relative_path=operation.path,
179
- recursion_level=recursion_level,
180
- data_generation_method=data_generation_method,
181
- correlation_id=correlation_id,
182
- )
183
-
184
-
185
- @dataclass
186
- class AfterExecution(CurrentOperationMixin, ExecutionEvent):
187
- """Happens after each tested API operation."""
188
-
189
- method: str
190
- path: str
191
- relative_path: str
192
- # Specification-specific operation name
193
- verbose_name: str
194
-
195
- # APIOperation test status - success / failure / error
196
- status: Status
197
- # The way data was generated
198
- data_generation_method: list[DataGenerationMethod]
199
- result: SerializedTestResult
200
- # Test running time
201
- elapsed_time: float
202
- correlation_id: str
203
- thread_id: int = field(default_factory=threading.get_ident)
204
- # Captured hypothesis stdout
205
- hypothesis_output: list[str] = field(default_factory=list)
206
-
207
- @classmethod
208
- def from_result(
209
- cls,
210
- result: TestResult,
211
- status: Status,
212
- elapsed_time: float,
213
- hypothesis_output: list[str],
214
- operation: APIOperation,
215
- data_generation_method: list[DataGenerationMethod],
216
- correlation_id: str,
217
- ) -> AfterExecution:
218
- return cls(
219
- method=operation.method.upper(),
220
- path=operation.full_path,
221
- relative_path=operation.path,
222
- verbose_name=operation.verbose_name,
223
- result=SerializedTestResult.from_test_result(result),
224
- status=status,
225
- elapsed_time=elapsed_time,
226
- hypothesis_output=hypothesis_output,
227
- data_generation_method=data_generation_method,
228
- correlation_id=correlation_id,
229
- )
230
-
231
-
232
- @dataclass
233
- class Interrupted(ExecutionEvent):
234
- """If execution was interrupted by Ctrl-C, or a received SIGTERM."""
235
-
236
- thread_id: int = field(default_factory=threading.get_ident)
237
-
238
-
239
- @enum.unique
240
- class InternalErrorType(str, enum.Enum):
241
- SCHEMA = "schema"
242
- OTHER = "other"
243
-
244
-
245
- DEFAULT_INTERNAL_ERROR_MESSAGE = "An internal error occurred during the test run"
246
-
247
-
248
- @dataclass
249
- class InternalError(ExecutionEvent):
250
- """An error that happened inside the runner."""
251
-
252
- is_terminal = True
253
-
254
- # Main error info
255
- type: InternalErrorType
256
- subtype: SchemaErrorType | None
257
- title: str
258
- message: str
259
- extras: list[str]
260
-
261
- # Exception info
262
- exception_type: str
263
- exception: str
264
- exception_with_traceback: str
265
- # Auxiliary data
266
- thread_id: int = field(default_factory=threading.get_ident)
267
-
268
- @classmethod
269
- def from_schema_error(cls, error: SchemaError) -> InternalError:
270
- return cls.with_exception(
271
- error,
272
- type_=InternalErrorType.SCHEMA,
273
- subtype=error.type,
274
- title="Schema Loading Error",
275
- message=error.message,
276
- extras=error.extras,
277
- )
278
-
279
- @classmethod
280
- def from_exc(cls, exc: Exception) -> InternalError:
281
- return cls.with_exception(
282
- exc,
283
- type_=InternalErrorType.OTHER,
284
- subtype=None,
285
- title="Test Execution Error",
286
- message=DEFAULT_INTERNAL_ERROR_MESSAGE,
287
- extras=[],
288
- )
289
-
290
- @classmethod
291
- def with_exception(
292
- cls,
293
- exc: Exception,
294
- type_: InternalErrorType,
295
- subtype: SchemaErrorType | None,
296
- title: str,
297
- message: str,
298
- extras: list[str],
299
- ) -> InternalError:
300
- exception_type = f"{exc.__class__.__module__}.{exc.__class__.__qualname__}"
301
- exception = format_exception(exc)
302
- exception_with_traceback = format_exception(exc, include_traceback=True)
303
- return cls(
304
- type=type_,
305
- subtype=subtype,
306
- title=title,
307
- message=message,
308
- extras=extras,
309
- exception_type=exception_type,
310
- exception=exception,
311
- exception_with_traceback=exception_with_traceback,
312
- )
313
-
314
-
315
- @dataclass
316
- class StatefulEvent(ExecutionEvent):
317
- """Represents an event originating from the state machine runner."""
318
-
319
- data: events.StatefulEvent
320
-
321
- __slots__ = ("data",)
322
-
323
- def asdict(self, **kwargs: Any) -> dict[str, Any]:
324
- return {"data": self.data.asdict(**kwargs), "event_type": self.__class__.__name__}
325
-
326
-
327
- @dataclass
328
- class AfterStatefulExecution(ExecutionEvent):
329
- """Happens after the stateful test run."""
330
-
331
- status: Status
332
- result: SerializedTestResult
333
- elapsed_time: float
334
- data_generation_method: list[DataGenerationMethod]
335
- thread_id: int = field(default_factory=threading.get_ident)
336
-
337
-
338
- @dataclass
339
- class Finished(ExecutionEvent):
340
- """The final event of the run.
341
-
342
- No more events after this point.
343
- """
344
-
345
- is_terminal = True
346
-
347
- passed_count: int
348
- skipped_count: int
349
- failed_count: int
350
- errored_count: int
351
-
352
- has_failures: bool
353
- has_errors: bool
354
- has_logs: bool
355
- is_empty: bool
356
- generic_errors: list[SerializedError]
357
- warnings: list[str]
358
-
359
- total: dict[str, dict[str | Status, int]]
360
-
361
- # Total test run execution time
362
- running_time: float
363
- thread_id: int = field(default_factory=threading.get_ident)
364
-
365
- @classmethod
366
- def from_results(cls, results: TestResultSet, running_time: float) -> Finished:
367
- return cls(
368
- passed_count=results.passed_count,
369
- skipped_count=results.skipped_count,
370
- failed_count=results.failed_count,
371
- errored_count=results.errored_count,
372
- has_failures=results.has_failures,
373
- has_errors=results.has_errors,
374
- has_logs=results.has_logs,
375
- is_empty=results.is_empty,
376
- total=results.total,
377
- generic_errors=[
378
- SerializedError.with_exception(
379
- type_=RuntimeErrorType.SCHEMA_GENERIC,
380
- exception=error,
381
- title=error.full_path,
382
- message=error.message,
383
- extras=[],
384
- )
385
- for error in results.generic_errors
386
- ],
387
- warnings=results.warnings,
388
- running_time=running_time,
389
- )
@@ -1,3 +0,0 @@
1
- from .core import BaseRunner
2
- from .solo import SingleThreadASGIRunner, SingleThreadRunner, SingleThreadWSGIRunner
3
- from .threadpool import ThreadPoolASGIRunner, ThreadPoolRunner, ThreadPoolWSGIRunner
@@ -1,88 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from dataclasses import dataclass
4
- from typing import TYPE_CHECKING, Any
5
-
6
- from ...constants import NOT_SET
7
- from ...internal.checks import CheckConfig
8
- from ...models import TestResult, TestResultSet
9
-
10
- if TYPE_CHECKING:
11
- import threading
12
-
13
- from ..._override import CaseOverride
14
- from ...exceptions import OperationSchemaError
15
- from ...models import Case
16
- from ...types import NotSet, RawAuth
17
-
18
-
19
- @dataclass
20
- class RunnerContext:
21
- """Holds context shared for a test run."""
22
-
23
- data: TestResultSet
24
- auth: RawAuth | None
25
- seed: int | None
26
- stop_event: threading.Event
27
- unique_data: bool
28
- outcome_cache: dict[int, BaseException | None]
29
- checks_config: CheckConfig
30
- override: CaseOverride | None
31
- no_failfast: bool
32
-
33
- __slots__ = (
34
- "data",
35
- "auth",
36
- "seed",
37
- "stop_event",
38
- "unique_data",
39
- "outcome_cache",
40
- "checks_config",
41
- "override",
42
- "no_failfast",
43
- )
44
-
45
- def __init__(
46
- self,
47
- *,
48
- seed: int | None,
49
- auth: RawAuth | None,
50
- stop_event: threading.Event,
51
- unique_data: bool,
52
- checks_config: CheckConfig,
53
- override: CaseOverride | None,
54
- no_failfast: bool,
55
- ) -> None:
56
- self.data = TestResultSet(seed=seed)
57
- self.auth = auth
58
- self.seed = seed
59
- self.stop_event = stop_event
60
- self.outcome_cache = {}
61
- self.unique_data = unique_data
62
- self.checks_config = checks_config
63
- self.override = override
64
- self.no_failfast = no_failfast
65
-
66
- def _repr_pretty_(self, *args: Any, **kwargs: Any) -> None: ...
67
-
68
- @property
69
- def is_stopped(self) -> bool:
70
- return self.stop_event.is_set()
71
-
72
- def add_result(self, result: TestResult) -> None:
73
- self.data.append(result)
74
-
75
- def add_generic_error(self, error: OperationSchemaError) -> None:
76
- self.data.generic_errors.append(error)
77
-
78
- def add_warning(self, message: str) -> None:
79
- self.data.add_warning(message)
80
-
81
- def cache_outcome(self, case: Case, outcome: BaseException | None) -> None:
82
- self.outcome_cache[hash(case)] = outcome
83
-
84
- def get_cached_outcome(self, case: Case) -> BaseException | None | NotSet:
85
- return self.outcome_cache.get(hash(case), NOT_SET)
86
-
87
-
88
- ALL_NOT_FOUND_WARNING_MESSAGE = "All API responses have a 404 status code. Did you specify the proper API location?"