Skip to content
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
65 changes: 56 additions & 9 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,27 @@ permissions:
contents: read

jobs:
# Determine which tests to run based on changed files
changes:
runs-on: ubuntu-latest
outputs:
schema-generation: ${{ steps.filter.outputs.schema-generation }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: filter
with:
filters: |
schema-generation:
- 'src/allotropy/allotrope/schemas/**'
- 'src/allotropy/allotrope/schema_parser/**'
- 'src/allotropy/allotrope/models/**'
- 'src/allotropy/allotrope/schemas.py'
- 'src/allotropy/exceptions.py'
- 'scripts/generate_schemas.py'
- 'scripts/download_schema.py'
- 'tests/allotrope/schema_parser/**'
- 'pyproject.toml'
test_py_310:
runs-on: ubuntu-latest
name: Tests (python 3.10)
Expand All @@ -27,9 +48,9 @@ jobs:
run: pip install "hatch>=1.13.0"
- name: Install click
run: pip install click!=8.3.0
- name: Run Tests
run: hatch run test_all.py3.10:pytest -n 2 tests
timeout-minutes: 15
- name: Run Tests (excluding schema generation)
run: hatch run test_all.py3.10:pytest -n 2 tests --ignore=tests/allotrope/schema_parser/generate_schemas_test.py
timeout-minutes: 10

test_py_311:
runs-on: ubuntu-latest
Expand All @@ -47,9 +68,9 @@ jobs:
# NOTE: due to bug: https://github.com/pallets/click/issues/3066
- name: Install click
run: pip install click!=8.3.0
- name: Run Tests
run: hatch run test_all.py3.11:pytest -n 2 tests
timeout-minutes: 15
- name: Run Tests (excluding schema generation)
run: hatch run test_all.py3.11:pytest -n 2 tests --ignore=tests/allotrope/schema_parser/generate_schemas_test.py
timeout-minutes: 10

test_py_312:
runs-on: ubuntu-latest
Expand All @@ -66,9 +87,35 @@ jobs:
run: pip install "hatch>=1.13.0"
- name: Install click
run: pip install click!=8.3.0
- name: Run Tests
run: hatch run test_all.py3.12:pytest -n 2 tests
timeout-minutes: 15
- name: Run Tests (excluding schema generation)
run: hatch run test_all.py3.12:pytest -n 2 tests --ignore=tests/allotrope/schema_parser/generate_schemas_test.py
timeout-minutes: 10

# Schema generation test - only runs when relevant files change or on main branch
schema_generation_test:
needs: changes
# Always run on main branch, otherwise only when schema files change
if: ${{ github.ref == 'refs/heads/main' || needs.changes.outputs.schema-generation == 'true' }}
runs-on: ubuntu-latest
name: Schema Generation Test
strategy:
matrix:
python-version: ["3.10"] # Only run on one Python version since output is the same

steps:
- uses: actions/checkout@v4
with:
lfs: true
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install hatch
run: pip install "hatch>=1.13.0"
- name: Install click
run: pip install click!=8.3.0
- name: Run Schema Generation Test
run: hatch run test_all.py${{ matrix.python-version }}:pytest tests/allotrope/schema_parser/generate_schemas_test.py -v
timeout-minutes: 5

lint:
runs-on: ubuntu-latest
Expand Down
5 changes: 2 additions & 3 deletions src/allotropy/allotrope/schema_parser/backup_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
from itertools import zip_longest
from pathlib import Path
import shutil

from allotropy.parsers.utils.uuids import random_uuid_str
import uuid

PathType = Path | str

Expand All @@ -19,7 +18,7 @@ def _files_equal(path1: PathType, path2: PathType) -> bool:

def _get_backup_path(path: PathType) -> Path:
_path = Path(path)
return Path(_path.parent, f".{_path.stem}.{random_uuid_str()}.bak{_path.suffix}")
return Path(_path.parent, f".{_path.stem}.{uuid.uuid4()!s}.bak{_path.suffix}")


def get_original_path(path: PathType) -> Path:
Expand Down
6 changes: 4 additions & 2 deletions src/allotropy/allotrope/schema_parser/model_class_editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
get_all_schema_components,
get_schema_definitions_mapping,
)
from allotropy.parsers.utils.values import assert_not_none

