| #!/usr/bin/env python3 |
| # |
| # Copyright 2018 - 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. |
| |
| """Unittests for project_file_gen.""" |
| |
| import copy |
| import os |
| import shutil |
| import unittest |
| |
| from unittest import mock |
| |
| from aidegen import constant |
| from aidegen import unittest_constants |
| from aidegen.lib import common_util |
| from aidegen.lib import project_file_gen |
| from atest import module_info |
| |
| |
| # pylint: disable=protected-access |
| class AidegenProjectFileGenUnittest(unittest.TestCase): |
| """Unit tests for project_file_gen.py.""" |
| |
| maxDiff = None |
| _TEST_DATA_PATH = unittest_constants.TEST_DATA_PATH |
| _ANDROID_PROJECT_PATH = os.path.join(_TEST_DATA_PATH, 'android_project') |
| _PROJECT_PATH = os.path.join(_TEST_DATA_PATH, 'project') |
| _ANDROID_FACET_SAMPLE = os.path.join(_TEST_DATA_PATH, 'android_facet.iml') |
| _PROJECT_FACET_SAMPLE = os.path.join(_TEST_DATA_PATH, 'project_facet.iml') |
| _MODULE_DEP_SAMPLE = os.path.join(_TEST_DATA_PATH, 'module_dependency.iml') |
| _IML_SAMPLE = os.path.join(_TEST_DATA_PATH, 'test.iml') |
| _CLASSPATH_SAMPLE = os.path.join(_TEST_DATA_PATH, 'eclipse.classpath') |
| _DEPENDENCIES_IML_SAMPLE = os.path.join(_TEST_DATA_PATH, 'dependencies.iml') |
| _MODULE_XML_SAMPLE = os.path.join(_TEST_DATA_PATH, 'modules.xml') |
| _MAIN_MODULE_XML_SAMPLE = os.path.join(_TEST_DATA_PATH, |
| 'modules_only_self_module.xml') |
| _VCS_XML_SAMPLE = os.path.join(_TEST_DATA_PATH, 'vcs.xml') |
| _IML_PATH = os.path.join(_ANDROID_PROJECT_PATH, 'android_project.iml') |
| _DEPENDENCIES_IML_PATH = os.path.join(_ANDROID_PROJECT_PATH, |
| 'dependencies.iml') |
| _IDEA_PATH = os.path.join(_ANDROID_PROJECT_PATH, '.idea') |
| _MODULE_PATH = os.path.join(_IDEA_PATH, 'modules.xml') |
| _VCS_PATH = os.path.join(_IDEA_PATH, 'vcs.xml') |
| _SOURCE_SAMPLE = os.path.join(_TEST_DATA_PATH, 'source.iml') |
| _LOCAL_PATH_TOKEN = '@LOCAL_PATH@' |
| _AOSP_FOLDER = '/aosp' |
| _JAR_DEP_LIST = ['test1.jar', 'test2.jar'] |
| _TEST_SOURCE_LIST = [ |
| 'a/b/c/d', 'a/b/c/d/e', 'a/b/c/d/e/f', 'a/b/c/d/f', 'e/f/a', 'e/f/b/c', |
| 'e/f/g/h' |
| ] |
| _ANDROID_SOURCE_DICT = { |
| 'test_data/project/level11/level21': True, |
| 'test_data/project/level11/level22/level31': False, |
| 'test_data/project/level12/level22': False, |
| } |
| _ANDROID_SOURCE_RELATIVE_PATH = 'test_data/project' |
| _SAMPLE_CONTENT_LIST = ['a/b/c/d', 'e/f'] |
| _SAMPLE_TRIMMED_SOURCE_LIST = ['a/b/c/d', 'e/f/a', 'e/f/b/c', 'e/f/g/h'] |
| _SAMPLE_EXCLUDE_FOLDERS = [ |
| ' <excludeFolder url="file://%s/.idea" />\n' |
| % _TEST_DATA_PATH, |
| ' <excludeFolder url="file://%s/out" />\n' % _TEST_DATA_PATH, |
| ] |
| |
| def test_handle_facet_for_android(self): |
| """Test _handle_facet with android project.""" |
| template = common_util.read_file_content( |
| project_file_gen._TEMPLATE_IML_PATH) |
| android_facet = project_file_gen._handle_facet( |
| template, self._ANDROID_PROJECT_PATH) |
| sample_android_facet = common_util.read_file_content( |
| self._ANDROID_FACET_SAMPLE) |
| self.assertEqual(android_facet, sample_android_facet) |
| |
| def test_handle_facet_for_normal(self): |
| """Test _handle_facet with normal module.""" |
| template = common_util.read_file_content( |
| project_file_gen._TEMPLATE_IML_PATH) |
| project_facet = project_file_gen._handle_facet(template, |
| self._PROJECT_PATH) |
| sample_project_facet = common_util.read_file_content( |
| self._PROJECT_FACET_SAMPLE) |
| self.assertEqual(project_facet, sample_project_facet) |
| |
| def test_handle_module_dependency(self): |
| """Test _module_dependency.""" |
| module_dependency = common_util.read_file_content( |
| project_file_gen._TEMPLATE_IML_PATH) |
| module_dependency = module_dependency.replace( |
| project_file_gen._MODULE_DEP_TOKEN, '') |
| correct_module_dep = common_util.read_file_content( |
| self._MODULE_DEP_SAMPLE) |
| self.assertEqual(correct_module_dep, module_dependency) |
| |
| def test_trim_same_root_source(self): |
| """Test _trim_same_root_source.""" |
| url_list = project_file_gen._trim_same_root_source( |
| self._TEST_SOURCE_LIST[:]) |
| self.assertEqual(url_list, self._SAMPLE_TRIMMED_SOURCE_LIST) |
| |
| def test_handle_source_folder(self): |
| """Test _handle_source_folder.""" |
| template = common_util.read_file_content( |
| project_file_gen._TEMPLATE_IML_PATH) |
| source = project_file_gen._handle_source_folder( |
| self._AOSP_FOLDER, template, |
| copy.deepcopy(self._ANDROID_SOURCE_DICT), True, |
| self._ANDROID_SOURCE_RELATIVE_PATH) |
| sample_source = common_util.read_file_content(self._SOURCE_SAMPLE) |
| self.assertEqual(source, sample_source) |
| |
| def test_generate_iml(self): |
| """Test _generate_iml.""" |
| # Test for main project. |
| try: |
| iml_path, dependencies_iml_path = project_file_gen._generate_iml( |
| self._AOSP_FOLDER, self._ANDROID_PROJECT_PATH, |
| copy.deepcopy(self._ANDROID_SOURCE_DICT), self._JAR_DEP_LIST, |
| self._ANDROID_SOURCE_RELATIVE_PATH, is_main_module=True) |
| test_iml = common_util.read_file_content(iml_path) |
| sample_iml = common_util.read_file_content(self._IML_SAMPLE) |
| finally: |
| os.remove(iml_path) |
| if dependencies_iml_path: |
| os.remove(dependencies_iml_path) |
| self.assertEqual(test_iml, sample_iml) |
| |
| # Test for sub projects. |
| try: |
| iml_path, _ = project_file_gen._generate_iml( |
| self._AOSP_FOLDER, self._ANDROID_PROJECT_PATH, |
| copy.deepcopy(self._ANDROID_SOURCE_DICT), self._JAR_DEP_LIST, |
| self._ANDROID_SOURCE_RELATIVE_PATH) |
| test_iml = common_util.read_file_content(iml_path) |
| sample_iml = common_util.read_file_content(self._IML_SAMPLE) |
| finally: |
| os.remove(iml_path) |
| self.assertEqual(test_iml, sample_iml) |
| |
| def test_generate_modules_xml(self): |
| """Test _generate_modules_xml.""" |
| # Test for main project. |
| try: |
| project_file_gen._generate_modules_xml(self._ANDROID_PROJECT_PATH, |
| []) |
| test_module = common_util.read_file_content(self._MODULE_PATH) |
| finally: |
| shutil.rmtree(self._IDEA_PATH) |
| sample_module = common_util.read_file_content(self._MODULE_XML_SAMPLE) |
| self.assertEqual(test_module, sample_module) |
| |
| # Test for sub projects which only has self module. |
| try: |
| project_file_gen._generate_modules_xml(self._ANDROID_PROJECT_PATH) |
| test_module = common_util.read_file_content(self._MODULE_PATH) |
| finally: |
| shutil.rmtree(self._IDEA_PATH) |
| sample_module = common_util.read_file_content( |
| self._MAIN_MODULE_XML_SAMPLE) |
| self.assertEqual(test_module, sample_module) |
| |
| def test_generate_vcs_xml(self): |
| """Test _generate_vcs_xml.""" |
| try: |
| git_path = os.path.join(self._ANDROID_PROJECT_PATH, |
| project_file_gen._GIT_FOLDER_NAME) |
| os.mkdir(git_path) |
| project_file_gen._generate_vcs_xml(self._ANDROID_PROJECT_PATH) |
| test_vcs = common_util.read_file_content(self._VCS_PATH) |
| finally: |
| shutil.rmtree(self._IDEA_PATH) |
| shutil.rmtree(git_path) |
| sample_vcs = common_util.read_file_content(self._VCS_XML_SAMPLE) |
| # The sample must base on the real path. |
| sample_vcs = sample_vcs.replace(self._LOCAL_PATH_TOKEN, |
| self._ANDROID_PROJECT_PATH) |
| self.assertEqual(test_vcs, sample_vcs) |
| |
| def test_get_uniq_iml_name(self): |
| """Test the unique name cache mechanism. |
| |
| By using the path data in module info json as input, if the count of |
| name data set is the same as sub folder path count, then it means |
| there's no duplicated name, the test PASS. |
| """ |
| # Add following test path |
| test_paths = { |
| 'cts/tests/tests/app', |
| 'cts/tests/app', |
| 'cts/tests/app/app1/../app', |
| 'cts/tests/app/app2/../app', |
| 'cts/tests/app/app3/../app', |
| 'frameworks/base/tests/xxxxxxxxxxxx/base', |
| 'frameworks/base', |
| 'external/xxxxx-xxx/robolectric', |
| 'external/robolectric', |
| } |
| mod_info = module_info.ModuleInfo() |
| test_paths.update(mod_info._get_path_to_module_info( |
| mod_info.name_to_module_info).keys()) |
| print('\n{} {}.'.format('Test_paths length:', len(test_paths))) |
| |
| path_list = [] |
| for k in test_paths: |
| path_list.append(k) |
| print('{} {}.'.format('path list with length:', len(path_list))) |
| |
| names = [project_file_gen.get_unique_iml_name(f) for f in path_list] |
| print('{} {}.'.format('Names list with length:', len(names))) |
| |
| self.assertEqual(len(names), len(path_list)) |
| dic = {} |
| for i, path in enumerate(path_list): |
| dic[names[i]] = path |
| print('{} {}.'.format('The size of name set is:', len(dic))) |
| self.assertEqual(len(dic), len(path_list)) |
| |
| def test_copy_project_files(self): |
| """Test _copy_constant_project_files.""" |
| project_file_gen._copy_constant_project_files( |
| self._ANDROID_PROJECT_PATH) |
| self.assertTrue( |
| os.path.isfile( |
| os.path.join(self._IDEA_PATH, |
| project_file_gen._CODE_STYLE_FOLDER, |
| 'codeStyleConfig.xml'))) |
| self.assertTrue( |
| os.path.isfile( |
| os.path.join(self._IDEA_PATH, |
| project_file_gen._COPYRIGHT_FOLDER, |
| 'Apache_2.xml'))) |
| self.assertTrue( |
| os.path.isfile( |
| os.path.join(self._IDEA_PATH, |
| project_file_gen._COPYRIGHT_FOLDER, |
| 'profiles_settings.xml'))) |
| shutil.rmtree(self._IDEA_PATH) |
| |
| @mock.patch('os.symlink') |
| @mock.patch.object(os.path, 'exists') |
| def test_generate_git_ignore(self, mock_path_exist, mock_link): |
| """Test _generate_git_ignore.""" |
| mock_path_exist.return_value = True |
| project_file_gen._generate_git_ignore(constant.AIDEGEN_ROOT_PATH) |
| self.assertFalse(mock_link.called) |
| |
| def test_filter_out_source_paths(self): |
| """Test _filter_out_source_paths.""" |
| test_set = {'a/java.jar', 'b/java.jar'} |
| module_relpath = 'a' |
| expected_result = {'b/java.jar'} |
| result_set = project_file_gen._filter_out_source_paths(test_set, |
| module_relpath) |
| self.assertEqual(result_set, expected_result) |
| |
| @mock.patch('aidegen.lib.project_info.ProjectInfo') |
| @mock.patch('aidegen.lib.project_info.ProjectInfo') |
| def test_merge_all_source_paths(self, mock_main_project, mock_sub_project): |
| """Test _merge_all_shared_source_paths.""" |
| mock_main_project.project_relative_path = 'main' |
| mock_main_project.source_path = { |
| 'source_folder_path': {'main/java.java', 'share1/java.java'}, |
| 'test_folder_path': {'main/test.java', 'share1/test.java'}, |
| 'jar_path': {'main/jar.jar', 'share1/jar.jar'}, |
| 'r_java_path': {'out/R.java'}, |
| } |
| mock_sub_project.project_relative_path = 'sub' |
| mock_sub_project.source_path = { |
| 'source_folder_path': {'sub/java.java', 'share2/java.java'}, |
| 'test_folder_path': {'sub/test.java', 'share2/test.java'}, |
| 'jar_path': {'sub/jar.jar', 'share2/jar.jar'}, |
| 'r_java_path': {'out/R.java'}, |
| } |
| expected_result = { |
| 'source_folder_path': { |
| 'main/java.java', |
| 'share1/java.java', |
| 'share2/java.java', |
| }, |
| 'test_folder_path': { |
| 'main/test.java', |
| 'share1/test.java', |
| 'share2/test.java', |
| }, |
| 'jar_path': { |
| 'main/jar.jar', |
| 'sub/jar.jar', |
| 'share1/jar.jar', |
| 'share2/jar.jar', |
| }, |
| 'r_java_path': {'out/R.java'} |
| } |
| projects = [mock_main_project, mock_sub_project] |
| project_file_gen._merge_all_shared_source_paths(projects) |
| self.assertEqual(mock_main_project.source_path, expected_result) |
| |
| def test_get_exclude_folders(self): |
| """Test _get_exclude_folders.""" |
| exclude_folders = project_file_gen._get_exclude_content( |
| self._TEST_DATA_PATH) |
| self.assertEqual(self._SAMPLE_EXCLUDE_FOLDERS, exclude_folders) |
| |
| |
| if __name__ == '__main__': |
| unittest.main() |