• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2#
3# Copyright 2018 - The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#     http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17"""Unittests for project_file_gen."""
18
19import copy
20import os
21import shutil
22import unittest
23
24from unittest import mock
25
26from aidegen import constant
27from aidegen import unittest_constants
28from aidegen.lib import project_file_gen
29from atest import module_info
30
31
32# pylint: disable=protected-access
33class AidegenProjectFileGenUnittest(unittest.TestCase):
34    """Unit tests for project_file_gen.py."""
35
36    maxDiff = None
37    _TEST_DATA_PATH = unittest_constants.TEST_DATA_PATH
38    _ANDROID_PROJECT_PATH = os.path.join(_TEST_DATA_PATH, 'android_project')
39    _PROJECT_PATH = os.path.join(_TEST_DATA_PATH, 'project')
40    _ANDROID_FACET_SAMPLE = os.path.join(_TEST_DATA_PATH, 'android_facet.iml')
41    _PROJECT_FACET_SAMPLE = os.path.join(_TEST_DATA_PATH, 'project_facet.iml')
42    _MODULE_DEP_SAMPLE = os.path.join(_TEST_DATA_PATH, 'module_dependency.iml')
43    _IML_SAMPLE = os.path.join(_TEST_DATA_PATH, 'test.iml')
44    _CLASSPATH_SAMPLE = os.path.join(_TEST_DATA_PATH, 'eclipse.classpath')
45    _DEPENDENCIES_IML_SAMPLE = os.path.join(_TEST_DATA_PATH, 'dependencies.iml')
46    _MODULE_XML_SAMPLE = os.path.join(_TEST_DATA_PATH, 'modules.xml')
47    _VCS_XML_SAMPLE = os.path.join(_TEST_DATA_PATH, 'vcs.xml')
48    _IML_PATH = os.path.join(_ANDROID_PROJECT_PATH, 'android_project.iml')
49    _DEPENDENCIES_IML_PATH = os.path.join(_ANDROID_PROJECT_PATH,
50                                          'dependencies.iml')
51    _IDEA_PATH = os.path.join(_ANDROID_PROJECT_PATH, '.idea')
52    _MODULE_PATH = os.path.join(_IDEA_PATH, 'modules.xml')
53    _VCS_PATH = os.path.join(_IDEA_PATH, 'vcs.xml')
54    _SOURCE_SAMPLE = os.path.join(_TEST_DATA_PATH, 'source.iml')
55    _LOCAL_PATH_TOKEN = '@LOCAL_PATH@'
56    _AOSP_FOLDER = '/aosp'
57    _JAR_DEP_LIST = ['test1.jar', 'test2.jar']
58    _TEST_SOURCE_LIST = [
59        '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',
60        'e/f/g/h'
61    ]
62    _ANDROID_SOURCE_DICT = {
63        'test_data/project/level11/level21': True,
64        'test_data/project/level11/level22/level31': False,
65        'test_data/project/level12/level22': False,
66    }
67    _ANDROID_SOURCE_RELATIVE_PATH = 'test_data/project'
68    _SAMPLE_CONTENT_LIST = ['a/b/c/d', 'e/f']
69    _SAMPLE_TRIMMED_SOURCE_LIST = ['a/b/c/d', 'e/f/a', 'e/f/b/c', 'e/f/g/h']
70
71    def test_handle_facet_for_android(self):
72        """Test _handle_facet with android project."""
73        template = project_file_gen._read_file_content(
74            project_file_gen._TEMPLATE_IML_PATH)
75        android_facet = project_file_gen._handle_facet(
76            template, self._ANDROID_PROJECT_PATH)
77        sample_android_facet = project_file_gen._read_file_content(
78            self._ANDROID_FACET_SAMPLE)
79        self.assertEqual(android_facet, sample_android_facet)
80
81    def test_handle_facet_for_normal(self):
82        """Test _handle_facet with normal module."""
83        template = project_file_gen._read_file_content(
84            project_file_gen._TEMPLATE_IML_PATH)
85        project_facet = project_file_gen._handle_facet(template,
86                                                       self._PROJECT_PATH)
87        sample_project_facet = project_file_gen._read_file_content(
88            self._PROJECT_FACET_SAMPLE)
89        self.assertEqual(project_facet, sample_project_facet)
90
91    def test_handle_module_dependency(self):
92        """Test _module_dependency."""
93        module_dependency = project_file_gen._read_file_content(
94            project_file_gen._TEMPLATE_IML_PATH)
95        module_dependency = module_dependency.replace(
96            project_file_gen._MODULE_DEP_TOKEN, '')
97        correct_module_dep = project_file_gen._read_file_content(
98            self._MODULE_DEP_SAMPLE)
99        self.assertEqual(correct_module_dep, module_dependency)
100
101    def test_trim_same_root_source(self):
102        """Test _trim_same_root_source."""
103        url_list = project_file_gen._trim_same_root_source(
104            self._TEST_SOURCE_LIST[:])
105        self.assertEqual(url_list, self._SAMPLE_TRIMMED_SOURCE_LIST)
106
107    def test_handle_source_folder(self):
108        """Test _handle_source_folder."""
109        template = project_file_gen._read_file_content(
110            project_file_gen._TEMPLATE_IML_PATH)
111        source = project_file_gen._handle_source_folder(
112            self._AOSP_FOLDER, template,
113            copy.deepcopy(self._ANDROID_SOURCE_DICT), True,
114            self._ANDROID_SOURCE_RELATIVE_PATH)
115        sample_source = project_file_gen._read_file_content(self._SOURCE_SAMPLE)
116        self.assertEqual(source, sample_source)
117
118    def test_generate_iml(self):
119        """Test _generate_iml."""
120        try:
121            iml_path, dependencies_iml_path = project_file_gen._generate_iml(
122                self._AOSP_FOLDER, self._ANDROID_PROJECT_PATH,
123                copy.deepcopy(self._ANDROID_SOURCE_DICT), self._JAR_DEP_LIST,
124                self._ANDROID_SOURCE_RELATIVE_PATH)
125            test_iml = project_file_gen._read_file_content(iml_path)
126            sample_iml = project_file_gen._read_file_content(self._IML_SAMPLE)
127        finally:
128            os.remove(iml_path)
129            os.remove(dependencies_iml_path)
130        self.assertEqual(test_iml, sample_iml)
131
132    def test_generate_modules_xml(self):
133        """Test _generate_modules_xml."""
134        try:
135            project_file_gen._generate_modules_xml(self._ANDROID_PROJECT_PATH)
136            test_module = project_file_gen._read_file_content(self._MODULE_PATH)
137        finally:
138            shutil.rmtree(self._IDEA_PATH)
139        sample_module = project_file_gen._read_file_content(
140            self._MODULE_XML_SAMPLE)
141        self.assertEqual(test_module, sample_module)
142
143    def test_generate_vcs_xml(self):
144        """Test _generate_vcs_xml."""
145        try:
146            git_path = os.path.join(self._ANDROID_PROJECT_PATH,
147                                    project_file_gen._GIT_FOLDER_NAME)
148            os.mkdir(git_path)
149            project_file_gen._generate_vcs_xml(self._ANDROID_PROJECT_PATH)
150            test_vcs = project_file_gen._read_file_content(self._VCS_PATH)
151        finally:
152            shutil.rmtree(self._IDEA_PATH)
153            shutil.rmtree(git_path)
154        sample_vcs = project_file_gen._read_file_content(self._VCS_XML_SAMPLE)
155        # The sample must base on the real path.
156        sample_vcs = sample_vcs.replace(self._LOCAL_PATH_TOKEN,
157                                        self._ANDROID_PROJECT_PATH)
158        self.assertEqual(test_vcs, sample_vcs)
159
160    def test_get_uniq_iml_name(self):
161        """Test the unique name cache mechanism.
162
163        By using the path data in module info json as input, if the count of
164        name data set is the same as sub folder path count, then it means
165        there's no duplicated name, the test PASS.
166        """
167        # Add following test path
168        test_paths = {
169            'cts/tests/tests/app',
170            'cts/tests/app',
171            'cts/tests/app/app1/../app',
172            'cts/tests/app/app2/../app',
173            'cts/tests/app/app3/../app',
174            'frameworks/base/tests/xxxxxxxxxxxx/base',
175            'frameworks/base',
176            'external/xxxxx-xxx/robolectric',
177            'external/robolectric',
178        }
179        mod_info = module_info.ModuleInfo()
180        test_paths.update(mod_info._get_path_to_module_info(
181            mod_info.name_to_module_info).keys())
182        print('\n{} {}.'.format('Test_paths length:', len(test_paths)))
183
184        path_list = []
185        for k in test_paths:
186            path_list.append(k)
187        print('{} {}.'.format('path list with length:', len(path_list)))
188
189        names = [project_file_gen.get_unique_iml_name(f) for f in path_list]
190        print('{} {}.'.format('Names list with length:', len(names)))
191
192        self.assertEqual(len(names), len(path_list))
193        dic = {}
194        for i, path in enumerate(path_list):
195            dic[names[i]] = path
196        print('{} {}.'.format('The size of name set is:', len(dic)))
197        self.assertEqual(len(dic), len(path_list))
198
199    def test_copy_project_files(self):
200        """Test _copy_constant_project_files."""
201        project_file_gen._copy_constant_project_files(
202            self._ANDROID_PROJECT_PATH)
203        self.assertTrue(
204            os.path.isfile(
205                os.path.join(self._IDEA_PATH,
206                             project_file_gen._CODE_STYLE_FOLDER,
207                             'codeStyleConfig.xml')))
208        self.assertTrue(
209            os.path.isfile(
210                os.path.join(self._IDEA_PATH,
211                             project_file_gen._COPYRIGHT_FOLDER,
212                             'Apache_2.xml')))
213        self.assertTrue(
214            os.path.isfile(
215                os.path.join(self._IDEA_PATH,
216                             project_file_gen._COPYRIGHT_FOLDER,
217                             'profiles_settings.xml')))
218        shutil.rmtree(self._IDEA_PATH)
219
220    def test_generate_classpath(self):
221        """Test _generate_classpath."""
222        try:
223            classpath = project_file_gen._generate_classpath(
224                self._ANDROID_PROJECT_PATH,
225                copy.deepcopy(list(sorted(self._ANDROID_SOURCE_DICT))),
226                self._JAR_DEP_LIST)
227            test_iml = project_file_gen._read_file_content(classpath)
228            sample_iml = project_file_gen._read_file_content(
229                self._CLASSPATH_SAMPLE)
230        finally:
231            os.remove(classpath)
232        self.assertEqual(test_iml, sample_iml)
233
234    @mock.patch('os.symlink')
235    @mock.patch.object(os.path, 'exists')
236    def test_generate_git_ignore(self, mock_path_exist, mock_link):
237        """Test _generate_git_ignore."""
238        mock_path_exist.return_value = True
239        project_file_gen._generate_git_ignore(constant.AIDEGEN_ROOT_PATH)
240        self.assertFalse(mock_link.called)
241
242
243if __name__ == '__main__':
244    unittest.main()
245