Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes: various fixes for payload loading, mocked responses #55

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ dependencies = [
"pytest-html>=4.1.0",
"stac-validator>=3.3.0",
"pytest-metadata>=3.0.0",
"openapi-core>=0.18.2",
"openapi-core>=0.19.4",
]
classifiers = [
"Programming Language :: Python :: 3",
Expand Down
36 changes: 22 additions & 14 deletions src/openeo_test_suite/lib/compliance_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ def test_endpoint(
method: str = "GET",
expected_status_codes: Union[list[int], int] = [200],
return_response: bool = False,
mock_response_content: bytes = None,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't seem to find where this mock_response_content is being used, is it necessary to add this?

required: bool = True,
):
full_endpoint_url = f"{base_url}{endpoint_path}"
session = Session()
Expand All @@ -43,13 +45,19 @@ def test_endpoint(
if bearer_token:
headers["Authorization"] = bearer_token

if payload:
payload = json.loads(payload)

response = session.request(
method=method.upper(),
url=full_endpoint_url,
json=payload,
headers=headers,
)

if mock_response_content:
response._content = mock_response_content

openapi_request = RequestsOpenAPIRequest(
Request(method.upper(), full_endpoint_url, json=payload, headers=headers)
)
Expand All @@ -70,9 +78,9 @@ def test_endpoint(
except Exception as e:
print_test_results(e, endpoint_path=endpoint_path, test_name=test_name)
if return_response:
return check_test_results(e), response
return check_test_results(e, required=required), response
else:
return check_test_results(e)
return check_test_results(e, required=required)
else:
if return_response:
return "", response
Expand Down Expand Up @@ -179,12 +187,13 @@ def print_test_results(e: Exception, endpoint_path: str, test_name: str = "?"):
print("")


def check_test_results(e: Exception):
def check_test_results(e: Exception, required: bool = True):
"""
prints the results of a openapi-core validation test

e: the exception that was raised as a part of the response validation test
test_name: the name of the test that ought to be displayed
required: is the endpoint required as per the spec.
"""

# message is important
Expand All @@ -196,7 +205,7 @@ def check_test_results(e: Exception):
elif e.actual_status_code == 500:
fail_log = "Endpoint expects an id and the item does not exist."
elif e.actual_status_code == 404 or e.actual_status_code == 501:
fail_log = "Endpoint is not implemented, only an error if it is REQUIRED."
fail_log = "Endpoint is not implemented." if required else ""
elif e.actual_status_code == 410:
fail_log = "Endpoint is not providing requested resource as it is gone. Logs are not provided if job is queued or created."
else:
Expand Down Expand Up @@ -287,14 +296,14 @@ def get_spec_path():
return _guess_root() / "openapi.yaml"


def load_payloads_from_directory(directory_path: str) -> Iterator[dict]:
def load_payloads_from_directory(directory_path: str) -> Iterator[str]:
for filename in pathlib.Path(directory_path).glob("*.json"):
file_path = os.path.join(directory_path, filename)
with open(file_path, "r") as file:
try:
# Load the JSON data from the file
data = json.load(file)
yield data
yield json.dumps(data)
except json.JSONDecodeError:
_log.error(f"Error decoding JSON in file: {filename}")
except Exception as e:
Expand All @@ -309,7 +318,7 @@ def set_uuid_in_job(json_data):
# Set the 'id' field to the generated UUID
json_data["process"]["id"] = new_id
# Return the modified JSON object
return new_id, json_data
return new_id, json.dumps(json_data)


def delete_id_resource(
Expand All @@ -336,19 +345,18 @@ def put_process_graphs(base_url: str, bearer_token: str): # TODO id and so fort

try:
for payload in payloads:
id, payload = set_uuid_in_udp(payload)
id = str(uuid.uuid4().hex)
created_udp_ids.append(id)
response = requests.put(
f"{base_url}process_graphs/{id}",
requests.put(
f"{base_url}/process_graphs/{id}",
data=payload,
headers={
"Content-Type": "application/json",
"Authorization": f"{bearer_token}",
},
)
print(response)
except Exception as e:
_log.error(f"Failed to create process graph: {e}")
print(f"Failed to create process graph: {e}")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just doing a print on any exception seems like asking for trouble down the line. Why not fail hard just here?

return created_udp_ids


Expand Down Expand Up @@ -377,11 +385,11 @@ def post_jobs(base_url: str, bearer_token: str):

# TESTING
for payload in payloads:
_, payload = set_uuid_in_job(payload)
# _, payload = set_uuid_in_job(payload)

response = requests.post(
full_endpoint_url,
data=json.dumps(payload),
data=payload,
headers={
"Content-Type": "application/json",
"Authorization": f"{bearer_token}",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,41 +1,43 @@
{
"title": "Custom Test Process",
"description": "Loads and Saves austrian ground motion data",
"title": "testpatch",
"description": null,
"plan": "eodc-cloud",
"budget": null,
"process": {
"categories": [],
"deprecated": false,
"experimental": false,
"process_graph": {
"load1": {
"process_id": "load_collection",
"arguments": {
"bands": [
"B01"
],
"properties": {},
"id": "CGLS_SSM_1KM",
"spatial_extent": {
"west": 16.186110851391813,
"east": 16.576456845030226,
"south": 48.08764096726651,
"north": 48.29291292355549
},
"temporal_extent": [
"2020-01-01T00:00:00Z",
"2020-12-13T00:00:00Z"
]
}
},
"save2": {
"process_id": "save_result",
"arguments": {
"data": {
"from_node": "load1"
},
"format": "NETCDF"
"load1": {
"process_id": "load_collection",
"arguments": {
"bands": [
"B01"
],
"properties": {},
"id": "CGLS_SSM_1KM",
"spatial_extent": {
"west": 16.186110851391813,
"east": 16.576456845030226,
"south": 48.08764096726651,
"north": 48.29291292355549
},
"temporal_extent": [
"2020-01-01T00:00:00Z",
"2020-12-13T00:00:00Z"
]
}
},
"result": true
}
},
"parameters": []
},
"plan": "free",
"budget": 100
}
"save2": {
"process_id": "save_result",
"arguments": {
"data": {
"from_node": "load1"
},
"format": "NETCDF"
},
"result": true
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,41 +1,43 @@
{
"title": "Custom Test Process",
"description": "Loads and Saves austrian ground motion data",
"title": "test",
"description": null,
"plan": "eodc-cloud",
"budget": null,
"process": {
"categories": [],
"deprecated": false,
"experimental": false,
"process_graph": {
"load1": {
"process_id": "load_collection",
"arguments": {
"bands": [
"B01"
],
"properties": {},
"id": "CGLS_SSM_1KM",
"spatial_extent": {
"west": 16.186110851391813,
"east": 16.576456845030226,
"south": 48.08764096726651,
"north": 48.29291292355549
},
"temporal_extent": [
"2020-01-01T00:00:00Z",
"2020-12-13T00:00:00Z"
]
}
},
"save2": {
"process_id": "save_result",
"arguments": {
"data": {
"from_node": "load1"
},
"format": "NETCDF"
"load1": {
"process_id": "load_collection",
"arguments": {
"bands": [
"B01"
],
"properties": {},
"id": "CGLS_SSM_1KM",
"spatial_extent": {
"west": 16.186110851391813,
"east": 16.576456845030226,
"south": 48.08764096726651,
"north": 48.29291292355549
},
"temporal_extent": [
"2020-01-01T00:00:00Z",
"2020-12-13T00:00:00Z"
]
}
},
"result": true
}
},
"parameters": []
},
"plan": "free",
"budget": 100
}
"save2": {
"process_id": "save_result",
"arguments": {
"data": {
"from_node": "load1"
},
"format": "NETCDF"
},
"result": true
}
}
}
}
Loading