def test_task_schema_with_optional_key_expected_match_set_to_dummy_value(): right_input = { "method": "string", "route": "string", "expected": {"expected_match": "dummy_value"}, } assert None is input_validator(right_input, TASK_SCHEMA)
def test_task_schema_with_optional_key_expected_match_set_to_partial(): right_input = { "method": "string", "route": "string", "expected": {"expected_match": "partial"}, } assert input_validator(right_input, TASK_SCHEMA)
def test_task_schema_with_optional_key_fail_on_and_code(): right_input = { "method": "string", "route": "string", "fail_on": [{ "code": 405 }], } assert input_validator(right_input, TASK_SCHEMA)
def test_task_schema_with_optional_key_fail_on_and_match_accepted(match_mode): right_input = { "method": "string", "route": "string", "fail_on": [{ "expected_match": match_mode }], } assert input_validator(right_input, TASK_SCHEMA)
def test_task_schema_with_optional_key_fail_on_and_body(): right_input = { "method": "string", "route": "string", "fail_on": [{ "body": { "key": "value" } }], } assert input_validator(right_input, TASK_SCHEMA)
def test_TASK_SCHEMA(): right_input = {"method": "GET", "route": "/foo/bar"} wrong_input = {"foo": "bar"} assert input_validator(right_input, TASK_SCHEMA) assert not input_validator(wrong_input, TASK_SCHEMA)
async def run(self) -> dict: """Run the task on a specified URL.""" # -- Input validation -- validated_task = input_validator(self.task, TASK_SCHEMA) if not validated_task: return self._response( "FAILED", f"Task must follow this schema : {TASK_SCHEMA}.") self.task = validated_task self.task["method"] = self.task["method"].upper() if self.task["method"] not in [ "GET", "POST", "PATCH", "PUT", "DELETE", "HEAD", "CONNECT", "OPTIONS", "TRACE", ]: return self._response("FAILED", "Invalid HTTP method.") # Jinja2 logic substitution template = jinja2.Template( json.dumps(self.task, cls=type_aware_encoder(self.output))) self.task = json.loads(template.render(**self.output)) self.task["headers"] = { **{ "Accept": "application/json", "Content-Type": "application/json" }, **self.task.get("headers", {}), } # -- Request -- loop = asyncio.get_event_loop() for _ in range(self.task["retry"] + 1): try: if self.output.get("__token__"): token = self.output["__token__"] self.task["headers"]["Authorization"] = "Bearer " + ( token() if callable(token) else token) self.response = await loop.run_in_executor( None, lambda: getattr(requests, self.task["method"].lower())( urljoin(self.url, self.task["route"]), json=self.task.get("body"), headers=self.task["headers"], verify=self.verify, ), ) except requests.exceptions.RequestException: failed_response = self._response("FAILED", "Request failed.") await asyncio.sleep(self.task["delay"]) continue # -- Output validation -- failed_response = self.validate_code() if failed_response is not None: await asyncio.sleep(self.task["delay"]) continue failed_response = self.validate_body() if failed_response is not None: await asyncio.sleep(self.task["delay"]) continue output_variable = self.task.get("output") if output_variable: self.output[output_variable] = self._response_body() return self._response("SUCCESS", "OK.") return failed_response