Skip to content

Commit d1cb955

Browse files
api-clients-generation-pipeline[bot]therveci.datadog-api-spec
authored
Add BDD tests to synthetics (#489)
* Support body in undo, add cassettes * Regenerate client from commit 8327a94 of spec repo Co-authored-by: Thomas Hervé <[email protected]> Co-authored-by: ci.datadog-api-spec <[email protected]> Co-authored-by: api-clients-generation-pipeline[bot] <54105614+api-clients-generation-pipeline[bot]@users.noreply.github.com>
1 parent b835fc3 commit d1cb955

9 files changed

+175
-32
lines changed

.apigentools-info

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
"spec_versions": {
55
"v1": {
66
"apigentools_version": "1.4.1.dev8",
7-
"regenerated": "2021-06-17 15:07:58.879914",
8-
"spec_repo_commit": "7f25c3e"
7+
"regenerated": "2021-06-21 15:11:55.610953",
8+
"spec_repo_commit": "8327a94"
99
},
1010
"v2": {
1111
"apigentools_version": "1.4.1.dev8",
12-
"regenerated": "2021-06-17 15:08:28.826169",
13-
"spec_repo_commit": "7f25c3e"
12+
"regenerated": "2021-06-21 15:12:23.084029",
13+
"spec_repo_commit": "8327a94"
1414
}
1515
}
1616
}

docs/v1/SyntheticsAssertionJSONPathTargetTarget.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Name | Type | Description | Notes
77
------------ | ------------- | ------------- | -------------
88
**json_path** | **str** | The JSON path to assert. | [optional]
99
**operator** | **str** | The specific operator to use on the path. | [optional]
10-
**target_value** | **{str: (bool, date, datetime, dict, float, int, list, str, none_type)}** | The path target value to compare to. | [optional]
10+
**target_value** | **bool, date, datetime, dict, float, int, list, str, none_type** | The path target value to compare to. | [optional]
1111

