зеркало из https://github.com/Azure/simdem.git
Revert "Revert "Provide options for summary output in text and json format. Fixes #57.""
This commit is contained in:
Родитель
bb6fd99bcb
Коммит
abdbb3d237
25
cli.py
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
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
|
||||||
|
|
||||||
|
|
4
main.py
4
main.py
|
@ -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()
|
||||||
|
|
Загрузка…
Ссылка в новой задаче