1#!/usr/bin/python3 2"""Create new scenario test instance from an existing results directory. 3 4This automates creation of regression tests for the results parsers. 5There are 2 primary use cases for this. 6 71) Bug fixing: Parser broke on some input in the field and we want 8to start with a test that operates on that input and fails. We 9then apply fixes to the parser implementation until it passes. 10 112) Regression alarms: We take input from various real scenarios that 12work as expected with the parser. These will be used to ensure 13we do not break the expected functionality of the parser while 14refactoring it. 15 16While much is done automatically, a scenario harness is meant to 17be easily extended and configured once generated. 18""" 19 20from __future__ import absolute_import 21from __future__ import division 22from __future__ import print_function 23 24import optparse, os, shutil, sys 25from os import path 26 27import common 28from autotest_lib.tko.parsers.test import scenario_base 29from autotest_lib.client.common_lib import autotemp 30 31usage = 'usage: %prog [options] results_dirpath scenerios_dirpath' 32parser = optparse.OptionParser(usage=usage) 33parser.add_option( 34 '-n', '--name', 35 help='Name for new scenario instance. Will use dirname if not specified') 36parser.add_option( 37 '-p', '--parser_result_tag', 38 default='v1', 39 help='Storage tag to use for initial parser result.') 40parser.add_option( 41 '-t', '--template_type', 42 default='base', 43 help='Type of unittest module to copy into new scenario.') 44 45 46def main(): 47 (options, args) = parser.parse_args() 48 if len(args) < 2: 49 parser.print_help() 50 sys.exit(1) 51 52 results_dirpath = path.normpath(args[0]) 53 if not path.exists(results_dirpath) or not path.isdir(results_dirpath): 54 print('Invalid results_dirpath:', results_dirpath) 55 parser.print_help() 56 sys.exit(1) 57 58 scenarios_dirpath = path.normpath(args[1]) 59 if not path.exists(scenarios_dirpath) or not path.isdir(scenarios_dirpath): 60 print('Invalid scenarios_dirpath:', scenarios_dirpath) 61 parser.print_help() 62 sys.exit(1) 63 64 results_dirname = path.basename(results_dirpath) 65 # Not everything is a valid python package name, fix if necessary 66 package_dirname = scenario_base.fix_package_dirname( 67 options.name or results_dirname) 68 69 scenario_package_dirpath = path.join( 70 scenarios_dirpath, package_dirname) 71 if path.exists(scenario_package_dirpath): 72 print( 73 'Scenario package already exists at path: %s' % 74 scenario_package_dirpath) 75 parser.print_help() 76 sys.exit(1) 77 78 # Create new scenario package 79 os.mkdir(scenario_package_dirpath) 80 81 # Create tmp_dir 82 tmp_dirpath = autotemp.tempdir(unique_id='new_scenario') 83 copied_dirpath = path.join(tmp_dirpath.name, results_dirname) 84 # Copy results_dir 85 shutil.copytree(results_dirpath, copied_dirpath) 86 87 # scenario_base.sanitize_results_data(copied_dirpath) 88 89 # Launch parser on copied_dirpath, collect emitted test objects. 90 harness = scenario_base.new_parser_harness(copied_dirpath) 91 try: 92 parser_result = harness.execute() 93 except Exception as e: 94 parser_result = e 95 96 scenario_base.store_parser_result( 97 scenario_package_dirpath, parser_result, 98 options.parser_result_tag) 99 100 scenario_base.store_results_dir( 101 scenario_package_dirpath, copied_dirpath) 102 103 scenario_base.write_config( 104 scenario_package_dirpath, 105 status_version=harness.status_version, 106 parser_result_tag=options.parser_result_tag, 107 ) 108 109 scenario_base.install_unittest_module( 110 scenario_package_dirpath, options.template_type) 111 tmp_dirpath.clean() 112 113 114if __name__ == '__main__': 115 main() 116