1#!/usr/bin/env python
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 module_info."""
18
19import os
20import unittest
21import mock
22
23import constants
24import module_info
25import unittest_constants as uc
26
27JSON_FILE_PATH = os.path.join(uc.TEST_DATA_DIR, uc.JSON_FILE)
28EXPECTED_MOD_TARGET = 'tradefed'
29EXPECTED_MOD_TARGET_PATH = ['tf/core']
30UNEXPECTED_MOD_TARGET = 'this_should_not_be_in_module-info.json'
31MOD_NO_PATH = 'module-no-path'
32PATH_TO_MULT_MODULES = 'shared/path/to/be/used'
33MULT_MOODULES_WITH_SHARED_PATH = ['module2', 'module1']
34
35#pylint: disable=protected-access
36class ModuleInfoUnittests(unittest.TestCase):
37    """Unit tests for module_info.py"""
38
39    @mock.patch('json.load', return_value={})
40    @mock.patch('__builtin__.open', new_callable=mock.mock_open)
41    @mock.patch('os.path.isfile', return_value=True)
42    def test_load_mode_info_file_out_dir_handling(self, _isfile, _open, _json):
43        """Test _load_module_info_file out dir handling."""
44        # Test out default out dir is used.
45        build_top = '/path/to/top'
46        default_out_dir = os.path.join(build_top, 'out/dir/here')
47        os_environ_mock = {constants.ANDROID_OUT: default_out_dir,
48                           'ANDROID_PRODUCT_OUT': default_out_dir,
49                           constants.ANDROID_BUILD_TOP: build_top}
50        default_out_dir_mod_targ = 'out/dir/here/module-info.json'
51        # Make sure module_info_target is what we think it is.
52        with mock.patch.dict('os.environ', os_environ_mock, clear=True):
53            mod_info = module_info.ModuleInfo()
54            self.assertEqual(default_out_dir_mod_targ,
55                             mod_info.module_info_target)
56
57        # Test out custom out dir is used (OUT_DIR=dir2).
58        custom_out_dir = os.path.join(build_top, 'out2/dir/here')
59        os_environ_mock = {constants.ANDROID_OUT: custom_out_dir,
60                           'OUT_DIR': 'out2',
61                           'ANDROID_PRODUCT_OUT': custom_out_dir,
62                           constants.ANDROID_BUILD_TOP: build_top}
63        custom_out_dir_mod_targ = 'out2/dir/here/module-info.json'
64        # Make sure module_info_target is what we think it is.
65        with mock.patch.dict('os.environ', os_environ_mock, clear=True):
66            mod_info = module_info.ModuleInfo()
67            self.assertEqual(custom_out_dir_mod_targ,
68                             mod_info.module_info_target)
69
70        # Test out custom abs out dir is used (OUT_DIR=/tmp/out/dir2).
71        abs_custom_out_dir = '/tmp/out/dir'
72        os_environ_mock = {constants.ANDROID_OUT: abs_custom_out_dir,
73                           'OUT_DIR': abs_custom_out_dir,
74                           'ANDROID_PRODUCT_OUT': abs_custom_out_dir,
75                           constants.ANDROID_BUILD_TOP: build_top}
76        custom_abs_out_dir_mod_targ = '/tmp/out/dir/module-info.json'
77        # Make sure module_info_target is what we think it is.
78        with mock.patch.dict('os.environ', os_environ_mock, clear=True):
79            mod_info = module_info.ModuleInfo()
80            self.assertEqual(custom_abs_out_dir_mod_targ,
81                             mod_info.module_info_target)
82
83    @mock.patch.object(module_info.ModuleInfo, '_load_module_info_file',)
84    def test_get_path_to_module_info(self, mock_load_module):
85        """Test that we correctly create the path to module info dict."""
86        mod_one = 'mod1'
87        mod_two = 'mod2'
88        mod_path_one = '/path/to/mod1'
89        mod_path_two = '/path/to/mod2'
90        mod_info_dict = {mod_one: {constants.MODULE_PATH: [mod_path_one]},
91                         mod_two: {constants.MODULE_PATH: [mod_path_two]}}
92        mock_load_module.return_value = ('mod_target', mod_info_dict)
93        path_to_mod_info = {mod_path_one: [{constants.MODULE_NAME: mod_one,
94                                            constants.MODULE_PATH: [mod_path_one]}],
95                            mod_path_two: [{constants.MODULE_NAME: mod_two,
96                                            constants.MODULE_PATH: [mod_path_two]}]}
97        mod_info = module_info.ModuleInfo()
98        self.assertDictEqual(path_to_mod_info,
99                             mod_info._get_path_to_module_info(mod_info_dict))
100
101    def test_is_module(self):
102        """Test that we get the module when it's properly loaded."""
103        # Load up the test json file and check that module is in it
104        mod_info = module_info.ModuleInfo(module_file=JSON_FILE_PATH)
105        self.assertTrue(mod_info.is_module(EXPECTED_MOD_TARGET))
106        self.assertFalse(mod_info.is_module(UNEXPECTED_MOD_TARGET))
107
108    def test_get_path(self):
109        """Test that we get the module path when it's properly loaded."""
110        # Load up the test json file and check that module is in it
111        mod_info = module_info.ModuleInfo(module_file=JSON_FILE_PATH)
112        self.assertEqual(mod_info.get_paths(EXPECTED_MOD_TARGET),
113                         EXPECTED_MOD_TARGET_PATH)
114        self.assertEqual(mod_info.get_paths(MOD_NO_PATH), [])
115
116    def test_get_module_names(self):
117        """test that we get the module name properly."""
118        mod_info = module_info.ModuleInfo(module_file=JSON_FILE_PATH)
119        self.assertEqual(mod_info.get_module_names(EXPECTED_MOD_TARGET_PATH[0]),
120                         [EXPECTED_MOD_TARGET])
121        self.assertEqual(mod_info.get_module_names(PATH_TO_MULT_MODULES),
122                         MULT_MOODULES_WITH_SHARED_PATH)
123
124
125
126if __name__ == '__main__':
127    unittest.main()
128