blob: d5ca8abb85f083631b482d65c4fa0da714065849 [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."""
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
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])
81 pool.apply_async(GenerateReferenceAppDescription, [self.test_repository])
Phil Dubach0d6ef062009-08-12 18:13:16 -070082
83 # generate test descriptions for android tests
Brian Muramatsubdcfc7c2011-12-01 14:32:02 -080084 results = []
Brian Muramatsu9157e0a2011-04-05 18:06:15 -070085 pool.close()
86 pool.join()
Brian Muramatsubdcfc7c2011-12-01 14:32:02 -080087 return sum(map(lambda result: result.get(), results))
Phil Dubach0d6ef062009-08-12 18:13:16 -070088
89 def __WritePlan(self, plan, plan_name):
90 print 'Generating test plan %s' % plan_name
91 plan.Write(os.path.join(self.plan_repository, plan_name + '.xml'))
92
93 def GenerateTestPlans(self):
94 """Generate default test plans."""
95 # TODO: Instead of hard-coding the plans here, use a configuration file,
96 # such as test_defs.xml
97 packages = []
Phil Dubach8dcedfe2009-08-20 16:10:39 -070098 descriptions = sorted(glob.glob(os.path.join(self.test_repository, '*.xml')))
Phil Dubach0d6ef062009-08-12 18:13:16 -070099 for description in descriptions:
100 doc = tools.XmlFile(description)
101 packages.append(doc.GetAttr('TestPackage', 'appPackageName'))
102
103 plan = tools.TestPlan(packages)
Tsu Chiang Chuangd4cce3b2011-05-12 12:19:54 -0700104 plan.Exclude('android\.core\.vm-tests')
105 plan.Exclude('android\.performance.*')
Brian Muramatsu87ff4df2011-12-16 11:41:17 -0800106 self.__WritePlan(plan, 'CTS')
Brian Muramatsu89ae08c2012-01-03 10:55:02 -0800107 self.__WritePlan(plan, 'CTS-TF')
Tsu Chiang Chuangd4cce3b2011-05-12 12:19:54 -0700108
Phil Dubach0d6ef062009-08-12 18:13:16 -0700109 plan.Exclude(r'android\.tests\.sigtest')
110 plan.Exclude(r'android\.core.*')
111 self.__WritePlan(plan, 'Android')
112
113 plan = tools.TestPlan(packages)
114 plan.Include(r'android\.core\.tests.*')
115 self.__WritePlan(plan, 'Java')
116
117 plan = tools.TestPlan(packages)
Tsu Chiang Chuang9a223d72011-04-27 17:19:46 -0700118 plan.Include(r'android\.core\.vm-tests-tf')
119 self.__WritePlan(plan, 'VM-TF')
120
121 plan = tools.TestPlan(packages)
Phil Dubach0d6ef062009-08-12 18:13:16 -0700122 plan.Include(r'android\.tests\.sigtest')
123 self.__WritePlan(plan, 'Signature')
124
125 plan = tools.TestPlan(packages)
126 plan.Include(r'android\.apidemos\.cts')
127 self.__WritePlan(plan, 'RefApp')
128
129 plan = tools.TestPlan(packages)
Phil Dubach60680482009-08-19 10:13:23 -0700130 plan.Include(r'android\.tests\.appsecurity')
131 self.__WritePlan(plan, 'AppSecurity')
132
Brian Muramatsu9157e0a2011-04-05 18:06:15 -0700133def LogGenerateDescription(name):
134 print 'Generating test description for package %s' % name
135
136def GenerateSignatureCheckDescription(test_repository):
137 """Generate the test description for the signature check."""
138 LogGenerateDescription('android.tests.sigtest')
139 package = tools.TestPackage('SignatureTest', 'android.tests.sigtest')
140 package.AddAttribute('appNameSpace', 'android.tests.sigtest')
141 package.AddAttribute('signatureCheck', 'true')
142 package.AddAttribute('runner', '.InstrumentationRunner')
143 package.AddTest('android.tests.sigtest.SignatureTest.signatureTest')
144 description = open(os.path.join(test_repository, 'SignatureTest.xml'), 'w')
145 package.WriteDescription(description)
146 description.close()
147
148def GenerateReferenceAppDescription(test_repository):
149 """Generate the test description for the reference app tests."""
150 LogGenerateDescription('android.apidemos.cts')
151 package = tools.TestPackage('ApiDemosReferenceTest', 'android.apidemos.cts')
152 package.AddAttribute('appNameSpace', 'android.apidemos.cts')
153 package.AddAttribute('packageToTest', 'com.example.android.apis')
154 package.AddAttribute('apkToTestName', 'ApiDemos')
155 package.AddAttribute('runner', 'android.test.InstrumentationTestRunner')
156 package.AddAttribute('referenceAppTest', 'true')
157 package.AddTest('android.apidemos.cts.ApiDemosTest.testNumberOfItemsInListView')
158 description = open(os.path.join(test_repository, 'ApiDemosReferenceTest.xml'), 'w')
159 package.WriteDescription(description)
160 description.close()
161
Phil Dubach0d6ef062009-08-12 18:13:16 -0700162if __name__ == '__main__':
163 builder = CtsBuilder(sys.argv)
Brian Muramatsubdcfc7c2011-12-01 14:32:02 -0800164 result = builder.GenerateTestDescriptions()
165 if result != 0:
166 sys.exit(result)
Phil Dubach0d6ef062009-08-12 18:13:16 -0700167 builder.GenerateTestPlans()