validations-libs/validations_libs/tests/callback_plugins/test_vf_validation_stdout.py
Jiri Podivin b191190a6b Constraining runtime selection and behavior to improve local testing stability
New issues were encountered during unit test execution on local machines,
caused by introduction of new runtime and unexpected mock behavior.

Patch limits the test execution enviornmnet to Python3.8, while removing
offending autospecced mocks from unit tests.

Closes-Bug: #1982750

Signed-off-by: Jiri Podivin <jpodivin@redhat.com>
Change-Id: I67e7e594cb1aa4f6043c1ca1869828efc7f119b5
2022-07-27 08:01:21 +00:00

195 lines
6.0 KiB
Python

# -*- coding: utf-8 -*-
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""
test_vf_validation_stdout
----------------------------------
Tests for `vf_validation_stdout` callback plugin.
"""
import re
try:
from unittest import mock
except ImportError:
import mock
from oslotest import base
from validations_libs.callback_plugins import vf_validation_stdout
from ansible.plugins.callback import CallbackBase
def is_iso_time(time_string):
"""
Checks if string represents valid time in ISO format,
with the default delimiter.
Regex is somewhat convoluted, but general enough to last
at least until the 9999 AD.
Returns:
True if string matches the pattern.
False otherwise.
"""
match = re.match(
r'\d{4}-[01][0-9]-[0-3][0-9]T[0-3][0-9](:[0-5][0-9]){2}\.\d+Z',
time_string)
if match:
return True
else:
return False
class TestValidationStdout(base.BaseTestCase):
"""Tests of validation_stdout callback module.
"""
def setUp(self):
super(TestValidationStdout, self).setUp()
self.module = mock.MagicMock()
def test_callback_instantiation(self):
"""
Verifying that the CallbackModule is instantiated properly.
Test checks presence of CallbackBase in the inheritance chain,
in order to ensure that folowing tests are performed with
the correct assumptions.
"""
callback = vf_validation_stdout.CallbackModule()
self.assertEqual(type(callback).__mro__[1], CallbackBase)
"""
Every ansible callback needs to define variable with name and version.
"""
self.assertIn('CALLBACK_NAME', dir(callback))
self.assertIn('CALLBACK_VERSION', dir(callback))
self.assertEqual(callback.CALLBACK_NAME, 'validation_stdout')
self.assertIsInstance(callback.CALLBACK_VERSION, float)
"""
Additionally, the 'validation_stdout' callback performs several
other operations during instantiation.
"""
self.assertEqual(callback.env, {})
self.assertIsNone(callback.start_time)
"""
Callback time sanity check only verifies general format
of the stored time to be iso format `YYYY-MM-DD HH:MM:SS.mmmmmm`
with 'T' as a separator.
For example: '2020-07-03T13:28:21.224103Z'
"""
self.assertTrue(is_iso_time(callback.current_time))
@mock.patch(
'ansible.playbook.play.Play._uuid',
return_value='bar')
@mock.patch(
'ansible.playbook.play.Play.get_name',
return_value='foo')
@mock.patch('ansible.playbook.play.Play')
def test_new_play(self, mock_play, mock_play_name, mock_play_uuid):
"""
From the callback point of view,
both Play and Task are virtually identical.
Test involving them are therefore also very similar.
"""
callback = vf_validation_stdout.CallbackModule()
callback.env['playbook_name'] = 'fizz'
callback.env['playbook_path'] = 'buzz/fizz'
play_dict = callback._new_play(mock_play)
mock_play_name.assert_called_once()
mock_play_uuid.__str__.called_once()
"""
Callback time sanity check only verifies general format
of the stored time to be iso format `YYYY-MM-DD HH:MM:SS.mmmmmm`
with 'T' as a separator.
For example: '2020-07-03T13:28:21.224103Z'
"""
self.assertTrue(is_iso_time(play_dict['play']['duration']['start']))
self.assertEqual('fizz', play_dict['play']['validation_id'])
self.assertEqual('buzz/fizz', play_dict['play']['validation_path'])
@mock.patch(
'ansible.playbook.task.Task._uuid',
return_value='bar')
@mock.patch(
'ansible.playbook.task.Task.get_name',
return_value='foo')
@mock.patch('ansible.playbook.task.Task')
def test_new_task(self, mock_task, mock_task_name, mock_task_uuid):
"""
From the callback point of view,
both Play and Task are virtually identical.
Test involving them are therefore also very similar.
"""
callback = vf_validation_stdout.CallbackModule()
task_dict = callback._new_task(mock_task)
mock_task_name.assert_called_once()
mock_task_uuid.__str__.assert_called_once()
"""
Callback time sanity check only verifies general format
of the stored time to be iso format `YYYY-MM-DD HH:MM:SS.mmmmmm`
with 'T' as a separator.
For example: '2020-07-03T13:28:21.224103Z'
"""
self.assertTrue(is_iso_time(task_dict['task']['duration']['start']))
def test_val_task(self):
"""
_val_task and _val_task_host methods are virtually identical.
Their tests are too.
"""
task_name = 'foo'
expected_dict = {
'task': {
'name': task_name,
'hosts': {}
}
}
callback = vf_validation_stdout.CallbackModule()
self.assertEqual(
expected_dict,
callback._val_task(task_name=task_name))
def test_val_task_host(self):
"""
_val_task and _val_task_host methods are virtually identical.
Their tests are too.
"""
task_name = 'foo'
expected_dict = {
'task': {
'name': task_name,
'hosts': {}
}
}
callback = vf_validation_stdout.CallbackModule()
self.assertEqual(
expected_dict,
callback._val_task_host(task_name=task_name))