#9995 ipatests: testReplicaInForwardZone fails on RHEL teardown: NetworkManager rewrites /etc/resolv.conf after ipa-replica-install --setup-dns
Closed: fixed by frenaud. Opened by pthube.

Issue

test_integration/test_replica_promotion.py::TestReplicaInForwardZone::test_replica_install_in_forward_zone can pass the test body but fail during class teardown on RHEL when uninstall_master() calls host.resolver.restore(). The integration test harness tracks /etc/resolv.conf in PlainFileResolver.current_state. ipa-replica-install --setup-dns and NetworkManager change the file on disk without updating that state, so restore triggers AssertionError: Resolver state changed unexpectedly.

Steps to Reproduce

1.Run TestReplicaInForwardZone (or full test_replica_promotion.py class uninstall path).
2.Test installs master with DNS, adds forward zone forward.test, joins replica as client with --hostname replica.forward.test, runs ipa-replica-install --setup-dns.
3.Test finishes; pytest class teardown runs tasks.uninstall_master(replica).
4.uninstall_master() ends with while host.resolver.has_backups(): host.resolver.restore().

Actual behavior

Teardown fails with:
AssertionError: Resolver state changed unexpectedly at host

Expected behavior

Teardown restores the resolver configuration saved at the start of the test session and uninstall completes without resolver assertion failures.

Additional info:

Root cause (RHEL + integration harness)
tasks.install_client() (default nameservers='master') calls client.resolver.backup() and setup_resolver(), so one backup is on the stack and current_state reflects the ipatests-managed resolv file. ipa-replica-install --setup-dns runs step “changing resolv.conf to point to ourselves” and starts BIND; resolver on the replica points at local DNS. On RHEL, NetworkManager often rewrites /etc/resolv.conf again (e.g. after install or during ipa-server-install --uninstall), using:
search forward.test (replica FQDN domain), and corporate/lab forwarders from NM, not the ipatests file. PlainFileResolver.restore() always calls check_state_expected() first: on-disk content must equal current_state. External writes by IPA/NM are invisible to the helper, so restore in teardown fails even though the test logic succeeded.

This is primarily a test-harness vs. real-system interaction on RHEL (NM + IPA DNS install), not a functional IPA bug in forward-zone replica install (install can succeed with exit code 0).

Logs: https://$ARTIFACTS_SERVER/idm-ci/freeipa/Nightly-Tier2/RHEL10.2/2026-04-27_20-24/tier-2/upstream-replica-promotion-testreplicainforwardzone/2/


Metadata Update from @dhanina:
- Custom field on_review adjusted to https://github.com/freeipa/freeipa/pull/8415

Metadata Update from @dhanina:
- Custom field rhbz adjusted to https://redhat.atlassian.net/browse/IDM-6160

master:

  • c31cc109566822f8070cee7a723195263fa2c7ac ipatests: fix replica forward-zone test teardown resolv.conf restore

ipa-4-13:

  • 4e727421dc4e9772d78e3e1351bc1ab5ccf99e72 ipatests: fix replica forward-zone test teardown resolv.conf restore

Metadata Update from @frenaud:
- Issue close_status updated to: fixed
- Issue status updated to: Closed (was: Open)

Metadata