Skip to content
Closed
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
57 changes: 48 additions & 9 deletions tests/_data/snapshots/README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,52 @@
# TEST FIXTURES
# Test Fixtures & Snapshot Workflow

## RE-CREATION
This directory contains serialized test snapshots (in JSON and XML formats) used to verify serialization and deserialization across supported CycloneDX schema versions.

Some assets here can be (re-)created automatically, by setting the env var `CDX_TEST_RECREATE_SNAPSHOTS=1`.
It might also help to set `PYTHONHASHSEED=0`!
As a shortcut just run:
## How Model Fixtures Are Discovered

```shell
CDX_TEST_RECREATE_SNAPSHOTS=1 poetry run tox -e py
```
Model factories are declared in [`tests/_data/models.py`](../models.py) and discovered dynamically at test runtime:

The files will be written as is, which might not be human-readable. feel free to reformat the files manually.
1. **Factory Discovery**:
- Any function named `get_bom_*()` is automatically discovered via `inspect.getmembers(sys.modules[__name__], isfunction)`.
- Valid factories are categorized into `all_get_bom_funct_valid`, `all_get_bom_funct_valid_immut`, and `all_get_bom_funct_valid_reversible_migrate`.
- Factories suffixed with `_invalid` are collected into `all_get_bom_funct_invalid`. These represent intentionally malformed or non-compliant models tested against error-handling and schema validation failure paths.

2. **Schema Version Constraints**:
- If a factory function name contains a version tag (e.g. `get_bom_v1_5_*`), `is_valid_for_schema_version()` checks it against `_LIMIT_GET_BOM_BY_VERSION_REGEX` (`^get_bom_(?P<sv>v(?P<major_version>1)_(?P<minor_version>[0-6]))?(.*)$`).
- Such factories are only executed against schema versions equal to or greater than the specified version.

3. **Snapshot Naming**:
- Snapshot filenames are generated by `mksname(purpose, sv, f)` in [`tests/__init__.py`](../../__init__.py):
```text
<function_name>-<schema_version>.<ext>[.bin]
```
For example: `get_bom_with_licenses-1.5.json.bin` or `get_bom_with_services_simple-1.4.xml.bin`.

4. **Incomplete Dependency Graphs**:
- Functions in `all_get_bom_funct_with_incomplete_deps` return BOMs where dependency graphs are deliberately incomplete.
- These test that serialization properly repairs or normalizes hanging references before outputting.

---

## Re-creation Workflow

When adding a new model factory or intentionally updating serialization output, snapshots must be regenerated:

1. **Regenerate Snapshots**:
Set `CDX_TEST_RECREATE_SNAPSHOTS=1` and `PYTHONHASHSEED=0` to ensure deterministic output:
```shell
CDX_TEST_RECREATE_SNAPSHOTS=1 PYTHONHASHSEED=0 poetry run tox -e py
```
Or target specific test files:
```shell
CDX_TEST_RECREATE_SNAPSHOTS=1 PYTHONHASHSEED=0 poetry run pytest tests/test_output_json.py tests/test_output_xml.py
```

2. **Review Diff**:
Inspect `git diff tests/_data/snapshots/` to confirm that **only** the intended snapshots were created or modified. Discard accidental changes with `git checkout tests/_data/snapshots/<unintended-file>`.

3. **Verify with Snapshot Re-creation Disabled**:
Always rerun tests without `CDX_TEST_RECREATE_SNAPSHOTS` to verify that serialization matches the recorded snapshots and that deserialization tests (`test_deserialize_json.py`, `test_deserialize_xml.py`) pass cleanly:
```shell
poetry run tox -e py
```