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.
247 lines
7.5 KiB
247 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:])
|