blob: 38f1ef494cd9b07dd367e585c9a2aacb94c0880b [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)
125 plan.Include(r'android\.core\.tests.*')
126 self.__WritePlan(plan, 'Java')
127
128 plan = tools.TestPlan(packages)
Tsu Chiang Chuang9a223d72011-04-27 17:19:46 -0700129 plan.Include(r'android\.core\.vm-tests-tf')
130 self.__WritePlan(plan, 'VM-TF')
131
132 plan = tools.TestPlan(packages)
Phil Dubach0d6ef062009-08-12 18:13:16 -0700133 plan.Include(r'android\.tests\.sigtest')
134 self.__WritePlan(plan, 'Signature')
135
136 plan = tools.TestPlan(packages)
Phil Dubach60680482009-08-19 10:13:23 -0700137 plan.Include(r'android\.tests\.appsecurity')
138 self.__WritePlan(plan, 'AppSecurity')
139
Keun young Parkff194172012-08-14 17:56:11 -0700140 # hard-coded white list for PDK plan
141 plan.Exclude('.*')
keunyoungc767cba2013-04-03 14:50:58 -0700142 plan.Include('android\.aadb')
Keun young Parkff194172012-08-14 17:56:11 -0700143 plan.Include('android\.bluetooth')
144 plan.Include('android\.graphics.*')
145 plan.Include('android\.hardware')
keunyoungde519462013-03-21 12:06:42 -0700146 plan.Include('android\.media')
147 plan.Exclude('android\.mediastress')
Keun young Parkff194172012-08-14 17:56:11 -0700148 plan.Include('android\.net')
149 plan.Include('android\.opengl.*')
150 plan.Include('android\.renderscript')
151 plan.Include('android\.telephony')
152 plan.Include('android\.nativemedia.*')
keunyoung0dec4052013-03-15 14:40:36 -0700153 plan.Include('com\.android\.pts\..*')
154 plan.Exclude('com\.android\.pts\.bootup')
Keun young Parkff194172012-08-14 17:56:11 -0700155 self.__WritePlan(plan, 'PDK')
156
Brian Muramatsu9157e0a2011-04-05 18:06:15 -0700157def LogGenerateDescription(name):
158 print 'Generating test description for package %s' % name
159
160def GenerateSignatureCheckDescription(test_repository):
161 """Generate the test description for the signature check."""
162 LogGenerateDescription('android.tests.sigtest')
163 package = tools.TestPackage('SignatureTest', 'android.tests.sigtest')
164 package.AddAttribute('appNameSpace', 'android.tests.sigtest')
165 package.AddAttribute('signatureCheck', 'true')
166 package.AddAttribute('runner', '.InstrumentationRunner')
167 package.AddTest('android.tests.sigtest.SignatureTest.signatureTest')
168 description = open(os.path.join(test_repository, 'SignatureTest.xml'), 'w')
169 package.WriteDescription(description)
170 description.close()
171
Phil Dubach0d6ef062009-08-12 18:13:16 -0700172if __name__ == '__main__':
173 builder = CtsBuilder(sys.argv)
Keun young Parkd93d0d12013-01-10 14:11:35 -0800174 result = builder.GenerateTestDescriptions()
175 if result != 0:
176 sys.exit(result)
Phil Dubach0d6ef062009-08-12 18:13:16 -0700177 builder.GenerateTestPlans()
Keun young Park3769d332012-08-29 10:16:37 -0700178