Merge "add spinner to highlight progress"
This commit is contained in:
commit
d1899b71ba
|
@ -18,6 +18,9 @@ import json
|
|||
import logging
|
||||
from prettytable import PrettyTable
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
import threading
|
||||
import yaml
|
||||
|
||||
try:
|
||||
|
@ -110,3 +113,38 @@ def read_extra_vars_file(extra_vars_file):
|
|||
"The extra_vars file must be properly formatted YAML/JSON."
|
||||
"Details: {}.").format(error)
|
||||
raise RuntimeError(error_msg)
|
||||
|
||||
|
||||
class Spinner(object):
|
||||
"""Animated spinner to indicate activity during processing"""
|
||||
busy = False
|
||||
delay = 0.1
|
||||
|
||||
@staticmethod
|
||||
def spinning_cursor():
|
||||
while 1:
|
||||
for cursor in '|/-\\':
|
||||
yield cursor
|
||||
|
||||
def __init__(self, delay=None):
|
||||
self.spinner_generator = self.spinning_cursor()
|
||||
if delay and float(delay):
|
||||
self.delay = delay
|
||||
|
||||
def spinner_task(self):
|
||||
while self.busy:
|
||||
sys.stdout.write(next(self.spinner_generator))
|
||||
sys.stdout.flush()
|
||||
time.sleep(self.delay)
|
||||
sys.stdout.write('\b')
|
||||
sys.stdout.flush()
|
||||
|
||||
def __enter__(self):
|
||||
self.busy = True
|
||||
threading.Thread(target=self.spinner_task).start()
|
||||
|
||||
def __exit__(self, exception, value, tb):
|
||||
self.busy = False
|
||||
time.sleep(self.delay)
|
||||
if exception is not None:
|
||||
return False
|
||||
|
|
|
@ -273,6 +273,58 @@ class TestValidationActions(TestCase):
|
|||
validations_dir='/tmp/foo')
|
||||
self.assertEqual(run_return, expected_run_return)
|
||||
|
||||
@mock.patch('validations_libs.ansible.Ansible._playbook_check',
|
||||
side_effect=RuntimeError)
|
||||
@mock.patch('validations_libs.utils.os.makedirs')
|
||||
@mock.patch('validations_libs.utils.os.access', return_value=True)
|
||||
@mock.patch('validations_libs.utils.os.path.exists', return_value=True)
|
||||
@mock.patch('validations_libs.utils.parse_all_validations_on_disk')
|
||||
def test_spinner_exception_failure_condition(self, mock_validation_dir,
|
||||
mock_exists, mock_access,
|
||||
mock_makedirs,
|
||||
mock_playbook_check):
|
||||
|
||||
mock_validation_dir.return_value = [{
|
||||
'description': 'My Validation One Description',
|
||||
'groups': ['prep', 'pre-deployment'],
|
||||
'id': 'foo',
|
||||
'name': 'My Validition One Name',
|
||||
'parameters': {}}]
|
||||
playbook = ['fake.yaml']
|
||||
inventory = 'tmp/inventory.yaml'
|
||||
|
||||
run = ValidationActions()
|
||||
|
||||
self.assertRaises(RuntimeError, run.run_validations, playbook,
|
||||
inventory, group=fakes.GROUPS_LIST,
|
||||
validations_dir='/tmp/foo')
|
||||
|
||||
@mock.patch('validations_libs.ansible.Ansible._playbook_check',
|
||||
side_effect=RuntimeError)
|
||||
@mock.patch('validations_libs.utils.os.makedirs')
|
||||
@mock.patch('validations_libs.utils.os.access', return_value=True)
|
||||
@mock.patch('validations_libs.utils.os.path.exists', return_value=True)
|
||||
@mock.patch('validations_libs.utils.parse_all_validations_on_disk')
|
||||
@mock.patch('sys.__stdin__.isatty', return_value=True)
|
||||
def test_spinner_forced_run(self, mock_stdin_isatty, mock_validation_dir,
|
||||
mock_exists, mock_access, mock_makedirs,
|
||||
mock_playbook_check):
|
||||
|
||||
mock_validation_dir.return_value = [{
|
||||
'description': 'My Validation One Description',
|
||||
'groups': ['prep', 'pre-deployment'],
|
||||
'id': 'foo',
|
||||
'name': 'My Validition One Name',
|
||||
'parameters': {}}]
|
||||
playbook = ['fake.yaml']
|
||||
inventory = 'tmp/inventory.yaml'
|
||||
|
||||
run = ValidationActions()
|
||||
|
||||
self.assertRaises(RuntimeError, run.run_validations, playbook,
|
||||
inventory, group=fakes.GROUPS_LIST,
|
||||
validations_dir='/tmp/foo')
|
||||
|
||||
@mock.patch('validations_libs.utils.get_validations_playbook',
|
||||
return_value=[])
|
||||
def test_validation_run_no_validation(self, mock_get_val):
|
||||
|
|
|
@ -14,11 +14,13 @@
|
|||
#
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import yaml
|
||||
|
||||
from validations_libs.ansible import Ansible as v_ansible
|
||||
from validations_libs.group import Group
|
||||
from validations_libs.cli.common import Spinner
|
||||
from validations_libs.validation_logs import ValidationLogs, ValidationLog
|
||||
from validations_libs import constants
|
||||
from validations_libs import utils as v_utils
|
||||
|
@ -374,26 +376,49 @@ class ValidationActions(object):
|
|||
validation_uuid, artifacts_dir = v_utils.create_artifacts_dir(
|
||||
log_path=log_path, prefix=os.path.basename(playbook))
|
||||
run_ansible = v_ansible(validation_uuid)
|
||||
_playbook, _rc, _status = run_ansible.run(
|
||||
workdir=artifacts_dir,
|
||||
playbook=playbook,
|
||||
base_dir=base_dir,
|
||||
playbook_dir=validations_dir,
|
||||
parallel_run=True,
|
||||
inventory=inventory,
|
||||
output_callback=output_callback,
|
||||
callback_whitelist=callback_whitelist,
|
||||
quiet=quiet,
|
||||
extra_vars=extra_vars,
|
||||
limit_hosts=_hosts,
|
||||
extra_env_variables=extra_env_vars,
|
||||
ansible_cfg=ansible_cfg,
|
||||
gathering_policy='explicit',
|
||||
ansible_artifact_path=artifacts_dir,
|
||||
log_path=log_path,
|
||||
run_async=run_async,
|
||||
python_interpreter=python_interpreter,
|
||||
ssh_user=ssh_user)
|
||||
if sys.__stdin__.isatty():
|
||||
with Spinner():
|
||||
_playbook, _rc, _status = run_ansible.run(
|
||||
workdir=artifacts_dir,
|
||||
playbook=playbook,
|
||||
base_dir=base_dir,
|
||||
playbook_dir=validations_dir,
|
||||
parallel_run=True,
|
||||
inventory=inventory,
|
||||
output_callback=output_callback,
|
||||
callback_whitelist=callback_whitelist,
|
||||
quiet=quiet,
|
||||
extra_vars=extra_vars,
|
||||
limit_hosts=_hosts,
|
||||
extra_env_variables=extra_env_vars,
|
||||
ansible_cfg=ansible_cfg,
|
||||
gathering_policy='explicit',
|
||||
ansible_artifact_path=artifacts_dir,
|
||||
log_path=log_path,
|
||||
run_async=run_async,
|
||||
python_interpreter=python_interpreter,
|
||||
ssh_user=ssh_user)
|
||||
else:
|
||||
_playbook, _rc, _status = run_ansible.run(
|
||||
workdir=artifacts_dir,
|
||||
playbook=playbook,
|
||||
base_dir=base_dir,
|
||||
playbook_dir=validations_dir,
|
||||
parallel_run=True,
|
||||
inventory=inventory,
|
||||
output_callback=output_callback,
|
||||
callback_whitelist=callback_whitelist,
|
||||
quiet=quiet,
|
||||
extra_vars=extra_vars,
|
||||
limit_hosts=_hosts,
|
||||
extra_env_variables=extra_env_vars,
|
||||
ansible_cfg=ansible_cfg,
|
||||
gathering_policy='explicit',
|
||||
ansible_artifact_path=artifacts_dir,
|
||||
log_path=log_path,
|
||||
run_async=run_async,
|
||||
python_interpreter=python_interpreter,
|
||||
ssh_user=ssh_user)
|
||||
results.append({'playbook': _playbook,
|
||||
'rc_code': _rc,
|
||||
'status': _status,
|
||||
|
|
Loading…
Reference in New Issue