schemathesis 3.15.4__py3-none-any.whl → 4.4.2__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.
- schemathesis/__init__.py +53 -25
- schemathesis/auths.py +507 -0
- schemathesis/checks.py +190 -25
- schemathesis/cli/__init__.py +27 -1219
- schemathesis/cli/__main__.py +4 -0
- schemathesis/cli/commands/__init__.py +133 -0
- schemathesis/cli/commands/data.py +10 -0
- schemathesis/cli/commands/run/__init__.py +602 -0
- schemathesis/cli/commands/run/context.py +228 -0
- schemathesis/cli/commands/run/events.py +60 -0
- schemathesis/cli/commands/run/executor.py +157 -0
- schemathesis/cli/commands/run/filters.py +53 -0
- schemathesis/cli/commands/run/handlers/__init__.py +46 -0
- schemathesis/cli/commands/run/handlers/base.py +45 -0
- schemathesis/cli/commands/run/handlers/cassettes.py +464 -0
- schemathesis/cli/commands/run/handlers/junitxml.py +60 -0
- schemathesis/cli/commands/run/handlers/output.py +1750 -0
- schemathesis/cli/commands/run/loaders.py +118 -0
- schemathesis/cli/commands/run/validation.py +256 -0
- schemathesis/cli/constants.py +5 -0
- schemathesis/cli/core.py +19 -0
- schemathesis/cli/ext/fs.py +16 -0
- schemathesis/cli/ext/groups.py +203 -0
- schemathesis/cli/ext/options.py +81 -0
- schemathesis/config/__init__.py +202 -0
- schemathesis/config/_auth.py +51 -0
- schemathesis/config/_checks.py +268 -0
- schemathesis/config/_diff_base.py +101 -0
- schemathesis/config/_env.py +21 -0
- schemathesis/config/_error.py +163 -0
- schemathesis/config/_generation.py +157 -0
- schemathesis/config/_health_check.py +24 -0
- schemathesis/config/_operations.py +335 -0
- schemathesis/config/_output.py +171 -0
- schemathesis/config/_parameters.py +19 -0
- schemathesis/config/_phases.py +253 -0
- schemathesis/config/_projects.py +543 -0
- schemathesis/config/_rate_limit.py +17 -0
- schemathesis/config/_report.py +120 -0
- schemathesis/config/_validator.py +9 -0
- schemathesis/config/_warnings.py +89 -0
- schemathesis/config/schema.json +975 -0
- schemathesis/core/__init__.py +72 -0
- schemathesis/core/adapter.py +34 -0
- schemathesis/core/compat.py +32 -0
- schemathesis/core/control.py +2 -0
- schemathesis/core/curl.py +100 -0
- schemathesis/core/deserialization.py +210 -0
- schemathesis/core/errors.py +588 -0
- schemathesis/core/failures.py +316 -0
- schemathesis/core/fs.py +19 -0
- schemathesis/core/hooks.py +20 -0
- schemathesis/core/jsonschema/__init__.py +13 -0
- schemathesis/core/jsonschema/bundler.py +183 -0
- schemathesis/core/jsonschema/keywords.py +40 -0
- schemathesis/core/jsonschema/references.py +222 -0
- schemathesis/core/jsonschema/types.py +41 -0
- schemathesis/core/lazy_import.py +15 -0
- schemathesis/core/loaders.py +107 -0
- schemathesis/core/marks.py +66 -0
- schemathesis/core/media_types.py +79 -0
- schemathesis/core/output/__init__.py +46 -0
- schemathesis/core/output/sanitization.py +54 -0
- schemathesis/core/parameters.py +45 -0
- schemathesis/core/rate_limit.py +60 -0
- schemathesis/core/registries.py +34 -0
- schemathesis/core/result.py +27 -0
- schemathesis/core/schema_analysis.py +17 -0
- schemathesis/core/shell.py +203 -0
- schemathesis/core/transforms.py +144 -0
- schemathesis/core/transport.py +223 -0
- schemathesis/core/validation.py +73 -0
- schemathesis/core/version.py +7 -0
- schemathesis/engine/__init__.py +28 -0
- schemathesis/engine/context.py +152 -0
- schemathesis/engine/control.py +44 -0
- schemathesis/engine/core.py +201 -0
- schemathesis/engine/errors.py +446 -0
- schemathesis/engine/events.py +284 -0
- schemathesis/engine/observations.py +42 -0
- schemathesis/engine/phases/__init__.py +108 -0
- schemathesis/engine/phases/analysis.py +28 -0
- schemathesis/engine/phases/probes.py +172 -0
- schemathesis/engine/phases/stateful/__init__.py +68 -0
- schemathesis/engine/phases/stateful/_executor.py +364 -0
- schemathesis/engine/phases/stateful/context.py +85 -0
- schemathesis/engine/phases/unit/__init__.py +220 -0
- schemathesis/engine/phases/unit/_executor.py +459 -0
- schemathesis/engine/phases/unit/_pool.py +82 -0
- schemathesis/engine/recorder.py +254 -0
- schemathesis/errors.py +47 -0
- schemathesis/filters.py +395 -0
- schemathesis/generation/__init__.py +25 -0
- schemathesis/generation/case.py +478 -0
- schemathesis/generation/coverage.py +1528 -0
- schemathesis/generation/hypothesis/__init__.py +121 -0
- schemathesis/generation/hypothesis/builder.py +992 -0
- schemathesis/generation/hypothesis/examples.py +56 -0
- schemathesis/generation/hypothesis/given.py +66 -0
- schemathesis/generation/hypothesis/reporting.py +285 -0
- schemathesis/generation/meta.py +227 -0
- schemathesis/generation/metrics.py +93 -0
- schemathesis/generation/modes.py +20 -0
- schemathesis/generation/overrides.py +127 -0
- schemathesis/generation/stateful/__init__.py +37 -0
- schemathesis/generation/stateful/state_machine.py +294 -0
- schemathesis/graphql/__init__.py +15 -0
- schemathesis/graphql/checks.py +109 -0
- schemathesis/graphql/loaders.py +285 -0
- schemathesis/hooks.py +270 -91
- schemathesis/openapi/__init__.py +13 -0
- schemathesis/openapi/checks.py +467 -0
- schemathesis/openapi/generation/__init__.py +0 -0
- schemathesis/openapi/generation/filters.py +72 -0
- schemathesis/openapi/loaders.py +315 -0
- schemathesis/pytest/__init__.py +5 -0
- schemathesis/pytest/control_flow.py +7 -0
- schemathesis/pytest/lazy.py +341 -0
- schemathesis/pytest/loaders.py +36 -0
- schemathesis/pytest/plugin.py +357 -0
- schemathesis/python/__init__.py +0 -0
- schemathesis/python/asgi.py +12 -0
- schemathesis/python/wsgi.py +12 -0
- schemathesis/schemas.py +682 -257
- schemathesis/specs/graphql/__init__.py +0 -1
- schemathesis/specs/graphql/nodes.py +26 -2
- schemathesis/specs/graphql/scalars.py +77 -12
- schemathesis/specs/graphql/schemas.py +367 -148
- schemathesis/specs/graphql/validation.py +33 -0
- schemathesis/specs/openapi/__init__.py +9 -1
- schemathesis/specs/openapi/_hypothesis.py +555 -318
- schemathesis/specs/openapi/adapter/__init__.py +10 -0
- schemathesis/specs/openapi/adapter/parameters.py +729 -0
- schemathesis/specs/openapi/adapter/protocol.py +59 -0
- schemathesis/specs/openapi/adapter/references.py +19 -0
- schemathesis/specs/openapi/adapter/responses.py +368 -0
- schemathesis/specs/openapi/adapter/security.py +144 -0
- schemathesis/specs/openapi/adapter/v2.py +30 -0
- schemathesis/specs/openapi/adapter/v3_0.py +30 -0
- schemathesis/specs/openapi/adapter/v3_1.py +30 -0
- schemathesis/specs/openapi/analysis.py +96 -0
- schemathesis/specs/openapi/checks.py +748 -82
- schemathesis/specs/openapi/converter.py +176 -37
- schemathesis/specs/openapi/definitions.py +599 -4
- schemathesis/specs/openapi/examples.py +581 -165
- schemathesis/specs/openapi/expressions/__init__.py +52 -5
- schemathesis/specs/openapi/expressions/extractors.py +25 -0
- schemathesis/specs/openapi/expressions/lexer.py +34 -31
- schemathesis/specs/openapi/expressions/nodes.py +97 -46
- schemathesis/specs/openapi/expressions/parser.py +35 -13
- schemathesis/specs/openapi/formats.py +122 -0
- schemathesis/specs/openapi/media_types.py +75 -0
- schemathesis/specs/openapi/negative/__init__.py +93 -73
- schemathesis/specs/openapi/negative/mutations.py +294 -103
- schemathesis/specs/openapi/negative/utils.py +0 -9
- schemathesis/specs/openapi/patterns.py +458 -0
- schemathesis/specs/openapi/references.py +60 -81
- schemathesis/specs/openapi/schemas.py +647 -666
- schemathesis/specs/openapi/serialization.py +53 -30
- schemathesis/specs/openapi/stateful/__init__.py +403 -68
- schemathesis/specs/openapi/stateful/control.py +87 -0
- schemathesis/specs/openapi/stateful/dependencies/__init__.py +232 -0
- schemathesis/specs/openapi/stateful/dependencies/inputs.py +428 -0
- schemathesis/specs/openapi/stateful/dependencies/models.py +341 -0
- schemathesis/specs/openapi/stateful/dependencies/naming.py +491 -0
- schemathesis/specs/openapi/stateful/dependencies/outputs.py +34 -0
- schemathesis/specs/openapi/stateful/dependencies/resources.py +339 -0
- schemathesis/specs/openapi/stateful/dependencies/schemas.py +447 -0
- schemathesis/specs/openapi/stateful/inference.py +254 -0
- schemathesis/specs/openapi/stateful/links.py +219 -78
- schemathesis/specs/openapi/types/__init__.py +3 -0
- schemathesis/specs/openapi/types/common.py +23 -0
- schemathesis/specs/openapi/types/v2.py +129 -0
- schemathesis/specs/openapi/types/v3.py +134 -0
- schemathesis/specs/openapi/utils.py +7 -6
- schemathesis/specs/openapi/warnings.py +75 -0
- schemathesis/transport/__init__.py +224 -0
- schemathesis/transport/asgi.py +26 -0
- schemathesis/transport/prepare.py +126 -0
- schemathesis/transport/requests.py +278 -0
- schemathesis/transport/serialization.py +329 -0
- schemathesis/transport/wsgi.py +175 -0
- schemathesis-4.4.2.dist-info/METADATA +213 -0
- schemathesis-4.4.2.dist-info/RECORD +192 -0
- {schemathesis-3.15.4.dist-info → schemathesis-4.4.2.dist-info}/WHEEL +1 -1
- schemathesis-4.4.2.dist-info/entry_points.txt +6 -0
- {schemathesis-3.15.4.dist-info → schemathesis-4.4.2.dist-info/licenses}/LICENSE +1 -1
- schemathesis/_compat.py +0 -57
- schemathesis/_hypothesis.py +0 -123
- schemathesis/auth.py +0 -214
- schemathesis/cli/callbacks.py +0 -240
- schemathesis/cli/cassettes.py +0 -351
- schemathesis/cli/context.py +0 -38
- schemathesis/cli/debug.py +0 -21
- schemathesis/cli/handlers.py +0 -11
- schemathesis/cli/junitxml.py +0 -41
- schemathesis/cli/options.py +0 -70
- schemathesis/cli/output/__init__.py +0 -1
- schemathesis/cli/output/default.py +0 -521
- schemathesis/cli/output/short.py +0 -40
- schemathesis/constants.py +0 -88
- schemathesis/exceptions.py +0 -257
- schemathesis/extra/_aiohttp.py +0 -27
- schemathesis/extra/_flask.py +0 -10
- schemathesis/extra/_server.py +0 -16
- schemathesis/extra/pytest_plugin.py +0 -251
- schemathesis/failures.py +0 -145
- schemathesis/fixups/__init__.py +0 -29
- schemathesis/fixups/fast_api.py +0 -30
- schemathesis/graphql.py +0 -5
- schemathesis/internal.py +0 -6
- schemathesis/lazy.py +0 -301
- schemathesis/models.py +0 -1113
- schemathesis/parameters.py +0 -91
- schemathesis/runner/__init__.py +0 -470
- schemathesis/runner/events.py +0 -242
- schemathesis/runner/impl/__init__.py +0 -3
- schemathesis/runner/impl/core.py +0 -791
- schemathesis/runner/impl/solo.py +0 -85
- schemathesis/runner/impl/threadpool.py +0 -367
- schemathesis/runner/serialization.py +0 -206
- schemathesis/serializers.py +0 -253
- schemathesis/service/__init__.py +0 -18
- schemathesis/service/auth.py +0 -10
- schemathesis/service/client.py +0 -62
- schemathesis/service/constants.py +0 -25
- schemathesis/service/events.py +0 -39
- schemathesis/service/handler.py +0 -46
- schemathesis/service/hosts.py +0 -74
- schemathesis/service/metadata.py +0 -42
- schemathesis/service/models.py +0 -21
- schemathesis/service/serialization.py +0 -184
- schemathesis/service/worker.py +0 -39
- schemathesis/specs/graphql/loaders.py +0 -215
- schemathesis/specs/openapi/constants.py +0 -7
- schemathesis/specs/openapi/expressions/context.py +0 -12
- schemathesis/specs/openapi/expressions/pointers.py +0 -29
- schemathesis/specs/openapi/filters.py +0 -44
- schemathesis/specs/openapi/links.py +0 -303
- schemathesis/specs/openapi/loaders.py +0 -453
- schemathesis/specs/openapi/parameters.py +0 -430
- schemathesis/specs/openapi/security.py +0 -129
- schemathesis/specs/openapi/validation.py +0 -24
- schemathesis/stateful.py +0 -358
- schemathesis/targets.py +0 -32
- schemathesis/types.py +0 -38
- schemathesis/utils.py +0 -475
- schemathesis-3.15.4.dist-info/METADATA +0 -202
- schemathesis-3.15.4.dist-info/RECORD +0 -99
- schemathesis-3.15.4.dist-info/entry_points.txt +0 -7
- /schemathesis/{extra → cli/ext}/__init__.py +0 -0
schemathesis/parameters.py
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
"""API operation parameters.
|
|
2
|
-
|
|
3
|
-
These are basic entities that describe what data could be sent to the API.
|
|
4
|
-
"""
|
|
5
|
-
from typing import TYPE_CHECKING, Any, Dict, Generator, Generic, List, TypeVar
|
|
6
|
-
|
|
7
|
-
import attr
|
|
8
|
-
|
|
9
|
-
if TYPE_CHECKING:
|
|
10
|
-
from .models import APIOperation
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
@attr.s(slots=True, eq=False) # pragma: no mutate
|
|
14
|
-
class Parameter:
|
|
15
|
-
"""A logically separate parameter bound to a location (e.g., to "query string").
|
|
16
|
-
|
|
17
|
-
For example, if the API requires multiple headers to be present, each header is presented as a separate
|
|
18
|
-
`Parameter` instance.
|
|
19
|
-
"""
|
|
20
|
-
|
|
21
|
-
# The parameter definition in the language acceptable by the API
|
|
22
|
-
definition: Any = attr.ib() # pragma: no mutate
|
|
23
|
-
|
|
24
|
-
@property
|
|
25
|
-
def location(self) -> str:
|
|
26
|
-
"""Where this parameter is located.
|
|
27
|
-
|
|
28
|
-
E.g. "query" or "body"
|
|
29
|
-
"""
|
|
30
|
-
raise NotImplementedError
|
|
31
|
-
|
|
32
|
-
@property
|
|
33
|
-
def name(self) -> str:
|
|
34
|
-
"""Parameter name."""
|
|
35
|
-
raise NotImplementedError
|
|
36
|
-
|
|
37
|
-
@property
|
|
38
|
-
def is_required(self) -> bool:
|
|
39
|
-
"""Whether the parameter is required for a successful API call."""
|
|
40
|
-
raise NotImplementedError
|
|
41
|
-
|
|
42
|
-
@property
|
|
43
|
-
def example(self) -> Any:
|
|
44
|
-
"""Parameter example."""
|
|
45
|
-
raise NotImplementedError
|
|
46
|
-
|
|
47
|
-
def serialize(self, operation: "APIOperation") -> str:
|
|
48
|
-
"""Get parameter's string representation."""
|
|
49
|
-
raise NotImplementedError
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
P = TypeVar("P", bound=Parameter)
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
@attr.s # pragma: no mutate
|
|
56
|
-
class ParameterSet(Generic[P]):
|
|
57
|
-
"""A set of parameters for the same location."""
|
|
58
|
-
|
|
59
|
-
items: List[P] = attr.ib(factory=list) # pragma: no mutate
|
|
60
|
-
|
|
61
|
-
def add(self, parameter: P) -> None:
|
|
62
|
-
"""Add a new parameter."""
|
|
63
|
-
self.items.append(parameter)
|
|
64
|
-
|
|
65
|
-
@property
|
|
66
|
-
def example(self) -> Dict[str, Any]:
|
|
67
|
-
"""Composite example gathered from individual parameters."""
|
|
68
|
-
return {item.name: item.example for item in self.items if item.example}
|
|
69
|
-
|
|
70
|
-
def __bool__(self) -> bool:
|
|
71
|
-
return bool(self.items)
|
|
72
|
-
|
|
73
|
-
def __iter__(self) -> Generator[P, None, None]:
|
|
74
|
-
yield from iter(self.items)
|
|
75
|
-
|
|
76
|
-
def __len__(self) -> int:
|
|
77
|
-
return len(self.items)
|
|
78
|
-
|
|
79
|
-
def __getitem__(self, item: int) -> P:
|
|
80
|
-
return self.items[item]
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
class PayloadAlternatives(ParameterSet[P]):
|
|
84
|
-
"""A set of alternative payloads."""
|
|
85
|
-
|
|
86
|
-
@property
|
|
87
|
-
def example(self) -> Any:
|
|
88
|
-
"""We take only the first example."""
|
|
89
|
-
# May be extended in the future
|
|
90
|
-
if self.items:
|
|
91
|
-
return self.items[0].example
|
schemathesis/runner/__init__.py
DELETED
|
@@ -1,470 +0,0 @@
|
|
|
1
|
-
from typing import Any, Callable, Dict, Generator, Iterable, List, Optional, Tuple, Union
|
|
2
|
-
from urllib.parse import urlparse
|
|
3
|
-
|
|
4
|
-
import hypothesis.errors
|
|
5
|
-
from hypothesis.database import DirectoryBasedExampleDatabase, InMemoryExampleDatabase
|
|
6
|
-
from starlette.applications import Starlette
|
|
7
|
-
|
|
8
|
-
from ..checks import DEFAULT_CHECKS
|
|
9
|
-
from ..constants import (
|
|
10
|
-
DEFAULT_DATA_GENERATION_METHODS,
|
|
11
|
-
DEFAULT_DEADLINE,
|
|
12
|
-
DEFAULT_STATEFUL_RECURSION_LIMIT,
|
|
13
|
-
HYPOTHESIS_IN_MEMORY_DATABASE_IDENTIFIER,
|
|
14
|
-
DataGenerationMethod,
|
|
15
|
-
)
|
|
16
|
-
from ..models import CheckFunction
|
|
17
|
-
from ..schemas import BaseSchema
|
|
18
|
-
from ..specs.graphql import loaders as gql_loaders
|
|
19
|
-
from ..specs.openapi import loaders as oas_loaders
|
|
20
|
-
from ..stateful import Stateful
|
|
21
|
-
from ..targets import DEFAULT_TARGETS, Target
|
|
22
|
-
from ..types import Filter, NotSet, RawAuth, RequestCert
|
|
23
|
-
from ..utils import deprecated, dict_not_none_values, dict_true_values, file_exists, get_requests_auth, import_app
|
|
24
|
-
from . import events
|
|
25
|
-
from .impl import (
|
|
26
|
-
BaseRunner,
|
|
27
|
-
SingleThreadASGIRunner,
|
|
28
|
-
SingleThreadRunner,
|
|
29
|
-
SingleThreadWSGIRunner,
|
|
30
|
-
ThreadPoolASGIRunner,
|
|
31
|
-
ThreadPoolRunner,
|
|
32
|
-
ThreadPoolWSGIRunner,
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
@deprecated(removed_in="4.0", replacement="schemathesis.runner.from_schema")
|
|
37
|
-
def prepare(
|
|
38
|
-
schema_uri: Union[str, Dict[str, Any]],
|
|
39
|
-
*,
|
|
40
|
-
# Runtime behavior
|
|
41
|
-
checks: Iterable[CheckFunction] = DEFAULT_CHECKS,
|
|
42
|
-
data_generation_methods: Tuple[DataGenerationMethod, ...] = DEFAULT_DATA_GENERATION_METHODS,
|
|
43
|
-
max_response_time: Optional[int] = None,
|
|
44
|
-
targets: Iterable[Target] = DEFAULT_TARGETS,
|
|
45
|
-
workers_num: int = 1,
|
|
46
|
-
seed: Optional[int] = None,
|
|
47
|
-
exit_first: bool = False,
|
|
48
|
-
dry_run: bool = False,
|
|
49
|
-
store_interactions: bool = False,
|
|
50
|
-
stateful: Optional[Stateful] = None,
|
|
51
|
-
stateful_recursion_limit: int = DEFAULT_STATEFUL_RECURSION_LIMIT,
|
|
52
|
-
# Schema loading
|
|
53
|
-
loader: Callable = oas_loaders.from_uri,
|
|
54
|
-
base_url: Optional[str] = None,
|
|
55
|
-
auth: Optional[Tuple[str, str]] = None,
|
|
56
|
-
auth_type: Optional[str] = None,
|
|
57
|
-
headers: Optional[Dict[str, str]] = None,
|
|
58
|
-
request_timeout: Optional[int] = None,
|
|
59
|
-
request_tls_verify: Union[bool, str] = True,
|
|
60
|
-
request_cert: Optional[RequestCert] = None,
|
|
61
|
-
endpoint: Optional[Filter] = None,
|
|
62
|
-
method: Optional[Filter] = None,
|
|
63
|
-
tag: Optional[Filter] = None,
|
|
64
|
-
operation_id: Optional[Filter] = None,
|
|
65
|
-
app: Optional[str] = None,
|
|
66
|
-
validate_schema: bool = True,
|
|
67
|
-
skip_deprecated_operations: bool = False,
|
|
68
|
-
force_schema_version: Optional[str] = None,
|
|
69
|
-
count_operations: bool = True,
|
|
70
|
-
# Hypothesis-specific configuration
|
|
71
|
-
hypothesis_deadline: Optional[Union[int, NotSet]] = None,
|
|
72
|
-
hypothesis_derandomize: Optional[bool] = None,
|
|
73
|
-
hypothesis_max_examples: Optional[int] = None,
|
|
74
|
-
hypothesis_phases: Optional[List[hypothesis.Phase]] = None,
|
|
75
|
-
hypothesis_report_multiple_bugs: Optional[bool] = None,
|
|
76
|
-
hypothesis_suppress_health_check: Optional[List[hypothesis.HealthCheck]] = None,
|
|
77
|
-
hypothesis_verbosity: Optional[hypothesis.Verbosity] = None,
|
|
78
|
-
) -> Generator[events.ExecutionEvent, None, None]:
|
|
79
|
-
"""Prepare a generator that will run test cases against the given API definition."""
|
|
80
|
-
# pylint: disable=too-many-locals
|
|
81
|
-
|
|
82
|
-
validate_loader(loader, schema_uri)
|
|
83
|
-
|
|
84
|
-
if auth is None:
|
|
85
|
-
# Auth type doesn't matter if auth is not passed
|
|
86
|
-
auth_type = None # type: ignore
|
|
87
|
-
hypothesis_settings = prepare_hypothesis_settings(
|
|
88
|
-
deadline=hypothesis_deadline,
|
|
89
|
-
derandomize=hypothesis_derandomize,
|
|
90
|
-
max_examples=hypothesis_max_examples,
|
|
91
|
-
phases=hypothesis_phases,
|
|
92
|
-
report_multiple_bugs=hypothesis_report_multiple_bugs,
|
|
93
|
-
suppress_health_check=hypothesis_suppress_health_check,
|
|
94
|
-
verbosity=hypothesis_verbosity,
|
|
95
|
-
)
|
|
96
|
-
return execute_from_schema(
|
|
97
|
-
schema_uri=schema_uri,
|
|
98
|
-
loader=loader,
|
|
99
|
-
base_url=base_url,
|
|
100
|
-
endpoint=endpoint,
|
|
101
|
-
method=method,
|
|
102
|
-
tag=tag,
|
|
103
|
-
operation_id=operation_id,
|
|
104
|
-
app=app,
|
|
105
|
-
validate_schema=validate_schema,
|
|
106
|
-
skip_deprecated_operations=skip_deprecated_operations,
|
|
107
|
-
force_schema_version=force_schema_version,
|
|
108
|
-
checks=checks,
|
|
109
|
-
data_generation_methods=data_generation_methods,
|
|
110
|
-
max_response_time=max_response_time,
|
|
111
|
-
targets=targets,
|
|
112
|
-
hypothesis_settings=hypothesis_settings,
|
|
113
|
-
seed=seed,
|
|
114
|
-
workers_num=workers_num,
|
|
115
|
-
exit_first=exit_first,
|
|
116
|
-
dry_run=dry_run,
|
|
117
|
-
auth=auth,
|
|
118
|
-
auth_type=auth_type,
|
|
119
|
-
headers=headers,
|
|
120
|
-
request_timeout=request_timeout,
|
|
121
|
-
request_tls_verify=request_tls_verify,
|
|
122
|
-
request_cert=request_cert,
|
|
123
|
-
store_interactions=store_interactions,
|
|
124
|
-
stateful=stateful,
|
|
125
|
-
stateful_recursion_limit=stateful_recursion_limit,
|
|
126
|
-
count_operations=count_operations,
|
|
127
|
-
)
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
def validate_loader(loader: Callable, schema_uri: Union[str, Dict[str, Any]]) -> None:
|
|
131
|
-
"""Sanity checking for input schema & loader."""
|
|
132
|
-
if loader not in (
|
|
133
|
-
oas_loaders.from_uri,
|
|
134
|
-
oas_loaders.from_aiohttp,
|
|
135
|
-
oas_loaders.from_dict,
|
|
136
|
-
oas_loaders.from_file,
|
|
137
|
-
oas_loaders.from_path,
|
|
138
|
-
oas_loaders.from_asgi,
|
|
139
|
-
oas_loaders.from_wsgi,
|
|
140
|
-
gql_loaders.from_dict,
|
|
141
|
-
gql_loaders.from_url,
|
|
142
|
-
gql_loaders.from_wsgi,
|
|
143
|
-
):
|
|
144
|
-
# Custom loaders are not checked
|
|
145
|
-
return
|
|
146
|
-
if isinstance(schema_uri, dict):
|
|
147
|
-
if loader not in (oas_loaders.from_dict, gql_loaders.from_dict):
|
|
148
|
-
raise ValueError("Dictionary as a schema is allowed only with `from_dict` loader")
|
|
149
|
-
elif loader in (oas_loaders.from_dict, gql_loaders.from_dict):
|
|
150
|
-
raise ValueError("Schema should be a dictionary for `from_dict` loader")
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
def execute_from_schema(
|
|
154
|
-
*,
|
|
155
|
-
schema_uri: Union[str, Dict[str, Any]],
|
|
156
|
-
loader: Callable = oas_loaders.from_uri,
|
|
157
|
-
base_url: Optional[str] = None,
|
|
158
|
-
endpoint: Optional[Filter] = None,
|
|
159
|
-
method: Optional[Filter] = None,
|
|
160
|
-
tag: Optional[Filter] = None,
|
|
161
|
-
operation_id: Optional[Filter] = None,
|
|
162
|
-
app: Optional[str] = None,
|
|
163
|
-
validate_schema: bool = True,
|
|
164
|
-
skip_deprecated_operations: bool = False,
|
|
165
|
-
force_schema_version: Optional[str] = None,
|
|
166
|
-
checks: Iterable[CheckFunction],
|
|
167
|
-
data_generation_methods: Tuple[DataGenerationMethod, ...] = DEFAULT_DATA_GENERATION_METHODS,
|
|
168
|
-
max_response_time: Optional[int] = None,
|
|
169
|
-
targets: Iterable[Target],
|
|
170
|
-
workers_num: int = 1,
|
|
171
|
-
hypothesis_settings: hypothesis.settings,
|
|
172
|
-
auth: Optional[RawAuth] = None,
|
|
173
|
-
auth_type: Optional[str] = None,
|
|
174
|
-
headers: Optional[Dict[str, Any]] = None,
|
|
175
|
-
request_timeout: Optional[int] = None,
|
|
176
|
-
request_tls_verify: Union[bool, str] = True,
|
|
177
|
-
request_cert: Optional[RequestCert] = None,
|
|
178
|
-
seed: Optional[int] = None,
|
|
179
|
-
exit_first: bool = False,
|
|
180
|
-
dry_run: bool = False,
|
|
181
|
-
store_interactions: bool = False,
|
|
182
|
-
stateful: Optional[Stateful] = None,
|
|
183
|
-
stateful_recursion_limit: int = DEFAULT_STATEFUL_RECURSION_LIMIT,
|
|
184
|
-
count_operations: bool = True,
|
|
185
|
-
) -> Generator[events.ExecutionEvent, None, None]:
|
|
186
|
-
"""Execute tests for the given schema.
|
|
187
|
-
|
|
188
|
-
Provides the main testing loop and preparation step.
|
|
189
|
-
"""
|
|
190
|
-
# pylint: disable=too-many-locals
|
|
191
|
-
try:
|
|
192
|
-
if app is not None:
|
|
193
|
-
app = import_app(app)
|
|
194
|
-
schema = load_schema(
|
|
195
|
-
schema_uri,
|
|
196
|
-
base_url=base_url,
|
|
197
|
-
loader=loader,
|
|
198
|
-
app=app,
|
|
199
|
-
validate_schema=validate_schema,
|
|
200
|
-
skip_deprecated_operations=skip_deprecated_operations,
|
|
201
|
-
auth=auth,
|
|
202
|
-
auth_type=auth_type,
|
|
203
|
-
headers=headers,
|
|
204
|
-
endpoint=endpoint,
|
|
205
|
-
method=method,
|
|
206
|
-
tag=tag,
|
|
207
|
-
operation_id=operation_id,
|
|
208
|
-
data_generation_methods=data_generation_methods,
|
|
209
|
-
force_schema_version=force_schema_version,
|
|
210
|
-
request_tls_verify=request_tls_verify,
|
|
211
|
-
request_cert=request_cert,
|
|
212
|
-
)
|
|
213
|
-
yield from from_schema(
|
|
214
|
-
schema,
|
|
215
|
-
checks=checks,
|
|
216
|
-
max_response_time=max_response_time,
|
|
217
|
-
targets=targets,
|
|
218
|
-
hypothesis_settings=hypothesis_settings,
|
|
219
|
-
auth=auth,
|
|
220
|
-
auth_type=auth_type,
|
|
221
|
-
headers=headers,
|
|
222
|
-
seed=seed,
|
|
223
|
-
workers_num=workers_num,
|
|
224
|
-
request_timeout=request_timeout,
|
|
225
|
-
request_tls_verify=request_tls_verify,
|
|
226
|
-
request_cert=request_cert,
|
|
227
|
-
exit_first=exit_first,
|
|
228
|
-
dry_run=dry_run,
|
|
229
|
-
store_interactions=store_interactions,
|
|
230
|
-
stateful=stateful,
|
|
231
|
-
stateful_recursion_limit=stateful_recursion_limit,
|
|
232
|
-
count_operations=count_operations,
|
|
233
|
-
).execute()
|
|
234
|
-
except Exception as exc:
|
|
235
|
-
yield events.InternalError.from_exc(exc)
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
def load_schema(
|
|
239
|
-
schema_uri: Union[str, Dict[str, Any]],
|
|
240
|
-
*,
|
|
241
|
-
base_url: Optional[str] = None,
|
|
242
|
-
loader: Callable = oas_loaders.from_uri,
|
|
243
|
-
app: Any = None,
|
|
244
|
-
validate_schema: bool = True,
|
|
245
|
-
skip_deprecated_operations: bool = False,
|
|
246
|
-
data_generation_methods: Tuple[DataGenerationMethod, ...] = DEFAULT_DATA_GENERATION_METHODS,
|
|
247
|
-
force_schema_version: Optional[str] = None,
|
|
248
|
-
request_tls_verify: Union[bool, str] = True,
|
|
249
|
-
request_cert: Optional[RequestCert] = None,
|
|
250
|
-
# Network request parameters
|
|
251
|
-
auth: Optional[Tuple[str, str]] = None,
|
|
252
|
-
auth_type: Optional[str] = None,
|
|
253
|
-
headers: Optional[Dict[str, str]] = None,
|
|
254
|
-
# Schema filters
|
|
255
|
-
endpoint: Optional[Filter] = None,
|
|
256
|
-
method: Optional[Filter] = None,
|
|
257
|
-
tag: Optional[Filter] = None,
|
|
258
|
-
operation_id: Optional[Filter] = None,
|
|
259
|
-
) -> BaseSchema:
|
|
260
|
-
"""Load schema via specified loader and parameters."""
|
|
261
|
-
loader_options = dict_true_values(
|
|
262
|
-
base_url=base_url,
|
|
263
|
-
endpoint=endpoint,
|
|
264
|
-
method=method,
|
|
265
|
-
tag=tag,
|
|
266
|
-
operation_id=operation_id,
|
|
267
|
-
app=app,
|
|
268
|
-
data_generation_methods=data_generation_methods,
|
|
269
|
-
)
|
|
270
|
-
|
|
271
|
-
if not isinstance(schema_uri, dict):
|
|
272
|
-
if file_exists(schema_uri):
|
|
273
|
-
loader = oas_loaders.from_path
|
|
274
|
-
elif loader is not oas_loaders.from_path:
|
|
275
|
-
if app is not None and not urlparse(schema_uri).netloc:
|
|
276
|
-
# If `schema` is not an existing filesystem path, or a URL then it is considered as a path within
|
|
277
|
-
# the given app
|
|
278
|
-
loader = oas_loaders.get_loader_for_app(app)
|
|
279
|
-
loader_options.update(dict_true_values(headers=headers))
|
|
280
|
-
else:
|
|
281
|
-
loader_options.update(dict_true_values(headers=headers, auth=auth, auth_type=auth_type))
|
|
282
|
-
|
|
283
|
-
if loader is oas_loaders.from_uri and loader_options.get("auth"):
|
|
284
|
-
loader_options["auth"] = get_requests_auth(loader_options["auth"], loader_options.pop("auth_type", None))
|
|
285
|
-
if loader in (oas_loaders.from_uri, oas_loaders.from_aiohttp):
|
|
286
|
-
loader_options["verify"] = request_tls_verify
|
|
287
|
-
loader_options["cert"] = request_cert
|
|
288
|
-
|
|
289
|
-
return loader(
|
|
290
|
-
schema_uri,
|
|
291
|
-
validate_schema=validate_schema,
|
|
292
|
-
skip_deprecated_operations=skip_deprecated_operations,
|
|
293
|
-
force_schema_version=force_schema_version,
|
|
294
|
-
**loader_options,
|
|
295
|
-
)
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
def from_schema(
|
|
299
|
-
schema: BaseSchema,
|
|
300
|
-
*,
|
|
301
|
-
checks: Iterable[CheckFunction] = DEFAULT_CHECKS,
|
|
302
|
-
max_response_time: Optional[int] = None,
|
|
303
|
-
targets: Iterable[Target] = DEFAULT_TARGETS,
|
|
304
|
-
workers_num: int = 1,
|
|
305
|
-
hypothesis_settings: Optional[hypothesis.settings] = None,
|
|
306
|
-
auth: Optional[RawAuth] = None,
|
|
307
|
-
auth_type: Optional[str] = None,
|
|
308
|
-
headers: Optional[Dict[str, Any]] = None,
|
|
309
|
-
request_timeout: Optional[int] = None,
|
|
310
|
-
request_tls_verify: Union[bool, str] = True,
|
|
311
|
-
request_cert: Optional[RequestCert] = None,
|
|
312
|
-
seed: Optional[int] = None,
|
|
313
|
-
exit_first: bool = False,
|
|
314
|
-
dry_run: bool = False,
|
|
315
|
-
store_interactions: bool = False,
|
|
316
|
-
stateful: Optional[Stateful] = None,
|
|
317
|
-
stateful_recursion_limit: int = DEFAULT_STATEFUL_RECURSION_LIMIT,
|
|
318
|
-
count_operations: bool = True,
|
|
319
|
-
) -> BaseRunner:
|
|
320
|
-
hypothesis_settings = hypothesis_settings or hypothesis.settings(deadline=DEFAULT_DEADLINE)
|
|
321
|
-
if workers_num > 1:
|
|
322
|
-
if not schema.app:
|
|
323
|
-
return ThreadPoolRunner(
|
|
324
|
-
schema=schema,
|
|
325
|
-
checks=checks,
|
|
326
|
-
max_response_time=max_response_time,
|
|
327
|
-
targets=targets,
|
|
328
|
-
hypothesis_settings=hypothesis_settings,
|
|
329
|
-
auth=auth,
|
|
330
|
-
auth_type=auth_type,
|
|
331
|
-
headers=headers,
|
|
332
|
-
seed=seed,
|
|
333
|
-
workers_num=workers_num,
|
|
334
|
-
request_timeout=request_timeout,
|
|
335
|
-
request_tls_verify=request_tls_verify,
|
|
336
|
-
request_cert=request_cert,
|
|
337
|
-
exit_first=exit_first,
|
|
338
|
-
dry_run=dry_run,
|
|
339
|
-
store_interactions=store_interactions,
|
|
340
|
-
stateful=stateful,
|
|
341
|
-
stateful_recursion_limit=stateful_recursion_limit,
|
|
342
|
-
count_operations=count_operations,
|
|
343
|
-
)
|
|
344
|
-
if isinstance(schema.app, Starlette):
|
|
345
|
-
return ThreadPoolASGIRunner(
|
|
346
|
-
schema=schema,
|
|
347
|
-
checks=checks,
|
|
348
|
-
max_response_time=max_response_time,
|
|
349
|
-
targets=targets,
|
|
350
|
-
hypothesis_settings=hypothesis_settings,
|
|
351
|
-
auth=auth,
|
|
352
|
-
auth_type=auth_type,
|
|
353
|
-
headers=headers,
|
|
354
|
-
seed=seed,
|
|
355
|
-
exit_first=exit_first,
|
|
356
|
-
dry_run=dry_run,
|
|
357
|
-
store_interactions=store_interactions,
|
|
358
|
-
stateful=stateful,
|
|
359
|
-
stateful_recursion_limit=stateful_recursion_limit,
|
|
360
|
-
count_operations=count_operations,
|
|
361
|
-
)
|
|
362
|
-
return ThreadPoolWSGIRunner(
|
|
363
|
-
schema=schema,
|
|
364
|
-
checks=checks,
|
|
365
|
-
max_response_time=max_response_time,
|
|
366
|
-
targets=targets,
|
|
367
|
-
hypothesis_settings=hypothesis_settings,
|
|
368
|
-
auth=auth,
|
|
369
|
-
auth_type=auth_type,
|
|
370
|
-
headers=headers,
|
|
371
|
-
seed=seed,
|
|
372
|
-
workers_num=workers_num,
|
|
373
|
-
exit_first=exit_first,
|
|
374
|
-
dry_run=dry_run,
|
|
375
|
-
store_interactions=store_interactions,
|
|
376
|
-
stateful=stateful,
|
|
377
|
-
stateful_recursion_limit=stateful_recursion_limit,
|
|
378
|
-
count_operations=count_operations,
|
|
379
|
-
)
|
|
380
|
-
if not schema.app:
|
|
381
|
-
return SingleThreadRunner(
|
|
382
|
-
schema=schema,
|
|
383
|
-
checks=checks,
|
|
384
|
-
max_response_time=max_response_time,
|
|
385
|
-
targets=targets,
|
|
386
|
-
hypothesis_settings=hypothesis_settings,
|
|
387
|
-
auth=auth,
|
|
388
|
-
auth_type=auth_type,
|
|
389
|
-
headers=headers,
|
|
390
|
-
seed=seed,
|
|
391
|
-
request_timeout=request_timeout,
|
|
392
|
-
request_tls_verify=request_tls_verify,
|
|
393
|
-
request_cert=request_cert,
|
|
394
|
-
exit_first=exit_first,
|
|
395
|
-
dry_run=dry_run,
|
|
396
|
-
store_interactions=store_interactions,
|
|
397
|
-
stateful=stateful,
|
|
398
|
-
stateful_recursion_limit=stateful_recursion_limit,
|
|
399
|
-
count_operations=count_operations,
|
|
400
|
-
)
|
|
401
|
-
if isinstance(schema.app, Starlette):
|
|
402
|
-
return SingleThreadASGIRunner(
|
|
403
|
-
schema=schema,
|
|
404
|
-
checks=checks,
|
|
405
|
-
max_response_time=max_response_time,
|
|
406
|
-
targets=targets,
|
|
407
|
-
hypothesis_settings=hypothesis_settings,
|
|
408
|
-
auth=auth,
|
|
409
|
-
auth_type=auth_type,
|
|
410
|
-
headers=headers,
|
|
411
|
-
seed=seed,
|
|
412
|
-
exit_first=exit_first,
|
|
413
|
-
dry_run=dry_run,
|
|
414
|
-
store_interactions=store_interactions,
|
|
415
|
-
stateful=stateful,
|
|
416
|
-
stateful_recursion_limit=stateful_recursion_limit,
|
|
417
|
-
count_operations=count_operations,
|
|
418
|
-
)
|
|
419
|
-
return SingleThreadWSGIRunner(
|
|
420
|
-
schema=schema,
|
|
421
|
-
checks=checks,
|
|
422
|
-
max_response_time=max_response_time,
|
|
423
|
-
targets=targets,
|
|
424
|
-
hypothesis_settings=hypothesis_settings,
|
|
425
|
-
auth=auth,
|
|
426
|
-
auth_type=auth_type,
|
|
427
|
-
headers=headers,
|
|
428
|
-
seed=seed,
|
|
429
|
-
exit_first=exit_first,
|
|
430
|
-
dry_run=dry_run,
|
|
431
|
-
store_interactions=store_interactions,
|
|
432
|
-
stateful=stateful,
|
|
433
|
-
stateful_recursion_limit=stateful_recursion_limit,
|
|
434
|
-
count_operations=count_operations,
|
|
435
|
-
)
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
def prepare_hypothesis_settings(
|
|
439
|
-
database: Optional[str] = None,
|
|
440
|
-
deadline: Optional[Union[int, NotSet]] = None,
|
|
441
|
-
derandomize: Optional[bool] = None,
|
|
442
|
-
max_examples: Optional[int] = None,
|
|
443
|
-
phases: Optional[List[hypothesis.Phase]] = None,
|
|
444
|
-
report_multiple_bugs: Optional[bool] = None,
|
|
445
|
-
suppress_health_check: Optional[List[hypothesis.HealthCheck]] = None,
|
|
446
|
-
verbosity: Optional[hypothesis.Verbosity] = None,
|
|
447
|
-
) -> hypothesis.settings:
|
|
448
|
-
kwargs = dict_not_none_values(
|
|
449
|
-
derandomize=derandomize,
|
|
450
|
-
max_examples=max_examples,
|
|
451
|
-
phases=phases,
|
|
452
|
-
report_multiple_bugs=report_multiple_bugs,
|
|
453
|
-
suppress_health_check=suppress_health_check,
|
|
454
|
-
verbosity=verbosity,
|
|
455
|
-
)
|
|
456
|
-
# `deadline` is special, since Hypothesis allows passing `None`
|
|
457
|
-
if deadline is not None:
|
|
458
|
-
if isinstance(deadline, NotSet):
|
|
459
|
-
kwargs["deadline"] = None
|
|
460
|
-
else:
|
|
461
|
-
kwargs["deadline"] = deadline
|
|
462
|
-
if database is not None:
|
|
463
|
-
if database.lower() == "none":
|
|
464
|
-
kwargs["database"] = None
|
|
465
|
-
elif database == HYPOTHESIS_IN_MEMORY_DATABASE_IDENTIFIER:
|
|
466
|
-
kwargs["database"] = InMemoryExampleDatabase()
|
|
467
|
-
else:
|
|
468
|
-
kwargs["database"] = DirectoryBasedExampleDatabase(database)
|
|
469
|
-
kwargs.setdefault("deadline", DEFAULT_DEADLINE)
|
|
470
|
-
return hypothesis.settings(print_blob=False, **kwargs)
|