• 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 or len(argv)==7):
58      print 'Usage: %s <testRoot> <ctsOutputDir> <tempDir> <androidRootDir> <docletPath> [-pts]' % 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      print '-pts:           generate plan for PTS.'
66      sys.exit(1)
67    self.test_root = sys.argv[1]
68    self.out_dir = sys.argv[2]
69    self.temp_dir = sys.argv[3]
70    self.android_root = sys.argv[4]
71    self.doclet_path = sys.argv[5]
72    self.isCts = True
73    if len(argv) ==7 and sys.argv[6] == "-pts":
74      self.isCts = False
75
76    self.test_repository = os.path.join(self.out_dir, 'repository/testcases')
77    self.plan_repository = os.path.join(self.out_dir, 'repository/plans')
78
79  def GenerateTestDescriptions(self):
80    """Generate test descriptions for all packages."""
81    pool = Pool(processes=2)
82
83    # individually generate descriptions not following conventions
84    pool.apply_async(GenerateSignatureCheckDescription, [self.test_repository])
85
86    # generate test descriptions for android tests
87    results = []
88    pool.close()
89    pool.join()
90    return sum(map(lambda result: result.get(), results))
91
92  def __WritePlan(self, plan, plan_name):
93    print 'Generating test plan %s' % plan_name
94    plan.Write(os.path.join(self.plan_repository, plan_name + '.xml'))
95
96  def GenerateTestPlans(self):
97    """Generate default test plans."""
98    # TODO: Instead of hard-coding the plans here, use a configuration file,
99    # such as test_defs.xml
100    packages = []
101    descriptions = sorted(glob.glob(os.path.join(self.test_repository, '*.xml')))
102    for description in descriptions:
103      doc = tools.XmlFile(description)
104      packages.append(doc.GetAttr('TestPackage', 'appPackageName'))
105
106    if not self.isCts: # PTS
107      plan = tools.TestPlan(packages)
108      plan.Include('.*')
109      plan.Exclude(r'android\.tests\.sigtest')
110      self.__WritePlan(plan, 'PTS')
111      return
112
113    plan = tools.TestPlan(packages)
114    plan.Exclude('android\.performance.*')
115    self.__WritePlan(plan, 'CTS')
116    self.__WritePlan(plan, 'CTS-TF')
117
118    plan.Exclude(r'android\.tests\.sigtest')
119    plan.Exclude(r'android\.core.*')
120    self.__WritePlan(plan, 'Android')
121
122    plan = tools.TestPlan(packages)
123    plan.Include(r'android\.core\.tests.*')
124    self.__WritePlan(plan, 'Java')
125
126    plan = tools.TestPlan(packages)
127    plan.Include(r'android\.core\.vm-tests-tf')
128    self.__WritePlan(plan, 'VM-TF')
129
130    plan = tools.TestPlan(packages)
131    plan.Include(r'android\.tests\.sigtest')
132    self.__WritePlan(plan, 'Signature')
133
134    plan = tools.TestPlan(packages)
135    plan.Include(r'android\.tests\.appsecurity')
136    self.__WritePlan(plan, 'AppSecurity')
137
138    # hard-coded white list for PDK plan
139    plan.Exclude('.*')
140    plan.Include('android\.bluetooth')
141    plan.Include('android\.graphics.*')
142    plan.Include('android\.hardware')
143    plan.Include('android\.media.*')
144    plan.Include('android\.net')
145    plan.Include('android\.opengl.*')
146    plan.Include('android\.renderscript')
147    plan.Include('android\.telephony')
148    plan.Include('android\.nativemedia.*')
149    self.__WritePlan(plan, 'PDK')
150
151def LogGenerateDescription(name):
152  print 'Generating test description for package %s' % name
153
154def GenerateSignatureCheckDescription(test_repository):
155  """Generate the test description for the signature check."""
156  LogGenerateDescription('android.tests.sigtest')
157  package = tools.TestPackage('SignatureTest', 'android.tests.sigtest')
158  package.AddAttribute('appNameSpace', 'android.tests.sigtest')
159  package.AddAttribute('signatureCheck', 'true')
160  package.AddAttribute('runner', '.InstrumentationRunner')
161  package.AddTest('android.tests.sigtest.SignatureTest.signatureTest')
162  description = open(os.path.join(test_repository, 'SignatureTest.xml'), 'w')
163  package.WriteDescription(description)
164  description.close()
165
166if __name__ == '__main__':
167  builder = CtsBuilder(sys.argv)
168  if builder.isCts:
169    result = builder.GenerateTestDescriptions()
170    if result != 0:
171      sys.exit(result)
172  builder.GenerateTestPlans()
173
174