1#!/usr/bin/env python
2#
3# Copyright (C) 2017 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#      http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17"""A tool to generate TradeFed test config file.
18"""
19
20import os
21import shutil
22import sys
23from xml.dom.minidom import parse
24
25ATTRIBUTE_LABEL = 'android:label'
26ATTRIBUTE_RUNNER = 'android:name'
27ATTRIBUTE_PACKAGE = 'package'
28
29PLACEHOLDER_LABEL = '{LABEL}'
30PLACEHOLDER_EXTRA_CONFIGS = '{EXTRA_CONFIGS}'
31PLACEHOLDER_MODULE = '{MODULE}'
32PLACEHOLDER_PACKAGE = '{PACKAGE}'
33PLACEHOLDER_RUNNER = '{RUNNER}'
34PLACEHOLDER_TEST_TYPE = '{TEST_TYPE}'
35
36
37def main(argv):
38  """Entry point of auto_gen_test_config.
39
40  Args:
41    argv: A list of arguments.
42  Returns:
43    0 if no error, otherwise 1.
44  """
45  if len(argv) != 4 and len(argv) != 6:
46    sys.stderr.write(
47        'Invalid arguments. The script requires 4 arguments for file paths: '
48        'target_config android_manifest empty_config '
49        'instrumentation_test_config_template '
50        'and 2 optional arguments for extra configs: '
51        '--extra-configs \'EXTRA_CONFIGS\'.\n')
52    return 1
53
54  target_config = argv[0]
55  android_manifest = argv[1]
56  empty_config = argv[2]
57  instrumentation_test_config_template = argv[3]
58  extra_configs = '\n'.join(argv[5].split('\\n')) if len(argv) == 6 else ''
59
60  manifest = parse(android_manifest)
61  instrumentation_elements = manifest.getElementsByTagName('instrumentation')
62  manifest_elements = manifest.getElementsByTagName('manifest')
63  if len(instrumentation_elements) != 1 or len(manifest_elements) != 1:
64    # Failed to locate instrumentation or manifest element in AndroidManifest.
65    # file. Empty test config file will be created.
66    shutil.copyfile(empty_config, target_config)
67    return 0
68
69  module = os.path.splitext(os.path.basename(target_config))[0]
70  instrumentation = instrumentation_elements[0]
71  manifest = manifest_elements[0]
72  if instrumentation.attributes.has_key(ATTRIBUTE_LABEL):
73    label = instrumentation.attributes[ATTRIBUTE_LABEL].value
74  else:
75    label = module
76  runner = instrumentation.attributes[ATTRIBUTE_RUNNER].value
77  package = manifest.attributes[ATTRIBUTE_PACKAGE].value
78  test_type = ('InstrumentationTest'
79               if runner.endswith('.InstrumentationTestRunner')
80               else 'AndroidJUnitTest')
81
82  with open(instrumentation_test_config_template) as template:
83    config = template.read()
84    config = config.replace(PLACEHOLDER_LABEL, label)
85    config = config.replace(PLACEHOLDER_MODULE, module)
86    config = config.replace(PLACEHOLDER_PACKAGE, package)
87    config = config.replace(PLACEHOLDER_TEST_TYPE, test_type)
88    config = config.replace(PLACEHOLDER_EXTRA_CONFIGS, extra_configs)
89    config = config.replace(PLACEHOLDER_RUNNER, runner)
90    with open(target_config, 'w') as config_file:
91      config_file.write(config)
92  return 0
93
94if __name__ == '__main__':
95  sys.exit(main(sys.argv[1:]))
96