Skip to content

Commit

Permalink
test: Add support for .in templates in salt formulas tests
Browse files Browse the repository at this point in the history
  • Loading branch information
JBWatenbergScality committed Mar 19, 2021
1 parent bc98afc commit dc7625a
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 4 deletions.
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ repos:
files: ^(salt/tests/unit/formulas/.*\.py)$
args: [--strict]
additional_dependencies:
- 'pyenchant~=2.0'
- pytest

- repo: https://github.com/warpnet/salt-lint
Expand Down
1 change: 1 addition & 0 deletions .pylint-dict
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
API
arg
basename
buildargs
Expand Down
1 change: 1 addition & 0 deletions salt/tests/unit/formulas/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from tests.unit.formulas.fixtures.data import fixture_base_grains
from tests.unit.formulas.fixtures.data import fixture_base_kubernetes
from tests.unit.formulas.fixtures.data import fixture_base_pillar
from tests.unit.formulas.fixtures.data import fixture_buildchain_template_context
from tests.unit.formulas.fixtures.data import fixture_metalk8s_versions
from tests.unit.formulas.fixtures.environment import fixture_template_loader
from tests.unit.formulas.fixtures.environment import fixture_environment
Expand Down
21 changes: 21 additions & 0 deletions salt/tests/unit/formulas/fixtures/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from pathlib import Path
from typing import Any
import sys
import textwrap

import pytest
import yaml
Expand Down Expand Up @@ -41,6 +42,26 @@ def fixture_metalk8s_versions() -> Any:
return versions.SALT_VERSIONS_JSON


@pytest.fixture(scope="session", name="buildchain_template_context")
def fixture_buildchain_template_context() -> Any:
"""Emulate .in template context for buildchain."""
buildchain_path = paths.REPO_ROOT / "buildchain"
sys.path.insert(0, str(buildchain_path))
# pylint: disable=import-error,import-outside-toplevel
from buildchain import versions

# pylint: enable=import-error,import-outside-toplevel

sys.path.pop(0)
ui_theme_options: Path = paths.REPO_ROOT / "shell-ui" / "theme.json"
return {
"VERSION": versions.VERSION,
"ThemeConfig": textwrap.indent(
ui_theme_options.read_text(encoding="utf-8"), 4 * " "
),
}


@pytest.fixture(scope="session", name="base_kubernetes")
def fixture_base_kubernetes() -> kubernetes.K8sData:
"""Return a basic dataset for mocking Kubernetes API.
Expand Down
38 changes: 34 additions & 4 deletions salt/tests/unit/formulas/fixtures/environment.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Fixtures for setting up a Jinja rendering environment."""
import json
from string import Template
from typing import Any, Callable, Dict, Tuple

import jinja2
Expand All @@ -11,32 +12,61 @@
)
import salt.utils.jinja # type: ignore


from tests.unit.formulas import paths


class BuildchainTemplate(Template):
"""Template class using @@ as a delimiter."""

delimiter = "@@"


class MockedFSLoader(jinja2.FileSystemLoader):
"""A FilesystemLoader with overrides for arbitrary templates."""

def __init__(self, directory: str, mock_templates: Dict[str, str]):
def __init__(
self,
directory: str,
mock_templates: Dict[str, str],
buildchain_template_context: Dict[str, str],
):
super().__init__(directory)
self._mock_templates = mock_templates
self._buildchain_template_context = buildchain_template_context

def get_source(
self, environment: jinja2.Environment, template: str
) -> Tuple[str, str, Callable[..., Any]]:
mock_template = self._mock_templates.get(template)
if mock_template is not None:
return mock_template, template, lambda: None
return super().get_source(environment, template)
try:
return super().get_source(environment, template)
except jinja2.TemplateNotFound:
# If template is not found we check if a .in template
# exists and use a mocked context
source, path, is_up_to_date = super().get_source(
environment, template + ".in"
)
source_buildchain_template = BuildchainTemplate(source)
new_source = source_buildchain_template.substitute(
self._buildchain_template_context
)
return new_source, path, is_up_to_date


@pytest.fixture(scope="session", name="template_loader")
def fixture_template_loader(metalk8s_versions: Any) -> jinja2.FileSystemLoader:
def fixture_template_loader(
metalk8s_versions: Any, buildchain_template_context: Dict[str, str]
) -> jinja2.FileSystemLoader:
"""Load templates using the salt/ directory as a root."""
mock_templates = {
"metalk8s/versions.json": json.dumps(metalk8s_versions),
}
return MockedFSLoader(str(paths.SALT_DIR), mock_templates)
return MockedFSLoader(
str(paths.SALT_DIR), mock_templates, buildchain_template_context
)


@pytest.fixture(scope="session", name="environment")
Expand Down

0 comments on commit dc7625a

Please sign in to comment.