SCHEMA_DIR_PATH = "src/allotropy/allotrope/schemas"
SHARED_FOLDER_MODULE = "allotropy.allotrope.models.shared"
Expand Down Expand Up @@ -196,7 +195,10 @@ def create(contents: str) -> DataclassField:
type_string, default_value = (
content.split("=") if "=" in content else (content, None)
)
types = _parse_field_types(assert_not_none(type_string))
if type_string is None:
msg = f"Expected non-null type string for field {name}."
raise ValueError(msg)
types = _parse_field_types(type_string)

return DataclassField(name, default_value, types)

Expand Down
6 changes: 2 additions & 4 deletions src/allotropy/allotrope/schema_parser/path_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
import re
from typing import Any

from allotropy.exceptions import AllotropeValidationError

ALLOTROPE_DIR: Path = Path(__file__).parent.parent
ALLOTROPY_DIR: Path = ALLOTROPE_DIR.parent
ROOT_DIR: Path = ALLOTROPE_DIR.parent.parent.parent
Expand Down Expand Up @@ -74,10 +72,10 @@ def get_schema_path_from_manifest(manifest: str) -> Path:
def get_schema_path_from_asm(asm_dict: Mapping[str, Any]) -> Path:
if "$asm.manifest" not in asm_dict:
msg = "File is not valid ASM - missing $asm.manifest field"
raise AllotropeValidationError(msg)
raise ValueError(msg)
if not isinstance(asm_dict["$asm.manifest"], str):
msg = f"File is not valid ASM - $asm.manifest is not a string: {asm_dict['$asm.manifest']}"
raise AllotropeValidationError(msg)
raise ValueError(msg)
return get_schema_path_from_manifest(asm_dict["$asm.manifest"])


Expand Down
3 changes: 2 additions & 1 deletion src/allotropy/allotrope/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@
get_schema_path_from_manifest,
SHARED_SCHEMAS_DEFINITIONS_PATH,
)
from allotropy.constants import DEFAULT_ENCODING
from allotropy.exceptions import AllotropeSerializationError, AllotropeValidationError

DEFAULT_ENCODING = "UTF-8"

# Override format checker to remove "uri-reference" check, which ASM schemas fail against.
FORMAT_CHECKER = copy.deepcopy(
jsonschema.validators.Draft202012Validator.FORMAT_CHECKER
Expand Down
31 changes: 4 additions & 27 deletions tests/allotrope/schema_parser/generate_schemas_test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from pathlib import Path
import re

import pytest

Expand All @@ -20,33 +19,11 @@ def _get_schema_paths() -> list[Path]:
]


def _pick_subset(paths: list[Path], count: int = 8) -> list[Path]:
if not paths:
return []
if len(paths) <= count:
return paths
step = max(1, len(paths) // count)
# Evenly sample across the set for broad coverage
return [paths[i] for i in range(0, len(paths), step)][:count]


def test_generate_schemas_smoke_subset() -> None:
"""Fast smoke test over a representative subset of schemas."""
paths = _get_schema_paths()
subset = _pick_subset(paths, count=8)
# Build a regex that matches exactly any of the chosen relative schema paths
escaped = [re.escape(str(p)) for p in subset]
pattern = rf"^({'|'.join(escaped)})$"
models_changed = generate_schemas(dry_run=True, schema_regex=pattern)
assert (
not models_changed
), f"Expected no models files to have changed by generate-schemas script, found changes in: {models_changed}.\nPlease run 'hatch run scripts:generate-schemas' and validate the changes."


@pytest.mark.long
def test_generate_schemas_runs_to_completion() -> None:
"""Full run once across all schemas. Marked long for optional execution."""
models_changed = generate_schemas(dry_run=True)
@pytest.mark.parametrize("schema_path", _get_schema_paths())
def test_generate_schemas_runs_to_completion(schema_path: Path) -> None:
"""Test that schema generation produces no unexpected changes."""
models_changed = generate_schemas(dry_run=True, schema_regex=str(schema_path))
assert (
not models_changed
), f"Expected no models files to have changed by generate-schemas script, found changes in: {models_changed}.\nPlease run 'hatch run scripts:generate-schemas' and validate the changes."
Loading