• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/python
2
3# Copyright (C) 2009 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"""Module for generating CTS test descriptions and test plans."""
18
19import glob
20import os
21import re
22import subprocess
23import sys
24import xml.dom.minidom as dom
25from cts import tools
26from multiprocessing import Pool
27
28def GetSubDirectories(root):
29  """Return all directories under the given root directory."""
30  return [x for x in os.listdir(root) if os.path.isdir(os.path.join(root, x))]
31
32
33def GetMakeFileVars(makefile_path):
34  """Extracts variable definitions from the given make file.
35
36  Args:
37    makefile_path: Path to the make file.
38
39  Returns:
40    A dictionary mapping variable names to their assigned value.
41  """
42  result = {}
43  pattern = re.compile(r'^\s*([^:#=\s]+)\s*:=\s*(.*?[^\\])$', re.MULTILINE + re.DOTALL)
44  stream = open(makefile_path, 'r')
45  content = stream.read()
46  for match in pattern.finditer(content):
47    result[match.group(1)] = match.group(2)
48  stream.close()
49  return result
50
51
52class CtsBuilder(object):
53  """Main class for generating test descriptions and test plans."""
54
55  def __init__(self, argv):
56    """Initialize the CtsBuilder from command line arguments."""
57    if not len(argv) == 6:
58      print 'Usage: %s <testRoot> <ctsOutputDir> <tempDir> <androidRootDir> <docletPath>' % argv[0]
59      print ''
60      print 'testRoot:       Directory under which to search for CTS tests.'
61      print 'ctsOutputDir:   Directory in which the CTS repository should be created.'
62      print 'tempDir:        Directory to use for storing temporary files.'
63      print 'androidRootDir: Root directory of the Android source tree.'
64      print 'docletPath:     Class path where the DescriptionGenerator doclet can be found.'
65      sys.exit(1)
66    self.test_root = sys.argv[1]
67    self.out_dir = sys.argv[2]
68    self.temp_dir = sys.argv[3]
69    self.android_root = sys.argv[4]
70    self.doclet_path = sys.argv[5]
71
72    self.test_repository = os.path.join(self.out_dir, 'repository/testcases')
73    self.plan_repository = os.path.join(self.out_dir, 'repository/plans')
74
75  def GenerateTestDescriptions(self):
76    """Generate test descriptions for all packages."""
77    pool = Pool(processes=2)
78
79    # individually generate descriptions not following conventions
80    pool.apply_async(GenerateSignatureCheckDescription, [self.test_repository])
81
82    # generate test descriptions for android tests
83    results = []
84    pool.close()
85    pool.join()
86    return sum(map(lambda result: result.get(), results))
87
88  def __WritePlan(self, plan, plan_name):
89    print 'Generating test plan %s' % plan_name
90    plan.Write(os.path.join(self.plan_repository, plan_name + '.xml'))
91
92  def GenerateTestPlans(self):
93    """Generate default test plans."""
94    # TODO: Instead of hard-coding the plans here, use a configuration file,
95    # such as test_defs.xml
96    packages = []
97    descriptions = sorted(glob.glob(os.path.join(self.test_repository, '*.xml')))
98    for description in descriptions:
99      doc = tools.XmlFile(description)
100      packages.append(doc.GetAttr('TestPackage', 'appPackageName'))
101
102    plan = tools.TestPlan(packages)
103    plan.Exclude('android\.performance.*')
104    self.__WritePlan(plan, 'CTS')
105    self.__WritePlan(plan, 'CTS-TF')
106
107    plan.Exclude(r'android\.tests\.sigtest')
108    plan.Exclude(r'android\.core.*')
109    self.__WritePlan(plan, 'Android')
110
111    plan = tools.TestPlan(packages)
112    plan.Include(r'android\.core\.tests.*')
113    self.__WritePlan(plan, 'Java')
114
115    plan = tools.TestPlan(packages)
116    plan.Include(r'android\.core\.vm-tests-tf')
117    self.__WritePlan(plan, 'VM-TF')
118
119    plan = tools.TestPlan(packages)
120    plan.Include(r'android\.tests\.sigtest')
121    self.__WritePlan(plan, 'Signature')
122
123    plan = tools.TestPlan(packages)
124    plan.Include(r'android\.tests\.appsecurity')
125    self.__WritePlan(plan, 'AppSecurity')
126
127def LogGenerateDescription(name):
128  print 'Generating test description for package %s' % name
129
130def GenerateSignatureCheckDescription(test_repository):
131  """Generate the test description for the signature check."""
132  LogGenerateDescription('android.tests.sigtest')
133  package = tools.TestPackage('SignatureTest', 'android.tests.sigtest')
134  package.AddAttribute('appNameSpace', 'android.tests.sigtest')
135  package.AddAttribute('signatureCheck', 'true')
136  package.AddAttribute('runner', '.InstrumentationRunner')
137  package.AddTest('android.tests.sigtest.SignatureTest.signatureTest')
138  description = open(os.path.join(test_repository, 'SignatureTest.xml'), 'w')
139  package.WriteDescription(description)
140  description.close()
141
142if __name__ == '__main__':
143  builder = CtsBuilder(sys.argv)
144  result = builder.GenerateTestDescriptions()
145  if result != 0:
146    sys.exit(result)
147  builder.GenerateTestPlans()
148