callback adjustment for no hosts matched

The validation_json callback will now consider the no hosts being matched
case as a validation failure. And record the result as such.

To prevent unnecessary confusion, the host indicated in the created
log file will be designated as 'No host matched'. And will be displayed
as such on the VF stdout.

Basic test coverage included.

Signed-off-by: Jiri Podivin <jpodivin@redhat.com>
Change-Id: I613203698b726941162239185de77949bf30254c
This commit is contained in:
Jiri Podivin 2021-07-09 11:03:37 +02:00
parent 8dd362023d
commit 26ea5efffc
2 changed files with 112 additions and 1 deletions

View File

@ -187,6 +187,41 @@ class CallbackModule(CallbackBase):
result['play']['duration']['end'] = end_time
result['play']['duration']['time_elapsed'] = time_elapsed
def v2_playbook_on_no_hosts_matched(self):
no_match_result = self._val_task('No tasks run')
no_match_result['task']['status'] = "FAILED"
no_match_result['task']['info'] = (
"None of the hosts specified"
" were matched in the inventory file")
output = {
'plays': self.results,
'stats': {
'No host matched':{
'changed': 0,
'failures': 1,
'ignored': 0,
'ok': 0,
'rescued': 0,
'skipped': 0,
'unreachable': 0}},
'validation_output': self.simple_results + [no_match_result]
}
log_file = "{}/{}_{}_{}.json".format(
VALIDATIONS_LOG_DIR,
os.getenv(
'ANSIBLE_UUID',
self.results[0].get('play').get('id')),
self.env['playbook_name'],
self.current_time)
with open(log_file, 'w') as js:
js.write(json.dumps(output,
cls=AnsibleJSONEncoder,
indent=4,
sort_keys=True))
def __getattribute__(self, name):
"""Return ``_record_task_result`` partial with a dict
containing skipped/failed if necessary

View File

@ -290,7 +290,10 @@ class TestValidationJson(base.TestCase):
mock_new_task.assert_called_once_with(callback, mock_task)
self.assertIn({'task': {'host': 'foo'}}, callback.results[0]['tasks'])
@mock.patch('json.dumps', return_value='json_dump_foo')
@mock.patch(
'json.dumps',
return_value='json_dump_foo',
autospec=True)
@mock.patch(
'validations_common.callback_plugins.validation_json.open',
create=True)
@ -349,6 +352,79 @@ class TestValidationJson(base.TestCase):
mock_json_dumps.assert_called_once_with(output, **kwargs)
mock_write.assert_called_once_with('json_dump_foo')
@mock.patch(
'json.dumps',
return_value='json_dump_foo',
autospec=True)
@mock.patch(
'validations_common.callback_plugins.validation_json.open',
create=True)
def test_v2_playbook_on_no_hosts_matched(self, mock_open,
mock_json_dumps):
results = [
{
'play': {
'id': 'fizz'
}
}
]
validation_task = {
'task': {
'name': 'No tasks run',
'hosts': {}}}
validation_json.VALIDATIONS_LOG_DIR = '/home/foo/validations'
callback = validation_json.CallbackModule()
dummy_stats = AggregateStats()
callback.results = results
callback.simple_results = results
callback.env['playbook_name'] = 'foo'
callback.current_time = 'foo-bar-fooTfoo:bar:foo.fizz'
dummy_stats.processed['foohost'] = 5
no_match_result = validation_task
no_match_result['task']['status'] = "FAILED"
no_match_result['task']['info'] = (
"None of the hosts specified"
" were matched in the inventory file")
output = {
'plays': results,
'stats': {
'No host matched':{
'changed': 0,
'failures': 1,
'ignored': 0,
'ok': 0,
'rescued': 0,
'skipped': 0,
'unreachable': 0}},
'validation_output': results + [no_match_result]
}
log_file = "{}/{}_{}_{}.json".format(
"/home/foo/validations",
'fizz',
'foo',
'foo-bar-fooTfoo:bar:foo.fizz')
kwargs = {
'cls': AnsibleJSONEncoder,
'indent': 4,
'sort_keys': True
}
callback.v2_playbook_on_no_hosts_matched()
mock_write = mock_open.return_value.__enter__.return_value.write
mock_open.assert_called_once_with(log_file, 'w')
mock_json_dumps.assert_called_once_with(output, **kwargs)
mock_write.assert_called_once_with('json_dump_foo')
@mock.patch('time.time', return_value=99.99)
@mock.patch(
'validations_common.callback_plugins.validation_json.secondsToStr',