Repository navigation
Description
❌ This issue is not open for contribution. Visit Contributing guidelines to learn about the contributing process and how to find suitable issues.
Observed Behavior
Eight tests that change MORANGO_SYSTEM_ID and expect a new instance ID fail on hosts where Morango cannot read a MAC address. They pass on hosts where it can. In CI, the same tests pass and fail between runs on the same commit.
The tests expect InstanceIDModel.get_or_create_current_instance(clear_cache=True) to create a new instance after MORANGO_SYSTEM_ID changes. On a host without a readable MAC address, it returns the existing instance with created=False:
tests/testapp/tests/test_api.py::MorangoInfoTestCase::test_id_changes_id_hash_changestests/testapp/tests/test_uuid_utilities.py::InstanceIDModelTestCase::test_instance_id_cachingtests/testapp/tests/sync/test_controller.py::SerializeIntoStoreTestCase::test_last_saved_instance_updatestests/testapp/tests/sync/test_controller.py::RecordMaxCounterUpdatesDuringSerialization::test_new_rmc_for_non_existent_modeltests/testapp/tests/sync/test_operations.py::QueueStoreIntoBufferV1TestCase::test_fsic_counterstests/testapp/tests/sync/test_operations.py::QueueStoreIntoBufferV1TestCase::test_fsic_specific_idtests/testapp/tests/sync/test_operations.py::QueueStoreIntoBufferV2TestCase::test_fsic_counterstests/testapp/tests/sync/test_operations.py::QueueStoreIntoBufferV2TestCase::test_fsic_specific_id
Expected Behavior
The tests give the same result on every host, whether or not Morango can read a MAC address on that host.
Steps to Reproduce
The failure depends on the host, so these steps simulate a host without a readable MAC address.
-
Unset
MORANGO_SYSTEM_IDandMORANGO_NODE_IDin your shell. -
Save this pytest plugin as
no_mac.pyin a directory outside the repository:# Simulates a host with no readable MAC address: ifcfg finds no interfaces, and # uuid.getnode returns a random node, which has the multicast bit set import uuid def pytest_configure(config): import ifcfg uuid.getnode = lambda: 0x010203040506 ifcfg.interfaces = lambda: {}
-
From the repository root, run the tests with the plugin:
PYTHONPATH=<plugin directory> python -O -m pytest -p no_mac \ tests/testapp/tests/test_api.py::MorangoInfoTestCase::test_id_changes_id_hash_changes \ tests/testapp/tests/test_uuid_utilities.py::InstanceIDModelTestCase::test_instance_id_caching \ tests/testapp/tests/sync/test_controller.py::SerializeIntoStoreTestCase::test_last_saved_instance_updates \ tests/testapp/tests/sync/test_controller.py::RecordMaxCounterUpdatesDuringSerialization::test_new_rmc_for_non_existent_model \ tests/testapp/tests/sync/test_operations.py::QueueStoreIntoBufferV1TestCase \ tests/testapp/tests/sync/test_operations.py::QueueStoreIntoBufferV2TestCase -
The run reports
8 failed, 25 passed. -
To compare, make the plugin return a real MAC address:
uuid.getnodereturns0x001122334455, andifcfg.interfacesreturns{"eth0": {"device": "eth0", "ether": "00:11:22:33:44:55"}}. The same run reports33 passed.
Minimal Reproduction Environment / Conditions
- Commit: reproduced on
release-v0.9.x@799d70dand on the branch of Reorder filters produced by Scope #410. The results are the same on both. - Environment: Linux, Python 3.10, SQLite. The CI failures below are from a tox
py3.9job. - CI trigger (unconfirmed): some CI runners probably give no usable network interface to
ifcfg, anduuid.getnode()falls back to a random node. This explains why the failures come and go.
Errors, Logs & Telemetry
From a CI run:
> self.assertNotEqual(m_info.data["instance_hash"], old_id_hash)
E AssertionError: 'fifag-gokiv' == 'fifag-gokiv'
tests/testapp/tests/test_api.py:1151: AssertionError
> self.assertTrue(created)
E AssertionError: False is not true
tests/testapp/tests/test_uuid_utilities.py:200: AssertionError
> self.assertNotEqual(new_id.id, self.current_id.id)
E AssertionError: '0ff26305271e1133dcfd3350ab7fd63f' == '0ff26305271e1133dcfd3350ab7fd63f'
tests/testapp/tests/sync/test_controller.py:337: AssertionError
> assert i.id not in buffer_ids
E AssertionError: assert '055e7be12e154c9a7a9c2974f70d803c' not in <QuerySet [...]>
tests/testapp/tests/sync/test_operations.py:66: AssertionError
====== 8 failed, 614 passed, 31 skipped, 2 warnings in 1619.20s (0:26:59) ======
Deliverables & Testing Requirements
- The eight tests pass on hosts with and without a readable MAC address.
- The tests do not depend on
MORANGO_SYSTEM_IDorMORANGO_NODE_IDbeing set or unset in the environment that runs them. - Regression safety: the test suite runs with the same host identity on every host, so a future test cannot depend on the host MAC address. Tests that need a different host, such as one without a readable MAC address, mock it explicitly.
- The production behavior described under Notes is intended. A test records it: on a host without a readable MAC address, a change to
MORANGO_SYSTEM_IDkeeps the current instance. - The fix changes only tests. It does not change production code.
Technical Pointers & Root Cause Clues
- Legacy instance lookup:
get_or_create_current_instance(morango/models/core.py:154-163) first returns any current instance that matches the 0.4 system parameters. Those parameters do not includeMORANGO_SYSTEM_ID. - Node ID sources: the 0.4
node_id(get_0_4_system_parameters,morango/models/utils.py:19-47) is empty whenuuid.getnode()returns a random node. The 0.5node_id(get_0_5_mac_address,morango/models/utils.py:213-238) is also empty whenifcfgfinds no usable interface anduuid.getnode()is random. - Match on empty node IDs: when both node IDs are empty, the stored instance matches the 0.4 lookup. A change to
MORANGO_SYSTEM_IDthen does not create a new instance. - Partial mocks: some of the tests mock
ifcfg.interfaces, but none mockuuid.getnode. Instances created insetUp, or by other code before the mock applies, use the real host values. - Related: Switch ifcfg utility for get-mac to find MAC addresses #216 (replace
ifcfgfor MAC address lookup).
Notes & Edge Cases
- Production behavior (unconfirmed impact): on a device without a readable MAC address, a change to
MORANGO_SYSTEM_IDdoes not change the instance ID. The code comment says the legacy lookup must not "mess with" a matching legacy instance, so this can be intended. This issue does not require a change to it. - Environment variables: if you set
MORANGO_NODE_IDto hide the failures locally,InstanceIDModelTestCase::test_consistent_0_5_instance_idfails instead. That test expects a node ID from its mockedifcfgvalue. - Data integrity: no data impact. Only the tests are affected.
Metadata
Severity / Priority: P2 (CI fails at random. Rerunning the job is the workaround.)
Area: bug, tests, CI
AI Usage
I used Claude Code to look into these failures while working on #410. Claude found that the failures depend on the host MAC address, reproduced them with the pytest plugin above, and showed the same results on release-v0.9.x@799d70d and on the #410 branch. It then drafted this issue, and I reviewed it before filing.

Activity