blob: 0a62b10a4dbecb28f516de85489a174f42f0b94d [file] [log] [blame]
Colin Cross8bb10e82018-06-07 16:46:02 -07001#!/usr/bin/env python
2#
3# Copyright (C) 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#
Colin Cross72119102019-05-20 13:14:18 -070017"""Unit tests for manifest_fixer.py."""
Colin Cross8bb10e82018-06-07 16:46:02 -070018
Cole Faustc41dd722021-11-09 15:08:26 -080019import io
Colin Cross8bb10e82018-06-07 16:46:02 -070020import sys
21import unittest
22from xml.dom import minidom
Cole Faustc41dd722021-11-09 15:08:26 -080023import xml.etree.ElementTree as ET
Colin Cross8bb10e82018-06-07 16:46:02 -070024
25import manifest_fixer
26
27sys.dont_write_bytecode = True
28
Colin Cross8bb10e82018-06-07 16:46:02 -070029class CompareVersionGtTest(unittest.TestCase):
30 """Unit tests for compare_version_gt function."""
31
32 def test_sdk(self):
33 """Test comparing sdk versions."""
34 self.assertTrue(manifest_fixer.compare_version_gt('28', '27'))
35 self.assertFalse(manifest_fixer.compare_version_gt('27', '28'))
36 self.assertFalse(manifest_fixer.compare_version_gt('28', '28'))
37
38 def test_codename(self):
39 """Test comparing codenames."""
40 self.assertTrue(manifest_fixer.compare_version_gt('Q', 'P'))
41 self.assertFalse(manifest_fixer.compare_version_gt('P', 'Q'))
42 self.assertFalse(manifest_fixer.compare_version_gt('Q', 'Q'))
43
44 def test_sdk_codename(self):
45 """Test comparing sdk versions with codenames."""
46 self.assertTrue(manifest_fixer.compare_version_gt('Q', '28'))
47 self.assertFalse(manifest_fixer.compare_version_gt('28', 'Q'))
48
49 def test_compare_numeric(self):
50 """Test that numbers are compared in numeric and not lexicographic order."""
51 self.assertTrue(manifest_fixer.compare_version_gt('18', '8'))
52
53
54class RaiseMinSdkVersionTest(unittest.TestCase):
55 """Unit tests for raise_min_sdk_version function."""
56
Colin Cross496d66d2018-09-10 14:02:18 -070057 def raise_min_sdk_version_test(self, input_manifest, min_sdk_version,
Colin Cross7b59e7b2018-09-10 13:35:13 -070058 target_sdk_version, library):
Colin Cross8bb10e82018-06-07 16:46:02 -070059 doc = minidom.parseString(input_manifest)
Colin Cross7b59e7b2018-09-10 13:35:13 -070060 manifest_fixer.raise_min_sdk_version(doc, min_sdk_version,
61 target_sdk_version, library)
Cole Faustc41dd722021-11-09 15:08:26 -080062 output = io.StringIO()
Colin Cross8bb10e82018-06-07 16:46:02 -070063 manifest_fixer.write_xml(output, doc)
64 return output.getvalue()
65
66 manifest_tmpl = (
67 '<?xml version="1.0" encoding="utf-8"?>\n'
68 '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n'
69 '%s'
70 '</manifest>\n')
71
Colin Cross1b6a3cf2018-07-24 14:51:30 -070072 # pylint: disable=redefined-builtin
73 def uses_sdk(self, min=None, target=None, extra=''):
Colin Cross496d66d2018-09-10 14:02:18 -070074 attrs = ''
Colin Cross1b6a3cf2018-07-24 14:51:30 -070075 if min:
76 attrs += ' android:minSdkVersion="%s"' % (min)
77 if target:
78 attrs += ' android:targetSdkVersion="%s"' % (target)
Colin Cross8bb10e82018-06-07 16:46:02 -070079 if extra:
Colin Cross496d66d2018-09-10 14:02:18 -070080 attrs += ' ' + extra
Colin Cross1b6a3cf2018-07-24 14:51:30 -070081 return ' <uses-sdk%s/>\n' % (attrs)
Colin Cross8bb10e82018-06-07 16:46:02 -070082
Cole Faustc41dd722021-11-09 15:08:26 -080083 def assert_xml_equal(self, output, expected):
84 self.assertEqual(ET.canonicalize(output), ET.canonicalize(expected))
85
Colin Cross8bb10e82018-06-07 16:46:02 -070086 def test_no_uses_sdk(self):
87 """Tests inserting a uses-sdk element into a manifest."""
88
89 manifest_input = self.manifest_tmpl % ''
Colin Cross1b6a3cf2018-07-24 14:51:30 -070090 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='28')
Colin Cross7b59e7b2018-09-10 13:35:13 -070091 output = self.raise_min_sdk_version_test(manifest_input, '28', '28', False)
Cole Faustc41dd722021-11-09 15:08:26 -080092 self.assert_xml_equal(output, expected)
Colin Cross8bb10e82018-06-07 16:46:02 -070093
94 def test_no_min(self):
95 """Tests inserting a minSdkVersion attribute into a uses-sdk element."""
96
97 manifest_input = self.manifest_tmpl % ' <uses-sdk extra="foo"/>\n'
Colin Cross1b6a3cf2018-07-24 14:51:30 -070098 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='28',
99 extra='extra="foo"')
Colin Cross7b59e7b2018-09-10 13:35:13 -0700100 output = self.raise_min_sdk_version_test(manifest_input, '28', '28', False)
Cole Faustc41dd722021-11-09 15:08:26 -0800101 self.assert_xml_equal(output, expected)
Colin Cross8bb10e82018-06-07 16:46:02 -0700102
103 def test_raise_min(self):
104 """Tests inserting a minSdkVersion attribute into a uses-sdk element."""
105
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700106 manifest_input = self.manifest_tmpl % self.uses_sdk(min='27')
Colin Cross496d66d2018-09-10 14:02:18 -0700107 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='28')
Colin Cross7b59e7b2018-09-10 13:35:13 -0700108 output = self.raise_min_sdk_version_test(manifest_input, '28', '28', False)
Cole Faustc41dd722021-11-09 15:08:26 -0800109 self.assert_xml_equal(output, expected)
Colin Cross8bb10e82018-06-07 16:46:02 -0700110
111 def test_raise(self):
112 """Tests raising a minSdkVersion attribute."""
113
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700114 manifest_input = self.manifest_tmpl % self.uses_sdk(min='27')
Colin Cross496d66d2018-09-10 14:02:18 -0700115 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='28')
Colin Cross7b59e7b2018-09-10 13:35:13 -0700116 output = self.raise_min_sdk_version_test(manifest_input, '28', '28', False)
Cole Faustc41dd722021-11-09 15:08:26 -0800117 self.assert_xml_equal(output, expected)
Colin Cross8bb10e82018-06-07 16:46:02 -0700118
119 def test_no_raise_min(self):
120 """Tests a minSdkVersion that doesn't need raising."""
121
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700122 manifest_input = self.manifest_tmpl % self.uses_sdk(min='28')
Colin Cross496d66d2018-09-10 14:02:18 -0700123 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='27')
Colin Cross7b59e7b2018-09-10 13:35:13 -0700124 output = self.raise_min_sdk_version_test(manifest_input, '27', '27', False)
Cole Faustc41dd722021-11-09 15:08:26 -0800125 self.assert_xml_equal(output, expected)
Colin Cross8bb10e82018-06-07 16:46:02 -0700126
127 def test_raise_codename(self):
128 """Tests raising a minSdkVersion attribute to a codename."""
129
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700130 manifest_input = self.manifest_tmpl % self.uses_sdk(min='28')
Colin Cross496d66d2018-09-10 14:02:18 -0700131 expected = self.manifest_tmpl % self.uses_sdk(min='P', target='P')
Colin Cross7b59e7b2018-09-10 13:35:13 -0700132 output = self.raise_min_sdk_version_test(manifest_input, 'P', 'P', False)
Cole Faustc41dd722021-11-09 15:08:26 -0800133 self.assert_xml_equal(output, expected)
Colin Cross8bb10e82018-06-07 16:46:02 -0700134
135 def test_no_raise_codename(self):
136 """Tests a minSdkVersion codename that doesn't need raising."""
137
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700138 manifest_input = self.manifest_tmpl % self.uses_sdk(min='P')
Colin Cross496d66d2018-09-10 14:02:18 -0700139 expected = self.manifest_tmpl % self.uses_sdk(min='P', target='28')
Colin Cross7b59e7b2018-09-10 13:35:13 -0700140 output = self.raise_min_sdk_version_test(manifest_input, '28', '28', False)
Cole Faustc41dd722021-11-09 15:08:26 -0800141 self.assert_xml_equal(output, expected)
Colin Cross8bb10e82018-06-07 16:46:02 -0700142
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700143 def test_target(self):
144 """Tests an existing targetSdkVersion is preserved."""
145
146 manifest_input = self.manifest_tmpl % self.uses_sdk(min='26', target='27')
147 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='27')
Colin Cross7b59e7b2018-09-10 13:35:13 -0700148 output = self.raise_min_sdk_version_test(manifest_input, '28', '29', False)
Cole Faustc41dd722021-11-09 15:08:26 -0800149 self.assert_xml_equal(output, expected)
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700150
151 def test_no_target(self):
152 """Tests inserting targetSdkVersion when minSdkVersion exists."""
153
154 manifest_input = self.manifest_tmpl % self.uses_sdk(min='27')
Colin Cross7b59e7b2018-09-10 13:35:13 -0700155 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='29')
156 output = self.raise_min_sdk_version_test(manifest_input, '28', '29', False)
Cole Faustc41dd722021-11-09 15:08:26 -0800157 self.assert_xml_equal(output, expected)
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700158
159 def test_target_no_min(self):
Colin Cross7b59e7b2018-09-10 13:35:13 -0700160 """"Tests inserting targetSdkVersion when minSdkVersion exists."""
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700161
Colin Cross496d66d2018-09-10 14:02:18 -0700162 manifest_input = self.manifest_tmpl % self.uses_sdk(target='27')
163 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='27')
Colin Cross7b59e7b2018-09-10 13:35:13 -0700164 output = self.raise_min_sdk_version_test(manifest_input, '28', '29', False)
Cole Faustc41dd722021-11-09 15:08:26 -0800165 self.assert_xml_equal(output, expected)
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700166
167 def test_no_target_no_min(self):
168 """Tests inserting targetSdkVersion when minSdkVersion does not exist."""
169
170 manifest_input = self.manifest_tmpl % ''
Colin Cross7b59e7b2018-09-10 13:35:13 -0700171 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='29')
172 output = self.raise_min_sdk_version_test(manifest_input, '28', '29', False)
Cole Faustc41dd722021-11-09 15:08:26 -0800173 self.assert_xml_equal(output, expected)
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700174
175 def test_library_no_target(self):
Colin Cross496d66d2018-09-10 14:02:18 -0700176 """Tests inserting targetSdkVersion when minSdkVersion exists."""
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700177
Colin Cross496d66d2018-09-10 14:02:18 -0700178 manifest_input = self.manifest_tmpl % self.uses_sdk(min='27')
Andrew Wheeler18dcd042021-01-12 21:02:03 -0600179 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='16')
Colin Cross7b59e7b2018-09-10 13:35:13 -0700180 output = self.raise_min_sdk_version_test(manifest_input, '28', '29', True)
Cole Faustc41dd722021-11-09 15:08:26 -0800181 self.assert_xml_equal(output, expected)
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700182
183 def test_library_target_no_min(self):
Colin Cross496d66d2018-09-10 14:02:18 -0700184 """Tests inserting targetSdkVersion when minSdkVersion exists."""
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700185
Colin Cross496d66d2018-09-10 14:02:18 -0700186 manifest_input = self.manifest_tmpl % self.uses_sdk(target='27')
187 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='27')
Colin Cross7b59e7b2018-09-10 13:35:13 -0700188 output = self.raise_min_sdk_version_test(manifest_input, '28', '29', True)
Cole Faustc41dd722021-11-09 15:08:26 -0800189 self.assert_xml_equal(output, expected)
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700190
191 def test_library_no_target_no_min(self):
Colin Cross496d66d2018-09-10 14:02:18 -0700192 """Tests inserting targetSdkVersion when minSdkVersion does not exist."""
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700193
Colin Cross496d66d2018-09-10 14:02:18 -0700194 manifest_input = self.manifest_tmpl % ''
Andrew Wheeler18dcd042021-01-12 21:02:03 -0600195 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='16')
Colin Cross7b59e7b2018-09-10 13:35:13 -0700196 output = self.raise_min_sdk_version_test(manifest_input, '28', '29', True)
Cole Faustc41dd722021-11-09 15:08:26 -0800197 self.assert_xml_equal(output, expected)
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700198
Colin Cross8bb10e82018-06-07 16:46:02 -0700199 def test_extra(self):
200 """Tests that extra attributes and elements are maintained."""
201
202 manifest_input = self.manifest_tmpl % (
203 ' <!-- comment -->\n'
204 ' <uses-sdk android:minSdkVersion="27" extra="foo"/>\n'
205 ' <application/>\n')
206
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700207 # pylint: disable=line-too-long
Colin Cross8bb10e82018-06-07 16:46:02 -0700208 expected = self.manifest_tmpl % (
209 ' <!-- comment -->\n'
Cole Faustc41dd722021-11-09 15:08:26 -0800210 ' <uses-sdk android:minSdkVersion="28" extra="foo" android:targetSdkVersion="29"/>\n'
Colin Cross8bb10e82018-06-07 16:46:02 -0700211 ' <application/>\n')
212
Colin Cross7b59e7b2018-09-10 13:35:13 -0700213 output = self.raise_min_sdk_version_test(manifest_input, '28', '29', False)
Colin Cross8bb10e82018-06-07 16:46:02 -0700214
Cole Faustc41dd722021-11-09 15:08:26 -0800215 self.assert_xml_equal(output, expected)
Colin Cross8bb10e82018-06-07 16:46:02 -0700216
217 def test_indent(self):
218 """Tests that an inserted element copies the existing indentation."""
219
220 manifest_input = self.manifest_tmpl % ' <!-- comment -->\n'
221
Colin Cross1b6a3cf2018-07-24 14:51:30 -0700222 # pylint: disable=line-too-long
Colin Cross8bb10e82018-06-07 16:46:02 -0700223 expected = self.manifest_tmpl % (
Colin Cross7b59e7b2018-09-10 13:35:13 -0700224 ' <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="29"/>\n'
Colin Cross8bb10e82018-06-07 16:46:02 -0700225 ' <!-- comment -->\n')
226
Colin Cross7b59e7b2018-09-10 13:35:13 -0700227 output = self.raise_min_sdk_version_test(manifest_input, '28', '29', False)
Colin Cross8bb10e82018-06-07 16:46:02 -0700228
Cole Faustc41dd722021-11-09 15:08:26 -0800229 self.assert_xml_equal(output, expected)
Colin Cross8bb10e82018-06-07 16:46:02 -0700230
Jiyong Parkc08f46f2018-06-18 11:01:00 +0900231
Baligh Uddin5b16dfb2020-02-11 17:27:19 -0800232class AddLoggingParentTest(unittest.TestCase):
233 """Unit tests for add_logging_parent function."""
234
Cole Faustc41dd722021-11-09 15:08:26 -0800235 def assert_xml_equal(self, output, expected):
236 self.assertEqual(ET.canonicalize(output), ET.canonicalize(expected))
237
Baligh Uddin5b16dfb2020-02-11 17:27:19 -0800238 def add_logging_parent_test(self, input_manifest, logging_parent=None):
239 doc = minidom.parseString(input_manifest)
240 if logging_parent:
241 manifest_fixer.add_logging_parent(doc, logging_parent)
Cole Faustc41dd722021-11-09 15:08:26 -0800242 output = io.StringIO()
Baligh Uddin5b16dfb2020-02-11 17:27:19 -0800243 manifest_fixer.write_xml(output, doc)
244 return output.getvalue()
245
246 manifest_tmpl = (
247 '<?xml version="1.0" encoding="utf-8"?>\n'
248 '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n'
249 '%s'
250 '</manifest>\n')
251
252 def uses_logging_parent(self, logging_parent=None):
253 attrs = ''
254 if logging_parent:
255 meta_text = ('<meta-data android:name="android.content.pm.LOGGING_PARENT" '
256 'android:value="%s"/>\n') % (logging_parent)
257 attrs += ' <application>\n %s </application>\n' % (meta_text)
258
259 return attrs
260
261 def test_no_logging_parent(self):
262 """Tests manifest_fixer with no logging_parent."""
263 manifest_input = self.manifest_tmpl % ''
264 expected = self.manifest_tmpl % self.uses_logging_parent()
265 output = self.add_logging_parent_test(manifest_input)
Cole Faustc41dd722021-11-09 15:08:26 -0800266 self.assert_xml_equal(output, expected)
Baligh Uddin5b16dfb2020-02-11 17:27:19 -0800267
268 def test_logging_parent(self):
269 """Tests manifest_fixer with no logging_parent."""
270 manifest_input = self.manifest_tmpl % ''
271 expected = self.manifest_tmpl % self.uses_logging_parent('FOO')
272 output = self.add_logging_parent_test(manifest_input, 'FOO')
Cole Faustc41dd722021-11-09 15:08:26 -0800273 self.assert_xml_equal(output, expected)
Baligh Uddin5b16dfb2020-02-11 17:27:19 -0800274
275
Jiyong Parkc08f46f2018-06-18 11:01:00 +0900276class AddUsesLibrariesTest(unittest.TestCase):
277 """Unit tests for add_uses_libraries function."""
278
Cole Faustc41dd722021-11-09 15:08:26 -0800279 def assert_xml_equal(self, output, expected):
280 self.assertEqual(ET.canonicalize(output), ET.canonicalize(expected))
281
Jiyong Parkc08f46f2018-06-18 11:01:00 +0900282 def run_test(self, input_manifest, new_uses_libraries):
283 doc = minidom.parseString(input_manifest)
Jaewoong Junge4948c72019-05-14 08:06:16 -0700284 manifest_fixer.add_uses_libraries(doc, new_uses_libraries, True)
Cole Faustc41dd722021-11-09 15:08:26 -0800285 output = io.StringIO()
Jiyong Parkc08f46f2018-06-18 11:01:00 +0900286 manifest_fixer.write_xml(output, doc)
287 return output.getvalue()
288
289 manifest_tmpl = (
290 '<?xml version="1.0" encoding="utf-8"?>\n'
291 '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n'
292 ' <application>\n'
293 '%s'
294 ' </application>\n'
295 '</manifest>\n')
296
297 def uses_libraries(self, name_required_pairs):
298 ret = ''
299 for name, required in name_required_pairs:
300 ret += (
301 ' <uses-library android:name="%s" android:required="%s"/>\n'
302 ) % (name, required)
303
304 return ret
305
306 def test_empty(self):
307 """Empty new_uses_libraries must not touch the manifest."""
308 manifest_input = self.manifest_tmpl % self.uses_libraries([
309 ('foo', 'true'),
310 ('bar', 'false')])
311 expected = manifest_input
312 output = self.run_test(manifest_input, [])
Cole Faustc41dd722021-11-09 15:08:26 -0800313 self.assert_xml_equal(output, expected)
Jiyong Parkc08f46f2018-06-18 11:01:00 +0900314
315 def test_not_overwrite(self):
316 """new_uses_libraries must not overwrite existing tags."""
317 manifest_input = self.manifest_tmpl % self.uses_libraries([
318 ('foo', 'true'),
319 ('bar', 'false')])
320 expected = manifest_input
321 output = self.run_test(manifest_input, ['foo', 'bar'])
Cole Faustc41dd722021-11-09 15:08:26 -0800322 self.assert_xml_equal(output, expected)
Jiyong Parkc08f46f2018-06-18 11:01:00 +0900323
324 def test_add(self):
325 """New names are added with 'required:true'."""
326 manifest_input = self.manifest_tmpl % self.uses_libraries([
327 ('foo', 'true'),
328 ('bar', 'false')])
329 expected = self.manifest_tmpl % self.uses_libraries([
330 ('foo', 'true'),
331 ('bar', 'false'),
332 ('baz', 'true'),
333 ('qux', 'true')])
334 output = self.run_test(manifest_input, ['bar', 'baz', 'qux'])
Cole Faustc41dd722021-11-09 15:08:26 -0800335 self.assert_xml_equal(output, expected)
Jiyong Parkc08f46f2018-06-18 11:01:00 +0900336
337 def test_no_application(self):
338 """When there is no <application> tag, the tag is added."""
339 manifest_input = (
340 '<?xml version="1.0" encoding="utf-8"?>\n'
341 '<manifest xmlns:android='
342 '"http://schemas.android.com/apk/res/android">\n'
343 '</manifest>\n')
344 expected = self.manifest_tmpl % self.uses_libraries([
345 ('foo', 'true'),
346 ('bar', 'true')])
347 output = self.run_test(manifest_input, ['foo', 'bar'])
Cole Faustc41dd722021-11-09 15:08:26 -0800348 self.assert_xml_equal(output, expected)
Jiyong Parkc08f46f2018-06-18 11:01:00 +0900349
350 def test_empty_application(self):
351 """Even when here is an empty <application/> tag, the libs are added."""
352 manifest_input = (
353 '<?xml version="1.0" encoding="utf-8"?>\n'
354 '<manifest xmlns:android='
355 '"http://schemas.android.com/apk/res/android">\n'
356 ' <application/>\n'
357 '</manifest>\n')
358 expected = self.manifest_tmpl % self.uses_libraries([
359 ('foo', 'true'),
360 ('bar', 'true')])
361 output = self.run_test(manifest_input, ['foo', 'bar'])
Cole Faustc41dd722021-11-09 15:08:26 -0800362 self.assert_xml_equal(output, expected)
Jiyong Parkc08f46f2018-06-18 11:01:00 +0900363
364
David Brazdild5b74992018-08-28 12:41:01 +0100365class AddUsesNonSdkApiTest(unittest.TestCase):
366 """Unit tests for add_uses_libraries function."""
367
Cole Faustc41dd722021-11-09 15:08:26 -0800368 def assert_xml_equal(self, output, expected):
369 self.assertEqual(ET.canonicalize(output), ET.canonicalize(expected))
370
David Brazdild5b74992018-08-28 12:41:01 +0100371 def run_test(self, input_manifest):
372 doc = minidom.parseString(input_manifest)
373 manifest_fixer.add_uses_non_sdk_api(doc)
Cole Faustc41dd722021-11-09 15:08:26 -0800374 output = io.StringIO()
David Brazdild5b74992018-08-28 12:41:01 +0100375 manifest_fixer.write_xml(output, doc)
376 return output.getvalue()
377
378 manifest_tmpl = (
379 '<?xml version="1.0" encoding="utf-8"?>\n'
380 '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n'
381 ' <application%s/>\n'
382 '</manifest>\n')
383
384 def uses_non_sdk_api(self, value):
385 return ' android:usesNonSdkApi="true"' if value else ''
386
387 def test_set_true(self):
388 """Empty new_uses_libraries must not touch the manifest."""
389 manifest_input = self.manifest_tmpl % self.uses_non_sdk_api(False)
390 expected = self.manifest_tmpl % self.uses_non_sdk_api(True)
391 output = self.run_test(manifest_input)
Cole Faustc41dd722021-11-09 15:08:26 -0800392 self.assert_xml_equal(output, expected)
David Brazdild5b74992018-08-28 12:41:01 +0100393
394 def test_already_set(self):
395 """new_uses_libraries must not overwrite existing tags."""
396 manifest_input = self.manifest_tmpl % self.uses_non_sdk_api(True)
397 expected = manifest_input
398 output = self.run_test(manifest_input)
Cole Faustc41dd722021-11-09 15:08:26 -0800399 self.assert_xml_equal(output, expected)
David Brazdild5b74992018-08-28 12:41:01 +0100400
401
Victor Hsiehd181c8b2019-01-29 13:00:33 -0800402class UseEmbeddedDexTest(unittest.TestCase):
403 """Unit tests for add_use_embedded_dex function."""
Victor Hsiehce7818e2018-10-22 11:16:25 -0700404
Cole Faustc41dd722021-11-09 15:08:26 -0800405 def assert_xml_equal(self, output, expected):
406 self.assertEqual(ET.canonicalize(output), ET.canonicalize(expected))
407
Victor Hsiehce7818e2018-10-22 11:16:25 -0700408 def run_test(self, input_manifest):
409 doc = minidom.parseString(input_manifest)
Victor Hsiehd181c8b2019-01-29 13:00:33 -0800410 manifest_fixer.add_use_embedded_dex(doc)
Cole Faustc41dd722021-11-09 15:08:26 -0800411 output = io.StringIO()
Victor Hsiehce7818e2018-10-22 11:16:25 -0700412 manifest_fixer.write_xml(output, doc)
413 return output.getvalue()
414
415 manifest_tmpl = (
416 '<?xml version="1.0" encoding="utf-8"?>\n'
417 '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n'
418 ' <application%s/>\n'
419 '</manifest>\n')
420
Victor Hsiehd181c8b2019-01-29 13:00:33 -0800421 def use_embedded_dex(self, value):
422 return ' android:useEmbeddedDex="%s"' % value
Victor Hsiehce7818e2018-10-22 11:16:25 -0700423
424 def test_manifest_with_undeclared_preference(self):
425 manifest_input = self.manifest_tmpl % ''
Victor Hsiehd181c8b2019-01-29 13:00:33 -0800426 expected = self.manifest_tmpl % self.use_embedded_dex('true')
Victor Hsiehce7818e2018-10-22 11:16:25 -0700427 output = self.run_test(manifest_input)
Cole Faustc41dd722021-11-09 15:08:26 -0800428 self.assert_xml_equal(output, expected)
Victor Hsiehce7818e2018-10-22 11:16:25 -0700429
Victor Hsiehd181c8b2019-01-29 13:00:33 -0800430 def test_manifest_with_use_embedded_dex(self):
431 manifest_input = self.manifest_tmpl % self.use_embedded_dex('true')
Victor Hsiehce7818e2018-10-22 11:16:25 -0700432 expected = manifest_input
433 output = self.run_test(manifest_input)
Cole Faustc41dd722021-11-09 15:08:26 -0800434 self.assert_xml_equal(output, expected)
Victor Hsiehce7818e2018-10-22 11:16:25 -0700435
Victor Hsiehd181c8b2019-01-29 13:00:33 -0800436 def test_manifest_with_not_use_embedded_dex(self):
437 manifest_input = self.manifest_tmpl % self.use_embedded_dex('false')
Victor Hsiehce7818e2018-10-22 11:16:25 -0700438 self.assertRaises(RuntimeError, self.run_test, manifest_input)
439
Colin Crosse4246ab2019-02-05 21:55:21 -0800440
441class AddExtractNativeLibsTest(unittest.TestCase):
442 """Unit tests for add_extract_native_libs function."""
443
Cole Faustc41dd722021-11-09 15:08:26 -0800444 def assert_xml_equal(self, output, expected):
445 self.assertEqual(ET.canonicalize(output), ET.canonicalize(expected))
446
Colin Crosse4246ab2019-02-05 21:55:21 -0800447 def run_test(self, input_manifest, value):
448 doc = minidom.parseString(input_manifest)
449 manifest_fixer.add_extract_native_libs(doc, value)
Cole Faustc41dd722021-11-09 15:08:26 -0800450 output = io.StringIO()
Colin Crosse4246ab2019-02-05 21:55:21 -0800451 manifest_fixer.write_xml(output, doc)
452 return output.getvalue()
453
454 manifest_tmpl = (
Colin Cross72119102019-05-20 13:14:18 -0700455 '<?xml version="1.0" encoding="utf-8"?>\n'
456 '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n'
457 ' <application%s/>\n'
458 '</manifest>\n')
Colin Crosse4246ab2019-02-05 21:55:21 -0800459
460 def extract_native_libs(self, value):
461 return ' android:extractNativeLibs="%s"' % value
462
463 def test_set_true(self):
464 manifest_input = self.manifest_tmpl % ''
465 expected = self.manifest_tmpl % self.extract_native_libs('true')
466 output = self.run_test(manifest_input, True)
Cole Faustc41dd722021-11-09 15:08:26 -0800467 self.assert_xml_equal(output, expected)
Colin Crosse4246ab2019-02-05 21:55:21 -0800468
469 def test_set_false(self):
470 manifest_input = self.manifest_tmpl % ''
471 expected = self.manifest_tmpl % self.extract_native_libs('false')
472 output = self.run_test(manifest_input, False)
Cole Faustc41dd722021-11-09 15:08:26 -0800473 self.assert_xml_equal(output, expected)
Colin Crosse4246ab2019-02-05 21:55:21 -0800474
475 def test_match(self):
476 manifest_input = self.manifest_tmpl % self.extract_native_libs('true')
477 expected = manifest_input
478 output = self.run_test(manifest_input, True)
Cole Faustc41dd722021-11-09 15:08:26 -0800479 self.assert_xml_equal(output, expected)
Colin Crosse4246ab2019-02-05 21:55:21 -0800480
481 def test_conflict(self):
482 manifest_input = self.manifest_tmpl % self.extract_native_libs('true')
483 self.assertRaises(RuntimeError, self.run_test, manifest_input, False)
484
485
Jaewoong Jungc27ab662019-05-30 15:51:14 -0700486class AddNoCodeApplicationTest(unittest.TestCase):
487 """Unit tests for set_has_code_to_false function."""
488
Cole Faustc41dd722021-11-09 15:08:26 -0800489 def assert_xml_equal(self, output, expected):
490 self.assertEqual(ET.canonicalize(output), ET.canonicalize(expected))
491
Jaewoong Jungc27ab662019-05-30 15:51:14 -0700492 def run_test(self, input_manifest):
493 doc = minidom.parseString(input_manifest)
494 manifest_fixer.set_has_code_to_false(doc)
Cole Faustc41dd722021-11-09 15:08:26 -0800495 output = io.StringIO()
Jaewoong Jungc27ab662019-05-30 15:51:14 -0700496 manifest_fixer.write_xml(output, doc)
497 return output.getvalue()
498
499 manifest_tmpl = (
500 '<?xml version="1.0" encoding="utf-8"?>\n'
501 '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n'
502 '%s'
503 '</manifest>\n')
504
505 def test_no_application(self):
506 manifest_input = self.manifest_tmpl % ''
507 expected = self.manifest_tmpl % ' <application android:hasCode="false"/>\n'
508 output = self.run_test(manifest_input)
Cole Faustc41dd722021-11-09 15:08:26 -0800509 self.assert_xml_equal(output, expected)
Jaewoong Jungc27ab662019-05-30 15:51:14 -0700510
511 def test_has_application_no_has_code(self):
512 manifest_input = self.manifest_tmpl % ' <application/>\n'
513 expected = self.manifest_tmpl % ' <application android:hasCode="false"/>\n'
514 output = self.run_test(manifest_input)
Cole Faustc41dd722021-11-09 15:08:26 -0800515 self.assert_xml_equal(output, expected)
Jaewoong Jungc27ab662019-05-30 15:51:14 -0700516
517 def test_has_application_has_code_false(self):
518 """ Do nothing if there's already an application elemeent. """
519 manifest_input = self.manifest_tmpl % ' <application android:hasCode="false"/>\n'
520 output = self.run_test(manifest_input)
Cole Faustc41dd722021-11-09 15:08:26 -0800521 self.assert_xml_equal(output, manifest_input)
Jaewoong Jungc27ab662019-05-30 15:51:14 -0700522
523 def test_has_application_has_code_true(self):
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000524 """ Do nothing if there's already an application element even if its
Jaewoong Jungc27ab662019-05-30 15:51:14 -0700525 hasCode attribute is true. """
526 manifest_input = self.manifest_tmpl % ' <application android:hasCode="true"/>\n'
527 output = self.run_test(manifest_input)
Cole Faustc41dd722021-11-09 15:08:26 -0800528 self.assert_xml_equal(output, manifest_input)
Jaewoong Jungc27ab662019-05-30 15:51:14 -0700529
530
Gurpreet Singh75d65f32022-01-24 17:44:05 +0000531class AddTestOnlyApplicationTest(unittest.TestCase):
532 """Unit tests for set_test_only_flag_to_true function."""
533
534 def assert_xml_equal(self, output, expected):
535 self.assertEqual(ET.canonicalize(output), ET.canonicalize(expected))
536
537 def run_test(self, input_manifest):
538 doc = minidom.parseString(input_manifest)
539 manifest_fixer.set_test_only_flag_to_true(doc)
540 output = io.StringIO()
541 manifest_fixer.write_xml(output, doc)
542 return output.getvalue()
543
544 manifest_tmpl = (
545 '<?xml version="1.0" encoding="utf-8"?>\n'
546 '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n'
547 '%s'
548 '</manifest>\n')
549
550 def test_no_application(self):
551 manifest_input = self.manifest_tmpl % ''
552 expected = self.manifest_tmpl % ' <application android:testOnly="true"/>\n'
553 output = self.run_test(manifest_input)
554 self.assert_xml_equal(output, expected)
555
556 def test_has_application_no_test_only(self):
557 manifest_input = self.manifest_tmpl % ' <application/>\n'
558 expected = self.manifest_tmpl % ' <application android:testOnly="true"/>\n'
559 output = self.run_test(manifest_input)
560 self.assert_xml_equal(output, expected)
561
562 def test_has_application_test_only_true(self):
563 """ If there's already an application element."""
564 manifest_input = self.manifest_tmpl % ' <application android:testOnly="true"/>\n'
565 output = self.run_test(manifest_input)
566 self.assert_xml_equal(output, manifest_input)
567
568 def test_has_application_test_only_false(self):
569 """ If there's already an application element with the testOnly attribute as false."""
570 manifest_input = self.manifest_tmpl % ' <application android:testOnly="false"/>\n'
571 output = self.run_test(manifest_input)
572 self.assert_xml_equal(output, manifest_input)
573
William Loh5a082f92022-05-17 20:21:50 +0000574
575class SetMaxSdkVersionTest(unittest.TestCase):
576 """Unit tests for set_max_sdk_version function."""
577
578 def assert_xml_equal(self, output, expected):
579 self.assertEqual(ET.canonicalize(output), ET.canonicalize(expected))
580
581 def run_test(self, input_manifest, max_sdk_version):
582 doc = minidom.parseString(input_manifest)
583 manifest_fixer.set_max_sdk_version(doc, max_sdk_version)
584 output = io.StringIO()
585 manifest_fixer.write_xml(output, doc)
586 return output.getvalue()
587
588 manifest_tmpl = (
589 '<?xml version="1.0" encoding="utf-8"?>\n'
590 '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n'
591 '%s'
592 '</manifest>\n')
593
594 def permission(self, max=None):
595 if max is None:
596 return ' <permission/>'
597 return ' <permission android:maxSdkVersion="%s"/>\n' % max
598
599 def uses_permission(self, max=None):
600 if max is None:
601 return ' <uses-permission/>'
602 return ' <uses-permission android:maxSdkVersion="%s"/>\n' % max
603
604 def test_permission_no_max_sdk_version(self):
605 """Tests if permission has no maxSdkVersion attribute"""
606 manifest_input = self.manifest_tmpl % self.permission()
607 expected = self.manifest_tmpl % self.permission()
608 output = self.run_test(manifest_input, '9000')
609 self.assert_xml_equal(output, expected)
610
611 def test_permission_max_sdk_version_changed(self):
612 """Tests if permission maxSdkVersion attribute is set to current"""
613 manifest_input = self.manifest_tmpl % self.permission('current')
614 expected = self.manifest_tmpl % self.permission(9000)
615 output = self.run_test(manifest_input, '9000')
616 self.assert_xml_equal(output, expected)
617
618 def test_permission_max_sdk_version_not_changed(self):
619 """Tests if permission maxSdkVersion attribute is not set to current"""
620 manifest_input = self.manifest_tmpl % self.permission(30)
621 expected = self.manifest_tmpl % self.permission(30)
622 output = self.run_test(manifest_input, '9000')
623 self.assert_xml_equal(output, expected)
624
625 def test_uses_permission_no_max_sdk_version(self):
626 """Tests if uses-permission has no maxSdkVersion attribute"""
627 manifest_input = self.manifest_tmpl % self.uses_permission()
628 expected = self.manifest_tmpl % self.uses_permission()
629 output = self.run_test(manifest_input, '9000')
630 self.assert_xml_equal(output, expected)
631
632 def test_uses_permission_max_sdk_version_changed(self):
633 """Tests if uses-permission maxSdkVersion attribute is set to current"""
634 manifest_input = self.manifest_tmpl % self.uses_permission('current')
635 expected = self.manifest_tmpl % self.uses_permission(9000)
636 output = self.run_test(manifest_input, '9000')
637 self.assert_xml_equal(output, expected)
638
639 def test_uses_permission_max_sdk_version_not_changed(self):
640 """Tests if uses-permission maxSdkVersion attribute is not set to current"""
641 manifest_input = self.manifest_tmpl % self.uses_permission(30)
642 expected = self.manifest_tmpl % self.uses_permission(30)
643 output = self.run_test(manifest_input, '9000')
644 self.assert_xml_equal(output, expected)
645
Alexei Nicoara69cf0f32022-07-27 14:59:18 +0100646class OverrideDefaultVersionTest(unittest.TestCase):
647 """Unit tests for override_default_version function."""
648
649 def assert_xml_equal(self, output, expected):
650 self.assertEqual(ET.canonicalize(output), ET.canonicalize(expected))
651
652 def run_test(self, input_manifest, version):
653 doc = minidom.parseString(input_manifest)
654 manifest_fixer.override_placeholder_version(doc, version)
655 output = io.StringIO()
656 manifest_fixer.write_xml(output, doc)
657 return output.getvalue()
658
659 manifest_tmpl = (
660 '<?xml version="1.0" encoding="utf-8"?>\n'
661 '<manifest xmlns:android="http://schemas.android.com/apk/res/android" '
662 'android:versionCode="%s">\n'
663 '</manifest>\n')
664
665 def test_doesnt_override_existing_version(self):
666 """Tests that an existing version is not overridden"""
667 manifest_input = self.manifest_tmpl % '12345'
668 expected = manifest_input
669 output = self.run_test(manifest_input, '67890')
670 self.assert_xml_equal(output, expected)
671
672 def test_overrides_default_version(self):
673 """Tests that a default version is overridden"""
674 manifest_input = self.manifest_tmpl % '0'
675 expected = self.manifest_tmpl % '67890'
676 output = self.run_test(manifest_input, '67890')
677 self.assert_xml_equal(output, expected)
678
679
Colin Cross8bb10e82018-06-07 16:46:02 -0700680if __name__ == '__main__':
Colin Cross4af387c2019-05-16 13:16:29 -0700681 unittest.main(verbosity=2)