blob: 90da254630385f62c6cc174973b57578239dfb00 [file] [log] [blame]
Jack Wang2abd80a2009-06-29 18:47:03 -07001#!/usr/bin/python2.4
2#
3#
4# Copyright 2009, The Android Open Source Project
5#
6# Licensed under the Apache License, Version 2.0 (the "License");
7# you may not use this file except in compliance with the License.
8# You may obtain a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS,
14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15# See the License for the specific language governing permissions and
16# limitations under the License.
17
18"""Utility to create Android project files for tests."""
19
20# python imports
21import datetime
22import optparse
23import os
24import string
25import sys
26
27# local imports
28import android_mk
29import android_manifest
30
31
32class TestsConsts(object):
33 """Constants for test Android.mk and AndroidManifest.xml creation."""
34
35 MK_BUILD_INCLUDE = "call all-makefiles-under,$(LOCAL_PATH)"
36 MK_BUILD_STRING = "\ninclude $(%s)\n" % MK_BUILD_INCLUDE
37 TEST_MANIFEST_TEMPLATE = """<?xml version="1.0" encoding="utf-8"?>
38<!-- Copyright (C) $YEAR The Android Open Source Project
39
40 Licensed under the Apache License, Version 2.0 (the "License");
41 you may not use this file except in compliance with the License.
42 You may obtain a copy of the License at
43
44 http://www.apache.org/licenses/LICENSE-2.0
45
46 Unless required by applicable law or agreed to in writing, software
47 distributed under the License is distributed on an "AS IS" BASIS,
48 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
49 See the License for the specific language governing permissions and
50 limitations under the License.
51-->
52
53<manifest xmlns:android="http://schemas.android.com/apk/res/android"
54 package="$PACKAGE_NAME.tests">
55
56 <application>
57 <uses-library android:name="android.test.runner" />
58 </application>
59
60 <instrumentation android:name="android.test.InstrumentationTestRunner"
61 android:targetPackage="$PACKAGE_NAME"
62 android:label="Tests for $MODULE_NAME">
63 </instrumentation>
64</manifest>
65"""
66 TEST_MK_TEMPLATE = """LOCAL_PATH := $$(call my-dir)
67include $$(CLEAR_VARS)
68
69LOCAL_MODULE_TAGS := tests
70
71LOCAL_JAVA_LIBRARIES := android.test.runner
72
73LOCAL_SRC_FILES := $$(call all-java-files-under, src)
74
75LOCAL_PACKAGE_NAME := ${MODULE_NAME}Tests${CERTIFICATE}
76
77LOCAL_INSTRUMENTATION_FOR := ${MODULE_NAME}
78
79LOCAL_SDK_VERSION := current
80
81include $$(BUILD_PACKAGE)
82"""
83 TESTS_FOLDER = "tests"
84
85
86def _GenerateTestManifest(manifest, module_name, mapping=None):
87 """Create and populate tests/AndroidManifest.xml with variable values from
88 Android.mk and AndroidManifest.xml.
89
90 Does nothing if tests/AndroidManifest.xml already exists.
91
92 Args:
93 manifest: AndroidManifest object for application manifest
94 module_name: module name used for labelling
95 mapping: optional user defined mapping of variable values, replaces values
96 extracted from AndroidManifest.xml
97 Raises:
98 IOError: tests/AndroidManifest.xml cannot be opened for writing
99 """
100 # skip if file already exists
Jeff Davidsonc1224d32010-06-17 11:53:49 -0700101 tests_path = "%s/%s" % (manifest.GetAppPath(), TestsConsts.TESTS_FOLDER)
Jack Wang2abd80a2009-06-29 18:47:03 -0700102 tests_manifest_path = "%s/%s" % (tests_path, manifest.FILENAME)
103 if os.path.exists(tests_manifest_path):
104 _PrintMessage("%s already exists, not overwritten" % tests_manifest_path)
105 return
106
107 if not mapping:
108 package_name = manifest.GetPackageName()
109 mapping = {"PACKAGE_NAME":package_name, "MODULE_NAME":module_name,
110 "YEAR":datetime.date.today().year}
111 output = string.Template(TestsConsts.TEST_MANIFEST_TEMPLATE).substitute(mapping)
112
113 # create tests folder if not existent
114 if not os.path.exists(tests_path):
115 os.mkdir(tests_path)
116
117 # write tests/AndroidManifest.xml
118 tests_manifest = open(tests_manifest_path, mode="w")
119 tests_manifest.write(output)
120 tests_manifest.close()
121 _PrintMessage("Created %s" % tests_manifest_path)
122
123
Brett Chabota39865a2012-01-17 15:54:39 -0800124def _GenerateTestMK(mk, app_path, mapping=None):
Jack Wang2abd80a2009-06-29 18:47:03 -0700125 """Create and populate tests/Android.mk with variable values from Android.mk.
126
127 Does nothing if tests/Android.mk already exists.
128
129 Args:
130 mk: AndroidMK object for application makefile
Brett Chabota39865a2012-01-17 15:54:39 -0800131 app_path: path to the application being tested
Jack Wang2abd80a2009-06-29 18:47:03 -0700132 mapping: optional user defined mapping of variable values, replaces
133 values stored in mk
134 Raises:
135 IOError: tests/Android.mk cannot be opened for writing
136 """
137 # skip if file already exists
Brett Chabota39865a2012-01-17 15:54:39 -0800138 tests_path = "%s/%s" % (app_path, TestsConsts.TESTS_FOLDER)
Jack Wang2abd80a2009-06-29 18:47:03 -0700139 tests_mk_path = "%s/%s" % (tests_path, mk.FILENAME)
140 if os.path.exists(tests_mk_path):
141 _PrintMessage("%s already exists, not overwritten" % tests_mk_path)
142 return
143
144 # append test build if not existent in makefile
145 if not mk.HasInclude(TestsConsts.MK_BUILD_INCLUDE):
Brett Chabota39865a2012-01-17 15:54:39 -0800146 mk_path = "%s/%s" % (app_path, mk.FILENAME)
Jack Wang2abd80a2009-06-29 18:47:03 -0700147 mk_file = open(mk_path, mode="a")
148 mk_file.write(TestsConsts.MK_BUILD_STRING)
149 mk_file.close()
150
151 # construct tests/Android.mk
152 # include certificate definition if existent in makefile
153 certificate = mk.GetVariable(mk.CERTIFICATE)
154 if certificate:
155 cert_definition = ("\n%s := %s" % (mk.CERTIFICATE, certificate))
156 else:
157 cert_definition = ""
158 if not mapping:
159 module_name = mk.GetVariable(mk.PACKAGE_NAME)
160 mapping = {"MODULE_NAME":module_name, "CERTIFICATE":cert_definition}
161 output = string.Template(TestsConsts.TEST_MK_TEMPLATE).substitute(mapping)
162
163 # create tests folder if not existent
164 if not os.path.exists(tests_path):
165 os.mkdir(tests_path)
166
167 # write tests/Android.mk to disk
168 tests_mk = open(tests_mk_path, mode="w")
169 tests_mk.write(output)
170 tests_mk.close()
171 _PrintMessage("Created %s" % tests_mk_path)
172
173
174def _ParseArgs(argv):
175 """Parse the command line arguments.
176
177 Args:
178 argv: the list of command line arguments
179 Returns:
180 a tuple of options and individual command line arguments.
181 """
182 parser = optparse.OptionParser(usage="%s <app_path>" % sys.argv[0])
183 options, args = parser.parse_args(argv)
184 if len(args) < 1:
185 _PrintError("Error: Incorrect syntax")
186 parser.print_usage()
187 sys.exit()
188 return (options, args)
189
190
191def _PrintMessage(msg):
192 print >> sys.stdout, msg
193
194
195def _PrintError(msg):
196 print >> sys.stderr, msg
197
198
199def _ValidateInputFiles(mk, manifest):
200 """Verify that required variables are defined in input files.
201
202 Args:
203 mk: AndroidMK object for application makefile
204 manifest: AndroidManifest object for application manifest
205 Raises:
206 RuntimeError: mk does not define LOCAL_PACKAGE_NAME or
207 manifest does not define package variable
208 """
209 module_name = mk.GetVariable(mk.PACKAGE_NAME)
210 if not module_name:
211 raise RuntimeError("Variable %s missing from %s" %
212 (mk.PACKAGE_NAME, mk.FILENAME))
213
214 package_name = manifest.GetPackageName()
215 if not package_name:
216 raise RuntimeError("Variable package missing from %s" % manifest.FILENAME)
217
218
219def main(argv):
220 options, args = _ParseArgs(argv)
221 app_path = args[0];
222
223 if not os.path.exists(app_path):
224 _PrintError("Error: Application path %s not found" % app_path)
225 sys.exit()
226
227 try:
Brett Chabota39865a2012-01-17 15:54:39 -0800228 mk = android_mk.CreateAndroidMK(path=app_path)
Jack Wang2abd80a2009-06-29 18:47:03 -0700229 manifest = android_manifest.AndroidManifest(app_path=app_path)
230 _ValidateInputFiles(mk, manifest)
231
232 module_name = mk.GetVariable(mk.PACKAGE_NAME)
Brett Chabota39865a2012-01-17 15:54:39 -0800233 _GenerateTestMK(mk, app_path)
Jack Wang2abd80a2009-06-29 18:47:03 -0700234 _GenerateTestManifest(manifest, module_name)
235 except Exception, e:
236 _PrintError("Error: %s" % e)
237 _PrintError("Error encountered, script aborted")
238 sys.exit()
239
240 src_path = app_path + "/tests/src"
241 if not os.path.exists(src_path):
242 os.mkdir(src_path)
243
244
245if __name__ == "__main__":
246 main(sys.argv[1:])