mirror of
https://github.com/ansible/awx.git
synced 2026-03-29 06:45:09 -02:30
AAP-60470 Add dispatcherctl and dispatcherd commands as updated interface to dispatcherd lib (#16206)
* Add dispatcherctl command * Add tests for dispatcherctl command * Exit early if sqlite3 * Switch to dispatcherd mgmt cmd * Move unwanted command options to run_dispatcher * Add test for new stuff * Update the SOS report status command * make docs always reference new command * Consistently error if given config file
This commit is contained in:
17
awx/main/tests/functional/management/test_dispatcherd.py
Normal file
17
awx/main/tests/functional/management/test_dispatcherd.py
Normal file
@@ -0,0 +1,17 @@
|
||||
import pytest
|
||||
|
||||
from awx.main.dispatch.config import get_dispatcherd_config
|
||||
from awx.main.management.commands.dispatcherd import _hash_config
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_dispatcherd_config_hash_is_stable(settings, monkeypatch):
|
||||
monkeypatch.setenv('AWX_COMPONENT', 'dispatcher')
|
||||
settings.CLUSTER_HOST_ID = 'test-node'
|
||||
settings.JOB_EVENT_WORKERS = 1
|
||||
settings.DISPATCHER_SCHEDULE = {}
|
||||
|
||||
config_one = get_dispatcherd_config(for_service=True)
|
||||
config_two = get_dispatcherd_config(for_service=True)
|
||||
|
||||
assert _hash_config(config_one) == _hash_config(config_two)
|
||||
@@ -9,7 +9,7 @@ from unittest import mock
|
||||
import pytest
|
||||
|
||||
from awx.main.tasks.system import CleanupImagesAndFiles, execution_node_health_check, inspect_established_receptor_connections, clear_setting_cache
|
||||
from awx.main.management.commands.run_dispatcher import Command
|
||||
from awx.main.management.commands.dispatcherd import Command
|
||||
from awx.main.models import Instance, Job, ReceptorAddress, InstanceLink
|
||||
|
||||
|
||||
|
||||
92
awx/main/tests/unit/commands/test_dispatcherctl.py
Normal file
92
awx/main/tests/unit/commands/test_dispatcherctl.py
Normal file
@@ -0,0 +1,92 @@
|
||||
import io
|
||||
|
||||
import pytest
|
||||
|
||||
from django.core.management.base import CommandError
|
||||
|
||||
from awx.main.management.commands import dispatcherctl
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def clear_dispatcher_env(monkeypatch, mocker):
|
||||
monkeypatch.delenv('DISPATCHERD_CONFIG_FILE', raising=False)
|
||||
mocker.patch.object(dispatcherctl.logging, 'basicConfig')
|
||||
mocker.patch.object(dispatcherctl, 'connection', mocker.Mock(vendor='postgresql'))
|
||||
|
||||
|
||||
def test_dispatcherctl_runs_control_with_generated_config(mocker):
|
||||
command = dispatcherctl.Command()
|
||||
command.stdout = io.StringIO()
|
||||
|
||||
data = {'foo': 'bar'}
|
||||
mocker.patch.object(dispatcherctl, '_build_command_data_from_args', return_value=data)
|
||||
dispatcher_setup = mocker.patch.object(dispatcherctl, 'dispatcher_setup')
|
||||
config_data = {'setting': 'value'}
|
||||
mocker.patch.object(dispatcherctl, 'get_dispatcherd_config', return_value=config_data)
|
||||
|
||||
control = mocker.Mock()
|
||||
control.control_with_reply.return_value = [{'status': 'ok'}]
|
||||
mocker.patch.object(dispatcherctl, 'get_control_from_settings', return_value=control)
|
||||
mocker.patch.object(dispatcherctl.yaml, 'dump', return_value='payload\n')
|
||||
|
||||
command.handle(
|
||||
command='running',
|
||||
config=dispatcherctl.DEFAULT_CONFIG_FILE,
|
||||
expected_replies=1,
|
||||
log_level='INFO',
|
||||
)
|
||||
|
||||
dispatcher_setup.assert_called_once_with(config_data)
|
||||
control.control_with_reply.assert_called_once_with('running', data=data, expected_replies=1)
|
||||
assert command.stdout.getvalue() == 'payload\n'
|
||||
|
||||
|
||||
def test_dispatcherctl_rejects_custom_config_path():
|
||||
command = dispatcherctl.Command()
|
||||
command.stdout = io.StringIO()
|
||||
|
||||
with pytest.raises(CommandError):
|
||||
command.handle(
|
||||
command='running',
|
||||
config='/tmp/dispatcher.yml',
|
||||
expected_replies=1,
|
||||
log_level='INFO',
|
||||
)
|
||||
|
||||
|
||||
def test_dispatcherctl_rejects_sqlite_db(mocker):
|
||||
command = dispatcherctl.Command()
|
||||
command.stdout = io.StringIO()
|
||||
|
||||
mocker.patch.object(dispatcherctl, 'connection', mocker.Mock(vendor='sqlite'))
|
||||
|
||||
with pytest.raises(CommandError, match='sqlite3'):
|
||||
command.handle(
|
||||
command='running',
|
||||
config=dispatcherctl.DEFAULT_CONFIG_FILE,
|
||||
expected_replies=1,
|
||||
log_level='INFO',
|
||||
)
|
||||
|
||||
|
||||
def test_dispatcherctl_raises_when_replies_missing(mocker):
|
||||
command = dispatcherctl.Command()
|
||||
command.stdout = io.StringIO()
|
||||
|
||||
mocker.patch.object(dispatcherctl, '_build_command_data_from_args', return_value={})
|
||||
mocker.patch.object(dispatcherctl, 'dispatcher_setup')
|
||||
mocker.patch.object(dispatcherctl, 'get_dispatcherd_config', return_value={})
|
||||
control = mocker.Mock()
|
||||
control.control_with_reply.return_value = [{'status': 'ok'}]
|
||||
mocker.patch.object(dispatcherctl, 'get_control_from_settings', return_value=control)
|
||||
mocker.patch.object(dispatcherctl.yaml, 'dump', return_value='- status: ok\n')
|
||||
|
||||
with pytest.raises(CommandError):
|
||||
command.handle(
|
||||
command='running',
|
||||
config=dispatcherctl.DEFAULT_CONFIG_FILE,
|
||||
expected_replies=2,
|
||||
log_level='INFO',
|
||||
)
|
||||
|
||||
control.control_with_reply.assert_called_once_with('running', data={}, expected_replies=2)
|
||||
Reference in New Issue
Block a user