Skip to content

Make the syndic client tests go through a syndic - #70441

Open
ggiesen wants to merge 3 commits into
saltstack:3008.xfrom
ggiesen:fix-test-syndic-runtime-client
Open

ggiesen wants to merge 3 commits into
saltstack:3008.xfrom
ggiesen:fix-test-syndic-runtime-client

Conversation

@ggiesen

@ggiesen ggiesen commented Oct 20, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Makes tests/integration/client/test_syndic.py send its jobs through a syndic, which it has never done (#58975).

SaltClientTestCaseMixin.client caches one LocalClient for the whole session, built from the config of the first test class that asks for it. In a full run other client tests come first, so TestSyndic gets the master's client and pings the regular minion, and passes. When it runs on its own, the client points at syndic_master, which no fixture starts, and test_ping and test_fib fail with "The salt master could not be contacted". PR runs that touch salt/minion.py run it on its own, through tests/filename_map.yml. That's why all the Linux and Windows integration jobs on #70423 fail in these two tests and nothing else.

  • SaltClientTestCaseMixin caches one client per config.
  • test_syndic.py starts the syndic master and the syndic for the module, and SyndicCase targets the minion behind the syndic.
  • salt_syndic_factory uses the current salt-factories arguments. The nested {"master": None, "minion": None, "syndic": {...}} defaults were written out as literal keys in syndic.conf, so none of them applied. The syndic's master also gets the master of masters' publish_port on 127.0.0.2, as in tests/pytests/scenarios/syndic/sync/conftest.py, because the syndic subscribes to the master of masters on its own master's publish_port. The fixture also stops the syndic's master and minion when the syndic is terminated, as the scenario does.
  • tests/integration/files/conf/syndic is removed, since only that fixture read it.

What issues does this PR fix or reference?

Refs #58975, #70423

Previous Behavior

TestSyndic passed in full runs without going through a syndic, and failed when run on its own.

New Behavior

TestSyndic sends test.ping and test.fib through the syndic master, the syndic and the syndic's master to the syndic's minion. It passes on its own and after the other client tests.

Merge requirements satisfied?

  • Docs
  • Changelog
  • Tests written/updated

Tests only, so no changelog entry.

Locally on Linux with Python 3.14, pytest tests/integration/client/test_syndic.py --slow-tests --core-tests fails both tests on 3008.x and passes with this change, with both --transport=zeromq and --transport=tcp. tests/integration/client/ as a whole (test_kwarg, test_standard, then test_syndic) passes, 18 tests. I haven't run it on Windows.

Commits signed with GPG?

No

@ggiesen
ggiesen requested a review from a team as a code owner October 20, 2026 16:20
tests/integration/client/test_syndic.py has never tested a syndic
(saltstack#58975). SaltClientTestCaseMixin caches one LocalClient for the whole
session, built from the config of the first test class that asks for
it. When other client tests run first, TestSyndic gets the master's
client and pings the regular minion. When it runs on its own, which is
what happens on PRs that touch salt/minion.py through
tests/filename_map.yml, the client points at a syndic master that
nothing starts, and both tests fail.

- Cache one client per config.
- Start the syndic master and the syndic for the module, and target the
  minion behind the syndic.
- Build the syndic factory with the current salt-factories arguments.
  The nested defaults were written out as literal master, minion and
  syndic keys, so none of them applied. The syndic's master also needs
  the master of masters' publish_port, since that's the port the syndic
  subscribes on, as in tests/pytests/scenarios/syndic.
- Remove tests/integration/files/conf/syndic, which only that fixture
  read.
Comment thread tests/conftest.py Outdated
}
config_overrides = {"log_level_logfile": "info"}
master_overrides = {
"interface": interface,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

why do we need to override interface and publish_port here given it is the same value as default?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

You're right, they're redundant. salt-factories writes the syndic's config to conf/master.d/syndic.conf, and the syndic's master reads master.d from the same conf dir, so config_defaults already sets them on that master. Dropped them in 172cf3d; the tests still pass on zeromq and tcp, which they can't unless that master really listens on 127.0.0.2 with the shared publish_port.

Comment thread tests/conftest.py
# The syndic subscribes to the master of masters on its own master's
# publish_port, so both masters need the same publish_port, and the
# syndic's master listens on another address.
interface = "127.0.0.2"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

MacOS only has 127.0.0.1, this might fail on MacOS

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch. Added the same ifconfig lo0 alias 127.0.0.2 up that tests/pytests/integration/minion/conftest.py and the failover multimaster scenario use on macOS and FreeBSD, in 172cf3d. I can't run it on macOS here, so that part is untested.

This branch was previously deployed

1 inactive deployment
ci — 75d393ba Deployed Oct 22, 2026 by ggiesen via Build Onedir Packages / macOS (x86_64) #27763
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants