mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-06 19:37:29 +00:00
203 lines
12 KiB
Python
Executable File
203 lines
12 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
from __future__ import with_statement
|
|
from string import Template
|
|
import re, fnmatch, os
|
|
|
|
VERSION = "0.8.0"
|
|
|
|
TEST_FUNC_REGEX = r"^(void\s+(test_%s__(\w+))\(\s*(void)?\s*\))\s*\{"
|
|
|
|
CLAY_HEADER = """
|
|
/*
|
|
* Clay v0.7.0
|
|
*
|
|
* This is an autogenerated file. Do not modify.
|
|
* To add new unit tests or suites, regenerate the whole
|
|
* file with `./clay`
|
|
*/
|
|
"""
|
|
|
|
TEMPLATE_SUITE = Template(
|
|
r"""
|
|
{
|
|
"${clean_name}",
|
|
${initialize},
|
|
${cleanup},
|
|
${cb_ptr}, ${cb_count}
|
|
}
|
|
""")
|
|
|
|
def main():
|
|
from optparse import OptionParser
|
|
|
|
parser = OptionParser()
|
|
|
|
parser.add_option('-c', '--clay-path', dest='clay_path')
|
|
parser.add_option('-v', '--report-to', dest='print_mode', default='stdout')
|
|
|
|
options, args = parser.parse_args()
|
|
|
|
for folder in args:
|
|
builder = ClayTestBuilder(folder,
|
|
clay_path = options.clay_path,
|
|
print_mode = options.print_mode)
|
|
|
|
builder.render()
|
|
|
|
|
|
class ClayTestBuilder:
|
|
def __init__(self, path, clay_path = None, print_mode = 'stdout'):
|
|
self.declarations = []
|
|
self.callbacks = []
|
|
self.suites = []
|
|
self.suite_list = []
|
|
|
|
self.clay_path = os.path.abspath(clay_path) if clay_path else None
|
|
self.print_mode = print_mode
|
|
|
|
self.path = os.path.abspath(path)
|
|
self.modules = ["clay_sandbox.c", "clay_fixtures.c", "clay_fs.c"]
|
|
|
|
print("Loading test suites...")
|
|
|
|
for root, dirs, files in os.walk(self.path):
|
|
module_root = root[len(self.path):]
|
|
module_root = [c for c in module_root.split(os.sep) if c]
|
|
|
|
tests_in_module = fnmatch.filter(files, "*.c")
|
|
tests_in_module.sort()
|
|
|
|
for test_file in tests_in_module:
|
|
full_path = os.path.join(root, test_file)
|
|
test_name = "_".join(module_root + [test_file[:-2]])
|
|
|
|
with open(full_path) as f:
|
|
self._process_test_file(test_name, f.read())
|
|
|
|
if not self.suites:
|
|
raise RuntimeError(
|
|
'No tests found under "%s"' % folder_name)
|
|
|
|
def render(self):
|
|
main_file = os.path.join(self.path, 'clay_main.c')
|
|
with open(main_file, "w") as out:
|
|
template = Template(self._load_file('clay.c'))
|
|
|
|
output = template.substitute(
|
|
clay_print = self._get_print_method(),
|
|
clay_modules = self._get_modules(),
|
|
|
|
suites_str = ", ".join(self.suite_list),
|
|
|
|
test_callbacks = ",\n\t".join(self.callbacks),
|
|
cb_count = len(self.callbacks),
|
|
|
|
test_suites = ",\n\t".join(self.suites),
|
|
suite_count = len(self.suites),
|
|
)
|
|
|
|
out.write(output)
|
|
|
|
header_file = os.path.join(self.path, 'clay.h')
|
|
with open(header_file, "w") as out:
|
|
template = Template(self._load_file('clay.h'))
|
|
|
|
output = template.substitute(
|
|
extern_declarations = "\n".join(self.declarations),
|
|
)
|
|
|
|
out.write(output)
|
|
|
|
print ('Written Clay suite to "%s"' % self.path)
|
|
|
|
#####################################################
|
|
# Internal methods
|
|
#####################################################
|
|
def _get_print_method(self):
|
|
return {
|
|
'stdout' : 'printf(__VA_ARGS__)',
|
|
'stderr' : 'fprintf(stderr, __VA_ARGS__)',
|
|
'silent' : ''
|
|
}[self.print_mode]
|
|
|
|
def _load_file(self, filename):
|
|
if self.clay_path:
|
|
filename = os.path.join(self.clay_path, filename)
|
|
with open(filename) as cfile:
|
|
return cfile.read()
|
|
|
|
else:
|
|
import zlib, base64, sys
|
|
content = CLAY_FILES[filename]
|
|
|
|
if sys.version_info >= (3, 0):
|
|
content = bytearray(content, 'utf_8')
|
|
content = base64.b64decode(content)
|
|
content = zlib.decompress(content)
|
|
return str(content)
|
|
else:
|
|
content = base64.b64decode(content)
|
|
return zlib.decompress(content)
|
|
|
|
def _get_modules(self):
|
|
return "\n".join(self._load_file(f) for f in self.modules)
|
|
|
|
def _parse_comment(self, comment):
|
|
comment = comment[2:-2]
|
|
comment = comment.splitlines()
|
|
comment = [line.strip() for line in comment]
|
|
comment = "\n".join(comment)
|
|
|
|
return comment
|
|
|
|
def _process_test_file(self, test_name, contents):
|
|
regex_string = TEST_FUNC_REGEX % test_name
|
|
regex = re.compile(regex_string, re.MULTILINE)
|
|
|
|
callbacks = []
|
|
initialize = cleanup = "{NULL, NULL, 0}"
|
|
|
|
for (declaration, symbol, short_name, _) in regex.findall(contents):
|
|
self.declarations.append("extern %s;" % declaration)
|
|
func_ptr = '{"%s", &%s, %d}' % (
|
|
short_name, symbol, len(self.suites)
|
|
)
|
|
|
|
if short_name == 'initialize':
|
|
initialize = func_ptr
|
|
elif short_name == 'cleanup':
|
|
cleanup = func_ptr
|
|
else:
|
|
callbacks.append(func_ptr)
|
|
|
|
if not callbacks:
|
|
return
|
|
|
|
clean_name = test_name.replace("_", "::")
|
|
|
|
suite = TEMPLATE_SUITE.substitute(
|
|
clean_name = clean_name,
|
|
initialize = initialize,
|
|
cleanup = cleanup,
|
|
cb_ptr = "&_all_callbacks[%d]" % len(self.callbacks),
|
|
cb_count = len(callbacks)
|
|
).strip()
|
|
|
|
self.callbacks += callbacks
|
|
self.suites.append(suite)
|
|
self.suite_list.append(clean_name)
|
|
|
|
print(" %s (%d tests)" % (clean_name, len(callbacks)))
|
|
|
|
CLAY_FILES = {
|
|
"clay.c" : r"""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""",
|
|
"clay_sandbox.c" : r"""eJyNVe9v2jAQ/Zz8FVcqlaTQkm7Vpon1w7R2E1pbENC1UousNHGKtcRBsWGjFf/7znYgP6DdEBJR7nz33rt7RkhfsgCCqZ8BCWJ/SWa+nN6fep8+TLq2LUyYcWkzQRZ+zEIik5lOcoKUC2mOHqoXrv1iW6PxlzEZg5B42mIROKqEo8JtOBDShb0z8FzbsjIq5xkHb523NyK90XlviAeOhSRJGlK3npc/O34QUCHyqrek/8OFM1W2a68qmCPGy3g10sd5FNGsDYI9UyIhpvwph54fNLTy8MLPSJDOuYQzOO3WckxByheoTCbuJ5iDZazG+GqARBptUE/658L83owuhoNh/1vv8qJhg7VCTvssCmkE5LZ3/f6dUeI7lWOazAYKs3N+2x+euwZlGwz4mi77NBYUy+WQmVIqSjNwGALyusDgc8GjC60WczXOGglMfqISH5wNIzZBSS0zHnyp2qpTkvE5VV10ZHsxVKppgXplPJgtnbXqGGqvNVelSzQsa2Xj17Y6h9CLQE6pymZZyhOK+ocpFbyJg/GX4POlnDL+1AaZLUGmMBcUOtgfDjv2K6AaKt7IcdVhmWAFWQnYCiXmIYsMtvGUCRBLIWmyARWzXxRBVPAoAsE8yzR4ltFAphh8A+Dxq+iO34C2ccXRSXn9FykLQRt6zoXPw8f0j6Pe6U1XAEpu9ybKPs0Hr1ks1vZqBlNkgSgRZrcQJBIkS0rF6h7ElWVxSHIIhukGR2kDVYBIn8XaRg1dT0lzpz8NZb2NYddXRtXeBQZj7jQqw3LRBOV7R6llW1gMu6He+FAlUWf/Ajh6nmYJDu2Zarhq0IP+qHcH6LbffhaCiH0xpUIPuWRHa8uOikRhxPo8WD6PBz0Py6qFoNlpbuyyGUSthmJ2BCcTdd9ivmlUjbdaRTG1R+u1K7KgpZC2i+HsUhbbYFJZsqvRV/LzYphjSn6hU2ZE/HNAtX8GNSFztek6pkylMYp0fXN5uXUmV6SwSXUjdYX/9wQcHOxa4t0LZZAqo5TZeh89byc/c8A4q8xsZ2qFz1+bVFxx""",
|
|
"clay_fixtures.c" : r"""eJyFUV1LwzAUfW5+xZU9rLUVJ4ggZQ9DFAUfRCZMRglZmrBAl5Qkk03xv9v0a82U+Zabc+45595rLLGCAlXSWKBrouEccbGzW81wSew6HCIrYljicTuqJBsWoS8UmFbPobXA8npye5OlFSI+GbaglbK4YDJFKOjeMAVjdfUInUPkyFZLWu7DWiKBxtgpKN78RZETEByactlLXcBVBmdTGF+OIxQEPhrHGdRQ1zzMv5xUYN84ROLY8b1MEPeTJEdsV3tRq0wdt06tWcWVzXpS9I3QSPCccbh7nr3jh6fF/O31Hr/M5o9ouGpa4NYlPHmBVt074i/lBLy+OsWHEjkcXLAhMl+p3Wk3bjBV1VIG6TxOApgWZN8s4k8bWjAit+W/NnoTejMddI+GqW1GTOaCox8pOffr""",
|
|
"clay_fs.c" : r"""eJylVdtu20YQfSa/YkAD8TKWY8dJX6L0wXDEVqgsBhINN7UFhiGX1qIkl9hd+dLG/57ZCynJUWEkfZE0s7NnZufMGe2xsqAlpJfj6ZsT399DgzUUojhKo8npb3Mg+ud8PBlNE/hq/NP4LJ5G49n5aTKOp71zNJvFs4vx06DzPz6MZ6HvS5UplkO+zAS89EtWUd7KtM3UkuS8kcqdGE/o/+t71tYm/ArTi8lk6HuS/UNTBRVtbtRyAGzo+x4rgaQ2zMaFvucJqlaicdd8z15AHKkE/rbxIQI6+DqrKp4TF3YAJ2GH/AxwTeu8fTBRA0jtl0Xp0K+sucAsx9suzPPauX2v5AIIMxYweO9AhnBwwELAbvTFXLGFrmf/aF+X4/Uu2L++3scEjwjmitRnQ/+x7/0tZ0XXecIaBTUv6AC22i/5SuRPnQWVynAy/z3CSYg/zpPZxVkCJQLp4m2YvYqVbJHrEHU7bJgG+y7IZNBQf1HBz2nNxQN5oeEHoDnnJdlOHYa2aa18dRetmlxziI8ZOl8bCV5ruk3u3ptw9OlUnaeMquxGorOfd/OcKs2kpEKlBFuMibHUuKUCm8gbW1aoOTge4HFwyZqC30l4EgdlhmYR+J4tVVBK1q0wpnv0U4JkKmqygxTDQEdfFKcfRpNRMsKx6zgzM7oLL+c4oz9A80aSs/jjp40U6bpmA46t0vgVzZpVS7TLApg3lOwe55A6ivMqe3AKCV4GoQXZo5WkXbk4kr5c0qpK+UoRW5SrMBM3t1cLg60HV19YSS0nVuA+wE/dY/zSg8XF32StX/S9h2OrobIVeLskUhVUCM2eF8wfpKI1oM3FO/hsb3+GHDeCo/DVdRNozjx6zxQ5fB06lXXwehIsPr2n+S0xtR4vBqboLvguYwqD9YUBvLD1D/DesFfr5ejPcTJPTpOLObHn/4PLnkprmpJ+WQy3pbpeqNZOcenovvVCxm1ZIK0bEl4Hrpdpf2pbYs2rjchDs+f6nfVfAXYRuu6hGRx9Yc1R3gZD5zVBweGsd5wsNjVuXG+0y81O6KRuDt4u+r8Ro/B6JRWOo5RG5OuxM6QZYUeGfVAcdM9B6b3lRlpqr8ya4gu/363wZ0W9oekNjt4udvVA1N/1oNxuQvfiHc342TdbTYNa0u2XPiN9I/NV464Qs/e1a8PxiLJvClb63wD3Q6FA""",
|
|
"clay.h" : r"""eJy9Vctu2zAQPEdfsbV6sAQhTq9pGsAIbMSAERStg7YngqZWEVGZVEmqcVH030NSfkm2qqYHn0wtOTuzu0M65JlIMQNC7ubjb2Qx+bwg94QEoQ1ygUfxIOSCFVWKcKNNWvDlZX4bBD8lT4EV9BchVGtUZhhccGGASZFyw6VIggu71jaSUwVxxgtM6iOFZWntolJStWIpaqZ4ucnlgDqXVZESupTKRO93GohGQ1iBVFTl0MeG8eYzqr/jKIF6IUv6o0IL3mIz3YC6tCHPXH98F6azr4vHTxPycby4Dw7VOShfm0rhsFmmjxFBVw2WTVhTkS7l+jWQrbq/QEK0Pc+CYBTHAcQw9vOwbYMVZUpqeOYmB1yXBWfcgO81rFBr+oT2/Gg3ecu6qrQhpZ0oGVqASsBNIWoO2u9EcPsBrhLrlulsPiHEreazB78aTCvBvABGiwIyamefXsMAwn3OBN5FR8TuZD/xTSfvZF0iM5hC1hBgpNfQo6Am6ad/01235Ve2r46YaxDSgFEVnuLdzuouR/b9P+bEHO5Mg7qKjpnPPKlTEs4wqKuo51IJ+Y/XaSOpecPqYAIPj/P56cvQgtVd74Rtyt9hto5uArqt11fN3nR7jkMjdgrbe6YN7KnIH2pjOuqZSsWcoWxG+zaOnqkSXDy1a/AiTnimyykLtK9ufTEuB6cfjg3Ta7J+qSGQVsr9GEeCa2SVc9j14IT/vI4VmlymdtOSKOrOal/f29+4NqgEOdz5E2z/GF4ABeagMA=="""
|
|
}
|
|
|
|
if __name__ == '__main__':
|
|
main()
|