sdr-visualizer 1.2.4__tar.gz → 1.2.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/CHANGELOG.md +33 -2
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/PKG-INFO +5 -4
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/README.md +4 -3
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/docs/ADAPTER_GUIDE.md +30 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/docs/PERFORMANCE.md +32 -7
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/docs/PRODUCT_CONTRACT.md +2 -2
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/pyproject.toml +1 -1
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/scripts/perf_browser_check.py +2 -2
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/scripts/perf_check.py +49 -32
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/__init__.py +1 -1
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/adapters/aa.py +6 -5
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/adapters/cja.py +6 -5
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/analysis/lineage_layout.py +1 -1
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/cli/lineage_output.py +1 -1
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/render/lineage_payload.py +1 -1
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/usage/collector.py +8 -1
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/usage/sdk_worker.py +7 -1
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_adapters_aa.py +2 -2
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_adapters_cja.py +3 -3
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_cli.py +4 -4
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_perf.py +65 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_perf_browser_check.py +16 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_release_documentation.py +9 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_workspace_usage_collection.py +34 -7
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_workspace_usage_sdk.py +72 -8
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/.gitignore +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/AGENTS.md +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/CODE_OF_CONDUCT.md +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/CONTRIBUTING.md +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/LICENSE +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/SECURITY.md +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/THIRD_PARTY_LICENSES +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/docs/ADAPTER_CORRECTNESS_1.1.2.md +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/docs/ARCHITECTURE.md +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/docs/DEPENDABOT_AUTOMATION.md +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/docs/EMBEDDED_DATA_FORMAT.md +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/docs/LINEAGE.md +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/docs/RELEASE_EVIDENCE_TEMPLATE.md +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/docs/RELEASING.md +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/docs/SHOWCASE.md +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/docs/WORKSPACE_USAGE.md +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/docs/payload-schema.json +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/docs/workspace-usage-schema.json +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/scripts/capture_screenshot.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/scripts/check_color_pack_parity.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/scripts/check_markdown_links.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/scripts/check_workflow_policy.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/scripts/corpus_check.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/scripts/dependabot_review.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/scripts/generate_aa_large_fixture.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/scripts/generate_cja_lineage_poc.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/scripts/generate_examples.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/scripts/generate_large_fixture.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/scripts/mutate_fixture.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/scripts/package_smoke_check.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/scripts/perf_lineage_poc.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/scripts/workspace_usage_fixture.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/__main__.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/adapters/__init__.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/adapters/base.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/adapters/cja_lineage.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/analysis/__init__.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/analysis/diff.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/analysis/formula_tree.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/analysis/references.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/analysis/segment_tree.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/analysis/trend.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/cli/__init__.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/cli/exit_codes.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/cli/lineage.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/cli/main.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/cli/output_safety.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/cli/workspace_usage.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/core/__init__.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/core/exceptions.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/core/lineage.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/core/models.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/core/structure_limits.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/core/visualizer.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/core/workspace_usage.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/input/__init__.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/input/detect.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/input/lineage_discovery.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/input/loader.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/input/series.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/input/shell_out.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/input/workspace_usage.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/render/__init__.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/render/color_packs.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/render/data_payload.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/render/lineage_renderer.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/render/renderer.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/render/static/cja_lineage.css +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/render/static/cja_lineage.js +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/render/static/cja_lineage_graph.js +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/render/static/cja_lineage_roles.js +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/render/static/d3.min.js +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/render/static/visualizer.css +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/render/static/visualizer.js +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/render/static/visualizer_trend.js +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/render/templates/catalog.html.j2 +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/render/templates/changes.html.j2 +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/render/templates/cja_lineage.html.j2 +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/render/templates/graph.html.j2 +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/render/templates/index.html.j2 +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/render/templates/trend.html.j2 +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/render/trend_charts.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/render/workspace_usage.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/usage/__init__.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/usage/aa_api.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/usage/aa_sdk.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/usage/auth.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/usage/cja_api.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/usage/cja_sdk.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/usage/normalize.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/src/sdr_visualizer/usage/transport.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/__init__.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/adapter_cases.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/browser_support.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/conftest.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/fixtures/__init__.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/fixtures/aa_snapshot_clean.json +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/fixtures/aa_snapshot_messy.json +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/fixtures/cja_lineage_degraded.json +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/fixtures/cja_lineage_enriched.json +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/fixtures/cja_lineage_hostile.json +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/fixtures/cja_lineage_shared.json +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/fixtures/cja_snapshot_clean.json +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/fixtures/cja_snapshot_hostile.json +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/fixtures/cja_snapshot_messy.json +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/fixtures/cja_snapshot_minimal.json +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/fixtures/workspace_usage_aa_all_types.json +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/fixtures/workspace_usage_cja_all_types.json +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_adapter_correctness.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_adapter_fuzz.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_analysis_diff.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_analysis_formula_tree.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_analysis_references.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_analysis_segment_tree.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_analysis_trend.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_browser_functional.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_browser_support.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_cja_lineage.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_cja_lineage_driver.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_cli_flags.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_color_pack_parity.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_color_packs.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_corpus_check.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_data_payload.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_dependabot_review.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_entrypoint.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_generate_examples.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_input_modes.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_input_series.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_lineage_browser.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_lineage_cli.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_lineage_discovery.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_lineage_performance.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_lineage_renderer.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_markdown_links.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_minimal_fixture.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_mutate_fixture.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_output_safety.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_package_smoke_check.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_payload_schema.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_renderer.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_renderer_anatomy.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_renderer_graph.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_semantic_properties.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_structure_limits.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_trend_charts.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_workflow_policy.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_workspace_usage.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_workspace_usage_aa_sdk.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_workspace_usage_auth.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_workspace_usage_cja_sdk.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_workspace_usage_cli.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_workspace_usage_offline.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_workspace_usage_payload.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_workspace_usage_perf.py +0 -0
- {sdr_visualizer-1.2.4 → sdr_visualizer-1.2.6}/tests/test_workspace_usage_transport.py +0 -0
|
@@ -4,6 +4,32 @@ All notable changes to `sdr-visualizer` will be documented here. The format foll
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [1.2.6] - 2026-10-27
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- Advance the catalog tested-through generator markers to `cja_auto_sdr`
|
|
12
|
+
3.13.2 and `aa_auto_sdr` 1.24.1. Snapshots that declare those versions no
|
|
13
|
+
longer print a newer-than-tested warning. Later versions are still accepted
|
|
14
|
+
with a compatibility warning. The separate lineage allowlist is unchanged.
|
|
15
|
+
|
|
16
|
+
## [1.2.5] - 2026-10-17
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- Kill a Workspace worker directly when it rejects process-group cleanup and
|
|
21
|
+
stays running, then report the original cleanup error, so collection no
|
|
22
|
+
longer waits on a worker that ignored the group signal.
|
|
23
|
+
- Fail the Python performance gate when any published tier fixture is missing,
|
|
24
|
+
warn when a report reaches 90% of its size budget, and treat a Workspace
|
|
25
|
+
interaction of exactly 100 ms as over budget, matching the published limit.
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
|
|
29
|
+
- Document CJA catalog generator-version provenance, correct adapter
|
|
30
|
+
tested-through marker guidance, and remove obsolete lineage POC/private
|
|
31
|
+
module descriptions.
|
|
32
|
+
|
|
7
33
|
## [1.2.4] - 2026-10-17
|
|
8
34
|
|
|
9
35
|
### Changed
|
|
@@ -12,6 +38,8 @@ All notable changes to `sdr-visualizer` will be documented here. The format foll
|
|
|
12
38
|
3.12.12 and `aa_auto_sdr` 1.21.24. Snapshots declaring those versions no
|
|
13
39
|
longer raise a newer-than-tested warning; later versions remain accepted
|
|
14
40
|
with a compatibility warning. The separate lineage allowlist is unchanged.
|
|
41
|
+
- Clarify release retention-setting versus artifact-expiry checks and the
|
|
42
|
+
marker-only sibling review disposition.
|
|
15
43
|
|
|
16
44
|
### Fixed
|
|
17
45
|
|
|
@@ -34,7 +62,6 @@ All notable changes to `sdr-visualizer` will be documented here. The format foll
|
|
|
34
62
|
- Make live AA Workspace collection and manual assistive-technology testing
|
|
35
63
|
optional release evidence, retain automated accessibility and keyboard checks,
|
|
36
64
|
and scope release license signoff to project and vendored D3 notices.
|
|
37
|
-
|
|
38
65
|
- Update the optional AA Workspace SDK to `aanalytics2==0.5.5.post2` and align
|
|
39
66
|
its collection version guard with the package pin.
|
|
40
67
|
- Automatically review and merge verified, lockfile-only patch updates to
|
|
@@ -42,6 +69,8 @@ All notable changes to `sdr-visualizer` will be documented here. The format foll
|
|
|
42
69
|
dependency changes on the manual-review path.
|
|
43
70
|
- Replace the README catalog screenshot with a feature slideshow covering search,
|
|
44
71
|
references, anatomy, comparisons, trends, and offline reports across AA and CJA.
|
|
72
|
+
- Add canonical `AGENTS.md` contributor guidance and ship it in the source
|
|
73
|
+
distribution.
|
|
45
74
|
|
|
46
75
|
## [1.2.2] - 2026-09-21
|
|
47
76
|
|
|
@@ -752,7 +781,9 @@ The following are explicitly internal and may change without notice:
|
|
|
752
781
|
- Workspace project visualization (v0.4)
|
|
753
782
|
- Schema map view (v0.5)
|
|
754
783
|
|
|
755
|
-
[Unreleased]: https://github.com/brian-a-au/sdr-visualizer/compare/v1.2.
|
|
784
|
+
[Unreleased]: https://github.com/brian-a-au/sdr-visualizer/compare/v1.2.6...HEAD
|
|
785
|
+
[1.2.6]: https://github.com/brian-a-au/sdr-visualizer/releases/tag/v1.2.6
|
|
786
|
+
[1.2.5]: https://github.com/brian-a-au/sdr-visualizer/releases/tag/v1.2.5
|
|
756
787
|
[1.2.4]: https://github.com/brian-a-au/sdr-visualizer/releases/tag/v1.2.4
|
|
757
788
|
[1.2.3]: https://github.com/brian-a-au/sdr-visualizer/releases/tag/v1.2.3
|
|
758
789
|
[1.2.2]: https://github.com/brian-a-au/sdr-visualizer/releases/tag/v1.2.2
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: sdr-visualizer
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.6
|
|
4
4
|
Summary: Static-output visual catalog generator for Adobe Customer Journey Analytics and Adobe Analytics implementations.
|
|
5
5
|
Project-URL: Homepage, https://brian-a-au.github.io/sdr-visualizer/
|
|
6
6
|
Project-URL: Documentation, https://github.com/brian-a-au/sdr-visualizer#documentation
|
|
@@ -280,8 +280,9 @@ the trend is the newest usable snapshot in the directory.
|
|
|
280
280
|
The output is CI-gated against the budgets in
|
|
281
281
|
[`docs/PERFORMANCE.md`](https://github.com/brian-a-au/sdr-visualizer/blob/main/docs/PERFORMANCE.md).
|
|
282
282
|
Build time and HTML size are enforced at every published tier (100 / 500 / 1,000 / 2,000
|
|
283
|
-
components). Browser-measured budgets
|
|
284
|
-
|
|
283
|
+
components). Browser-measured budgets for initial render and filter/search are
|
|
284
|
+
enforced at all four tiers, from 100 components (< 200ms, < 50ms) and 500
|
|
285
|
+
components (< 500ms, < 100ms) up to 1,000 (< 1s, < 150ms) and 2,000
|
|
285
286
|
(< 2s, < 300ms), plus a 700ms cap on the graph view's main-thread block.
|
|
286
287
|
These guarantees cover up to 8,000 reference edges. Denser valid reports use an
|
|
287
288
|
explicit graph opt-in and sit outside the published size and latency limits.
|
|
@@ -334,7 +335,7 @@ arguments and exit codes are described in the
|
|
|
334
335
|
Its embedded payload and Python modules are internal and do not extend the
|
|
335
336
|
catalog schema or JSON sidecar contract.
|
|
336
337
|
|
|
337
|
-
**Performance budgets.** The tier table
|
|
338
|
+
**Performance budgets.** The tier table in [`docs/PERFORMANCE.md`](https://github.com/brian-a-au/sdr-visualizer/blob/main/docs/PERFORMANCE.md) is a guarantee, not a goal: loosening a budget is a breaking change; tightening one is minor.
|
|
338
339
|
|
|
339
340
|
Warnings (snapshot generator newer than the tested version; 5,000+ component reports) are informational and never make a valid snapshot fail.
|
|
340
341
|
|
|
@@ -257,8 +257,9 @@ the trend is the newest usable snapshot in the directory.
|
|
|
257
257
|
The output is CI-gated against the budgets in
|
|
258
258
|
[`docs/PERFORMANCE.md`](https://github.com/brian-a-au/sdr-visualizer/blob/main/docs/PERFORMANCE.md).
|
|
259
259
|
Build time and HTML size are enforced at every published tier (100 / 500 / 1,000 / 2,000
|
|
260
|
-
components). Browser-measured budgets
|
|
261
|
-
|
|
260
|
+
components). Browser-measured budgets for initial render and filter/search are
|
|
261
|
+
enforced at all four tiers, from 100 components (< 200ms, < 50ms) and 500
|
|
262
|
+
components (< 500ms, < 100ms) up to 1,000 (< 1s, < 150ms) and 2,000
|
|
262
263
|
(< 2s, < 300ms), plus a 700ms cap on the graph view's main-thread block.
|
|
263
264
|
These guarantees cover up to 8,000 reference edges. Denser valid reports use an
|
|
264
265
|
explicit graph opt-in and sit outside the published size and latency limits.
|
|
@@ -311,7 +312,7 @@ arguments and exit codes are described in the
|
|
|
311
312
|
Its embedded payload and Python modules are internal and do not extend the
|
|
312
313
|
catalog schema or JSON sidecar contract.
|
|
313
314
|
|
|
314
|
-
**Performance budgets.** The tier table
|
|
315
|
+
**Performance budgets.** The tier table in [`docs/PERFORMANCE.md`](https://github.com/brian-a-au/sdr-visualizer/blob/main/docs/PERFORMANCE.md) is a guarantee, not a goal: loosening a budget is a breaking change; tightening one is minor.
|
|
315
316
|
|
|
316
317
|
Warnings (snapshot generator newer than the tested version; 5,000+ component reports) are informational and never make a valid snapshot fail.
|
|
317
318
|
|
|
@@ -37,6 +37,36 @@ Reads the JSON output of [`cja_auto_sdr`](https://github.com/brian-a-au/cja_auto
|
|
|
37
37
|
- Calc metrics ship `metric_references` and `segment_references` arrays; the adapter merges these and de-dupes.
|
|
38
38
|
- Derived fields appear only in CJA — there's no AA equivalent.
|
|
39
39
|
|
|
40
|
+
### CJA generator version provenance
|
|
41
|
+
|
|
42
|
+
The adapter reads `metadata["Tool Version"]` or `metadata["tool_version"]`
|
|
43
|
+
when declared; otherwise `adapter_version` is `unknown` and no
|
|
44
|
+
newer-than-tested warning is possible. The example above illustrates accepted
|
|
45
|
+
version metadata, not a field guaranteed by the exporter.
|
|
46
|
+
|
|
47
|
+
Public source inspection at `cja_auto_sdr` **v3.12.12**, commit
|
|
48
|
+
`73c3f60e531358d339828abbbb94bbb0afb69b0b`, confirms that its
|
|
49
|
+
[catalog metadata builder](https://github.com/brian-a-au/cja_auto_sdr/blob/73c3f60e531358d339828abbbb94bbb0afb69b0b/src/cja_auto_sdr/generator.py#L1160-L1308)
|
|
50
|
+
omits the generator version. The
|
|
51
|
+
[JSON payload builder](https://github.com/brian-a-au/cja_auto_sdr/blob/73c3f60e531358d339828abbbb94bbb0afb69b0b/src/cja_auto_sdr/output/sdr/__init__.py#L507-L575)
|
|
52
|
+
passes that metadata through without adding a version. There is no additional
|
|
53
|
+
catalog field for the adapter to read in this version.
|
|
54
|
+
|
|
55
|
+
The separate
|
|
56
|
+
[run summary](https://github.com/brian-a-au/cja_auto_sdr/blob/73c3f60e531358d339828abbbb94bbb0afb69b0b/src/cja_auto_sdr/generator.py#L2516-L2530)
|
|
57
|
+
and
|
|
58
|
+
[diff snapshot format](https://github.com/brian-a-au/cja_auto_sdr/blob/73c3f60e531358d339828abbbb94bbb0afb69b0b/src/cja_auto_sdr/diff/models.py#L300-L375)
|
|
59
|
+
record `tool_version`, but those are different artifacts. The catalog adapter
|
|
60
|
+
does not join external provenance or infer a version from the locally installed
|
|
61
|
+
exporter, timestamps, or inventory schema versions. Existing undeclared catalog
|
|
62
|
+
snapshots remain `unknown`; exporter-side version metadata would be needed to
|
|
63
|
+
make their generator version available at export time.
|
|
64
|
+
|
|
65
|
+
The tested-through marker comes from recorded validation with an exact upstream
|
|
66
|
+
version and the historical compatibility corpus, as required by the
|
|
67
|
+
[compatibility policy](PRODUCT_CONTRACT.md#compatibility-policy). Taking the
|
|
68
|
+
highest version string found in fixtures or old snapshots is insufficient.
|
|
69
|
+
|
|
40
70
|
### CJA component mappings
|
|
41
71
|
|
|
42
72
|
| CJA input | Normalized collection | Embedded type |
|
|
@@ -191,19 +191,44 @@ uv run python scripts/perf_browser_check.py
|
|
|
191
191
|
|
|
192
192
|
CI runs `perf_check.py` after `pytest` in the test job. The browser gate runs in
|
|
193
193
|
the separate `browser-perf` job after browser functional tests. A regression
|
|
194
|
-
that exceeds any budget fails the build.
|
|
194
|
+
that exceeds any budget fails the build. `perf_check.py` fails when any tier
|
|
195
|
+
fixture is missing and prints a non-failing warning when an HTML size reaches
|
|
196
|
+
90% of its budget.
|
|
195
197
|
|
|
196
198
|
## What we measure
|
|
197
199
|
|
|
198
200
|
One representative Python-side run looks like this:
|
|
199
201
|
|
|
200
202
|
```text
|
|
201
|
-
[CJA] build time: 0.01s (budget
|
|
202
|
-
[CJA] HTML size : 0.
|
|
203
|
-
[
|
|
204
|
-
[
|
|
205
|
-
[CJA
|
|
206
|
-
[CJA
|
|
203
|
+
[CJA-100] build time: 0.01s (budget 1.0s, median of 3)
|
|
204
|
+
[CJA-100] HTML size : 0.43MB (budget 0.5MB)
|
|
205
|
+
[CJA-500] build time: 0.02s (budget 3.0s, median of 3)
|
|
206
|
+
[CJA-500] HTML size : 0.57MB (budget 2MB)
|
|
207
|
+
[CJA] build time: 0.06s (budget 6.0s, median of 3)
|
|
208
|
+
[CJA] HTML size : 0.81MB (budget 4MB)
|
|
209
|
+
[AA] build time: 0.04s (budget 6.0s, median of 3)
|
|
210
|
+
[AA] HTML size : 0.70MB (budget 4MB)
|
|
211
|
+
[CJA-dense] build time: 0.09s (budget 6.0s, median of 3)
|
|
212
|
+
[CJA-dense] HTML size : 1.42MB (budget 4MB)
|
|
213
|
+
[CJA-compare] build time: 0.07s (budget 9.0s, median of 3)
|
|
214
|
+
[CJA-compare] HTML size : 0.82MB (budget 4.5MB)
|
|
215
|
+
[CJA-trend] build time: 0.19s (budget 6.0s, median of 3, 6 snapshots)
|
|
216
|
+
[CJA-trend] HTML size : 0.82MB (budget 4.5MB)
|
|
217
|
+
[CJA-XL] build time: 0.08s (budget 12.0s, median of 3)
|
|
218
|
+
[CJA-XL] HTML size : 1.09MB (budget 8MB)
|
|
219
|
+
[cja_snapshot_small-usage] build time: 0.02s (budget 1.0s, median of 3)
|
|
220
|
+
[cja_snapshot_small-usage] HTML size : 0.48MB (budget 0.5MB)
|
|
221
|
+
warning: [cja_snapshot_small-usage] HTML size at 95% of budget
|
|
222
|
+
[cja_snapshot_medium-usage] build time: 0.24s (budget 3.0s, median of 3)
|
|
223
|
+
[cja_snapshot_medium-usage] HTML size : 1.18MB (budget 2MB)
|
|
224
|
+
[cja_snapshot_large-usage] build time: 0.30s (budget 6.0s, median of 3)
|
|
225
|
+
[cja_snapshot_large-usage] HTML size : 1.58MB (budget 4MB)
|
|
226
|
+
[aa_snapshot_large-usage] build time: 0.29s (budget 6.0s, median of 3)
|
|
227
|
+
[aa_snapshot_large-usage] HTML size : 1.40MB (budget 4MB)
|
|
228
|
+
[cja_snapshot_xl-usage] build time: 0.36s (budget 12.0s, median of 3)
|
|
229
|
+
[cja_snapshot_xl-usage] HTML size : 2.06MB (budget 8MB)
|
|
230
|
+
[CJA-usage-repeated] build time: 0.35s (budget 6.0s, median of 3)
|
|
231
|
+
[CJA-usage-repeated] HTML size : 1.78MB (budget 4MB)
|
|
207
232
|
OK: all budgets met
|
|
208
233
|
```
|
|
209
234
|
|
|
@@ -207,8 +207,8 @@ unusable, and capped-out members do not warn. The current markers are:
|
|
|
207
207
|
|
|
208
208
|
| Platform | Warning threshold |
|
|
209
209
|
|---|---:|
|
|
210
|
-
| CJA (`cja_auto_sdr`) | 3.
|
|
211
|
-
| AA (`aa_auto_sdr`) | 1.
|
|
210
|
+
| CJA (`cja_auto_sdr`) | 3.13.2 |
|
|
211
|
+
| AA (`aa_auto_sdr`) | 1.24.1 |
|
|
212
212
|
|
|
213
213
|
A marker is evidence of exercised compatibility, not a promise about every
|
|
214
214
|
possible snapshot produced by that version. It may advance only after a
|
|
@@ -313,8 +313,8 @@ def _workspace_failures(label: str, measured: dict, project_count: int) -> list[
|
|
|
313
313
|
):
|
|
314
314
|
failures.append(f"[{label}] page replacement did not advance the project range")
|
|
315
315
|
for field, action in (("openMs", "first open"), ("pageMs", "page replacement")):
|
|
316
|
-
if measured[field]
|
|
317
|
-
failures.append(f"[{label}] Workspace {action} {measured[field]:.1f}ms
|
|
316
|
+
if measured[field] >= WORKSPACE_INTERACTION_BUDGET_MS:
|
|
317
|
+
failures.append(f"[{label}] Workspace {action} {measured[field]:.1f}ms >= 100ms")
|
|
318
318
|
return failures
|
|
319
319
|
|
|
320
320
|
|
|
@@ -4,14 +4,14 @@ Renders fixtures and asserts the build-time + HTML-size budgets across all
|
|
|
4
4
|
four documented tiers. CI runs this after pytest (see .github/workflows/test.yml).
|
|
5
5
|
|
|
6
6
|
- CJA small (100 components, `generate_large_fixture.py --scale 0.083`):
|
|
7
|
-
100-component budgets (build < 1s, size < 0.5MB).
|
|
7
|
+
100-component budgets (build < 1s, size < 0.5MB). Required.
|
|
8
8
|
- CJA medium (~500 components, `--scale 0.417`): 500-component budgets
|
|
9
|
-
(build < 3s, size < 2MB).
|
|
9
|
+
(build < 3s, size < 2MB). Required.
|
|
10
10
|
- CJA / AA large (~1,200 / ~900 components): 1,000-component budgets
|
|
11
11
|
(build < 6s, size < 4MB)
|
|
12
12
|
- CJA XL (~2,000 components, generated on demand via
|
|
13
13
|
`generate_large_fixture.py --scale 1.67 --output tests/fixtures/cja_snapshot_xl.json`):
|
|
14
|
-
2,000-component budgets (build < 12s, size < 8MB).
|
|
14
|
+
2,000-component budgets (build < 12s, size < 8MB). Required.
|
|
15
15
|
|
|
16
16
|
Build time is the median of 3 runs per fixture.
|
|
17
17
|
|
|
@@ -71,6 +71,25 @@ TREND_SERIES_LEN = 6
|
|
|
71
71
|
TREND_BUILD_BUDGET_S = TREND_SERIES_LEN * 1.0
|
|
72
72
|
TREND_SIZE_BUDGET_BYTES = SIZE_BUDGET_BYTES + 500_000
|
|
73
73
|
|
|
74
|
+
# Non-failing early warning for deterministic HTML size growth.
|
|
75
|
+
HEADROOM_WARNING_RATIO = 0.9
|
|
76
|
+
|
|
77
|
+
GENERATE = "uv run python scripts/generate_large_fixture.py"
|
|
78
|
+
REQUIRED_FIXTURES = [
|
|
79
|
+
("CJA_SMALL", f"{GENERATE} --scale 0.083 --output tests/fixtures/cja_snapshot_small.json"),
|
|
80
|
+
("CJA_MEDIUM", f"{GENERATE} --scale 0.417 --output tests/fixtures/cja_snapshot_medium.json"),
|
|
81
|
+
("CJA_LARGE", GENERATE),
|
|
82
|
+
("AA_LARGE", "uv run python scripts/generate_aa_large_fixture.py"),
|
|
83
|
+
("CJA_XL", f"{GENERATE} --scale 1.67 --output tests/fixtures/cja_snapshot_xl.json"),
|
|
84
|
+
]
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def _headroom_note(label: str, size_bytes: int, budget_bytes: int) -> str | None:
|
|
88
|
+
if HEADROOM_WARNING_RATIO * budget_bytes <= size_bytes < budget_bytes:
|
|
89
|
+
pct = size_bytes * 100 // budget_bytes
|
|
90
|
+
return f"warning: [{label}] HTML size at {pct}% of budget"
|
|
91
|
+
return None
|
|
92
|
+
|
|
74
93
|
|
|
75
94
|
def _load_usage_fixture():
|
|
76
95
|
spec = importlib.util.spec_from_file_location(
|
|
@@ -118,6 +137,8 @@ def _measure_compare(old_snap: dict, new_snap: dict) -> tuple[list[str], str]:
|
|
|
118
137
|
f"[CJA-compare] build time: {elapsed:.2f}s (budget {COMPARE_BUILD_BUDGET_S}s, median of 3)",
|
|
119
138
|
f"[CJA-compare] HTML size : {size_mb:.2f}MB (budget {COMPARE_SIZE_BUDGET_BYTES / 1_000_000:g}MB)",
|
|
120
139
|
]
|
|
140
|
+
if note := _headroom_note("CJA-compare", size_bytes, COMPARE_SIZE_BUDGET_BYTES):
|
|
141
|
+
msgs.append(note)
|
|
121
142
|
failures = []
|
|
122
143
|
if elapsed >= COMPARE_BUILD_BUDGET_S:
|
|
123
144
|
failures.append(
|
|
@@ -152,6 +173,8 @@ def _measure_trend(base_snap: dict, mutate) -> tuple[list[str], str]:
|
|
|
152
173
|
f"median of 3, {TREND_SERIES_LEN} snapshots)",
|
|
153
174
|
f"[CJA-trend] HTML size : {size_mb:.2f}MB (budget {TREND_SIZE_BUDGET_BYTES / 1_000_000:g}MB)",
|
|
154
175
|
]
|
|
176
|
+
if note := _headroom_note("CJA-trend", size_bytes, TREND_SIZE_BUDGET_BYTES):
|
|
177
|
+
msgs.append(note)
|
|
155
178
|
failures = []
|
|
156
179
|
if elapsed >= TREND_BUILD_BUDGET_S:
|
|
157
180
|
failures.append(f"CJA-trend build time {elapsed:.2f}s over budget {TREND_BUILD_BUDGET_S}s")
|
|
@@ -187,6 +210,8 @@ def _measure(
|
|
|
187
210
|
f"[{label}] build time: {elapsed:.2f}s (budget {build_budget_s}s, median of 3)",
|
|
188
211
|
f"[{label}] HTML size : {size_mb:.2f}MB (budget {size_budget_bytes / 1_000_000:g}MB)",
|
|
189
212
|
]
|
|
213
|
+
if note := _headroom_note(label, size_bytes, size_budget_bytes):
|
|
214
|
+
msgs.append(note)
|
|
190
215
|
failures = []
|
|
191
216
|
if elapsed >= build_budget_s:
|
|
192
217
|
failures.append(f"[{label}] build time {elapsed:.2f}s >= {build_budget_s}s budget")
|
|
@@ -198,17 +223,18 @@ def _measure(
|
|
|
198
223
|
|
|
199
224
|
|
|
200
225
|
def main() -> int:
|
|
201
|
-
|
|
202
|
-
(
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
226
|
+
missing = [
|
|
227
|
+
(globals()[name], command)
|
|
228
|
+
for name, command in REQUIRED_FIXTURES
|
|
229
|
+
if not globals()[name].exists()
|
|
230
|
+
]
|
|
231
|
+
for fixture, command in missing:
|
|
232
|
+
print(
|
|
233
|
+
f"sdr-visualizer: fixture {fixture} missing; run `{command}` first.",
|
|
234
|
+
file=sys.stderr,
|
|
235
|
+
)
|
|
236
|
+
if missing:
|
|
237
|
+
return 2
|
|
212
238
|
|
|
213
239
|
cja_snap = json.loads(CJA_LARGE.read_text(encoding="utf-8"))
|
|
214
240
|
aa_snap = json.loads(AA_LARGE.read_text(encoding="utf-8"))
|
|
@@ -218,13 +244,10 @@ def main() -> int:
|
|
|
218
244
|
(CJA_SMALL, "CJA-100", SMALL_BUILD_BUDGET_S, SMALL_SIZE_BUDGET_BYTES),
|
|
219
245
|
(CJA_MEDIUM, "CJA-500", MEDIUM_BUILD_BUDGET_S, MEDIUM_SIZE_BUDGET_BYTES),
|
|
220
246
|
]:
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
print(tier_report)
|
|
226
|
-
else:
|
|
227
|
-
print(f"note: {path.name} not generated; skipping {label} gate")
|
|
247
|
+
snap = json.loads(path.read_text(encoding="utf-8"))
|
|
248
|
+
tier_failures, tier_report = _measure(label, snap, cja_adapt, build_b, size_b)
|
|
249
|
+
small_failures += tier_failures
|
|
250
|
+
print(tier_report)
|
|
228
251
|
|
|
229
252
|
cja_failures, cja_report = _measure("CJA", cja_snap, cja_adapt)
|
|
230
253
|
print(cja_report)
|
|
@@ -245,15 +268,11 @@ def main() -> int:
|
|
|
245
268
|
trend_failures, trend_report = _measure_trend(cja_snap, mutate)
|
|
246
269
|
print(trend_report)
|
|
247
270
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
xl_snap
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
)
|
|
254
|
-
print(xl_report)
|
|
255
|
-
else:
|
|
256
|
-
print("note: cja_snapshot_xl.json not generated; skipping 2,000-component gate")
|
|
271
|
+
xl_snap = json.loads(CJA_XL.read_text(encoding="utf-8"))
|
|
272
|
+
xl_failures, xl_report = _measure(
|
|
273
|
+
"CJA-XL", xl_snap, cja_adapt, XL_BUILD_BUDGET_S, XL_SIZE_BUDGET_BYTES
|
|
274
|
+
)
|
|
275
|
+
print(xl_report)
|
|
257
276
|
|
|
258
277
|
# Preserve every original gate, then repeat its tier with bounded evidence.
|
|
259
278
|
# Small approaches the HTML cap; XL approaches the normalized 1 MiB cap.
|
|
@@ -266,8 +285,6 @@ def main() -> int:
|
|
|
266
285
|
(AA_LARGE, aa_adapt, BUILD_BUDGET_S, SIZE_BUDGET_BYTES, 10_000),
|
|
267
286
|
(CJA_XL, cja_adapt, XL_BUILD_BUDGET_S, XL_SIZE_BUDGET_BYTES, 10_000),
|
|
268
287
|
]:
|
|
269
|
-
if not path.exists():
|
|
270
|
-
continue # Same optional fixtures as the original Python matrix.
|
|
271
288
|
snap = json.loads(path.read_text(encoding="utf-8"))
|
|
272
289
|
encoded = usage_fixture.usage_json(adapter(snap), project_count=projects, pad_input=True)
|
|
273
290
|
errors, report = _measure(
|
|
@@ -351,11 +351,12 @@ def _walk_segment_definition(definition: Any) -> tuple[int, list[str]]:
|
|
|
351
351
|
# ---------------------------------------------------------------------------
|
|
352
352
|
|
|
353
353
|
|
|
354
|
-
# The newest aa_auto_sdr version this release was validated against
|
|
355
|
-
#
|
|
356
|
-
#
|
|
357
|
-
#
|
|
358
|
-
|
|
354
|
+
# The newest aa_auto_sdr version this release was validated against.
|
|
355
|
+
# Advance from recorded release validation with that exact generator version
|
|
356
|
+
# and the historical compatibility corpus; snapshot declarations alone do not
|
|
357
|
+
# establish this marker. Undeclared versions stay unknown and do not warn.
|
|
358
|
+
# The compatibility policy warns about newer declared versions, never refuses.
|
|
359
|
+
TESTED_THROUGH_GENERATOR_VERSION = "1.24.1"
|
|
359
360
|
|
|
360
361
|
|
|
361
362
|
def generator_version_warning(adapter_version: str) -> str | None:
|
|
@@ -363,11 +363,12 @@ def _walk_for_contexts(node: Any, out: list[str]) -> None:
|
|
|
363
363
|
# ---------------------------------------------------------------------------
|
|
364
364
|
|
|
365
365
|
|
|
366
|
-
# The newest cja_auto_sdr version this release was validated against
|
|
367
|
-
#
|
|
368
|
-
#
|
|
369
|
-
#
|
|
370
|
-
|
|
366
|
+
# The newest cja_auto_sdr version this release was validated against.
|
|
367
|
+
# Advance from recorded release validation with that exact generator version
|
|
368
|
+
# and the historical compatibility corpus; snapshot declarations alone do not
|
|
369
|
+
# establish this marker. Undeclared versions stay unknown and do not warn.
|
|
370
|
+
# The compatibility policy warns about newer declared versions, never refuses.
|
|
371
|
+
TESTED_THROUGH_GENERATOR_VERSION = "3.13.2"
|
|
371
372
|
|
|
372
373
|
|
|
373
374
|
def generator_version_warning(adapter_version: str) -> str | None:
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import contextlib
|
|
5
6
|
import importlib.metadata
|
|
6
7
|
import os
|
|
7
8
|
import selectors
|
|
@@ -416,10 +417,16 @@ def _stop(process):
|
|
|
416
417
|
except PermissionError as error:
|
|
417
418
|
# On macOS an exiting process group can reject a signal before
|
|
418
419
|
# waitpid reports its leader's exit. Only accept cleanup once the
|
|
419
|
-
# child has actually exited, within the existing wait bound
|
|
420
|
+
# child has actually exited, within the existing wait bound;
|
|
421
|
+
# otherwise kill the leader directly so the Popen context can finish
|
|
422
|
+
# once it exits, then report the refused group signal.
|
|
420
423
|
try:
|
|
421
424
|
process.wait(timeout=2)
|
|
422
425
|
except subprocess.TimeoutExpired:
|
|
426
|
+
with contextlib.suppress(OSError):
|
|
427
|
+
process.kill()
|
|
428
|
+
with contextlib.suppress(subprocess.TimeoutExpired):
|
|
429
|
+
process.wait(timeout=2)
|
|
423
430
|
raise error from None
|
|
424
431
|
return
|
|
425
432
|
process.wait(timeout=2)
|
|
@@ -125,10 +125,16 @@ def _stop(process):
|
|
|
125
125
|
pass
|
|
126
126
|
except PermissionError as error:
|
|
127
127
|
# An exiting process group can reject a signal before its leader is
|
|
128
|
-
# reaped. Accept cleanup only after exit within the existing bound
|
|
128
|
+
# reaped. Accept cleanup only after exit within the existing bound;
|
|
129
|
+
# otherwise kill the leader directly so the Popen context can finish
|
|
130
|
+
# once it exits, then report the refused group signal.
|
|
129
131
|
try:
|
|
130
132
|
process.wait(timeout=2)
|
|
131
133
|
except subprocess.TimeoutExpired:
|
|
134
|
+
with contextlib.suppress(OSError):
|
|
135
|
+
process.kill()
|
|
136
|
+
with contextlib.suppress(subprocess.TimeoutExpired):
|
|
137
|
+
process.wait(timeout=2)
|
|
132
138
|
raise error from None
|
|
133
139
|
return
|
|
134
140
|
process.wait(timeout=2)
|
|
@@ -521,5 +521,5 @@ def test_equal_older_or_unparseable_versions_do_not_warn():
|
|
|
521
521
|
def test_tuple_length_mismatch_versions_compare_correctly():
|
|
522
522
|
from sdr_visualizer.adapters.aa import generator_version_warning
|
|
523
523
|
|
|
524
|
-
assert generator_version_warning("1.
|
|
525
|
-
assert generator_version_warning("1.
|
|
524
|
+
assert generator_version_warning("1.25") is not None
|
|
525
|
+
assert generator_version_warning("1.24") is None
|
|
@@ -858,12 +858,12 @@ def test_equal_older_or_unparseable_versions_do_not_warn():
|
|
|
858
858
|
|
|
859
859
|
|
|
860
860
|
def test_tuple_length_mismatch_versions_compare_correctly():
|
|
861
|
-
# (3,
|
|
861
|
+
# (3, 14) > (3, 13, 2), while the shorter (3, 13) sorts below the
|
|
862
862
|
# longer tested tuple. This pins Python tuple ordering as the contract.
|
|
863
863
|
from sdr_visualizer.adapters.cja import generator_version_warning
|
|
864
864
|
|
|
865
|
-
assert generator_version_warning("3.
|
|
866
|
-
assert generator_version_warning("3.
|
|
865
|
+
assert generator_version_warning("3.14") is not None
|
|
866
|
+
assert generator_version_warning("3.13") is None
|
|
867
867
|
|
|
868
868
|
|
|
869
869
|
# ---------------------------------------------------------------------------
|
|
@@ -1101,10 +1101,10 @@ def test_tested_generator_version_does_not_warn(tmp_path, capsys):
|
|
|
1101
1101
|
@pytest.mark.parametrize(
|
|
1102
1102
|
("platform", "version", "warns"),
|
|
1103
1103
|
[
|
|
1104
|
-
("cja", "3.
|
|
1105
|
-
("cja", "3.
|
|
1106
|
-
("aa", "1.
|
|
1107
|
-
("aa", "1.
|
|
1104
|
+
("cja", "3.13.2", False),
|
|
1105
|
+
("cja", "3.13.3", True),
|
|
1106
|
+
("aa", "1.24.1", False),
|
|
1107
|
+
("aa", "1.24.2", True),
|
|
1108
1108
|
],
|
|
1109
1109
|
)
|
|
1110
1110
|
def test_catalog_generator_warning_boundary(platform, version, warns, tmp_path, capsys):
|
|
@@ -160,3 +160,68 @@ def test_fixture_and_corpus_tier_budgets_agree_exactly():
|
|
|
160
160
|
assert corpus._tier_budget_bytes(2001) is None
|
|
161
161
|
assert perf_check.COMPARE_SIZE_BUDGET_BYTES == 4_500_000
|
|
162
162
|
assert perf_check.TREND_SIZE_BUDGET_BYTES == 4_500_000
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
@pytest.mark.parametrize("delta,expected", [(-1, None), (0, "90%"), (1, "90%")])
|
|
166
|
+
def test_headroom_note_boundary(delta, expected):
|
|
167
|
+
note = perf_check._headroom_note("CJA-100", 450_000 + delta, 500_000)
|
|
168
|
+
if expected is None:
|
|
169
|
+
assert note is None
|
|
170
|
+
else:
|
|
171
|
+
assert expected in note
|
|
172
|
+
assert "CJA-100" in note
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def test_headroom_note_absent_at_or_over_budget():
|
|
176
|
+
assert perf_check._headroom_note("x", 500_000, 500_000) is None
|
|
177
|
+
assert perf_check._headroom_note("x", 500_001, 500_000) is None
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def test_measure_report_includes_headroom_note_without_failing(monkeypatch):
|
|
181
|
+
monkeypatch.setattr(perf_check, "render", lambda impl: "x" * 460_000)
|
|
182
|
+
monkeypatch.setattr(perf_check.time, "perf_counter", lambda: 0)
|
|
183
|
+
failures, report = perf_check._measure(
|
|
184
|
+
"CJA-100", {}, lambda snap: None, size_budget_bytes=500_000
|
|
185
|
+
)
|
|
186
|
+
assert failures == []
|
|
187
|
+
assert "warning: [CJA-100] HTML size at 92% of budget" in report
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
@pytest.mark.parametrize("mode,label", [("compare", "CJA-compare"), ("trend", "CJA-trend")])
|
|
191
|
+
def test_comparative_report_includes_headroom_note_without_failing(monkeypatch, mode, label):
|
|
192
|
+
monkeypatch.setattr(perf_check, "cja_adapt", lambda snap: None)
|
|
193
|
+
monkeypatch.setattr(perf_check, "build_payload_with_options", lambda impl: {"meta": {}})
|
|
194
|
+
monkeypatch.setattr(perf_check, "diff_implementations", lambda *args: {"baseline": {}})
|
|
195
|
+
monkeypatch.setattr(perf_check, "build_trend", lambda *args, **kwargs: {})
|
|
196
|
+
monkeypatch.setattr(perf_check, "render_payload", lambda payload: "x" * 4_050_000)
|
|
197
|
+
monkeypatch.setattr(perf_check.time, "perf_counter", lambda: 0)
|
|
198
|
+
if mode == "compare":
|
|
199
|
+
failures, report = perf_check._measure_compare({}, {})
|
|
200
|
+
else:
|
|
201
|
+
failures, report = perf_check._measure_trend({}, lambda snap: snap)
|
|
202
|
+
assert failures == []
|
|
203
|
+
assert f"warning: [{label}] HTML size at 90% of budget" in report
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def test_main_fails_when_any_tier_fixture_missing(tmp_path, monkeypatch, capsys):
|
|
207
|
+
for name in ("CJA_SMALL", "CJA_MEDIUM", "CJA_LARGE", "AA_LARGE", "CJA_XL"):
|
|
208
|
+
monkeypatch.setattr(perf_check, name, tmp_path / f"{name.lower()}.json")
|
|
209
|
+
assert perf_check.main() == 2
|
|
210
|
+
out = capsys.readouterr()
|
|
211
|
+
for flag in ("--scale 0.083", "--scale 0.417", "--scale 1.67", "generate_aa_large_fixture"):
|
|
212
|
+
assert flag in out.err
|
|
213
|
+
for name in ("cja_small", "cja_medium", "cja_large", "aa_large", "cja_xl"):
|
|
214
|
+
assert f"{name}.json missing" in out.err
|
|
215
|
+
assert "OK: all budgets met" not in out.out
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def test_main_names_only_the_missing_tier(tmp_path, monkeypatch, capsys):
|
|
219
|
+
present = tmp_path / "present.json"
|
|
220
|
+
present.write_text("{}", encoding="utf-8")
|
|
221
|
+
for name in ("CJA_MEDIUM", "CJA_LARGE", "AA_LARGE", "CJA_XL"):
|
|
222
|
+
monkeypatch.setattr(perf_check, name, present)
|
|
223
|
+
monkeypatch.setattr(perf_check, "CJA_SMALL", tmp_path / "cja_snapshot_small.json")
|
|
224
|
+
assert perf_check.main() == 2
|
|
225
|
+
err = capsys.readouterr().err
|
|
226
|
+
assert "cja_snapshot_small.json" in err
|
|
227
|
+
assert "--scale 0.417" not in err
|
|
@@ -157,3 +157,19 @@ def test_comparative_browser_render_boundary(monkeypatch, mode, delta):
|
|
|
157
157
|
page.evaluate.side_effect = [1, 0, 59, 0, 100]
|
|
158
158
|
failures = perf_browser_check._check_trend(page, Path("/tmp/boundary.html"))
|
|
159
159
|
assert bool(failures) == (delta >= 0)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
@pytest.mark.parametrize("ms,fails", [(99.9, False), (100.0, True)])
|
|
163
|
+
def test_workspace_gate_rejects_exact_budget(ms, fails):
|
|
164
|
+
observations = {
|
|
165
|
+
"eager": 0,
|
|
166
|
+
"total": 10000,
|
|
167
|
+
"first": 50,
|
|
168
|
+
"second": 50,
|
|
169
|
+
"firstRange": "Showing 1–50 of 10000",
|
|
170
|
+
"secondRange": "Showing 51–100 of 10000",
|
|
171
|
+
"openMs": ms,
|
|
172
|
+
"pageMs": 3,
|
|
173
|
+
}
|
|
174
|
+
failures = perf_browser_check._workspace_failures("synthetic", observations, 10000)
|
|
175
|
+
assert bool(failures) == fails
|