Ejemplo n.º 1
0
 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 = validation_json.CallbackModule()
     self.assertEqual(type(callback).__mro__[1], CallbackBase)
     """
     Every ansible callback needs to define variable with name and version.
     The validation_json plugin also defines CALLBACK_TYPE,
     so we need to check it too.
     """
     self.assertIn('CALLBACK_NAME', dir(callback))
     self.assertIn('CALLBACK_VERSION', dir(callback))
     self.assertIn('CALLBACK_TYPE', dir(callback))
     self.assertEqual(callback.CALLBACK_NAME, 'validation_json')
     self.assertIsInstance(callback.CALLBACK_VERSION, float)
     self.assertEqual(callback.CALLBACK_TYPE, 'aggregate')
     """
     Additionally, the 'validation_json' callback performs several
     other operations during instantiation.
     """
     self.assertEqual(callback.results, [])
     self.assertEqual(callback.simple_results, [])
     self.assertEqual(callback.env, {})
     self.assertIsNone(callback.t0)
     """
     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))
Ejemplo n.º 2
0
 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 = validation_json.CallbackModule()
     self.assertEqual(expected_dict,
                      callback._val_task_host(task_name=task_name))
Ejemplo n.º 3
0
    def test_getattribute_valid_unlisted(self, mock_record_task_result):
        """
        Since the validation_json.CallbackModule defines it's own
        __getattribute__ method, we can't use `dir` to safely check
        the name of attributes individually,
        as dir itself uses the __getattribute__ method.
        Instead we check if the namespace of the CallbackBase class
        is a subset of validation_json.CallbackModule namespace.
        """
        callback = validation_json.CallbackModule()

        listed_names = set(dir(callback))

        self.assertTrue(listed_names.issuperset(set(dir(CallbackBase))))
Ejemplo n.º 4
0
    def test_v2_playbook_on_start(self, mock_loader, mock_path_splitext,
                                  mock_path_basename):

        callback = validation_json.CallbackModule()
        dummy_playbook = Playbook(mock_loader)
        dummy_playbook._basedir = '/bar'
        dummy_playbook._file_name = '/bar/foo.yaml'

        callback.v2_playbook_on_start(dummy_playbook)

        mock_path_basename.assert_called_once_with('/bar/foo.yaml')
        mock_path_splitext.assert_called_once_with('foo.yaml')

        self.assertEqual('foo', callback.env['playbook_name'])
        self.assertEqual('/bar', callback.env['playbook_path'])
Ejemplo n.º 5
0
    def test_getattribute_invalid(self):
        """
        Attempting to call __getattribute__ method with invalid attribute
        name should result in exception.
        """
        callback = validation_json.CallbackModule()

        fake_names = [
            name + 'x' for name in [
                'v2_runner_on_ok', 'v2_runner_on_failed',
                'v2_runner_on_unreachable', 'v2_runner_on_skipped'
            ]
        ]

        for name in fake_names:
            self.assertRaises(AttributeError, callback.__getattribute__, name)
Ejemplo n.º 6
0
    def test_getattribute_valid_listed(self, mock_record_task_result):
        """
        All of the listed attribute names are checked.
        The __getattribute__ method returns a partial,
        the args supplied to it are stored a tuple.
        """
        listed_names = [
            'v2_runner_on_ok', 'v2_runner_on_failed',
            'v2_runner_on_unreachable', 'v2_runner_on_skipped'
        ]

        callback = validation_json.CallbackModule()

        for name in listed_names:
            attribute = callback.__getattribute__(name)
            self.assertEqual(({name.split('_')[-1]: True}, ), attribute.args)
Ejemplo n.º 7
0
 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 = validation_json.CallbackModule()
     task_dict = callback._new_task(mock_task)
     mock_task_name.assert_called_once()
     mock_task_uuid.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']))
Ejemplo n.º 8
0
    def test_v2_playbook_on_stats(self, mock_open, mock_json_dumps):

        results = [{'play': {'id': 'fizz'}}]

        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

        output = {
            'plays': results,
            'stats': {
                'foohost': {
                    'ok': 0,
                    'failures': 0,
                    'unreachable': 0,
                    'changed': 0,
                    'skipped': 0,
                    'rescued': 0,
                    'ignored': 0
                }
            },
            'validation_output': results
        }

        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_stats(dummy_stats)
        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')
Ejemplo n.º 9
0
    def test_record_task_result(self, mock_secondsToStr, mock_time):
        """
        Method CallbackModule._record_task_result works mostly with dicts
        and performs few other calls. Therefore the assertions are placed
        on calls to those few functions and the operations performed
        with supplied MagicMock objects.
        """
        mock_on_info = mock.MagicMock()
        mock_result = mock.MagicMock()
        """
        As we have just initialized the callback, we can't expect it to have
        populated properties as the method expects.
        Following lines explicitly set all necessary properties.
        """
        callback_results = [{
            'play': {
                'id': 'fizz',
                'duration': {}
            },
            'tasks': [{
                'hosts': {}
            }]
        }]

        callback_simple_results = [{'task': {'hosts': {}}}]

        callback = validation_json.CallbackModule()
        callback.results = callback_results
        callback.simple_results = callback_simple_results
        callback.t0 = 0

        callback._record_task_result(mock_on_info, mock_result)

        mock_time.assert_called()
        mock_secondsToStr.assert_called_once_with(99.99)
        """
        Asserting on set lets us check if the method accessed all expected
        properties of our MagicMock, while also leaving space for
        possible future expansion.
        """
        self.assertGreaterEqual(set(dir(mock_result)),
                                set(['_result', '_host', '_task']))
Ejemplo n.º 10
0
 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 = validation_json.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.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(play_dict['play']['duration']['start']))
     self.assertEqual('fizz', play_dict['play']['validation_id'])
     self.assertEqual('buzz/fizz', play_dict['play']['validation_path'])
Ejemplo n.º 11
0
 def test_v2_playbook_on_handler_task_start(self, mock_task, mock_new_task):
     """
     CallbackModule methods v2_playbook_on_task_start
     and v2_playbook_on_handler_task_start are virtually identical.
     The only exception being is_conditional parameter
     of the v2_playbook_on_task_start, which isn't used by the method
     at all.
     Therefore both of their tests share documentation.
     In order to verify methods functionality we first append
     a dummy result at the end of CallbackModule.result list.
     Simple dictionary is more than sufficient.
     """
     callback = validation_json.CallbackModule()
     callback.results.append({'fizz': 'buzz', 'tasks': []})
     callback.v2_playbook_on_handler_task_start(mock_task)
     """
     First we verify that CallbackModule._new_task method was indeed
     called with supplied arguments.
     Afterwards we verify that the supplied dummy task is present
     in first (and in our case only) element of CallbackModule.result list.
     """
     mock_new_task.assert_called_once_with(callback, mock_task)
     self.assertIn({'task': {'host': 'foo'}}, callback.results[0]['tasks'])
Ejemplo n.º 12
0
    def test_v2_playbook_on_play_start(self, mock_play, mock_new_play):
        callback = validation_json.CallbackModule()
        callback.v2_playbook_on_play_start(mock_play)

        self.assertIn({'play': {'host': 'foo'}}, callback.results)