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