Revert "Revert "Provide options for summary output in text and json format. Fixes #57.""

This commit is contained in:
Ross Gardler 2017-09-08 07:08:58 -07:00 коммит произвёл GitHub
Родитель bb6fd99bcb
Коммит abdbb3d237
4 изменённых файлов: 80 добавлений и 15 удалений

25
cli.py
Просмотреть файл

@ -18,6 +18,7 @@ PEXPECT_CONTINUATION_PROMPT = u'[PEXPECT_PROMPT+'
class Ui(object): class Ui(object):
_shell = None _shell = None
demo = None demo = None
execution_log = ""
def __init__(self): def __init__(self):
pass pass
@ -39,7 +40,7 @@ class Ui(object):
def heading(self, text): def heading(self, text):
"""Display a heading""" """Display a heading"""
self.display(text, colorama.Fore.CYAN + colorama.Style.BRIGHT, True) self.display(text, colorama.Fore.CYAN + colorama.Style.BRIGHT, True)
print() self.new_line()
def description(self, text): def description(self, text):
"""Display some descriptive text. Usually this is text from the demo """Display some descriptive text. Usually this is text from the demo
@ -84,10 +85,10 @@ to select it) and a title (to be displayed).
def new_line(self): def new_line(self):
"""Move to the next line""" """Move to the next line"""
print() self.display("", colorama.Fore.WHITE, True)
def horizontal_rule(self): def horizontal_rule(self):
print("\n\n============================================\n\n") self.display("\n\n============================================\n\n", colorama.Fore.WHITE)
def clear(self): def clear(self):
"""Clears the screen ready for anew section of the script.""" """Clears the screen ready for anew section of the script."""
@ -102,12 +103,22 @@ to select it) and a title (to be displayed).
new_line is set to True. new_line is set to True.
""" """
print(color, end="") self.execution_log += color
print(text, end="", flush=True) if self.demo.output_format == "log":
print(color, end="")
self.execution_log += text
if self.demo.output_format == "log":
print(text, end="", flush=True)
if new_line: if new_line:
print(colorama.Style.RESET_ALL) self.execution_log += colorama.Style.RESET_ALL + "\n"
if self.demo.output_format == "log":
print(colorama.Style.RESET_ALL)
else: else:
print(colorama.Style.RESET_ALL, end="") self.execution_log += colorama.Style.RESET_ALL
if self.demo.output_format == "log":
print(colorama.Style.RESET_ALL, end="")
def log(self, level, text): def log(self, level, text):
if config.is_debug: if config.is_debug:

59
demo.py
Просмотреть файл

