Skip to content

Add unit tests for conductor ironic sync orchestrators#2367

Open
berendt wants to merge 2 commits into
mainfrom
implement/issue-2227-ironic-sync-tests
Open

Add unit tests for conductor ironic sync orchestrators#2367
berendt wants to merge 2 commits into
mainfrom
implement/issue-2227-ironic-sync-tests

Conversation

@berendt

@berendt berendt commented Jun 12, 2026

Copy link
Copy Markdown
Member

Implements #2227.

Adds tests/unit/tasks/conductor/test_ironic_sync.py covering the four
sync orchestrators in osism/tasks/conductor/ironic.py. Tests focus on
state transitions and branch coverage, asserting on push_task_output
substrings rather than exact strings, as the issue requests.

What the single commit adds

A new test module organised into four clearly-labelled sections, one per
target function. It patches the module-level imports
(osism_utils, openstack, netbox, deep_compare, mask_secrets,
_matches_netbox_filter, _prepare_node_attributes,
_sync_ironic_device, _sync_ironic_device_dry_run) following the
existing mocker + SimpleNamespace conventions used in the sibling
test_netbox.py / test_config.py.

_sync_ironic_device (ironic.py:354)

  • Create path: node created with automated_clean=False;
    target_raid_config applied via baremetal_node_set_target_raid_config;
    a (False, "error") result raises an exception mentioning
    target_raid_config.
  • Update path: deep_compare populates node_updates → update with
    full node_attributes; the driver password key (resolved via
    driver_params[driver]["password"]) is popped, and a password-only
    delta drops driver_info so no update happens unless force=True.
  • Port reconciliation: extra ports deleted, new MACs created,
    comparison is case-insensitive.
  • State machine: management-validation failure returns early;
    enroll / clean failed move to manageable; power is forced off;
    boot-validation failure on available demotes to manageable;
    adoption from manageable and from available; the normal
    manageprovideavailable path including the automated_clean
    toggles; set_boot_device failure is caught; is_adoption derives
    from the provision_state == "active" custom field.

_sync_ironic_device_dry_run (ironic.py:570)

  • Secret values collected from password/secret/ironic_osism_*
    string keys and passed to mask_secrets (call args verified;
    non-strings and unrelated keys ignored).
  • Create branch (adopt vs. available, with active implying adopt) and
    update branch (update vs. no-update-needed, port create/delete,
    current provision_state reported).

sync_ironic (ironic.py:681)

  • NetBox/Ironic unreachable → finish_task_output(rc=1); node_name
    not found; dry-run path; lock acquired (device synced and released in
    finally, even on exception) and lock contention; stale-node cleanup
    (delete, dry-run "Would delete", clean failedmanageable first,
    ineligible "Cannot remove"); skip/extra_kernel_params propagation;
    ports_attributes filtering by enabled and not mgmt_only and mac_address.

sync_netbox_from_ironic (ironic.py:877)

  • Filtered selection (primary match, secondary fallback, no match, all
    unreachable) and unfiltered selection (primary unreachable, all/one
    secondary reachable, no secondaries message); node-name not found;
    set_* called with secondary_nb_list=reachable_secondaries;
    failed-device reporting; Ironic unreachable.

Verification

  • black --check and flake8 pass on the new file.
  • pytest was not run in this local environment per my standing
    workflow preference of letting CI run the suite; the Zuul
    python-osism-unit-tests job is the verification gate for this draft.

Notes

  • The change is purely additive (one new test file); no production code
    is touched.
  • Per the issue, coverage of some defensive except branches and
    message-only push paths is intentionally left lower.

Assisted-by: Claude:claude-opus-4-8

Cover the four sync entry points in osism/tasks/conductor/ironic.py
in a new tests/unit/tasks/conductor/test_ironic_sync.py, focusing on
state transitions and branch coverage rather than exact task-output
strings:

- _sync_ironic_device: node creation and update paths, driver
  password popping, target_raid_config handling, port reconciliation
  (case-insensitive MAC match, create and delete) and the full
  validation/provisioning state machine (enroll, clean failed, power
  off, boot-validation demotion, adoption from manageable/available,
  and the normal manage->provide->available transition).
- _sync_ironic_device_dry_run: secret-value collection and masking,
  the create branch (adopt vs available messages) and the update
  branch (update vs no-update, port reconciliation, provision_state
  reporting).
- sync_ironic: NetBox/Ironic reachability, node-name filtering,
  dry-run path, locking (acquire, release-on-error, lock contention),
  stale-node cleanup (delete, dry-run, clean-failed, ineligible) and
  kernel-parameter/ports propagation.
- sync_netbox_from_ironic: filtered and unfiltered NetBox selection,
  primary/secondary reachability, node sync with reachable
  secondaries and failed-device reporting.

Tests follow the existing mocker + SimpleNamespace conventions and
patch the module-level imports (osism_utils, openstack, netbox,
deep_compare, mask_secrets).

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Christian Berendt <berendt@osism.tech>
@berendt berendt force-pushed the implement/issue-2227-ironic-sync-tests branch from 68bf6a7 to 809aad6 Compare June 12, 2026 12:48
@berendt berendt marked this pull request as ready for review June 12, 2026 12:48
@berendt berendt requested a review from ideaship June 12, 2026 12:48

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • The new test module is quite large (~950 lines); consider splitting it into smaller files or grouping related tests into classes (e.g. per orchestrator) to keep each unit more focused and easier to navigate.
  • There is some repeated setup logic for openstack.baremetal_node_show and baremetal_node_validate in multiple tests; extracting additional fixtures or helper functions for common scenarios (e.g. 'manageable node with valid validation', 'available node with boot failure') would reduce duplication and make the intent of each test clearer.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new test module is quite large (~950 lines); consider splitting it into smaller files or grouping related tests into classes (e.g. per orchestrator) to keep each unit more focused and easier to navigate.
- There is some repeated setup logic for `openstack.baremetal_node_show` and `baremetal_node_validate` in multiple tests; extracting additional fixtures or helper functions for common scenarios (e.g. 'manageable node with valid validation', 'available node with boot failure') would reduce duplication and make the intent of each test clearer.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

sync_ironic collects NetBox devices in a set, but the tests built device
stand-ins as types.SimpleNamespace, which defines __eq__ without __hash__
and is therefore unhashable. Replace it with a plain class so instances
use the default identity hash, matching real pynetbox objects.

Assisted-by: Claude:claude-fable-5
Signed-off-by: Christian Berendt <berendt@osism.tech>
@berendt berendt force-pushed the implement/issue-2227-ironic-sync-tests branch from aa15de1 to ecd456b Compare June 12, 2026 13:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Ready

Development

Successfully merging this pull request may close these issues.

2 participants