AIDEGen: aidegen_functional_test add upload binary test use case function.
Try to run use cases of AIDEGen when uploading binary by making use of
aidegen_functional_test. Add a special group of use cases' tests to run
by using aidegen_functional_test. We need to run aidegen_functiunal_test in
smoke_test.sh which is triggered by release_checker.py when aosp/943977 is ready.
We can easily change use cases by just modifying verify_binary_upload.json.
Bug: 137343144
Test: 1. Patch aosp/1094929.
2. m aidegen and copy aidegen-dev to prebuilts/asuite/aidegen/linux-x86
and rename to aidegen.
3. m aidegen_functional_test;aidegen_functional_test-dev -b
all tests passed!
Change-Id: I5dc73cc7a8fbb29de421632eed65db23adda36e8
diff --git a/aidegen/aidegen_main.py b/aidegen/aidegen_main.py
index 94601bc..0eb4530 100644
--- a/aidegen/aidegen_main.py
+++ b/aidegen/aidegen_main.py
@@ -84,8 +84,6 @@
_SKIP_MSG = _SKIP_BUILD_INFO_FUTURE.format(
common_util.COLORED_INFO('aidegen [ module(s) ] -s'))
_TIME_EXCEED_MSG = '\n{} {}\n'.format(_INFO, _SKIP_MSG)
-_LOG_FORMAT = '%(asctime)s %(filename)s:%(lineno)s:%(levelname)s: %(message)s'
-_DATE_FORMAT = '%Y-%m-%d %H:%M:%S'
def _parse_args(args):
@@ -156,18 +154,6 @@
return parser.parse_args(args)
-def _configure_logging(verbose):
- """Configure the logger.
-
- Args:
- verbose: A boolean. If true, display DEBUG level logs.
- """
- log_format = _LOG_FORMAT
- datefmt = _DATE_FORMAT
- level = logging.DEBUG if verbose else logging.INFO
- logging.basicConfig(level=level, format=log_format, datefmt=datefmt)
-
-
def _get_ide_util_instance(args):
"""Get an IdeUtil class instance for launching IDE.
@@ -332,7 +318,7 @@
exit_code = constant.EXIT_CODE_NORMAL
try:
args = _parse_args(argv)
- _configure_logging(args.verbose)
+ common_util.configure_logging(args.verbose)
references = [constant.ANDROID_TREE] if _is_whole_android_tree(
args.targets, args.android_tree) else []
aidegen_metrics.starts_asuite_metrics(references)
diff --git a/aidegen/aidegen_main_unittest.py b/aidegen/aidegen_main_unittest.py
index c0a9b1e..fc6923c 100644
--- a/aidegen/aidegen_main_unittest.py
+++ b/aidegen/aidegen_main_unittest.py
@@ -22,9 +22,9 @@
import unittest
from unittest import mock
-import aidegen.unittest_constants as uc
from aidegen import aidegen_main
from aidegen import constant
+from aidegen import unittest_constants
from aidegen.lib import aidegen_metrics
from aidegen.lib import common_util
from aidegen.lib import eclipse_project_file_gen
@@ -59,8 +59,9 @@
self.assertEqual(args.ide[0], 's')
args = aidegen_main._parse_args(['-i', 'e'])
self.assertEqual(args.ide[0], 'e')
- args = aidegen_main._parse_args(['-p', uc.TEST_MODULE])
- self.assertEqual(args.ide_installed_path, uc.TEST_MODULE)
+ args = aidegen_main._parse_args(['-p', unittest_constants.TEST_MODULE])
+ self.assertEqual(args.ide_installed_path,
+ unittest_constants.TEST_MODULE)
args = aidegen_main._parse_args(['-n'])
self.assertEqual(args.no_launch, True)
args = aidegen_main._parse_args(['-r'])
@@ -68,22 +69,6 @@
args = aidegen_main._parse_args(['-s'])
self.assertEqual(args.skip_build, True)
- @mock.patch('aidegen_main.logging.basicConfig')
- def test_configure_logging(self, mock_log_config):
- """Test _configure_logging with different arguments."""
- aidegen_main._configure_logging(True)
- log_format = aidegen_main._LOG_FORMAT
- datefmt = aidegen_main._DATE_FORMAT
- level = aidegen_main.logging.DEBUG
- self.assertTrue(
- mock_log_config.called_with(
- level=level, format=log_format, datefmt=datefmt))
- aidegen_main._configure_logging(False)
- level = aidegen_main.logging.INFO
- self.assertTrue(
- mock_log_config.called_with(
- level=level, format=log_format, datefmt=datefmt))
-
@mock.patch.object(ide_util.IdeUtil, 'is_ide_installed')
def test_get_ide_util_instance(self, mock_installed):
"""Test _get_ide_util_instance with different conditions."""
diff --git a/aidegen/lib/common_util.py b/aidegen/lib/common_util.py
index 9173685..dd3de36 100644
--- a/aidegen/lib/common_util.py
+++ b/aidegen/lib/common_util.py
@@ -30,13 +30,17 @@
from aidegen import constant
from aidegen.lib import errors
+from atest import atest_utils
from atest import constants
from atest import module_info
-from atest.atest_utils import colorize
-COLORED_INFO = partial(colorize, color=constants.MAGENTA, highlight=False)
-COLORED_PASS = partial(colorize, color=constants.GREEN, highlight=False)
-COLORED_FAIL = partial(colorize, color=constants.RED, highlight=False)
+
+COLORED_INFO = partial(
+ atest_utils.colorize, color=constants.MAGENTA, highlight=False)
+COLORED_PASS = partial(
+ atest_utils.colorize, color=constants.GREEN, highlight=False)
+COLORED_FAIL = partial(
+ atest_utils.colorize, color=constants.RED, highlight=False)
FAKE_MODULE_ERROR = '{} is a fake module.'
OUTSIDE_ROOT_ERROR = '{} is outside android root.'
PATH_NOT_EXISTS_ERROR = 'The path {} doesn\'t exist.'
@@ -52,6 +56,8 @@
_REBUILD_MODULE_INFO = '%s We should rebuild module-info.json file for it.'
_ENVSETUP_NOT_RUN = ('Please run "source build/envsetup.sh" and "lunch" before '
'running aidegen.')
+_LOG_FORMAT = '%(asctime)s %(filename)s:%(lineno)s:%(levelname)s: %(message)s'
+_DATE_FORMAT = '%Y-%m-%d %H:%M:%S'
def time_logged(func=None, *, message='', maximum=1):
@@ -114,8 +120,8 @@
rel_path = paths[0]
abs_path = os.path.join(get_android_root_dir(), rel_path)
# User inputs a module path or a relative path of android root folder.
- elif (atest_module_info.get_module_names(target) or os.path.isdir(
- os.path.join(get_android_root_dir(), target))):
+ elif (atest_module_info.get_module_names(target)
+ or os.path.isdir(os.path.join(get_android_root_dir(), target))):
rel_path = target.strip(os.sep)
abs_path = os.path.join(get_android_root_dir(), rel_path)
# User inputs a relative path of current directory.
@@ -385,8 +391,7 @@
Returns:
module_bp_java_deps.json path.
"""
- return os.path.join(get_soong_out_path(),
- constant.BLUEPRINT_JSONFILE_NAME)
+ return os.path.join(get_soong_out_path(), constant.BLUEPRINT_JSONFILE_NAME)
def back_to_cwd(func):
@@ -398,6 +403,7 @@
Returns:
The wrapper function.
"""
+
@wraps(func)
def wrapper(*args, **kwargs):
"""A wrapper function."""
@@ -422,8 +428,8 @@
android_out_dir_common_base = (os.path.join(
out_dir_common_base, os.path.basename(android_root_path))
if out_dir_common_base else None)
- return (android_out_dir or android_out_dir_common_base or
- constant.ANDROID_DEFAULT_OUT)
+ return (android_out_dir or android_out_dir_common_base
+ or constant.ANDROID_DEFAULT_OUT)
def get_android_root_dir():
@@ -463,3 +469,15 @@
Out directory's soong path.
"""
return os.path.join(get_android_root_dir(), get_android_out_dir(), 'soong')
+
+
+def configure_logging(verbose):
+ """Configure the logger.
+
+ Args:
+ verbose: A boolean. If true, display DEBUG level logs.
+ """
+ log_format = _LOG_FORMAT
+ datefmt = _DATE_FORMAT
+ level = logging.DEBUG if verbose else logging.INFO
+ logging.basicConfig(level=level, format=log_format, datefmt=datefmt)
diff --git a/aidegen/lib/common_util_unittest.py b/aidegen/lib/common_util_unittest.py
index 82e54fd..01df761 100644
--- a/aidegen/lib/common_util_unittest.py
+++ b/aidegen/lib/common_util_unittest.py
@@ -16,6 +16,7 @@
"""Unittests for common_util."""
+import logging
import os
import unittest
from unittest import mock
@@ -109,8 +110,8 @@
unittest_constants.TEST_MODULE)
self.assertEqual(expected, str(ctx.exception))
self.assertEqual(common_util._check_module(mod_info, '', False), False)
- self.assertEqual(common_util._check_module(mod_info, 'nothing', False),
- False)
+ self.assertEqual(
+ common_util._check_module(mod_info, 'nothing', False), False)
@mock.patch.object(common_util, '_check_module')
def test_check_modules(self, mock_check):
@@ -122,8 +123,8 @@
self.assertEqual(mock_check.call_count, 2)
target = 'nothing'
mock_check.return_value = False
- self.assertEqual(common_util._check_modules(mod_info, [target], False),
- False)
+ self.assertEqual(
+ common_util._check_modules(mod_info, [target], False), False)
@mock.patch.object(common_util, 'get_android_root_dir')
def test_get_abs_path(self, mock_get_root):
@@ -147,6 +148,22 @@
common_util.is_target('packages/apps/tests/test.jar',
['.so', '.a']), False)
+ @mock.patch.object(logging, 'basicConfig')
+ def test_configure_logging(self, mock_log_config):
+ """Test configure_logging with different arguments."""
+ common_util.configure_logging(True)
+ log_format = common_util._LOG_FORMAT
+ datefmt = common_util._DATE_FORMAT
+ level = common_util.logging.DEBUG
+ self.assertTrue(
+ mock_log_config.called_with(
+ level=level, format=log_format, datefmt=datefmt))
+ common_util.configure_logging(False)
+ level = common_util.logging.INFO
+ self.assertTrue(
+ mock_log_config.called_with(
+ level=level, format=log_format, datefmt=datefmt))
+
if __name__ == '__main__':
unittest.main()
diff --git a/aidegen_functional_test/aidegen_functional_test_main.py b/aidegen_functional_test/aidegen_functional_test_main.py
index fb16dd7..6257793 100644
--- a/aidegen_functional_test/aidegen_functional_test_main.py
+++ b/aidegen_functional_test/aidegen_functional_test_main.py
@@ -22,27 +22,24 @@
import itertools
import json
import os
+import subprocess
import sys
import xml.etree.ElementTree
import xml.parsers.expat
-import aidegen.lib.errors
-
from aidegen import aidegen_main
from aidegen.lib import common_util
-from aidegen.lib.common_util import COLORED_PASS
-from aidegen.lib.common_util import COLORED_FAIL
-from aidegen.lib.common_util import get_blueprint_json_path
-from aidegen.lib.common_util import get_related_paths
-from aidegen.lib.common_util import time_logged
+from aidegen.lib import errors
from atest import module_info
+
_ROOT_DIR = os.path.join(common_util.get_android_root_dir(),
'tools/asuite/aidegen_functional_test')
_TEST_DATA_PATH = os.path.join(_ROOT_DIR, 'test_data')
_ANDROID_SINGLE_PROJECT_JSON = os.path.join(_TEST_DATA_PATH,
'single_module.json')
_VERIFY_COMMANDS_JSON = os.path.join(_TEST_DATA_PATH, 'verify_commands.json')
+_VERIFY_BINARY_JSON = os.path.join(_TEST_DATA_PATH, 'verify_binary_upload.json')
_PRODUCT_DIR = '$PROJECT_DIR$'
_ANDROID_COMMON = 'android_common'
_LINUX_GLIBC_COMMON = 'linux_glibc_common'
@@ -68,12 +65,12 @@
args: A list of arguments.
Returns:
- An argparse.Namespace class instance holding parsed args.
+ An argparse.Namespace object holding parsed args.
"""
parser = argparse.ArgumentParser(
description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter,
- usage='aidegen_functional_test [-c | -v]')
+ usage='aidegen_functional_test [-c | -u | -b] -v -r')
group = parser.add_mutually_exclusive_group()
parser.required = False
group.add_argument(
@@ -83,12 +80,27 @@
dest='create_sample',
help=('Create aidegen project files and write data to sample json file '
'for aidegen_functional_test to compare.'))
- group.add_argument(
+ parser.add_argument(
'-v',
- '--verify',
+ '--verbose',
action='store_true',
- dest='verify_aidegen',
+ help='Show DEBUG level logging.')
+ parser.add_argument(
+ '-r',
+ '--remove_bp_json',
+ action='store_true',
+ help='Remove module_bp_java_deps.json for each use case test.')
+ group.add_argument(
+ '-u',
+ action='store_true',
+ dest='use_cases_verified',
help='Verify various use cases of executing aidegen.')
+ group.add_argument(
+ '-b',
+ action='store_true',
+ dest='binary_upload_verified',
+ help=('Verify aidegen\'s use cases by executing different aidegen '
+ 'commands.'))
return parser.parse_args(args)
@@ -132,7 +144,7 @@
data = {}
for target, filelist in _TEST_IML_DICT.items():
aidegen_main.main([target, '-n'])
- _, abs_path = get_related_paths(atest_module_info, target)
+ _, abs_path = common_util.get_related_paths(atest_module_info, target)
for filename in filelist:
real_iml_file = os.path.join(abs_path, filename)
item_name = os.path.basename(real_iml_file)
@@ -163,14 +175,15 @@
if set(s_items) != set(r_items):
diff_iter = _compare_content(name, item, s_items, r_items)
if diff_iter:
- print('\n%s\n%s' % (COLORED_FAIL('Test error...'),
- _TEST_ERROR % (name, item)))
+ print(
+ '\n%s\n%s' % (common_util.COLORED_FAIL('Test error...'),
+ _TEST_ERROR % (name, item)))
print('%s %s contents are different:' % (name, item))
for diff in diff_iter:
print(diff)
test_successful = False
if test_successful:
- print(COLORED_PASS(_ALL_PASS))
+ print(common_util.COLORED_PASS(_ALL_PASS))
def _compare_content(module_name, item_type, s_items, r_items):
@@ -244,32 +257,81 @@
# pylint: disable=broad-except
# pylint: disable=eval-used
-@time_logged
-def _verify_aidegen():
- """Verify various use cases of executing aidegen."""
- bp_json_path = get_blueprint_json_path()
- with open(_VERIFY_COMMANDS_JSON, 'r') as jsfile:
- data = json.load(jsfile)
+@common_util.back_to_cwd
+@common_util.time_logged
+def _verify_aidegen(verified_file_path, forced_remove_bp_json):
+ """Verify various use cases of executing aidegen.
+
+ There are two types of running commands:
+ 1. Use 'eval' to run the commands for present codes in aidegen_main.py,
+ such as:
+ aidegen_main.main(['tradefed', '-n', '-v'])
+ 2. Use 'subprocess.check_call' to run the commands for the binary codes of
+ aidegen such as:
+ aidegen tradefed -n -v
+
+ Remove module_bp_java_deps.json in the beginning of running use cases. If
+ users need to remove module_bp_java_deps.json between each use case they
+ can set forced_remove_bp_json true.
+
+ args:
+ verified_file_path: The json file path to be verified.
+ forced_remove_bp_json: Remove module_bp_java_deps.json for each use case
+ test.
+
+ raises:
+ There are two type of exceptions:
+ 1. aidegen.lib.errors for projects' or modules' issues such as,
+ ProjectPathNotExistError.
+ 2. Any exceptions other than aidegen.lib.errors such as,
+ subprocess.CalledProcessError.
+ """
+ os.chdir(common_util.get_android_root_dir())
+ bp_json_path = common_util.get_blueprint_json_path()
+ use_eval = (verified_file_path == _VERIFY_COMMANDS_JSON)
+ try:
+ with open(verified_file_path, 'r') as jsfile:
+ data = json.load(jsfile)
+ except IOError as err:
+ raise errors.JsonFileNotExistError(
+ '%s does not exist, error: %s.' % (verified_file_path, err))
+
+ try:
+ subprocess.check_call(
+ ['build/soong/soong_ui.bash --make-mode clean', '-j'],
+ shell=True)
+ except subprocess.CalledProcessError:
+ print('"make clean" command failed.')
+ raise
+
for use_case in data:
- if os.path.exists(bp_json_path):
+ print('Use case "{}" is running.'.format(use_case))
+ if forced_remove_bp_json and os.path.exists(bp_json_path):
os.remove(bp_json_path)
for cmd in data[use_case]:
+ print('Command "{}" is running.'.format(cmd))
try:
- eval(cmd)
- except (aidegen.lib.errors.ProjectOutsideAndroidRootError,
- aidegen.lib.errors.ProjectPathNotExistError,
- aidegen.lib.errors.NoModuleDefinedInModuleInfoError,
- aidegen.lib.errors.IDENotExistError) as err:
- print('{} command has raise error: {}.'.format(use_case, err))
+ if use_eval:
+ eval(cmd)
+ else:
+ subprocess.check_call(cmd, shell=True)
+ except (errors.ProjectOutsideAndroidRootError,
+ errors.ProjectPathNotExistError,
+ errors.NoModuleDefinedInModuleInfoError,
+ errors.IDENotExistError) as err:
+ print('"{}" raises error: {}.'.format(use_case, err))
+ raise
except BaseException:
exc_type, _, _ = sys.exc_info()
- print('{}.{} command {}.'.format(
- use_case, cmd, COLORED_FAIL('executes failed')))
+ print('"{}.{}" command {}.'.format(
+ use_case, cmd, common_util.COLORED_FAIL('executes failed')))
raise BaseException(
- 'Unexpected command {} exception {}.'.format(
+ 'Unexpected command "{}" exception: {}.'.format(
use_case, exc_type))
- print('{} command {}!'.format(use_case, COLORED_PASS('test passed')))
- print(COLORED_PASS(_ALL_PASS))
+ print('"{}" command {}!'.format(
+ use_case, common_util.COLORED_PASS('test passed')))
+ print(common_util.COLORED_PASS(_ALL_PASS))
+
def main(argv):
"""Main entry.
@@ -280,10 +342,13 @@
argv: A list of system arguments.
"""
args = _parse_args(argv)
+ common_util.configure_logging(args.verbose)
if args.create_sample:
_create_sample_json_file()
- elif args.verify_aidegen:
- _verify_aidegen()
+ elif args.use_cases_verified:
+ _verify_aidegen(_VERIFY_COMMANDS_JSON, args.remove_bp_json)
+ elif args.binary_upload_verified:
+ _verify_aidegen(_VERIFY_BINARY_JSON, args.remove_bp_json)
else:
test_some_sample_iml()
diff --git a/aidegen_functional_test/test_data/verify_binary_upload.json b/aidegen_functional_test/test_data/verify_binary_upload.json
new file mode 100644
index 0000000..b3fc26d
--- /dev/null
+++ b/aidegen_functional_test/test_data/verify_binary_upload.json
@@ -0,0 +1,14 @@
+{
+ "test whole android tree": ["aidegen -n"],
+ "test whole android tree with -a": ["aidegen -a -n -s"],
+ "test whole android tree with frameworks/base -a": ["aidegen frameworks/base -a -n -s"],
+ "test whole android tree in frameworks/base with -a": [
+ "cd frameworks/base",
+ "aidegen -a -n -s",
+ "cd ../.."
+ ],
+ "test Settings framework": ["aidegen Settings framework -n -s"],
+ "test framework launch Android Studio": ["aidegen framework -i s -n -s"],
+ "test framework launch Eclipse": ["aidegen framework -i e -n -s"],
+ "test help": ["aidegen -h"]
+}