Browse Source

Retrieve n latest validation results

New optional parameter for the CLI limiting
number of validation results returned by history subcommand.

Number of validations shown will be limited to 15
if the `--limit` arg is passed to the command.

Behavior without the `--limit` remains the same.

Resolves: rhbz#1944872

Signed-off-by: Jiri Podivin <jpodivin@redhat.com>
Change-Id: Ie79062e85351ed545c33001866773bf38fdf8517
changes/02/788902/10
Jiri Podivin 2 months ago
parent
commit
2932967b9f
3 changed files with 94 additions and 3 deletions
  1. +29
    -1
      validations_libs/cli/history.py
  2. +41
    -0
      validations_libs/tests/test_validation_actions.py
  3. +24
    -2
      validations_libs/validation_actions.py

+ 29
- 1
validations_libs/cli/history.py View File

@ -17,6 +17,7 @@
import json
import os
import sys
from argparse import ArgumentError
from cliff.command import Command
from cliff.lister import Lister
@ -36,6 +37,17 @@ class ListHistory(Lister):
metavar="<validation>",
type=str,
help='Display execution history for a validation')
parser.add_argument('--limit',
dest='history_limit',
type=int,
nargs='?',
const=15,
default=None,
help=(
'Display <n> most recent '
'runs of the selected <validation>. '
'<n> must be > 0\n'
'Default limit is set to 15.'))
parser.add_argument('--validation-log-dir', dest='validation_log_dir',
default=constants.VALIDATIONS_LOG_BASEDIR,
help=("Path where the validation log files "
@ -43,8 +55,24 @@ class ListHistory(Lister):
return parser
def take_action(self, parsed_args):
if parsed_args.history_limit:
if parsed_args.history_limit < 1:
raise ArgumentError(
(
"Number <n> of the most recent runs must be > 0. "
"You have provided {}").format(
parsed_args.history_limit))
self.app.LOG.info(
"Limiting output to last {} validations!".format(
parsed_args.history_limit))
else:
self.app.LOG.warning(
"Showing results of all validations since the beginning of time!"
)
actions = ValidationActions(parsed_args.validation_log_dir)
return actions.show_history(parsed_args.validation)
return actions.show_history(
validation_ids=parsed_args.validation,
history_limit=parsed_args.history_limit)
class GetHistory(Command):


+ 41
- 0
validations_libs/tests/test_validation_actions.py View File

@ -368,6 +368,47 @@ class TestValidationActions(TestCase):
'2019-11-25T13:40:14.404623Z',
'0:00:03.753')])
@mock.patch('os.stat')
@mock.patch('validations_libs.validation_logs.ValidationLogs.'
'get_all_logfiles',
return_value=[
'/tmp/123_foo_2020-03-30T13:17:22.447857Z.json',
'/tmp/123_bar_2020-03-05T13:17:22.447857Z.json'])
@mock.patch('json.load',
return_value=fakes.VALIDATIONS_LOGS_CONTENTS_LIST[0])
@mock.patch('six.moves.builtins.open')
def test_show_history_most_recent(self, mock_open, mock_load,
mock_get_log, mock_stat):
first_validation = mock.MagicMock()
second_validation = mock.MagicMock()
first_validation.st_mtime = 5
second_validation.st_mtime = 7
validations = {
'/tmp/123_foo_2020-03-30T13:17:22.447857Z.json': first_validation,
'/tmp/123_bar_2020-03-05T13:17:22.447857Z.json': second_validation
}
def _generator(x=None):
if x:
return validations[x]
return first_validation
mock_stat.side_effect = _generator
v_actions = ValidationActions()
col, values = v_actions.show_history(history_limit=1)
self.assertEqual(col, ('UUID', 'Validations',
'Status', 'Execution at',
'Duration'))
self.assertEqual(values, [('008886df-d297-1eaa-2a74-000000000008',
'512e', 'PASSED',
'2019-11-25T13:40:14.404623Z',
'0:00:03.753')])
@mock.patch('validations_libs.validation_logs.ValidationLogs.'
'get_logfile_by_validation',
return_value=['/tmp/123_foo_2020-03-30T13:17:22.447857Z.json'])


+ 24
- 2
validations_libs/validation_actions.py View File

@ -203,6 +203,19 @@ class ValidationActions(object):
return None, _hosts
return playbook, limit_hosts
def _retrieve_latest_results(self, logs, history_limit):
"""Retrieve the most recent validation results.
Previously retrieved logs are sorted in ascending order,
with the last time the file was modified serving as a key.
Finally we take the last `n` logs, where `n` == `history_limit`
and return them while discarding the time information.
"""
logs = sorted(
[(os.stat(path).st_mtime, path) for path in logs],
key=lambda path: path[0])
return [path[1] for path in logs[-history_limit:]]
def run_validations(self, validation_name=None, inventory='localhost',
group=None, extra_vars=None, validations_dir=None,
extra_env_vars=None, ansible_cfg=None, quiet=True,
@ -500,7 +513,8 @@ class ValidationActions(object):
return params
def show_history(self, validation_ids=None, extension='json',
log_path=constants.VALIDATIONS_LOG_BASEDIR):
log_path=constants.VALIDATIONS_LOG_BASEDIR,
history_limit=None):
"""Return validation executions history
:param validation_ids: The validation ids
@ -509,6 +523,9 @@ class ValidationActions(object):
:type extension: ``string``
:param log_path: The absolute path of the validations logs directory
:type log_path: ``string``
:param history_limit: The number of most recent history logs
to be displayed.
:type history_limit: ``int``
:return: Returns the information about the validation executions
history
@ -559,10 +576,15 @@ class ValidationActions(object):
validation_ids = [validation_ids]
logs = []
for validation_id in validation_ids:
logs.extend(vlogs.get_logfile_by_validation(validation_id))
logs.extend(
vlogs.get_logfile_by_validation(
validation_id))
else:
logs = vlogs.get_all_logfiles(extension)
if history_limit and history_limit < len(logs):
logs = self._retrieve_latest_results(logs, history_limit)
values = []
column_name = ('UUID', 'Validations',
'Status', 'Execution at',


Loading…
Cancel
Save