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

(Re-)implement ci checks that ensure example specs are re-compilable and artifacts are not stale 🥖 #256

Open
cisaacstern opened this issue Sep 22, 2024 · 0 comments

Comments

@cisaacstern
Copy link
Collaborator

In #225 the (end-to-end execution) testing of examples is moved into the examples build directories themselves, and the -core and -ext-ecoscope packages are not dealing with any examples testing.

The one ci check we've lost in #225 is a check that the specs can be re-compiled and reflect the current workflows accurately. Considerations:

  • The (welcome) addition of the pixi.lock as a derived artifact complicates this somewhat, as we won't (?) be able to do a direct equality check on those files
  • Not totally sure where these tests should live (top level of the repo, in examples/?)

For reference, here is the code we used before for these tests (which is not directly reusable because compiler behavior has changed):

import json
from dataclasses import dataclass
from pathlib import Path

import pytest
import ruamel.yaml

from ecoscope_workflows_core.compiler import DagCompiler, DagTypes, Spec

EXAMPLES = Path(__file__).parent.parent / "examples"


def _spec_path_to_dag_fname(path: Path, dag_type: DagTypes) -> str:
    return f"{path.stem.replace('-', '_')}_dag.{dag_type.replace('-', '_')}.py"


def _spec_path_to_jsonschema_fname(path: Path) -> str:
    return f"{path.stem.replace('-', '_')}_params_fillable.json"


def _spec_path_to_yaml_fname(path: Path) -> str:
    return f"{path.stem.replace('-', '_')}_params_fillable.yaml"


def _spec_path_to_param_fname(path: Path) -> str:
    return f"{path.stem.replace('-', '_')}_params.yaml"


@dataclass
class SpecFixture:
    path: Path
    spec: dict


@pytest.fixture(
    params=[
        path.absolute() for path in EXAMPLES.joinpath("compilation-specs").iterdir()
    ],
    ids=[path.name for path in EXAMPLES.joinpath("compilation-specs").iterdir()],
)
def spec_fixture(request: pytest.FixtureRequest) -> SpecFixture:
    example_spec_path: Path = request.param
    yaml = ruamel.yaml.YAML(typ="safe")
    with open(example_spec_path) as f:
        spec_dict = yaml.load(f)
    return SpecFixture(example_spec_path, spec_dict)


@pytest.mark.parametrize(
    "dag_type",
    [
        "jupytext",
        "script-async",
        "script-sequential",
    ],
)
def test_generate_dag(spec_fixture: SpecFixture, dag_type: DagTypes):
    spec = Spec(**spec_fixture.spec)
    dag_compiler = DagCompiler(spec=spec)
    dag_str = dag_compiler.generate_dag(dag_type)
    script_fname = _spec_path_to_dag_fname(path=spec_fixture.path, dag_type=dag_type)
    with open(EXAMPLES / "dags" / script_fname) as f:
        assert dag_str == f.read()


def test_dag_params_jsonschema(spec_fixture: SpecFixture):
    spec = Spec(**spec_fixture.spec)
    dag_compiler = DagCompiler(spec=spec)
    params = dag_compiler.get_params_jsonschema()
    jsonschema_fname = _spec_path_to_jsonschema_fname(spec_fixture.path)
    with open(EXAMPLES / "params" / jsonschema_fname) as f:
        assert params == json.load(f)


def test_dag_params_fillable_yaml(spec_fixture: SpecFixture):
    spec = Spec(**spec_fixture.spec)
    dag_compiler = DagCompiler(spec=spec)
    yaml_str = dag_compiler.get_params_fillable_yaml()
    yaml = ruamel.yaml.YAML(typ="rt")
    yaml_fname = _spec_path_to_yaml_fname(spec_fixture.path)
    with open(EXAMPLES / "params" / yaml_fname) as f:
        assert yaml.load(yaml_str) == yaml.load(f)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant