Commit b49eb7cc authored by Dom Sekotill's avatar Dom Sekotill
Browse files

Switch test code to behave-utils

behave-utils is where much of this replaced code was moved to for
re-use.
parent 5d093e2d
Loading
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@ force_single_line = true
strict = true
warn_unused_configs = true
warn_unreachable = true
mypy_path = tests, tests/stubs
mypy_path = tests
plugins =
  trio_typing.plugin

+1 −2
Original line number Diff line number Diff line
@@ -95,6 +95,5 @@ repos:
  - id: mypy
    args: ["--config-file=.lint.cfg"]
    additional_dependencies:
    - trio-typing
    - types-requests
    - git+https://code.kodo.org.uk/dom/type-stubs.git#type-stubs[jsonpath,parse]
    - git+https://code.kodo.org.uk/dom/behave-utils.git@v0.2#behave-utils
+7 −92
Original line number Diff line number Diff line
@@ -15,36 +15,28 @@ https://behave.readthedocs.io/en/stable/tutorial.html#environmental-controls
from __future__ import annotations

import sys
from contextlib import contextmanager
from os import environ
from pathlib import Path
from typing import TYPE_CHECKING
from typing import Any
from typing import Iterator
from typing import NamedTuple

from behave import fixture
from behave import use_fixture
from behave.model import Feature
from behave.model import Scenario
from behave.runner import Context
from behave_utils import URL
from behave_utils import redirect
from behave_utils.mysql import snapshot_rollback
from requests.sessions import Session
from utils import URL
from utils import make_secret
from utils import redirect
from wp import Mysql
from wp import Wordpress
from wp.docker import Container
from wp.docker import Image
from wp.docker import IPv4Address
from wp.docker import Network
from wp import Site
from wp import test_cluster

if TYPE_CHECKING:
	from behave.runner import FeatureContext
	from behave.runner import ScenarioContext

SITE_URL = URL("http://test.example.com")
BUILD_CONTEXT = Path(__file__).parent.parent


def before_all(context: Context) -> None:
@@ -58,7 +50,7 @@ def before_feature(context: FeatureContext, feature: Feature) -> None:
	"""
	Setup/revert fixtures before each feature
	"""
	use_fixture(db_snapshot_rollback, context)
	use_fixture(snapshot_rollback, context, context.site.database)


def before_scenario(context: ScenarioContext, scenario: Scenario) -> None:
@@ -68,23 +60,11 @@ def before_scenario(context: ScenarioContext, scenario: Scenario) -> None:
	context.session = use_fixture(requests_session, context)


class Site(NamedTuple):
	"""
	A named-tuple of information about the containers for a site fixture
	"""

	url: str
	address: IPv4Address
	frontend: Container
	backend: Wordpress
	database: Mysql


# Todo(dom.sekotill): When PEP-612 is properly implemented in mypy the [*a, **k] and default
# values nonsense can be removed from fixtures

@fixture
def setup_test_cluster(context: Context, /, site_url: str|None = None, *a: Any, **k: Any) -> Iterator[Site]:
def setup_test_cluster(context: Context, /, site_url: URL|None = None, *a: Any, **k: Any) -> Iterator[Site]:
	"""
	Prepare and return the details of a site fixture
	"""
@@ -116,71 +96,6 @@ def db_snapshot_rollback(context: FeatureContext, /, *a: Any, **k: Any) -> Itera
	db.mysql(input=snapshot)


@contextmanager
def test_cluster(site_url: str) -> Iterator[Site]:
	"""
	Configure and start all the necessary containers for use as test fixtures
	"""
	test_dir = Path(__file__).parent

	db_secret = make_secret(20)
	db_init = test_dir / "mysql-init.sql"

	with Network() as network:
		database = Mysql(
			Image.pull("mysql/mysql-server"),
			network=network,
			volumes={
				Path("/var/lib/mysql"),
				(db_init, Path("/docker-entrypoint-initdb.d") / db_init.name),
			},
			env=dict(
				MYSQL_DATABASE="test-db",
				MYSQL_USER="test-db-user",
				MYSQL_PASSWORD=db_secret,
			),
		)
		frontend = Container(
			Image.build(
				BUILD_CONTEXT,
				target='nginx',
				nginx_version=environ.get("NGINX_VERSION"),
			),
			network=network,
			volumes=[
				("static", Path("/app/static")),
				("media", Path("/app/media")),
			],
		)
		backend = Wordpress(
			Image.build(
				BUILD_CONTEXT,
				php_version=environ.get("PHP_VERSION"),
				wp_version=environ.get("WP_VERSION"),
			),
			network=network,
			volumes=frontend.volumes,
			env=dict(
				SITE_URL=site_url,
				SITE_ADMIN_EMAIL="test@kodo.org.uk",
				DB_NAME="test-db",
				DB_USER="test-db-user",
				DB_PASS=db_secret,
				DB_HOST="database:3306",
			),
		)

		backend.connect(network, "upstream")
		database.connect(network, "database")

		with database.started(), backend.started(), frontend.started():
			addr = frontend.inspect(
				f"$.NetworkSettings.Networks.{network}.IPAddress",
				str, IPv4Address,
			)
			yield Site(site_url, addr, frontend, backend, database)


if __name__ == "__main__":
	from subprocess import run

+1 −2
Original line number Diff line number Diff line
Python ~=3.9; python_version < '3.9'

behave
jsonpath-python ~=1.0
git+https://code.kodo.org.uk/dom/behave-utils.git@v0.2#behave-utils
requests ~=2.26
trio ~=0.19.0
+2 −2
Original line number Diff line number Diff line
@@ -16,8 +16,8 @@ from typing import TYPE_CHECKING

from behave import then
from behave import when
from utils.behave import PatternEnum
from utils.behave import register_pattern
from behave_utils.behave import PatternEnum
from behave_utils.behave import register_pattern
from wp import Container

if TYPE_CHECKING:
Loading