Files
httprunner/httprunner/loader/check.py
debugtalk 7213f86f80 change:
1, replace logging with loguru
2, replace string format with f-string
2020-03-07 12:16:11 +08:00

216 lines
6.4 KiB
Python

import io
import json
import os
import platform
import jsonschema
from loguru import logger
from httprunner import exceptions
schemas_root_dir = os.path.join(os.path.dirname(__file__), "schemas")
common_schema_path = os.path.join(schemas_root_dir, "common.schema.json")
api_schema_path = os.path.join(schemas_root_dir, "api.schema.json")
testcase_schema_v1_path = os.path.join(schemas_root_dir, "testcase.schema.v1.json")
testcase_schema_v2_path = os.path.join(schemas_root_dir, "testcase.schema.v2.json")
testsuite_schema_v1_path = os.path.join(schemas_root_dir, "testsuite.schema.v1.json")
testsuite_schema_v2_path = os.path.join(schemas_root_dir, "testsuite.schema.v2.json")
with io.open(api_schema_path, encoding='utf-8') as f:
api_schema = json.load(f)
with io.open(common_schema_path, encoding='utf-8') as f:
if platform.system() == "Windows":
absolute_base_path = 'file:///' + os.path.abspath(schemas_root_dir).replace("\\", "/") + '/'
else:
# Linux, Darwin
absolute_base_path = "file://" + os.path.abspath(schemas_root_dir) + "/"
common_schema = json.load(f)
resolver = jsonschema.RefResolver(absolute_base_path, common_schema)
with io.open(testcase_schema_v1_path, encoding='utf-8') as f:
testcase_schema_v1 = json.load(f)
with io.open(testcase_schema_v2_path, encoding='utf-8') as f:
testcase_schema_v2 = json.load(f)
with io.open(testsuite_schema_v1_path, encoding='utf-8') as f:
testsuite_schema_v1 = json.load(f)
with io.open(testsuite_schema_v2_path, encoding='utf-8') as f:
testsuite_schema_v2 = json.load(f)
class JsonSchemaChecker(object):
@staticmethod
def validate_format(content, scheme):
""" check api/testcase/testsuite format if valid
"""
try:
jsonschema.validate(content, scheme, resolver=resolver)
except jsonschema.exceptions.ValidationError as ex:
logger.error(str(ex))
raise exceptions.FileFormatError
return True
@staticmethod
def validate_api_format(content):
""" check api format if valid
"""
return JsonSchemaChecker.validate_format(content, api_schema)
@staticmethod
def validate_testcase_v1_format(content):
""" check testcase format v1 if valid
"""
return JsonSchemaChecker.validate_format(content, testcase_schema_v1)
@staticmethod
def validate_testcase_v2_format(content):
""" check testcase format v2 if valid
"""
return JsonSchemaChecker.validate_format(content, testcase_schema_v2)
@staticmethod
def validate_testsuite_v1_format(content):
""" check testsuite format v1 if valid
"""
return JsonSchemaChecker.validate_format(content, testsuite_schema_v1)
@staticmethod
def validate_testsuite_v2_format(content):
""" check testsuite format v2 if valid
"""
return JsonSchemaChecker.validate_format(content, testsuite_schema_v2)
def is_test_path(path):
""" check if path is valid json/yaml file path or a existed directory.
Args:
path (str/list/tuple): file path/directory or file path list.
Returns:
bool: True if path is valid file path or path list, otherwise False.
"""
if not isinstance(path, (str, list, tuple)):
return False
elif isinstance(path, (list, tuple)):
for p in path:
if not is_test_path(p):
return False
return True
else:
# path is string
if not os.path.exists(path):
return False
# path exists
if os.path.isfile(path):
# path is a file
file_suffix = os.path.splitext(path)[1].lower()
if file_suffix not in ['.json', '.yaml', '.yml']:
# path is not json/yaml file
return False
else:
return True
elif os.path.isdir(path):
# path is a directory
return True
else:
# path is neither a folder nor a file, maybe a symbol link or something else
return False
def is_test_content(data_structure):
""" check if data_structure is apis/testcases/testsuites.
Args:
data_structure (dict): should include keys, apis or testcases or testsuites
Returns:
bool: True if data_structure is valid apis/testcases/testsuites, otherwise False.
"""
if not isinstance(data_structure, dict):
return False
if "apis" in data_structure:
# maybe a group of api content
apis = data_structure["apis"]
if not isinstance(apis, list):
return False
for item in apis:
is_testcase = False
try:
JsonSchemaChecker.validate_api_format(item)
is_testcase = True
except exceptions.FileFormatError:
pass
if not is_testcase:
return False
return True
elif "testcases" in data_structure:
# maybe a testsuite, containing a group of testcases
testcases = data_structure["testcases"]
if not isinstance(testcases, list):
return False
for item in testcases:
is_testcase = False
try:
JsonSchemaChecker.validate_testcase_v2_format(item)
is_testcase = True
except exceptions.FileFormatError:
pass
try:
JsonSchemaChecker.validate_testcase_v2_format(item)
is_testcase = True
except exceptions.FileFormatError:
pass
if not is_testcase:
return False
return True
elif "testsuites" in data_structure:
# maybe a group of testsuites
testsuites = data_structure["testsuites"]
if not isinstance(testsuites, list):
return False
for item in testsuites:
is_testcase = False
try:
JsonSchemaChecker.validate_testsuite_v1_format(item)
is_testcase = True
except exceptions.FileFormatError:
pass
try:
JsonSchemaChecker.validate_testsuite_v2_format(item)
is_testcase = True
except exceptions.FileFormatError:
pass
if not is_testcase:
return False
return True
else:
return False