Testing Strategy & CI
Relevant source files
The following files were used as context for generating this wiki page:
Infrahub Sync utilizes a multi-layered testing strategy and a robust Continuous Integration (CI) pipeline to ensure the stability and reliability of its data synchronization engine. The project emphasizes safety by prioritizing read-only dry runs and idempotent operations, ensuring that synchronization tasks do not corrupt destination systems of record.
The testing architecture comprises unit tests for core utilities and adapter edge cases, coupled with opt-in integration tests for live system validation. The CI pipeline, managed via GitHub Actions and Invoke tasks, enforces strict code quality gates, including linting, type checking, and automated release workflows.
Sources: dev/constitution.md:16-25, AGENTS.md:5-10, AGENTS.md:120-130
Testing Principles & Core Requirements
The testing strategy is governed by several core principles defined in the project constitution. Developers must implement features and fixes alongside their corresponding tests to maintain high reliability across brittle external APIs.
- Offline by Default: The unit test suite must pass without network access or credentials. All external systems and SDKs must be stubbed or mocked.
- Atomic Tests: Tests must be single-purpose and isolated to specific behaviors.
- Parametrization: Prefer parametrized tests over loops for validating configuration parsing and adapter variants.
- Optional Dependency Handling: Tests for adapters that require optional SDKs must skip cleanly if the dependency is missing to ensure the overall test suite remains green in diverse environments.
Sources: dev/guidelines/testing-adapters.md:11-20, dev/constitution.md:73-80, dev/guides/testing-an-adapter.md:46-51
Test Categories
| Category | Description | Execution Command |
|---|---|---|
| Unit Tests | Test utils, adapter field mapping, and edge cases (401/403, timeouts, empty pages) using mocks. | uv run pytest -q |
| Integration Tests | Validate live connectivity and full synchronization flows against running servers. Marked with @pytest.mark.integration. | uv run pytest -m integration |
| CLI Sanity | Verify command-line behaviors including --help, list, and generate. | uv run infrahub-sync --help |
| Linting & Formatting | Verify code style, type safety, and YAML consistency. | uv run invoke lint |
Sources: AGENTS.md:65-72, AGENTS.md:120-130, dev/guides/testing-an-adapter.md:100-112
Continuous Integration Workflow
The CI process enforces quality gates that all code must pass before merging into the main branch. This is facilitated through invoke tasks that orchestrate various linters and formatters.
The diagram above illustrates the required local development workflow and the subsequent CI gates.
Sources: AGENTS.md:55-63, AGENTS.md:155-165, dev/constitution.md:103-110
Quality Gate Tools
| Tool | Purpose | Configuration File |
|---|---|---|
| Ruff | Primary linter and formatter for Python code. | pyproject.toml ([tool.ruff]) |
| Pylint | Static code analysis for catching deeper logic errors. | pyproject.toml ([tool.pylint]) |
| ty | Type checker for enforcing static typing. | pyproject.toml ([tool.ty]) |
| yamllint | Validates YAML configuration files and examples. | pyproject.toml ([project.optional-dependencies]) |
| rumdl | Lints and formats Markdown and MDX documentation. | pyproject.toml ([tool.rumdl]) |
Sources: pyproject.toml:95-230, pyproject.toml:340-360, tasks/docs.py:28-40
Adapter Testing Strategy
Adapters are the primary extension point and require specific testing implementations to ensure they adhere to the DiffSyncMixin contract.
Mocking Upstream Clients
Developers must stub upstream clients using unittest.mock.MagicMock. This allows testing the model_loader and obj_to_diffsync logic with deterministic API responses without network dependency.
from unittest.mock import MagicMock
from infrahub_sync.adapters.mysystem import MysystemAdapter
def make_adapter(config):
adapter = MysystemAdapter(target="source", adapter=config.source, config=config)
adapter.client = MagicMock()
return adapter
Sources: dev/guides/testing-an-adapter.md:46-55, dev/guidelines/testing-adapters.md:11-20
Incremental Sync Validation
Adapters supporting incremental sync must be tested for cursor compliance. This includes:
- Verifying
cursor_tier_forreturns the correctCursorTier. - Ensuring
list_changed_sinceapplies the correct change filters (e.g.,last_updated__gte). - Validating
list_existing_idsyields the expected unique identifiers.
Sources: dev/guides/testing-an-adapter.md:70-85, dev/guidelines/testing-adapters.md:32-42
Automated Release Pipeline
The project uses GitHub Actions to automate the release process, ensuring that versioning and changelogs are handled consistently.
The sequence diagram shows the interaction between the developer and automated workflows during a release.
Sources: RELEASING.md:15-30, RELEASING.md:50-70
Release Requirements
- News Fragments: Every PR into
mainmust include a news fragment in thechangelog/directory. This is enforced bychangelog-check.yml. - Version Labels: PR labels (e.g.,
type/bug,type/feature) determine the version bump (Patch, Minor, or Major). - Idempotency: Re-dispatched releases fail if no new fragments or version changes are detected, preventing empty releases.
Sources: RELEASING.md:100-115, RELEASING.md:148-160, pyproject.toml:375-420
Summary
The testing strategy for Infrahub Sync prioritizes offline verification and adapter consistency. By enforcing strict linting, type checking, and automated release workflows, the project maintains a high standard of code quality. The use of uv for dependency management and invoke for task orchestration provides a unified interface for both developers and CI environments.
Sources: dev/constitution.md:145-160, AGENTS.md:180-190