-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Use pytest for tests * Pin black * Update CI * Rename test_main to test_frappe_docker * Force project name "test"
- Loading branch information
Showing
12 changed files
with
464 additions
and
555 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
frappe @ git+git://github.com/frappe/frappe.git | ||
boto3-stubs[s3] | ||
black==22.1.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pytest==7.1.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,3 +7,6 @@ known_third_party = frappe | |
|
||
[codespell] | ||
skip = images/bench/Dockerfile | ||
|
||
[tool:pytest] | ||
addopts = -s --exitfirst |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import asyncio | ||
import json | ||
import socket | ||
from typing import Any, Iterable | ||
|
||
Address = tuple[str, int] | ||
|
||
|
||
async def wait_for_port(address: Address) -> None: | ||
# From https://github.com/clarketm/wait-for-it | ||
while True: | ||
try: | ||
_, writer = await asyncio.open_connection(*address) | ||
writer.close() | ||
await writer.wait_closed() | ||
break | ||
except (socket.gaierror, ConnectionError, OSError, TypeError): | ||
pass | ||
await asyncio.sleep(0.1) | ||
|
||
|
||
def get_redis_url(addr: str) -> Address: | ||
result = addr.replace("redis://", "") | ||
result = result.split("/")[0] | ||
parts = result.split(":") | ||
assert len(parts) == 2 | ||
return parts[0], int(parts[1]) | ||
|
||
|
||
def get_addresses(config: dict[str, Any]) -> Iterable[Address]: | ||
yield (config["db_host"], config["db_port"]) | ||
for key in ("redis_cache", "redis_queue", "redis_socketio"): | ||
yield get_redis_url(config[key]) | ||
|
||
|
||
async def async_main(addresses: set[Address]) -> None: | ||
tasks = [asyncio.wait_for(wait_for_port(addr), timeout=5) for addr in addresses] | ||
await asyncio.gather(*tasks) | ||
|
||
|
||
def main() -> int: | ||
with open("/home/frappe/frappe-bench/sites/common_site_config.json") as f: | ||
config = json.load(f) | ||
addresses = set(get_addresses(config)) | ||
asyncio.run(async_main(addresses)) | ||
return 0 | ||
|
||
|
||
if __name__ == "__main__": | ||
raise SystemExit(main()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
import os | ||
import shutil | ||
import subprocess | ||
from dataclasses import dataclass | ||
from pathlib import Path | ||
|
||
import pytest | ||
|
||
from tests.utils import CI, Compose | ||
|
||
|
||
def _add_version_var(name: str, env_path: Path): | ||
if not os.getenv(name): | ||
return | ||
|
||
if (gh_env := os.getenv("GITHUB_ENV")) and os.environ[name] == "develop": | ||
with open(gh_env, "a") as f: | ||
f.write(f"\n{name}=latest") | ||
|
||
os.environ[name] = "latest" | ||
|
||
with open(env_path, "a") as f: | ||
f.write(f"\n{name}={os.environ[name]}") | ||
|
||
|
||
@pytest.fixture(scope="session") | ||
def env_file(tmp_path_factory: pytest.TempPathFactory): | ||
tmp_path = tmp_path_factory.mktemp("frappe-docker") | ||
file_path = tmp_path / ".env" | ||
shutil.copy("example.env", file_path) | ||
|
||
for var in ("FRAPPE_VERSION", "ERPNEXT_VERSION"): | ||
_add_version_var(name=var, env_path=file_path) | ||
|
||
yield file_path | ||
os.remove(file_path) | ||
|
||
|
||
@pytest.fixture(scope="session") | ||
def compose(env_file: str): | ||
return Compose(project_name="test", env_file=env_file) | ||
|
||
|
||
@pytest.fixture(autouse=True, scope="session") | ||
def frappe_setup(compose: Compose): | ||
compose.stop() | ||
compose("up", "-d", "--quiet-pull") | ||
yield | ||
compose.stop() | ||
|
||
|
||
@pytest.fixture(scope="session") | ||
def frappe_site(compose: Compose): | ||
site_name = "tests" | ||
compose.bench( | ||
"new-site", | ||
site_name, | ||
"--mariadb-root-password", | ||
"123", | ||
"--admin-password", | ||
"admin", | ||
) | ||
compose("restart", "backend") | ||
yield site_name | ||
|
||
|
||
@pytest.fixture(scope="class") | ||
def erpnext_setup(compose: Compose): | ||
compose.stop() | ||
|
||
args = ["-f", "overrides/compose.erpnext.yaml"] | ||
if CI: | ||
args += ("-f", "tests/compose.ci-erpnext.yaml") | ||
compose(*args, "up", "-d", "--quiet-pull") | ||
|
||
yield | ||
compose.stop() | ||
|
||
|
||
@pytest.fixture(scope="class") | ||
def erpnext_site(compose: Compose): | ||
site_name = "test_erpnext_site" | ||
compose.bench( | ||
"new-site", | ||
site_name, | ||
"--mariadb-root-password", | ||
"123", | ||
"--admin-password", | ||
"admin", | ||
"--install-app", | ||
"erpnext", | ||
) | ||
compose("restart", "backend") | ||
yield site_name | ||
|
||
|
||
@pytest.fixture | ||
def postgres_setup(compose: Compose): | ||
compose.stop() | ||
compose("-f", "overrides/compose.postgres.yaml", "up", "-d", "--quiet-pull") | ||
compose.bench("set-config", "-g", "root_login", "postgres") | ||
compose.bench("set-config", "-g", "root_password", "123") | ||
yield | ||
compose.stop() | ||
|
||
|
||
@pytest.fixture | ||
def python_path(): | ||
return "/home/frappe/frappe-bench/env/bin/python" | ||
|
||
|
||
@dataclass | ||
class S3ServiceResult: | ||
access_key: str | ||
secret_key: str | ||
|
||
|
||
@pytest.fixture | ||
def s3_service(python_path: str, compose: Compose): | ||
access_key = "AKIAIOSFODNN7EXAMPLE" | ||
secret_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" | ||
cmd = ( | ||
"docker", | ||
"run", | ||
"--name", | ||
"minio", | ||
"-d", | ||
"-e", | ||
f"MINIO_ACCESS_KEY={access_key}", | ||
"-e", | ||
f"MINIO_SECRET_KEY={secret_key}", | ||
"--network", | ||
f"{compose.project_name}_default", | ||
"minio/minio", | ||
"server", | ||
"/data", | ||
) | ||
subprocess.check_call(cmd) | ||
|
||
compose("cp", "tests/_create_bucket.py", "backend:/tmp") | ||
compose.exec( | ||
"-e", | ||
f"S3_ACCESS_KEY={access_key}", | ||
"-e", | ||
f"S3_SECRET_KEY={secret_key}", | ||
"backend", | ||
python_path, | ||
"/tmp/_create_bucket.py", | ||
) | ||
|
||
yield S3ServiceResult(access_key=access_key, secret_key=secret_key) | ||
subprocess.call(("docker", "rm", "minio", "-f")) |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.