Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#75 Fixed the short tag reading #76

Merged
merged 2 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions pytest-backend/doc/changes/unreleased.md
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
# Unreleased

## Bug fixing

* #75: Fixed the project_short_tag fixture. Now it should be able to find the error_code_config.yml
regardless of the testing rootpath.
39 changes: 32 additions & 7 deletions pytest-backend/exasol/pytest_backend/project_short_tag.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,43 @@
from pathlib import Path
import yaml

FILE = "error_code_config.yml"
YML_FILE = 'error_code_config.yml'
STOP_FILE = 'pyproject.toml'


def read_from_yaml(dir: Path) -> str:
def _find_path_backwards(start_path: str | Path,
stop_file: str | Path = STOP_FILE,
target_path: str | Path = YML_FILE) -> Path | None:
"""
Read project-short-tag from yaml file ``FILE`` in the specified
directory ``dir``.
An utility searching for a specified path backwards. It begins with the given start
path and checks if the target path is among its siblings. Then it moves to the parent
path and so on, until it either reaches the root of the file structure or finds the
stop file. returns None if the search is unsuccessful.
"""
config_file = dir / FILE
if not config_file.exists():
current_path = Path(start_path)
root = Path(current_path.root)
while current_path != root:
result_path = Path(current_path, target_path)
if result_path.exists():
return result_path
stop_path = Path(current_path, stop_file)
if stop_path.exists():
return None
current_path = current_path.parent


def read_from_yaml(start_dir: Path) -> str | None:
"""
Read project-short-tag from yaml file ``FILE`` looking for it from the
specified starting directory ``start_dir``.
If the yml file cannot be found returns None.
If the yml file is found, but it doesn't have the expected format raises
a RuntimeError.
"""
config_file = _find_path_backwards(start_dir)
if config_file is None:
return None
with open(config_file, 'r') as file:
with config_file.open('r') as file:
ecc = yaml.safe_load(file)
try:
return next(t for t in ecc["error-tags"])
Expand Down
50 changes: 50 additions & 0 deletions pytest-backend/test/integration/pytest_backend_test.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
from textwrap import dedent
import os
import re
from inspect import cleandoc
from unittest import mock
import pytest

from exasol.pytest_backend import (BACKEND_OPTION, BACKEND_ALL, BACKEND_ONPREM)
Expand All @@ -8,6 +12,11 @@
pytest_plugins = ["pytester"]


def _testfile(body):
test_name = re.sub(r"^.*def ([^(]+).*", "\\1", body, flags=re.S)
return { test_name: cleandoc(body) }


def test_pytest_all_backends(pytester):
test_code = dedent("""
import pyexasol
Expand Down Expand Up @@ -76,3 +85,44 @@ def test_default_itde_options(itde_config):
assert itde_config.db_disk_size == DEFAULT_ITDE_DB_DISK_SIZE
assert itde_config.nameserver == []
assert itde_config.db_version == DEFAULT_ITDE_DB_VERSION


@pytest.mark.parametrize(
"pst_file, pst_env, pst_cli, expected",
[
("F", None, None, "F"),
("F", "E", None, "E"),
("F", "E", "C", "C"),
])
def test_project_short_tag(
request,
pytester,
pst_file,
pst_env,
pst_cli,
expected,
):
"""
This test sets different values for the project short tag in the file
error_code_config.yml, cli option --project-short-tag, and environment
variable PROJECT_SHORT_TAG and verifies their precedence.
"""
if pst_file:
pytester.makefile(".yml", **{
"error_code_config":
cleandoc(f"""
error-tags:
{pst_file}:
highest-index: 0
""")
})
pytester.makepyfile(**_testfile(
f"""
def test_project_short_tag(project_short_tag):
assert "{expected}" == project_short_tag
"""))
env = { "PROJECT_SHORT_TAG": pst_env } if pst_env else {}
cli_args = ["--project-short-tag", pst_cli] if pst_cli else []
with mock.patch.dict(os.environ, env):
result = pytester.runpytest(*cli_args)
assert result.ret == pytest.ExitCode.OK
38 changes: 38 additions & 0 deletions pytest-backend/test/unit/test_project_short_tag.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from textwrap import dedent
import pytest

from exasol.pytest_backend.project_short_tag import read_from_yaml, YML_FILE, STOP_FILE


def test_read_from_yaml(tmp_path):
start_dir = tmp_path / 'start_dir'
short_tag = 'ABC'
short_tag_file = tmp_path / YML_FILE
with short_tag_file.open('w') as f:
f.write(dedent(f"""
error-tags:
{short_tag}:
highest-index: 0
"""))
assert read_from_yaml(start_dir) == short_tag


def test_read_from_yaml_not_found(tmp_path):
start_dir = tmp_path / 'start_dir'
stop_file = tmp_path / STOP_FILE
with stop_file.open('w') as f:
f.write('[tool.poetry]')
assert read_from_yaml(start_dir) is None


def test_read_from_yaml_invalid(tmp_path):
start_dir = tmp_path / 'start_dir'
short_tag_file = tmp_path / YML_FILE
with short_tag_file.open('w') as f:
f.write(dedent(f"""
whatever:
ABC:
highest-index: 0
"""))
with pytest.raises(RuntimeError):
read_from_yaml(start_dir)
5 changes: 5 additions & 0 deletions pytest-saas/doc/changes/unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,8 @@
## Internal

* Relock dependencies

## Bug fixing

* #75: Fixed the project_short_tag fixture. Now it should be able to find the error_code_config.yml
regardless of the testing rootpath.
39 changes: 32 additions & 7 deletions pytest-saas/exasol/pytest_saas/project_short_tag.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,43 @@
from pathlib import Path
import yaml

FILE = "error_code_config.yml"
YML_FILE = 'error_code_config.yml'
STOP_FILE = 'pyproject.toml'


def read_from_yaml(dir: Path) -> str:
def _find_path_backwards(start_path: str | Path,
stop_file: str | Path = STOP_FILE,
target_path: str | Path = YML_FILE) -> Path | None:
"""
Read project-short-tag from yaml file ``FILE`` in the specified
directory ``dir``.
An utility searching for a specified path backwards. It begins with the given start
path and checks if the target path is among its siblings. Then it moves to the parent
path and so on, until it either reaches the root of the file structure or finds the
stop file. returns None if the search is unsuccessful.
"""
config_file = dir / FILE
if not config_file.exists():
current_path = Path(start_path)
root = Path(current_path.root)
while current_path != root:
result_path = Path(current_path, target_path)
if result_path.exists():
return result_path
stop_path = Path(current_path, stop_file)
if stop_path.exists():
return None
current_path = current_path.parent


def read_from_yaml(start_dir: Path) -> str | None:
"""
Read project-short-tag from yaml file ``FILE`` looking for it from the
specified starting directory ``start_dir``.
If the yml file cannot be found returns None.
If the yml file is found, but it doesn't have the expected format raises
a RuntimeError.
"""
config_file = _find_path_backwards(start_dir)
if config_file is None:
return None
with open(config_file, 'r') as file:
with config_file.open('r') as file:
ecc = yaml.safe_load(file)
try:
return next(t for t in ecc["error-tags"])
Expand Down
Loading