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