xref: /aosp_15_r20/tools/asuite/aidegen/sdk/jdk_table_unittest.py (revision c2e18aaa1096c836b086f94603d04f4eb9cf37f5)
1#!/usr/bin/env python3
2#
3# Copyright 2020, 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 JDKTableXML class."""
18
19import os
20import shutil
21import tempfile
22import unittest
23
24from unittest import mock
25from xml.etree import ElementTree
26
27from aidegen.lib import aidegen_metrics
28from aidegen.lib import common_util
29from aidegen.lib import xml_util
30from aidegen.sdk import android_sdk
31from aidegen.sdk import jdk_table
32
33
34# pylint: disable=protected-access
35# pylint: disable=too-many-arguments
36class JDKTableXMLUnittests(unittest.TestCase):
37    """Unit tests for JDKTableXML class."""
38
39    _JDK_TABLE_XML = 'jdk.table.xml'
40    _CONFIG_FILE = '/path/to/jdk.table.xml'
41    _JDK_CONTENT = '<jdk />'
42    _JDK_PATH = '/path/to/JDK'
43    _DEFAULT_ANDROID_SDK_PATH = '/path/to/Android/SDK'
44    _TEST_DIR = None
45
46    def setUp(self):
47        """Prepare the JDKTableXML class."""
48        JDKTableXMLUnittests._TEST_DIR = tempfile.mkdtemp()
49        self.jdk_table_xml = jdk_table.JDKTableXML(
50            self._CONFIG_FILE, self._JDK_CONTENT, self._JDK_PATH,
51            self._DEFAULT_ANDROID_SDK_PATH)
52
53    def tearDown(self):
54        """Clear the JDKTableXML class."""
55        self.jdk_table_xml = None
56        shutil.rmtree(JDKTableXMLUnittests._TEST_DIR)
57
58    @mock.patch.object(common_util, 'file_generate')
59    @mock.patch('os.path.exists')
60    @mock.patch.object(ElementTree, 'parse')
61    def test_init(self, mock_parse, mock_exists, mock_gen_file):
62        """Test initialize the attributes."""
63        self.assertEqual(self.jdk_table_xml._platform_version, None)
64        self.assertEqual(self.jdk_table_xml._android_sdk_version, None)
65        self.assertEqual(self.jdk_table_xml._modify_config, False)
66        mock_exists.return_value = True
67        mock_parse.return_value = None
68        jdk_table.JDKTableXML(None, None, None, None)
69        self.assertTrue(mock_parse.called)
70        mock_exists.return_value = False
71        jdk_table.JDKTableXML(None, None, None, None)
72        self.assertTrue(mock_parse.called)
73        self.assertTrue(mock_gen_file.called)
74
75    def test_android_sdk_version(self):
76        """Test android_sdk_version."""
77        self.assertEqual(self.jdk_table_xml.android_sdk_version, None)
78
79    def test_check_structure(self):
80        """Test _check_structure."""
81        tmp_file = os.path.join(self._TEST_DIR, self._JDK_TABLE_XML)
82        xml_str = ('<application>\n</application>')
83        with open(tmp_file, 'w', encoding='utf-8') as tmp_jdk_xml:
84            tmp_jdk_xml.write(xml_str)
85        self.jdk_table_xml._xml = ElementTree.parse(tmp_file)
86        self.assertFalse(self.jdk_table_xml._check_structure())
87        xml_str = ('<application>\n'
88                   '  <component>\n'
89                   '  </component>\n'
90                   '</application>')
91        with open(tmp_file, 'w', encoding='utf-8') as tmp_jdk_xml:
92            tmp_jdk_xml.write(xml_str)
93        self.jdk_table_xml._xml = ElementTree.parse(tmp_file)
94        self.assertFalse(self.jdk_table_xml._check_structure())
95        xml_str = ('<application>\n'
96                   '  <component name="ProjectJdkTable">\n'
97                   '  </component>\n'
98                   '</application>')
99        with open(tmp_file, 'w', encoding='utf-8') as tmp_jdk_xml:
100            tmp_jdk_xml.write(xml_str)
101        self.jdk_table_xml._xml = ElementTree.parse(tmp_file)
102        self.assertTrue(self.jdk_table_xml._check_structure())
103
104    @mock.patch.object(jdk_table.JDKTableXML, '_check_jdk21_in_xml')
105    def test_generate_jdk_config_string(self, mock_jdk_exists):
106        """Test _generate_jdk_config_string."""
107        mock_jdk_exists.return_value = True
108        self.jdk_table_xml._generate_jdk_config_string()
109        self.assertFalse(self.jdk_table_xml._modify_config)
110        mock_jdk_exists.return_value = False
111        expected_result = (b'<application>\n'
112                           b'  <component name="ProjectJdkTable">\n'
113                           b'    <jdk />\n'
114                           b'  </component>\n'
115                           b'</application>')
116        self.jdk_table_xml._generate_jdk_config_string()
117        test_result = ElementTree.tostring(self.jdk_table_xml._xml.getroot())
118        self.assertTrue(self.jdk_table_xml._modify_config)
119        self.assertEqual(test_result, expected_result)
120        xml_str = ('<application>\n'
121                   '  <component name="ProjectJdkTable">\n'
122                   '    <jdk>\n'
123                   '      <name value="test" />\n'
124                   '      <type value="JavaSDK" />\n'
125                   '    </jdk>\n'
126                   '  </component>\n'
127                   '</application>')
128        expected_result = (b'<application>\n'
129                           b'  <component name="ProjectJdkTable">\n'
130                           b'    <jdk>\n'
131                           b'      <name value="test" />\n'
132                           b'      <type value="JavaSDK" />\n'
133                           b'    </jdk>\n'
134                           b'    <jdk />\n'
135                           b'  </component>\n'
136                           b'</application>')
137        tmp_file = os.path.join(self._TEST_DIR, self._JDK_TABLE_XML)
138        with open(tmp_file, 'w', encoding='utf-8') as tmp_jdk_xml:
139            tmp_jdk_xml.write(xml_str)
140        self.jdk_table_xml._xml = ElementTree.parse(tmp_file)
141        self.jdk_table_xml._generate_jdk_config_string()
142        test_result = ElementTree.tostring(self.jdk_table_xml._xml.getroot())
143        self.assertEqual(test_result, expected_result)
144
145    @mock.patch.object(jdk_table.JDKTableXML, '_override_xml')
146    @mock.patch.object(ElementTree.ElementTree, 'write')
147    @mock.patch('os.path.exists')
148    @mock.patch.object(jdk_table.JDKTableXML, '_generate_sdk_config_string')
149    @mock.patch.object(jdk_table.JDKTableXML, '_generate_jdk_config_string')
150    @mock.patch.object(jdk_table.JDKTableXML, '_check_structure')
151    def test_config_jdk_table_xml(self, mock_check_structure, mock_gen_jdk,
152                                  mock_gen_sdk, mock_exist, mock_xml_write,
153                                  mock_override):
154        """Test config_jdk_table_xml."""
155        mock_check_structure.return_value = True
156        mock_exist.return_value = True
157        self.jdk_table_xml.config_jdk_table_xml()
158        self.assertTrue(mock_gen_jdk.called)
159        self.assertTrue(mock_gen_sdk.called)
160        self.jdk_table_xml._modify_config = False
161        self.jdk_table_xml.config_jdk_table_xml()
162        self.assertFalse(mock_xml_write.called)
163        self.jdk_table_xml._modify_config = True
164        self.jdk_table_xml._android_sdk_version = 'test'
165        self.jdk_table_xml.config_jdk_table_xml()
166        self.assertTrue(mock_xml_write.called)
167        mock_check_structure.return_value = False
168        mock_override.return_value = False
169        self.assertFalse(self.jdk_table_xml.config_jdk_table_xml())
170        mock_check_structure.return_value = False
171        mock_override.return_value = True
172        self.assertTrue(mock_gen_jdk.called)
173
174    def test_check_jdk21_in_xml(self):
175        """Test _check_jdk21_in_xml."""
176        xml_str = ('<test><jdk><name value="JDK21" /><type value="JavaSDK" />'
177                   '</jdk></test>')
178        self.jdk_table_xml._xml = ElementTree.fromstring(xml_str)
179        self.assertTrue(self.jdk_table_xml._check_jdk21_in_xml())
180        xml_str = ('<test><jdk><name value="test" /><type value="JavaSDK" />'
181                   '</jdk></test>')
182        self.jdk_table_xml._xml = ElementTree.fromstring(xml_str)
183        self.assertFalse(self.jdk_table_xml._check_jdk21_in_xml())
184        xml_str = ('<test><jdk><name value="test" /></jdk></test>')
185        self.jdk_table_xml._xml = ElementTree.fromstring(xml_str)
186        self.assertFalse(self.jdk_table_xml._check_jdk21_in_xml())
187
188    @mock.patch.object(android_sdk.AndroidSDK, 'is_android_sdk_path')
189    def test_check_android_sdk_in_xml(self, mock_is_android_sdk):
190        """Test _check_android_sdk_in_xml."""
191        self.jdk_table_xml._sdk._platform_mapping = {
192            'android-29': {
193                'api_level': 29,
194                'code_name': '29',
195            },
196        }
197        mock_is_android_sdk.return_value = True
198        xml_str = ('<test><jdk><name value="JDK21" /><type value="JavaSDK" />'
199                   '</jdk></test>')
200        self.jdk_table_xml._xml = ElementTree.fromstring(xml_str)
201        self.assertFalse(self.jdk_table_xml._check_android_sdk_in_xml())
202        xml_str = ('<test><jdk><name value="Android SDK 29 platform" />'
203                   '<type value="Android SDK" />'
204                   '<additional jdk="JDK21" sdk="android-29" />'
205                   '</jdk></test>')
206        self.jdk_table_xml._xml = ElementTree.fromstring(xml_str)
207        self.assertFalse(self.jdk_table_xml._check_android_sdk_in_xml())
208        xml_str = ('<test><jdk><name value="Android SDK 28 platform" />'
209                   '<type value="Android SDK" />'
210                   '<homePath value="/path/to/Android/SDK" />'
211                   '<additional jdk="JDK21" sdk="android-28" />'
212                   '</jdk></test>')
213        self.jdk_table_xml._xml = ElementTree.fromstring(xml_str)
214        self.assertFalse(self.jdk_table_xml._check_android_sdk_in_xml())
215        xml_str = ('<test><jdk><name value="Android SDK 29 platform" />'
216                   '<type value="Android SDK" />'
217                   '<homePath value="/path/to/Android/SDK" />'
218                   '<additional jdk="JDK21" sdk="android-29" />'
219                   '</jdk></test>')
220        self.jdk_table_xml._xml = ElementTree.fromstring(xml_str)
221        self.assertTrue(self.jdk_table_xml._check_android_sdk_in_xml())
222        mock_is_android_sdk.return_value = False
223        self.jdk_table_xml._xml = ElementTree.fromstring(xml_str)
224        self.assertFalse(self.jdk_table_xml._check_android_sdk_in_xml())
225
226    @mock.patch.object(aidegen_metrics, 'send_exception_metrics')
227    @mock.patch.object(android_sdk.AndroidSDK, 'path_analysis')
228    @mock.patch.object(common_util, 'read_file_content')
229    @mock.patch.object(jdk_table.JDKTableXML, '_check_android_sdk_in_xml')
230    def test_generate_sdk_config_string(self, mock_sdk_in_xml, mock_read_file,
231                                        mock_path_analysis, mock_metrics):
232        """Test _generate_sdk_config_string."""
233        mock_sdk_in_xml.return_value = True
234        self.jdk_table_xml._generate_sdk_config_string()
235        self.assertFalse(self.jdk_table_xml._modify_config)
236        mock_sdk_in_xml.return_value = False
237        mock_path_analysis.return_value = False
238        self.jdk_table_xml._generate_sdk_config_string()
239        self.assertTrue(mock_metrics.called)
240        mock_path_analysis.return_value = True
241        mock_read_file.return_value = ''
242        self.jdk_table_xml._generate_sdk_config_string()
243        self.assertTrue(self.jdk_table_xml._modify_config)
244
245    @mock.patch.object(aidegen_metrics, 'send_exception_metrics')
246    @mock.patch('builtins.input')
247    def test_override_xml(self, mock_input, mock_metrics):
248        """Test _override_xml."""
249        mock_input.side_effect = ['1', 'n']
250        self.assertFalse(self.jdk_table_xml._override_xml())
251        self.assertEqual(mock_input.call_count, 2)
252        mock_input.side_effect = ['n']
253        result = self.jdk_table_xml._override_xml()
254        self.assertFalse(result)
255        mock_input.side_effect = ['y']
256        expected_result = (b'<application>\n'
257                           b'  <component name="ProjectJdkTable">\n'
258                           b'  </component>\n'
259                           b'</application>')
260        self.jdk_table_xml._override_xml()
261        test_result = ElementTree.tostring(self.jdk_table_xml._xml.getroot())
262        self.assertEqual(test_result, expected_result)
263        self.assertTrue(mock_metrics.called)
264
265    @mock.patch.object(xml_util, 'parse_xml')
266    @mock.patch.object(aidegen_metrics, 'send_exception_metrics')
267    @mock.patch('builtins.input')
268    def test_skip_send_metrics(self, mock_input, mock_metrics, mock_parse):
269        """Test _override_xml."""
270        mock_input.side_effect = ['y']
271        self.jdk_table_xml._xml = None
272        self.jdk_table_xml._override_xml()
273        self.assertFalse(mock_metrics.called)
274        self.assertTrue(mock_parse.called)
275
276
277if __name__ == '__main__':
278    unittest.main()
279