mirror of
https://github.com/YunoHost/package_check.git
synced 2024-09-03 20:06:20 +02:00
207 lines
6.3 KiB
Python
Executable file
207 lines
6.3 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
|
|
from typing import Any
|
|
import argparse
|
|
import copy
|
|
import json
|
|
import os
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
import toml
|
|
|
|
from default_install_args import get_default_values_for_questions
|
|
|
|
|
|
def generate_test_list_base(
|
|
test_manifest: dict,
|
|
default_install_args: dict,
|
|
is_webapp: bool,
|
|
is_multi_instance: bool,
|
|
):
|
|
assert (
|
|
test_manifest["test_format"] == 1.0
|
|
), "Only test_format 1.0 is supported for now"
|
|
|
|
assert isinstance(
|
|
test_manifest["default"], dict
|
|
), "You should at least defined the 'default' test suite"
|
|
|
|
is_full_domain_app = (
|
|
"domain" in default_install_args and "path" not in default_install_args
|
|
)
|
|
|
|
for test_suite_id, test_suite in test_manifest.items():
|
|
# Ignore non-testsuite stuff like "test_format"
|
|
if not isinstance(test_suite, dict):
|
|
continue
|
|
|
|
install_args = copy.copy(default_install_args)
|
|
install_args.update(test_suite.get("args", {}))
|
|
|
|
default_meta = {
|
|
"preinstall": test_suite.get("preinstall", ""),
|
|
"preupgrade": test_suite.get("preupgrade", ""),
|
|
"install_args": install_args,
|
|
}
|
|
|
|
yield test_suite_id, "package_linter", default_meta
|
|
|
|
if is_webapp:
|
|
yield test_suite_id, "install.root", default_meta
|
|
if not is_full_domain_app:
|
|
yield test_suite_id, "install.subdir", default_meta
|
|
else:
|
|
yield test_suite_id, "install.nourl", default_meta
|
|
|
|
if (
|
|
os.environ.get("DIST") == "bullseye"
|
|
and is_webapp
|
|
and ("is_public" in install_args or "init_main_permission" in install_args)
|
|
):
|
|
# Testing private vs. public install doesnt make that much sense, remote it for bookworm etc...
|
|
yield test_suite_id, "install.private", default_meta
|
|
|
|
if is_multi_instance:
|
|
yield test_suite_id, "install.multi", default_meta
|
|
|
|
yield test_suite_id, "backup_restore", default_meta
|
|
|
|
yield test_suite_id, "upgrade", default_meta
|
|
for commit, infos in test_suite.get("test_upgrade_from", {}).items():
|
|
infos["upgrade_name"] = infos.pop("name")
|
|
if infos["upgrade_name"]:
|
|
infos["upgrade_name"] = infos["upgrade_name"].replace(
|
|
"Upgrade from ", ""
|
|
)
|
|
if "args" in infos:
|
|
infos["install_args"] = infos.pop("args")
|
|
upgrade_meta = copy.copy(default_meta)
|
|
upgrade_meta.update(infos)
|
|
yield test_suite_id, "upgrade." + commit, upgrade_meta
|
|
|
|
if is_webapp:
|
|
yield test_suite_id, "change_url", default_meta
|
|
|
|
|
|
def filter_test_list(test_manifest, base_test_list):
|
|
for test_suite_id, test_suite in test_manifest.items():
|
|
# Ignore non-testsuite stuff like "test_format"
|
|
if not isinstance(test_suite, dict):
|
|
continue
|
|
|
|
exclude = test_suite.get("exclude", [])
|
|
only = test_suite.get("only")
|
|
|
|
if test_suite_id == "default" and only:
|
|
raise Exception("'only' is not allowed on the default test suite")
|
|
|
|
if only:
|
|
tests_for_this_suite = {
|
|
test_id: meta
|
|
for suite_id, test_id, meta in base_test_list
|
|
if suite_id == test_suite_id and test_id in only
|
|
}
|
|
elif exclude:
|
|
tests_for_this_suite = {
|
|
test_id: meta
|
|
for suite_id, test_id, meta in base_test_list
|
|
if suite_id == test_suite_id and test_id not in exclude
|
|
}
|
|
else:
|
|
tests_for_this_suite = {
|
|
test_id: meta
|
|
for suite_id, test_id, meta in base_test_list
|
|
if suite_id == test_suite_id
|
|
}
|
|
|
|
yield test_suite_id, tests_for_this_suite
|
|
|
|
|
|
def dump_for_package_check(
|
|
test_list: dict[str, dict[str, Any]], package_check_tests_dir: Path
|
|
) -> None:
|
|
test_suite_i = 0
|
|
|
|
for test_suite_id, subtest_list in test_list.items():
|
|
test_suite_i += 1
|
|
|
|
subtest_i = 0
|
|
|
|
for test, meta in subtest_list.items():
|
|
meta = copy.copy(meta)
|
|
|
|
subtest_i += 1
|
|
|
|
if "." in test:
|
|
test_type, test_arg = test.split(".")
|
|
else:
|
|
test_type = test
|
|
test_arg = ""
|
|
|
|
J = {
|
|
"test_serie": test_suite_id,
|
|
"test_type": "TEST_" + test_type.upper(),
|
|
"test_arg": test_arg,
|
|
"preinstall_template": meta.pop("preinstall", ""),
|
|
"preupgrade_template": meta.pop("preupgrade", ""),
|
|
"install_args": "&".join(
|
|
[k + "=" + str(v) for k, v in meta.pop("install_args").items()]
|
|
),
|
|
"extra": meta, # Boring legacy logic just to ship the upgrade-from-commit's name ...
|
|
}
|
|
|
|
test_file_id = test_suite_i * 100 + subtest_i
|
|
|
|
json.dump(J, (package_check_tests_dir / f"{test_file_id}.json").open("w"))
|
|
|
|
|
|
def build_test_list(basedir: Path) -> dict[str, dict[str, Any]]:
|
|
test_manifest = toml.load((basedir / "tests.toml").open("r"))
|
|
|
|
manifest = toml.load((basedir / "manifest.toml").open("r"))
|
|
is_multi_instance = manifest.get("integration").get("multi_instance") is True
|
|
|
|
is_webapp = (
|
|
os.system(
|
|
f"grep -q '^ynh_add_nginx_config\|^ynh_nginx_add_config\|^ynh_config_add_nginx' '{str(basedir)}/scripts/install'"
|
|
)
|
|
== 0
|
|
)
|
|
|
|
default_install_args = get_default_values_for_questions(
|
|
manifest, raise_if_no_default=False
|
|
)
|
|
|
|
base_test_list = list(
|
|
generate_test_list_base(
|
|
test_manifest, default_install_args, is_webapp, is_multi_instance
|
|
)
|
|
)
|
|
test_list = dict(filter_test_list(test_manifest, base_test_list))
|
|
|
|
return test_list
|
|
|
|
|
|
def main() -> None:
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("app", type=Path, help="Path to the app directory")
|
|
parser.add_argument(
|
|
"-d",
|
|
"--dump-to",
|
|
type=Path,
|
|
required=False,
|
|
help="Dump the result to the package check directory",
|
|
)
|
|
args = parser.parse_args()
|
|
|
|
test_list = build_test_list(args.app)
|
|
|
|
if args.dump_to:
|
|
dump_for_package_check(test_list, args.dump_to)
|
|
else:
|
|
print(json.dumps(test_list, indent=4))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|