blob: 6c8959c2e6c07112524a79a4c27eba4ceb170f52 [file] [log] [blame]
Phil Dubachec19a572009-08-21 15:20:13 -07001#!/usr/bin/python
Phil Dubach0d6ef062009-08-12 18:13:16 -07002
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
Brian Muramatsu9157e0a2011-04-05 18:06:15 -070026from multiprocessing import Pool
Phil Dubach0d6ef062009-08-12 18:13:16 -070027
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."""
Keun young Parkd93d0d12013-01-10 14:11:35 -080057 if len(argv) != 6:
58 print 'Usage: %s <testRoot> <ctsOutputDir> <tempDir> <androidRootDir> <docletPath>' % argv[0]
Phil Dubach0d6ef062009-08-12 18:13:16 -070059 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
Phil Dubach0d6ef062009-08-12 18:13:16 -070075 def GenerateTestDescriptions(self):
76 """Generate test descriptions for all packages."""
Brian Muramatsu5df641c2011-12-28 15:46:57 -080077 pool = Pool(processes=2)
Brian Muramatsu9157e0a2011-04-05 18:06:15 -070078
Phil Dubach0d6ef062009-08-12 18:13:16 -070079 # individually generate descriptions not following conventions
Brian Muramatsu9157e0a2011-04-05 18:06:15 -070080 pool.apply_async(GenerateSignatureCheckDescription, [self.test_repository])
Phil Dubach0d6ef062009-08-12 18:13:16 -070081
82 # generate test descriptions for android tests
Brian Muramatsubdcfc7c2011-12-01 14:32:02 -080083 results = []
Brian Muramatsu9157e0a2011-04-05 18:06:15 -070084 pool.close()
85 pool.join()
Brian Muramatsubdcfc7c2011-12-01 14:32:02 -080086 return sum(map(lambda result: result.get(), results))
Phil Dubach0d6ef062009-08-12 18:13:16 -070087
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 = []
Phil Dubach8dcedfe2009-08-20 16:10:39 -070097 descriptions = sorted(glob.glob(os.path.join(self.test_repository, '*.xml')))
Phil Dubach0d6ef062009-08-12 18:13:16 -070098 for description in descriptions:
99 doc = tools.XmlFile(description)
100 packages.append(doc.GetAttr('TestPackage', 'appPackageName'))
Keun young Park965d1912013-02-08 11:37:16 -0800101 # sort the list to give the same sequence based on name
102 packages.sort()
Phil Dubach0d6ef062009-08-12 18:13:16 -0700103
Keun young Parkd93d0d12013-01-10 14:11:35 -0800104 ptsPattern = r'com\.android\.pts\..*'
105 plan = tools.TestPlan(packages)
106 plan.Exclude('.*')
107 plan.Include(ptsPattern)
108 self.__WritePlan(plan, 'PTS')
Keun young Park3769d332012-08-29 10:16:37 -0700109
Phil Dubach0d6ef062009-08-12 18:13:16 -0700110 plan = tools.TestPlan(packages)
Tsu Chiang Chuangd4cce3b2011-05-12 12:19:54 -0700111 plan.Exclude('android\.performance.*')
Brian Muramatsu87ff4df2011-12-16 11:41:17 -0800112 self.__WritePlan(plan, 'CTS')
Brian Muramatsu89ae08c2012-01-03 10:55:02 -0800113 self.__WritePlan(plan, 'CTS-TF')
Tsu Chiang Chuangd4cce3b2011-05-12 12:19:54 -0700114
Keun young Parkd93d0d12013-01-10 14:11:35 -0800115 plan = tools.TestPlan(packages)
116 plan.Exclude(ptsPattern)
117 plan.Exclude('android\.performance.*')
118 self.__WritePlan(plan, 'SDK')
119
Phil Dubach0d6ef062009-08-12 18:13:16 -0700120 plan.Exclude(r'android\.tests\.sigtest')
121 plan.Exclude(r'android\.core.*')
122 self.__WritePlan(plan, 'Android')
123
124 plan = tools.TestPlan(packages)
Keun young Parkd93d0d12013-01-10 14:11:35 -0800125 plan.Exclude(ptsPattern)
Phil Dubach0d6ef062009-08-12 18:13:16 -0700126 plan.Include(r'android\.core\.tests.*')
127 self.__WritePlan(plan, 'Java')
128
129 plan = tools.TestPlan(packages)
Keun young Parkd93d0d12013-01-10 14:11:35 -0800130 plan.Exclude(ptsPattern)
Tsu Chiang Chuang9a223d72011-04-27 17:19:46 -0700131 plan.Include(r'android\.core\.vm-tests-tf')
132 self.__WritePlan(plan, 'VM-TF')
133
134 plan = tools.TestPlan(packages)
Keun young Parkd93d0d12013-01-10 14:11:35 -0800135 plan.Exclude(ptsPattern)
Phil Dubach0d6ef062009-08-12 18:13:16 -0700136 plan.Include(r'android\.tests\.sigtest')
137 self.__WritePlan(plan, 'Signature')
138
139 plan = tools.TestPlan(packages)
Keun young Parkd93d0d12013-01-10 14:11:35 -0800140 plan.Exclude(ptsPattern)
Phil Dubach60680482009-08-19 10:13:23 -0700141 plan.Include(r'android\.tests\.appsecurity')
142 self.__WritePlan(plan, 'AppSecurity')
143
Keun young Parkff194172012-08-14 17:56:11 -0700144 # hard-coded white list for PDK plan
145 plan.Exclude('.*')
146 plan.Include('android\.bluetooth')
147 plan.Include('android\.graphics.*')
148 plan.Include('android\.hardware')
149 plan.Include('android\.media.*')
150 plan.Include('android\.net')
151 plan.Include('android\.opengl.*')
152 plan.Include('android\.renderscript')
153 plan.Include('android\.telephony')
154 plan.Include('android\.nativemedia.*')
keunyoung0dec4052013-03-15 14:40:36 -0700155 plan.Include('com\.android\.pts\..*')
156 plan.Exclude('com\.android\.pts\.bootup')
Keun young Parkff194172012-08-14 17:56:11 -0700157 self.__WritePlan(plan, 'PDK')
158
Brian Muramatsu9157e0a2011-04-05 18:06:15 -0700159def LogGenerateDescription(name):
160 print 'Generating test description for package %s' % name
161
162def GenerateSignatureCheckDescription(test_repository):
163 """Generate the test description for the signature check."""
164 LogGenerateDescription('android.tests.sigtest')
165 package = tools.TestPackage('SignatureTest', 'android.tests.sigtest')
166 package.AddAttribute('appNameSpace', 'android.tests.sigtest')
167 package.AddAttribute('signatureCheck', 'true')
168 package.AddAttribute('runner', '.InstrumentationRunner')
169 package.AddTest('android.tests.sigtest.SignatureTest.signatureTest')
170 description = open(os.path.join(test_repository, 'SignatureTest.xml'), 'w')
171 package.WriteDescription(description)
172 description.close()
173
Phil Dubach0d6ef062009-08-12 18:13:16 -0700174if __name__ == '__main__':
175 builder = CtsBuilder(sys.argv)
Keun young Parkd93d0d12013-01-10 14:11:35 -0800176 result = builder.GenerateTestDescriptions()
177 if result != 0:
178 sys.exit(result)
Phil Dubach0d6ef062009-08-12 18:13:16 -0700179 builder.GenerateTestPlans()
Keun young Park3769d332012-08-29 10:16:37 -0700180