1212
[[Back to Model list]](README.md#documentation-for-models) [[Back to API list]](README.md#documentation-for-api-endpoints) [[Back to README]](README.md)
1313

src/datadog_api_client/v1/model/synthetics_assertion_json_path_target_target.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,17 @@ def openapi_types():
6767
return {
6868
"json_path": (str,), # noqa: E501
6969
"operator": (str,), # noqa: E501
70-
"target_value": ({str: (bool, date, datetime, dict, float, int, list, str, none_type)},), # noqa: E501
70+
"target_value": (
71+
bool,
72+
date,
73+
datetime,
74+
dict,
75+
float,
76+
int,
77+
list,
78+
str,
79+
none_type,
80+
), # noqa: E501
7181
}
7282

7383
@cached_property
@@ -130,7 +140,7 @@ def __init__(self, *args, **kwargs): # noqa: E501
130140
_visited_composed_classes = (Animal,)
131141
json_path (str): The JSON path to assert.. [optional] # noqa: E501
132142
operator (str): The specific operator to use on the path.. [optional] # noqa: E501
133-
target_value ({str: (bool, date, datetime, dict, float, int, list, str, none_type)}): The path target value to compare to.. [optional] # noqa: E501
143+
target_value (bool, date, datetime, dict, float, int, list, str, none_type): The path target value to compare to.. [optional] # noqa: E501
134144
"""
135145

136146
_check_type = kwargs.pop("_check_type", True)

src/datadog_api_client/v1/openapi.yaml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8506,7 +8506,6 @@ components:
85068506
type: string
85078507
targetValue:
85088508
description: The path target value to compare to.
8509-
type: object
85108509
type: object
85118510
type:
85128511
$ref: '#/components/schemas/SyntheticsAssertionType'
@@ -19831,8 +19830,10 @@ paths:
1983119830
x-codegen-request-body-name: body
1983219831
x-menu-order: 1
1983319832
x-undo:
19834-
operationId: TODO
19835-
parameters: []
19833+
operationId: DeleteTests
19834+
parameters:
19835+
- name: body
19836+
template: '{"public_ids": ["{{ public_id }}"]}'
1983619837
type: unsafe
1983719838
/api/v1/synthetics/tests/api/{public_id}:
1983819839
get:

tests/conftest.py

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def pytest_configure(config):
6060

6161
import pytest
6262
from dateutil.relativedelta import relativedelta
63-
from jinja2 import Template
63+
from jinja2 import Template, Environment, meta
6464
from pytest_bdd import (
6565
given,
6666
parsers,
@@ -76,12 +76,7 @@ def pytest_bdd_before_step(request, feature, scenario, step, step_func):
7676
return
7777

7878
context = tracer.get_call_context()
79-
span = tracer.start_span(
80-
step.type,
81-
resource=step.name,
82-
span_type=step.type,
83-
child_of=context,
84-
)
79+
span = tracer.start_span(step.type, resource=step.name, span_type=step.type, child_of=context,)
8580
setattr(step_func, "__dd_span__", span)
8681

8782

@@ -226,11 +221,7 @@ def context(vcr, unique, unique_lower, freezer):
226221
@pytest.fixture(scope="session")
227222
def record_mode(request):
228223
"""Manage compatibility with DD client libraries."""
229-
return {
230-
"false": "none",
231-
"true": "rewrite",
232-
"none": "new_episodes",
233-
}[os.getenv("RECORD", "false").lower()]
224+
return {"false": "none", "true": "rewrite", "none": "new_episodes",}[os.getenv("RECORD", "false").lower()]
234225

235226

236227
def _disable_recording():
@@ -249,7 +240,7 @@ def vcr_config():
249240
config = dict(
250241
filter_headers=("DD-API-KEY", "DD-APPLICATION-KEY"),
251242
filter_query_parameters=("api_key", "application_key"),
252-
match_on=['method', 'scheme', 'host', 'port', 'path', 'query', 'body']
243+
match_on=["method", "scheme", "host", "port", "path", "query", "body"],
253244
)
254245
if tracer:
255246
config["ignore_hosts"] = [tracer.writer._hostname]
@@ -372,7 +363,7 @@ def request_body(context, data):
372363
context["api_request"]["kwargs"]["body"] = json.loads(tpl)
373364

374365

375-
@given(parsers.parse("body from file \"{path}\""))
366+
@given(parsers.parse('body from file "{path}"'))
376367
def request_body_from_file(context, path, package_name):
377368
"""Set request body."""
378369
version = package_name.split(".")[-1]
@@ -469,7 +460,16 @@ def cleanup(api, operation_id, response, client=client):
469460

470461
operation_name = snake_case(operation["operationId"])
471462
method = getattr(api, operation_name)
472-
args = [glom(response, parameter["source"]) for parameter in operation.get("parameters", [])]
463+
args = []
464+
for parameter in operation.get("parameters", []):
465+
if "source" in parameter:
466+
args.append(glom(response, parameter["source"]))
467+
elif "template" in parameter:
468+
variables = meta.find_undeclared_variables(Environment().parse(parameter["template"]))
469+
ctx = {}
470+
for var in variables:
471+
ctx[var] = glom(response, var)
472+
args.append(json.loads(Template(parameter["template"]).render(**ctx)))
473473

474474
if operation_name in client.configuration.unstable_operations:
475475
client.configuration.unstable_operations[operation_name] = True
@@ -490,9 +490,7 @@ def execute_request(undo, context, client, _package):
490490
exceptions = importlib.import_module(context["api"]["package"] + ".exceptions")
491491

492492
try:
493-
response = api_request["request"](
494-
*api_request["args"], **api_request["kwargs"]
495-
)
493+
response = api_request["request"](*api_request["args"], **api_request["kwargs"])
496494
client.last_response.urllib3_response.close()
497495
# Reserialise the response body to JSON to facilitate test assertions
498496
response_body_json = _package.api_client.ApiClient.sanitize_for_serialization(response[0])
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
2021-06-18T14:25:50.736130+02:00
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
interactions:
2+
- request:
3+
body: '{"config": {"assertions": [{"operator": "contains", "property": "content-type",
4+
"target": "application/json", "type": "header"}, {"operator": "is", "target":
5+
200, "type": "statusCode"}, {"operator": "validatesJSONPath", "target": {"jsonPath":
6+
"topKey", "operator": "isNot", "targetValue": "0"}, "type": "body"}, {"operator":
7+
"validatesJSONPath", "target": {"jsonPath": "something", "operator": "moreThan",
8+
"targetValue": 5}, "type": "body"}, {"operator": "isNot", "target": 200, "type":
9+
"statusCode"}, {"operator": "matches", "target": "20[04]", "type": "statusCode"},
10+
{"operator": "doesNotMatch", "target": "20[04]", "type": "statusCode"}], "configVariables":
11+
[], "request": {"basicAuth": {"password": "secret", "username": "admin"}, "body":
12+
"this is a body", "headers": {"Accept": "application/json"}, "method": "GET",
13+
"query": {"foo": "bar"}, "timeout": 30, "url": "https://www.datadoghq.com"}},
14+
"locations": ["aws:eu-central-1"], "message": "Notify @datadog.user", "name":
15+
"Test-Create_an_API_test_returns_OK_Returns_the_created_test_details_response-1624019150",
16+
"options": {"follow_redirects": true, "min_location_failed": 1, "monitor_options":
17+
{"renotify_interval": 100}, "tick_every": 60}, "status": "paused", "subtype":
18+
"http", "tags": ["foo:bar", "baz"], "type": "api"}'
19+
headers:
20+
Accept:
21+
- application/json
22+
Content-Type:
23+
- application/json
24+
Dd-Operation-Id:
25+
- CreateSyntheticsApiTest
26+
User-Agent:
27+
- datadog-api-client-python/1.1.1.dev7+dirty (python 3.8.10; os Darwin; arch
28+
x86_64)
29+
method: POST
30+
uri: https://api.datadoghq.com/api/v1/synthetics/tests/api
31+
response:
32+
body:
33+
string: '{"status":"paused","public_id":"z28-93g-afx","tags":["foo:bar","baz"],"org_id":321813,"locations":["aws:eu-central-1"],"message":"Notify
34+
@datadog.user","deleted_at":null,"name":"Test-Create_an_API_test_returns_OK_Returns_the_created_test_details_response-1624019150","monitor_id":38926045,"type":"api","created_at":"2021-06-18T12:25:51.393485+00:00","modified_at":"2021-06-18T12:25:51.393485+00:00","subtype":"http","config":{"request":{"body":"this
35+
is a body","url":"https://www.datadoghq.com","basicAuth":{"username":"admin","password":"secret"},"headers":{"Accept":"application/json"},"timeout":30,"query":{"foo":"bar"},"method":"GET"},"assertions":[{"operator":"contains","property":"content-type","type":"header","target":"application/json"},{"operator":"is","type":"statusCode","target":200},{"operator":"validatesJSONPath","type":"body","target":{"operator":"isNot","targetValue":"0","jsonPath":"topKey"}},{"operator":"validatesJSONPath","type":"body","target":{"operator":"moreThan","targetValue":5,"jsonPath":"something"}},{"operator":"isNot","type":"statusCode","target":200},{"operator":"matches","type":"statusCode","target":"20[04]"},{"operator":"doesNotMatch","type":"statusCode","target":"20[04]"}],"configVariables":[]},"options":{"follow_redirects":true,"monitor_options":{"notify_audit":false,"locked":false,"include_tags":true,"new_host_delay":300,"notify_no_data":false,"renotify_interval":100},"min_location_failed":1,"tick_every":60}}'
36+
headers:
37+
Connection:
38+
- keep-alive
39+
Content-Length:
40+
- '1456'
41+
Content-Type:
42+
- application/json
43+
Date:
44+
- Fri, 18 Jun 2021 12:25:51 GMT
45+
cache-control:
46+
- no-cache
47+
content-security-policy:
48+
- frame-ancestors 'self'; report-uri https://api.datadoghq.com/csp-report
49+
pragma:
50+
- no-cache
51+
strict-transport-security:
52+
- max-age=15724800;
53+
vary:
54+
- Accept-Encoding
55+
x-content-type-options:
56+
- nosniff
57+
x-dd-debug:
58+
- l8RQo2maZqJf6GFThBbKNE6dvthz6njusVtau3dPXJWL2RLFoN81H+BLPB/1xgs1
59+
x-dd-version:
60+
- '35.4781545'
61+
x-frame-options:
62+
- SAMEORIGIN
63+
x-ratelimit-limit:
64+
- '120'
65+
x-ratelimit-period:
66+
- '60'
67+
x-ratelimit-remaining:
68+
- '118'
69+
x-ratelimit-reset:
70+
- '9'
71+
status:
72+
code: 200
73+
message: OK
74+
- request:
75+
body: '{"public_ids": ["z28-93g-afx"]}'
76+
headers:
77+
Accept:
78+
- application/json
79+
Content-Type:
80+
- application/json
81+
Dd-Operation-Id:
82+
- DeleteTests
83+
User-Agent:
84+
- datadog-api-client-python/1.1.1.dev7+dirty (python 3.8.10; os Darwin; arch
85+
x86_64)
86+
method: POST
87+
uri: https://api.datadoghq.com/api/v1/synthetics/tests/delete
88+
response:
89+
body:
90+
string: '{"deleted_tests":[{"deleted_at":"2021-06-18T12:25:51.815581+00:00","public_id":"z28-93g-afx"}]}'
91+
headers:
92+
Connection:
93+
- keep-alive
94+
Content-Length:
95+
- '95'
96+
Content-Type:
97+
- application/json
98+
Date:
99+
- Fri, 18 Jun 2021 12:25:51 GMT
100+
cache-control:
101+
- no-cache
102+
content-security-policy:
103+
- frame-ancestors 'self'; report-uri https://api.datadoghq.com/csp-report
104+
pragma:
105+
- no-cache
106+
strict-transport-security:
107+
- max-age=15724800;
108+
vary:
109+
- Accept-Encoding
110+
x-content-type-options:
111+
- nosniff
112+
x-dd-debug:
113+
- vdJ3/nHEY1ioXQ6pQrBVvsQK1s4yyc+wufBMPSoXql71qZVuP/xMdtNo6DafhOAk
114+
x-dd-version:
115+
- '35.4781545'
116+
x-frame-options:
117+
- SAMEORIGIN
118+
x-ratelimit-limit:
119+
- '120'
120+
x-ratelimit-period:
121+
- '60'
122+
x-ratelimit-remaining:
123+
- '119'
124+
x-ratelimit-reset:
125+
- '9'
126+
status:
127+
code: 200
128+
message: OK
129+
version: 1

tests/v1/features/synthetics.feature

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,9 @@ Feature: Synthetics
7878
When the request is sent
7979
Then the response status is 400 - JSON format is wrong
8080

81-
@generated @skip
8281
Scenario: Create an API test returns "OK - Returns the created test details." response
8382
Given new "CreateSyntheticsAPITest" request
84-
And body with value {"config": {"assertions": [], "configVariables": [{"example": null, "id": null, "name": "VARIABLE_NAME", "pattern": null, "type": "global"}], "request": {"basicAuth": {"password": "", "username": ""}, "body": null, "certificate": {"cert": {"content": null, "filename": null, "updatedAt": null}, "key": {"content": null, "filename": null, "updatedAt": null}}, "dnsServer": null, "dnsServerPort": null, "headers": null, "host": null, "method": "GET", "noSavingResponseBody": null, "numberOfPackets": null, "port": null, "query": null, "shouldTrackHops": null, "timeout": null, "url": null}, "steps": [{"allowFailure": null, "assertions": [], "extractedValues": [{"field": "content-type", "name": null, "parser": {"type": "regex", "value": ".*"}, "type": "http_body"}], "isCritical": null, "name": null, "request": {"basicAuth": {"password": "", "username": ""}, "body": null, "certificate": {"cert": {"content": null, "filename": null, "updatedAt": null}, "key": {"content": null, "filename": null, "updatedAt": null}}, "dnsServer": null, "dnsServerPort": null, "headers": null, "host": null, "method": "GET", "noSavingResponseBody": null, "numberOfPackets": null, "port": null, "query": null, "shouldTrackHops": null, "timeout": null, "url": null}, "subtype": "http"}]}, "locations": [null], "message": null, "name": null, "options": {"accept_self_signed": null, "allow_insecure": null, "device_ids": ["laptop_large"], "disableCors": null, "follow_redirects": null, "min_failure_duration": null, "min_location_failed": null, "monitor_name": null, "monitor_options": {"renotify_interval": null}, "monitor_priority": null, "noScreenshot": null, "retry": {"count": null, "interval": null}, "tick_every": 30}, "status": "live", "subtype": "http", "tags": [null], "type": "api"}
83+
And body with value {"config":{"assertions":[{"operator":"contains","property":"content-type","target":"application/json","type":"header"},{"operator":"is","target":200,"type":"statusCode"},{"operator":"validatesJSONPath","target":{"jsonPath":"topKey","operator":"isNot","targetValue":"0"},"type":"body"},{"operator":"validatesJSONPath","target":{"jsonPath":"something","operator":"moreThan","targetValue":5},"type":"body"},{"operator":"isNot","target":200,"type":"statusCode"},{"operator":"matches","target":"20[04]","type":"statusCode"},{"operator":"doesNotMatch","target":"20[04]","type":"statusCode"}],"configVariables":[],"request":{"basicAuth":{"password":"secret","username":"admin"},"body":"this is a body","headers":{"Accept":"application/json"},"method":"GET","query":{"foo":"bar"},"timeout":30,"url":"https://www.datadoghq.com"}},"locations":["aws:eu-central-1"],"message":"Notify @datadog.user","name":"{{ unique }}","options":{"follow_redirects":true,"min_location_failed":1,"monitor_options":{"renotify_interval":100},"tick_every":60},"status":"paused","subtype":"http","tags":["foo:bar","baz"],"type":"api"}
8584
When the request is sent
8685
Then the response status is 200 OK - Returns the created test details.
8786

tests/v1/features/undo.json

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -894,8 +894,13 @@
894894
"CreateSyntheticsAPITest": {
895895
"tag": "Synthetics",
896896
"undo": {
897-
"operationId": "TODO",
898-
"parameters": [],
897+
"operationId": "DeleteTests",
898+
"parameters": [
899+
{
900+
"name": "body",
901+
"template": "{\"public_ids\": [\"{{ public_id }}\"]}"
902+
}
903+
],
899904
"type": "unsafe"
900905
}
901906
},

0 commit comments

Comments
 (0)