You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
246 lines
7.5 KiB
246 lines
7.5 KiB
#!/usr/bin/python2.4 |
|
# |
|
# |
|
# Copyright 2009, The Android Open Source Project |
|
# |
|
# Licensed under the Apache License, Version 2.0 (the "License"); |
|
# you may not use this file except in compliance with the License. |
|
# You may obtain a copy of the License at |
|
# |
|
# http://www.apache.org/licenses/LICENSE-2.0 |
|
# |
|
# Unless required by applicable law or agreed to in writing, software |
|
# distributed under the License is distributed on an "AS IS" BASIS, |
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
# See the License for the specific language governing permissions and |
|
# limitations under the License. |
|
|
|
"""Utility to create Android project files for tests.""" |
|
|
|
# python imports |
|
import datetime |
|
import optparse |
|
import os |
|
import string |
|
import sys |
|
|
|
# local imports |
|
import android_mk |
|
import android_manifest |
|
|
|
|
|
class TestsConsts(object): |
|
"""Constants for test Android.mk and AndroidManifest.xml creation.""" |
|
|
|
MK_BUILD_INCLUDE = "call all-makefiles-under,$(LOCAL_PATH)" |
|
MK_BUILD_STRING = "\ninclude $(%s)\n" % MK_BUILD_INCLUDE |
|
TEST_MANIFEST_TEMPLATE = """<?xml version="1.0" encoding="utf-8"?> |
|
<!-- Copyright (C) $YEAR The Android Open Source Project |
|
|
|
Licensed under the Apache License, Version 2.0 (the "License"); |
|
you may not use this file except in compliance with the License. |
|
You may obtain a copy of the License at |
|
|
|
http://www.apache.org/licenses/LICENSE-2.0 |
|
|
|
Unless required by applicable law or agreed to in writing, software |
|
distributed under the License is distributed on an "AS IS" BASIS, |
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
See the License for the specific language governing permissions and |
|
limitations under the License. |
|
--> |
|
|
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
|
package="$PACKAGE_NAME.tests"> |
|
|
|
<application> |
|
<uses-library android:name="android.test.runner" /> |
|
</application> |
|
|
|
<instrumentation android:name="android.test.InstrumentationTestRunner" |
|
android:targetPackage="$PACKAGE_NAME" |
|
android:label="Tests for $MODULE_NAME"> |
|
</instrumentation> |
|
</manifest> |
|
""" |
|
TEST_MK_TEMPLATE = """LOCAL_PATH := $$(call my-dir) |
|
include $$(CLEAR_VARS) |
|
|
|
LOCAL_MODULE_TAGS := tests |
|
|
|
LOCAL_JAVA_LIBRARIES := android.test.runner |
|
|
|
LOCAL_SRC_FILES := $$(call all-java-files-under, src) |
|
|
|
LOCAL_PACKAGE_NAME := ${MODULE_NAME}Tests${CERTIFICATE} |
|
|
|
LOCAL_INSTRUMENTATION_FOR := ${MODULE_NAME} |
|
|
|
LOCAL_SDK_VERSION := current |
|
|
|
include $$(BUILD_PACKAGE) |
|
""" |
|
TESTS_FOLDER = "tests" |
|
|
|
|
|
def _GenerateTestManifest(manifest, module_name, mapping=None): |
|
"""Create and populate tests/AndroidManifest.xml with variable values from |
|
Android.mk and AndroidManifest.xml. |
|
|
|
Does nothing if tests/AndroidManifest.xml already exists. |
|
|
|
Args: |
|
manifest: AndroidManifest object for application manifest |
|
module_name: module name used for labelling |
|
mapping: optional user defined mapping of variable values, replaces values |
|
extracted from AndroidManifest.xml |
|
Raises: |
|
IOError: tests/AndroidManifest.xml cannot be opened for writing |
|
""" |
|
# skip if file already exists |
|
tests_path = "%s/%s" % (manifest.GetAppPath(), TestsConsts.TESTS_FOLDER) |
|
tests_manifest_path = "%s/%s" % (tests_path, manifest.FILENAME) |
|
if os.path.exists(tests_manifest_path): |
|
_PrintMessage("%s already exists, not overwritten" % tests_manifest_path) |
|
return |
|
|
|
if not mapping: |
|
package_name = manifest.GetPackageName() |
|
mapping = {"PACKAGE_NAME":package_name, "MODULE_NAME":module_name, |
|
"YEAR":datetime.date.today().year} |
|
output = string.Template(TestsConsts.TEST_MANIFEST_TEMPLATE).substitute(mapping) |
|
|
|
# create tests folder if not existent |
|
if not os.path.exists(tests_path): |
|
os.mkdir(tests_path) |
|
|
|
# write tests/AndroidManifest.xml |
|
tests_manifest = open(tests_manifest_path, mode="w") |
|
tests_manifest.write(output) |
|
tests_manifest.close() |
|
_PrintMessage("Created %s" % tests_manifest_path) |
|
|
|
|
|
def _GenerateTestMK(mk, app_path, mapping=None): |
|
"""Create and populate tests/Android.mk with variable values from Android.mk. |
|
|
|
Does nothing if tests/Android.mk already exists. |
|
|
|
Args: |
|
mk: AndroidMK object for application makefile |
|
app_path: path to the application being tested |
|
mapping: optional user defined mapping of variable values, replaces |
|
values stored in mk |
|
Raises: |
|
IOError: tests/Android.mk cannot be opened for writing |
|
""" |
|
# skip if file already exists |
|
tests_path = "%s/%s" % (app_path, TestsConsts.TESTS_FOLDER) |
|
tests_mk_path = "%s/%s" % (tests_path, mk.FILENAME) |
|
if os.path.exists(tests_mk_path): |
|
_PrintMessage("%s already exists, not overwritten" % tests_mk_path) |
|
return |
|
|
|
# append test build if not existent in makefile |
|
if not mk.HasInclude(TestsConsts.MK_BUILD_INCLUDE): |
|
mk_path = "%s/%s" % (app_path, mk.FILENAME) |
|
mk_file = open(mk_path, mode="a") |
|
mk_file.write(TestsConsts.MK_BUILD_STRING) |
|
mk_file.close() |
|
|
|
# construct tests/Android.mk |
|
# include certificate definition if existent in makefile |
|
certificate = mk.GetVariable(mk.CERTIFICATE) |
|
if certificate: |
|
cert_definition = ("\n%s := %s" % (mk.CERTIFICATE, certificate)) |
|
else: |
|
cert_definition = "" |
|
if not mapping: |
|
module_name = mk.GetVariable(mk.PACKAGE_NAME) |
|
mapping = {"MODULE_NAME":module_name, "CERTIFICATE":cert_definition} |
|
output = string.Template(TestsConsts.TEST_MK_TEMPLATE).substitute(mapping) |
|
|
|
# create tests folder if not existent |
|
if not os.path.exists(tests_path): |
|
os.mkdir(tests_path) |
|
|
|
# write tests/Android.mk to disk |
|
tests_mk = open(tests_mk_path, mode="w") |
|
tests_mk.write(output) |
|
tests_mk.close() |
|
_PrintMessage("Created %s" % tests_mk_path) |
|
|
|
|
|
def _ParseArgs(argv): |
|
"""Parse the command line arguments. |
|
|
|
Args: |
|
argv: the list of command line arguments |
|
Returns: |
|
a tuple of options and individual command line arguments. |
|
""" |
|
parser = optparse.OptionParser(usage="%s <app_path>" % sys.argv[0]) |
|
options, args = parser.parse_args(argv) |
|
if len(args) < 1: |
|
_PrintError("Error: Incorrect syntax") |
|
parser.print_usage() |
|
sys.exit() |
|
return (options, args) |
|
|
|
|
|
def _PrintMessage(msg): |
|
print >> sys.stdout, msg |
|
|
|
|
|
def _PrintError(msg): |
|
print >> sys.stderr, msg |
|
|
|
|
|
def _ValidateInputFiles(mk, manifest): |
|
"""Verify that required variables are defined in input files. |
|
|
|
Args: |
|
mk: AndroidMK object for application makefile |
|
manifest: AndroidManifest object for application manifest |
|
Raises: |
|
RuntimeError: mk does not define LOCAL_PACKAGE_NAME or |
|
manifest does not define package variable |
|
""" |
|
module_name = mk.GetVariable(mk.PACKAGE_NAME) |
|
if not module_name: |
|
raise RuntimeError("Variable %s missing from %s" % |
|
(mk.PACKAGE_NAME, mk.FILENAME)) |
|
|
|
package_name = manifest.GetPackageName() |
|
if not package_name: |
|
raise RuntimeError("Variable package missing from %s" % manifest.FILENAME) |
|
|
|
|
|
def main(argv): |
|
options, args = _ParseArgs(argv) |
|
app_path = args[0]; |
|
|
|
if not os.path.exists(app_path): |
|
_PrintError("Error: Application path %s not found" % app_path) |
|
sys.exit() |
|
|
|
try: |
|
mk = android_mk.CreateAndroidMK(path=app_path) |
|
manifest = android_manifest.AndroidManifest(app_path=app_path) |
|
_ValidateInputFiles(mk, manifest) |
|
|
|
module_name = mk.GetVariable(mk.PACKAGE_NAME) |
|
_GenerateTestMK(mk, app_path) |
|
_GenerateTestManifest(manifest, module_name) |
|
except Exception, e: |
|
_PrintError("Error: %s" % e) |
|
_PrintError("Error encountered, script aborted") |
|
sys.exit() |
|
|
|
src_path = app_path + "/tests/src" |
|
if not os.path.exists(src_path): |
|
os.mkdir(src_path) |
|
|
|
|
|
if __name__ == "__main__": |
|
main(sys.argv[1:])
|
|
|