#!/usr/bin/env python3 # # Make a web page from a YAML test case file. # import os import sys import yaml import shutil from jinja2 import Environment, FileSystemLoader from argparse import ArgumentParser from parser import parse_format TEMPLATE_DIR="." # This command parses each line of a list and returns a structure of the form # (comment, command, output) to apply the following formatting for the respective # sections: # # pre-conditions: # notes: # expected: # - Start line with '$' for commands. # - Start line with '>' for command output. # - Everything else is a comment. # # run: steps: (only for automated tests) # - Start line with '#' for comments , everything else is a command. # def parse_list(lines, automated_run=False): processed_lines = [] for line in lines: p, c = '', '' sline = line.strip() if not sline: continue if automated_run: if sline[0] == '#': # Remove the '#' with the slice [1:] processed_lines.append((sline[1:], '', '')) else: # Add the '$ ' in the line for the command processed_lines.append(('', '$ '+sline, '')) else: if sline[0] == '$': processed_lines.append(('', sline, '')) elif sline[0] == '>': processed_lines.append(('', '', sline[1:].split('\n'))) else: processed_lines.append((sline, '', '')) return processed_lines def priority_color(priority): return \ (priority == 'low' and 'secondary') or \ (priority == 'medium' and 'info') or \ (priority == 'high' and 'warning') or \ (priority == 'critical' and 'danger') or 'light' def get_template_values(testcase_data): template_values = {} is_automated = False # Mandatory fields metadata = testcase_data.get('metadata') if not metadata: print("Error: missing mandatory field metadata") sys.exit(1) for mv in ['name', 'image-type', 'image-arch', 'type', 'exec-type', 'priority', 'description', 'expected']: value = metadata.get(mv) if value: if mv == 'exec-type' and value == 'automated': is_automated = True if mv == 'expected': template_values.update({ mv : parse_list(value) }) else: # Set also the prority_color if mv == 'priority': template_values.update({ 'priority_color' : priority_color(value) }) template_values.update({ mv.replace('-', '_') : value }) else: print("Error: missing mandatory field", mv) sys.exit(1) run = testcase_data.get('run') if not run: print("Error: missing mandatory field run") sys.exit(1) else: steps = run.get('steps') if not steps: print("Error: missing mandatory field steps for run") sys.exit(1) # 'is_automated' so automated tests steps are parsed differently. template_values.update({ 'run_steps' : parse_list(steps, automated_run=is_automated) }) # No mandatory fields for nm in ['notes', 'format', 'maintainer', 'resources', 'pre-conditions', 'post-conditions']: value = metadata.get(nm) if value: template_values.update({ nm.replace('-', '_') : parse_list(value) if nm in ['notes', 'pre-conditions', 'post-conditions'] else value }) install = testcase_data.get('install') if install: deps = install.get('deps') if not deps: print("Error: missing mandatory field deps for install") sys.exit(1) template_values.update({ 'install_steps' : deps }) # A install.deps directive will always add a preconditions section # to install the required packages using the macro to install packages. template_values.update({ 'packages_list' : ' '.join(deps) }) # Macros variables ostree_preconditions = metadata.get('macro_ostree_preconditions') if ostree_preconditions: template_values.update({ 'pkgname' : ostree_preconditions }) packages_list = metadata.get('macro_install_packages_preconditions') if packages_list: template_values.update({ 'packages_list' : packages_list }) return template_values def generate_test_case(tc_file, directory): try: with open(tc_file) as testcase: tc_data = yaml.safe_load(testcase) except yaml.scanner.ScannerError as e: print("yaml format error:", e) sys.exit(1) # Parse file to detect any syntax error. print("Parsing file", tc_file) parse_format(tc_data) env = Environment(loader=FileSystemLoader([TEMPLATE_DIR])) # Get template from environment and render it. data = env.get_template('templates/index.html').render(get_template_values(tc_data)) filename = os.path.splitext(os.path.basename(tc_file))[0] + ".html" print("Generating test case page", filename) with open(os.path.join(directory, filename), 'w') as html_file: html_file.write(data) if '__main__' == __name__: cli_parser = ArgumentParser(description="make_page") cli_parser.add_argument('-d', '--test-case-dir', help="Directory path for generated test cases") cli_parser.add_argument('yaml_files', help="YAML file or files directory") args = cli_parser.parse_args() directory = '.' if args.test_case_dir: directory = args.test_case_dir try: os.mkdir(directory) except FileExistsError: print("Directory '{}' already exists".format(directory)) except e: print("Error:", e) sys.exit(1) if os.path.isfile(args.yaml_files): generate_test_case(args.yaml_files, directory) else: for root, _, files in os.walk(args.yaml_files): for f in files: tc_file = os.path.join(root, f) if os.path.isfile(tc_file): generate_test_case(tc_file, directory) cssdir = os.path.join(directory, 'css') if not (os.path.exists(cssdir) and os.path.isdir(cssdir)): print("Copying css style to", cssdir) shutil.copytree('css/', cssdir)