Skip to content

Unit tests for osism/data/playbooks.py #2196

@berendt

Description

@berendt

Background

Follow-up to #2192 (foundation) and PR #2193 (pytest + Zuul infrastructure). osism/data/playbooks.py lazily loads YAML files from /interface/playbooks/ on first attribute access. The module-level __getattr__ is a subtle pattern and warrants regression tests so the lazy-loading and caching behavior stays intact.

Scope

Add tests/unit/data/test_playbooks.py covering the lazy loader and __getattr__ hook in osism/data/playbooks.py.

Test targets

_load_playbook_data()osism/data/playbooks.py:12

Reads every *.yml in /interface/playbooks/ and builds:

  • _MAP_ROLE2ENVIRONMENT: merged dict of all YAML contents
  • _MAP_ROLE2RUNTIME: maps each YAML filename stem to that file's top-level keys

Required cases:

  • Multiple YAML files merged correctly into _MAP_ROLE2ENVIRONMENT
  • _MAP_ROLE2RUNTIME[<stem>] contains exactly the top-level keys of that file
  • A YAML file with a yaml.YAMLError is skipped and does not crash the loader (verify logger.warning was called)
  • Early-return on re-entry: if _MAP_ROLE2ENVIRONMENT is already populated, the function does nothing (no re-read of the directory)

Use monkeypatch to redirect Path(\"/interface/playbooks\") to a tmp_path that the test controls. The module-level _MAP_ROLE2ENVIRONMENT and _MAP_ROLE2RUNTIME globals must be reset between tests — provide an autouse fixture that sets them back to None before each test.

__getattr__(name)osism/data/playbooks.py:34

  • osism.data.playbooks.MAP_ROLE2ENVIRONMENT triggers loading and returns the merged dict
  • osism.data.playbooks.MAP_ROLE2RUNTIME triggers loading and returns the filename-stem map
  • After first access, globals()[name] is set (verify no second load happens — spy on _load_playbook_data)
  • Accessing any other attribute raises AttributeError with the standard message

Mocking hints

  • Do not create /interface/playbooks on the developer machine. Use monkeypatch.setattr(\"osism.data.playbooks.Path\", ...) or patch the glob iterator directly.
  • Reset module-level caches (_MAP_ROLE2ENVIRONMENT, _MAP_ROLE2RUNTIME, and anything set in globals() by __getattr__) in an autouse fixture to avoid test-order dependencies.

Definition of Done

  • tests/unit/data/test_playbooks.py created
  • Lazy loading, caching, error swallowing, and __getattr__ paths all covered
  • pipenv run pytest tests/unit/data/test_playbooks.py passes locally
  • Tests are order-independent (pipenv run pytest -p no:randomly and pipenv run pytest --randomly-seed=... both pass — if pytest-randomly is added later)
  • flake8, mypy, python-black remain green
  • Zuul job python-osism-unit-tests passes

Dependencies

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions