2
0
mirror of https://github.com/frappe/frappe_docker.git synced 2024-11-09 23:00:56 +00:00

Refactor test

This commit is contained in:
Lev Vereshchagin 2022-02-08 15:49:14 +03:00
parent b2f63640ee
commit 7e562d7855

View File

@ -1,10 +1,12 @@
import os
import shlex
import shutil
import ssl
import subprocess
import sys
from enum import Enum
from functools import wraps
from textwrap import dedent
from time import sleep
from typing import Any, Callable, Optional
from urllib.error import HTTPError, URLError
@ -63,8 +65,13 @@ def log(text: str):
if CI:
print(f"::group::{text}")
else:
print(colored(text, Color.YELLOW))
output = (
f"\n{f' {text} '.center(os.get_terminal_size().columns, '=')}\n"
)
print(colored(output, Color.YELLOW))
ret = f(*args, **kwargs)
if CI:
print("::endgroup::")
return ret
@ -75,7 +82,7 @@ def log(text: str):
def run(*cmd: str):
print(colored(f"> {' '.join(cmd)}", Color.GREEN))
print(colored(f"> {shlex.join(cmd)}", Color.GREEN))
return subprocess.check_call(cmd)
@ -101,7 +108,7 @@ def docker_compose(*cmd: str):
return run(*args, *cmd)
def dco_exec(*cmd: str):
def docker_compose_exec(*cmd: str):
if TTY:
return docker_compose("exec", *cmd)
else:
@ -111,25 +118,31 @@ def dco_exec(*cmd: str):
@log("Setup .env")
def setup_env():
shutil.copy("example.env", "tests/.env")
if not CI:
return
for env in ("FRAPPE_VERSION", "ERPNEXT_VERSION"):
if os.environ[env] == "develop":
for var in ("FRAPPE_VERSION", "ERPNEXT_VERSION"):
if os.environ[var] == "develop":
with open(os.environ["GITHUB_ENV"], "a") as f:
f.write(f"\n{env}=latest")
os.environ[env] = "latest"
f.write(f"\n{var}=latest")
os.environ[var] = "latest"
with open("tests/.env", "a") as f:
f.write(
f"""
FRAPPE_VERSION={os.environ['FRAPPE_VERSION']}
ERPNEXT_VERSION={os.environ['ERPNEXT_VERSION']}
"""
dedent(
f"""
FRAPPE_VERSION={os.environ['FRAPPE_VERSION']}
ERPNEXT_VERSION={os.environ['ERPNEXT_VERSION']}
"""
)
)
with open("tests/.env") as f:
print(f.read())
@log("Print compose configuration")
@log("Print configuration")
def print_compose_configuration():
docker_compose("config")
@ -139,22 +152,22 @@ def create_containers():
docker_compose("up", "-d", "--quiet-pull")
@log("Check if backend services have connections")
@log("Check if Python services have connections")
def ping_links_in_backends():
for service in BACKEND_SERVICES:
for _ in range(10):
try:
dco_exec(service, "healthcheck.sh")
docker_compose_exec(service, "healthcheck.sh")
break
except subprocess.CalledProcessError:
sleep(1)
else:
raise Exception(f"Connections healthcheck failed for service {service}")
raise RuntimeError(f"Connections healthcheck failed for service {service}")
@log("Create test site")
@log("Create site")
def create_site():
dco_exec(
docker_compose_exec(
"backend",
"bench",
"new-site",
@ -176,14 +189,18 @@ _ssl_ctx.verify_mode = ssl.CERT_NONE
def ping_and_check_content(url: str, callback: Callable[[str], Optional[str]]):
request = Request(url, headers={"Host": SITE_NAME})
print(f"Checking {url}")
for _ in range(100):
try:
response = urlopen(request, context=_ssl_ctx)
except HTTPError as exc:
if exc.code not in (404, 502):
raise
except URLError:
pass
else:
text: str = response.read().decode()
ret = callback(text)
@ -192,32 +209,33 @@ def ping_and_check_content(url: str, callback: Callable[[str], Optional[str]]):
return
sleep(0.1)
raise AssertionError(f"Couldn't ping {url}")
raise RuntimeError(f"Couldn't ping {url}")
def index_callback(text: str):
def check_index_callback(text: str):
if "404 page not found" not in text:
return text[:200]
@log("Check /")
def check_index():
ping_and_check_content(url="http://127.0.0.1", callback=index_callback)
ping_and_check_content("http://127.0.0.1", check_index_callback)
@log("Check /api/method/version")
def check_api():
ping_and_check_content(
url="http://127.0.0.1/api/method/version",
callback=lambda text: text if '"message"' in text else None,
"http://127.0.0.1/api/method/version",
lambda text: text if '"message"' in text else None,
)
@log("Check if Frappe can connect to services in backends")
@log("Check if Frappe can connect to services in Python services")
def ping_frappe_connections_in_backends():
for service in BACKEND_SERVICES:
docker_compose("cp", "tests/_ping_frappe_connections.py", f"{service}:/tmp/")
dco_exec(
docker_compose_exec(
service,
"/home/frappe/frappe-bench/env/bin/python",
f"/tmp/_ping_frappe_connections.py",
@ -227,8 +245,8 @@ def ping_frappe_connections_in_backends():
@log("Check /assets")
def check_assets():
ping_and_check_content(
url="http://127.0.0.1/assets/frappe/images/frappe-framework-logo.svg",
callback=lambda text: text[:200] if text is not None else None,
"http://127.0.0.1/assets/frappe/images/frappe-framework-logo.svg",
lambda text: text[:200] if text else None,
)
@ -241,8 +259,8 @@ def check_files():
f"backend:/home/frappe/frappe-bench/sites/{SITE_NAME}/public/files/",
)
ping_and_check_content(
url=f"http://127.0.0.1/files/{file_name}",
callback=lambda text: text if text == "lalala\n" else None,
f"http://127.0.0.1/files/{file_name}",
lambda text: text if text == "lalala\n" else None,
)
@ -265,7 +283,7 @@ def prepare_s3_server():
"/data",
)
docker_compose("cp", "tests/_create_bucket.py", "backend:/tmp")
dco_exec(
docker_compose_exec(
"-e",
f"S3_ACCESS_KEY={S3_ACCESS_KEY}",
"-e",
@ -278,8 +296,10 @@ def prepare_s3_server():
@log("Push backup to S3")
def push_backup_to_s3():
dco_exec("backend", "bench", "--site", SITE_NAME, "backup", "--with-files")
dco_exec(
docker_compose_exec(
"backend", "bench", "--site", SITE_NAME, "backup", "--with-files"
)
docker_compose_exec(
"backend",
"push-backup",
"--site",
@ -297,10 +317,10 @@ def push_backup_to_s3():
)
@log("Check backup in S3")
@log("Check backup files in S3")
def check_backup_in_s3():
docker_compose("cp", "tests/_check_backup_files.py", "backend:/tmp")
dco_exec(
docker_compose_exec(
"-e",
f"S3_ACCESS_KEY={S3_ACCESS_KEY}",
"-e",
@ -316,14 +336,14 @@ def stop_s3_container():
run("docker", "rm", "minio", "-f")
@log("Recreate with https override")
@log("Recreate with HTTPS override")
def recreate_with_https_override():
docker_compose("-f", "overrides/compose.https.yaml", "up", "-d")
@log("Check / (https)")
@log("Check / (HTTPS)")
def check_index_https():
ping_and_check_content(url="https://127.0.0.1", callback=index_callback)
ping_and_check_content("https://127.0.0.1", check_index_callback)
@log("Stop containers")
@ -335,13 +355,14 @@ def stop_containers():
def create_containers_with_erpnext_override():
args = ["-f", "overrides/compose.erpnext.yaml"]
if CI:
args.extend(("-f", "tests/compose.ci-erpnext.yaml"))
args += ("-f", "tests/compose.ci-erpnext.yaml")
docker_compose(*args, "up", "-d", "--quiet-pull")
@log("Create ERPNext site")
def create_erpnext_site():
dco_exec(
docker_compose_exec(
"backend",
"bench",
"new-site",
@ -356,19 +377,19 @@ def create_erpnext_site():
docker_compose("restart", "backend")
@log("Check /api/method/erpnext.templates.pages.product_search.get_product_list")
@log("Check /api/method")
def check_erpnext_api():
ping_and_check_content(
url="http://127.0.0.1/api/method/erpnext.templates.pages.product_search.get_product_list",
callback=lambda text: text if '"message"' in text else None,
"http://127.0.0.1/api/method/erpnext.templates.pages.product_search.get_product_list",
lambda text: text if '"message"' in text else None,
)
@log("Check /assets/erpnext/js/setup_wizard.js")
@log("Check /assets")
def check_erpnext_assets():
ping_and_check_content(
url="http://127.0.0.1/assets/erpnext/js/setup_wizard.js",
callback=lambda text: text[:200] if text is not None else None,
"http://127.0.0.1/assets/erpnext/js/setup_wizard.js",
lambda text: text[:200] if text else None,
)
@ -379,9 +400,11 @@ def create_containers_with_postgres_override():
@log("Create Postgres site")
def create_postgres_site():
dco_exec("backend", "bench", "set-config", "-g", "root_login", "postgres")
dco_exec("backend", "bench", "set-config", "-g", "root_password", "123")
dco_exec(
docker_compose_exec(
"backend", "bench", "set-config", "-g", "root_login", "postgres"
)
docker_compose_exec("backend", "bench", "set-config", "-g", "root_password", "123")
docker_compose_exec(
"backend",
"bench",
"new-site",
@ -399,52 +422,76 @@ def delete_env():
os.remove("tests/.env")
@log("Show docker compose logs")
@log("Show logs")
def show_docker_compose_logs():
docker_compose("logs")
def start():
setup_env()
print_compose_configuration()
create_containers()
ping_links_in_backends()
def create_frappe_site_and_check_availability():
create_site()
check_index()
check_api()
ping_frappe_connections_in_backends()
check_assets()
check_files()
def check_s3():
prepare_s3_server()
try:
push_backup_to_s3()
check_backup_in_s3()
finally:
stop_s3_container()
def check_https():
print_compose_configuration()
recreate_with_https_override()
check_index_https()
stop_containers()
def check_erpnext():
print_compose_configuration()
create_containers_with_erpnext_override()
create_erpnext_site()
check_erpnext_api()
check_erpnext_assets()
stop_containers()
def check_postgres():
print_compose_configuration()
create_containers_with_postgres_override()
create_postgres_site()
ping_links_in_backends()
def main() -> int:
try:
patch_print()
setup_env()
print_compose_configuration()
create_containers()
ping_links_in_backends()
create_site()
check_index()
check_api()
ping_frappe_connections_in_backends()
check_assets()
check_files()
prepare_s3_server()
push_backup_to_s3()
check_backup_in_s3()
stop_s3_container()
recreate_with_https_override()
check_index_https()
stop_containers()
create_containers_with_erpnext_override()
create_erpnext_site()
check_erpnext_api()
check_erpnext_assets()
stop_containers()
create_containers_with_postgres_override()
create_postgres_site()
ping_links_in_backends()
start()
create_frappe_site_and_check_availability()
check_s3()
check_https()
check_erpnext()
check_postgres()
finally:
delete_env()
show_docker_compose_logs()
stop_containers()
print(colored("Tests successfully passed!", Color.YELLOW))
print(colored("\nTests successfully passed!", Color.YELLOW))
return 0