@ -1,7 +1,9 @@
# This class represents a Demo to be executed in SimDem. # This class represents a Demo to be executed in SimDem.
import datetime
import difflib import difflib
from itertools import tee, islice, zip_longest from itertools import tee, islice, zip_longest
import json
import os import os
import re import re
import sys import sys
@ -17,7 +19,7 @@ def get_next(some_iterable, window=1):
return zip_longest(items, nexts) return zip_longest(items, nexts)
class Demo(object): class Demo(object):
def __init__(self, is_running_in_docker, script_dir="demo_scripts", filename="README.md", is_simulation=True, is_automated=False, is_testing=False, is_fast_fail=True,is_learning = False, parent_script_dir = None, is_prep_only = False, is_prerequisite = False): def __init__(self, is_running_in_docker, script_dir="demo_scripts", filename="README.md", is_simulation=True, is_automated=False, is_testing=False, is_fast_fail=True,is_learning = False, parent_script_dir = None, is_prep_only = False, is_prerequisite = False, output_format="log"):
""" """
is_running_in_docker should be set to true is we are running inside a Docker container is_running_in_docker should be set to true is we are running inside a Docker container
script_dir is the location to look for scripts script_dir is the location to look for scripts
@ -51,6 +53,7 @@ class Demo(object):
else: else:
self.env = Environment(self.script_dir, is_test = self.is_testing) self.env = Environment(self.script_dir, is_test = self.is_testing)
self.is_prerequisite = is_prerequisite self.is_prerequisite = is_prerequisite
self.output_format = output_format
def set_script_dir(self, script_dir, base_dir = None): def set_script_dir(self, script_dir, base_dir = None):
if base_dir is not None and not base_dir.endswith(os.sep): if base_dir is not None and not base_dir.endswith(os.sep):
@ -220,7 +223,7 @@ class Demo(object):
if failed_tests > 0: if failed_tests > 0:
self.ui.instruction("View failure reports in context in the above output.") self.ui.instruction("View failure reports in context in the above output.")
if self.is_fast_fail: if self.is_fast_fail:
sys.exit(str(failed_tests) + " test failures. " + str(passed_tests) + " test passes.") self.output_results(False)
if not self.is_simulation and not self.is_testing and not self.is_prep_only: if not self.is_simulation and not self.is_testing and not self.is_prep_only:
next_steps = [] next_steps = []
@ -254,8 +257,51 @@ class Demo(object):
self.filename = match.groups()[1] self.filename = match.groups()[1]
self.run(self.mode) self.run(self.mode)
if failed_tests > 0: self.output_results(failed_tests == 0)
sys.exit("Test failures: " + str(failed_tests) + " test failures. " + str(passed_tests) + " test passes.")
def output_results(self, is_success, failure_message = "UNDEFINED FAILURE MESSAGE"):
"""Output the results of the run in the format requested. Note that
if `--output` is `log` (or undefined) we will have been outputing the
logs throughout execution."""
timestamp = datetime.datetime.utcnow().strftime("%Y%m%d - %H:%M")
test_name = self.script_dir
test_type = "SimDem"
resource_group = self.env.get("SIMDEM_RESOURCE_GROUP")
region = self.env.get("SIMDEM_LOCATION")
orchestrator = self.env.get("SIMDEM_ORCHESTRATOR")
if self.output_format == "summary":
if is_success:
result = "Succeful test"
else:
result = "Failed test:\t" + failure_message
result += "\nTime (UTC):\t" + timestamp
result += "\nTest Name:\t" + test_name
result += "\nOrchestrator:\t" + orchestrator
result += "\nResource Group:\t" + resource_group
result += "\nRegion:\t\t" + region
result += "\n\n"
elif self.output_format == "json":
meta = {
"TimeStampUTC": timestamp,
"TestName": test_name,
"TestType": test_type,
"ResourceGroup": resource_group,
"Region": region,
"Orchestrator": orchestrator,
"Success": success,
"FailureStr": failure_message
}
result = json.dumps(meta)
elif self.output_format != "log":
sys.exit("Invalid option for '--output', see 'simdem --help' for available options")
else:
result = "" # logs were output during execution
print(result)
if not is_success:
sys.exit("Failed with: " + failure_message)
def classify_lines(self): def classify_lines(self):
lines = None lines = None
@ -402,6 +448,9 @@ class Demo(object):
return classified_lines return classified_lines
def execute(self, lines): def execute(self, lines):
"""Execute the script found in the lines. Return the number of failed
tests and the number of passed tests."""
source_file_directory = None source_file_directory = None
is_first_line = True is_first_line = True
in_results = False in_results = False
@ -531,7 +580,7 @@ class Demo(object):
self.ui.new_para() self.ui.new_para()
self.ui.log("debug", "Execute prerequisite step in " + filename + " in " + new_dir) self.ui.log("debug", "Execute prerequisite step in " + filename + " in " + new_dir)
demo = Demo(self.is_docker, new_dir, filename, self.is_simulation, self.is_automated, self.is_testing, self.is_fast_fail, self.is_learning, self.script_dir, is_prerequisite = True); demo = Demo(self.is_docker, new_dir, filename, self.is_simulation, self.is_automated, self.is_testing, self.is_fast_fail, self.is_learning, self.script_dir, is_prerequisite = True, output_format=self.output_format)
demo.mode = self.mode demo.mode = self.mode
demo.set_ui(self.ui) demo.set_ui(self.ui)
demo.run_if_validation_fails(self.mode) demo.run_if_validation_fails(self.mode)

Просмотреть файл

@ -133,7 +133,10 @@ class Environment(object):
"""Returns a either a value for a supplied key or, if key is None, a """Returns a either a value for a supplied key or, if key is None, a
dictionary containing the current environment""" dictionary containing the current environment"""
if key: if key:
return self.env[key] if key not in self.env:
return "UNDEFINED"
else:
return self.env[key]
else: else:
return self.env return self.env

Просмотреть файл

@ -74,6 +74,8 @@ def main():
help="Turn on debug logging by setting to True.") help="Turn on debug logging by setting to True.")
p.add_option('--webui', '-w', default="False", p.add_option('--webui', '-w', default="False",
help="If set to anything other than False will interact with the user through a Web UI rather than the CLI.") help="If set to anything other than False will interact with the user through a Web UI rather than the CLI.")
p.add_option('--output', '-o', default="log",
help="Format of the output. The default is `log` which will output all stdout data. Other options are `summary` which provides a summary of the execution status and `json`")
options, arguments = p.parse_args() options, arguments = p.parse_args()
@ -123,7 +125,7 @@ def main():
filename = "README.md" filename = "README.md"
is_docker = os.path.isfile('/.dockerenv') is_docker = os.path.isfile('/.dockerenv')
demo = Demo(is_docker, script_dir, filename, simulate, is_automatic, is_test, is_fast_fail); demo = Demo(is_docker, script_dir, filename, simulate, is_automatic, is_test, is_fast_fail, output_format=options.output);
if options.webui == "False": if options.webui == "False":
ui = Ui() ui = Ui()