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