1#!/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# 17"""Unit tests for manifest_fixer.py.""" 18 19import io 20import sys 21import unittest 22from xml.dom import minidom 23import xml.etree.ElementTree as ET 24 25import manifest_fixer 26 27sys.dont_write_bytecode = True 28 29class 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 57 def raise_min_sdk_version_test(self, input_manifest, min_sdk_version, 58 target_sdk_version, library): 59 doc = minidom.parseString(input_manifest) 60 manifest_fixer.raise_min_sdk_version(doc, min_sdk_version, 61 target_sdk_version, library) 62 output = io.StringIO() 63 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 72 # pylint: disable=redefined-builtin 73 def uses_sdk(self, min=None, target=None, extra=''): 74 attrs = '' 75 if min: 76 attrs += ' android:minSdkVersion="%s"' % (min) 77 if target: 78 attrs += ' android:targetSdkVersion="%s"' % (target) 79 if extra: 80 attrs += ' ' + extra 81 return ' <uses-sdk%s/>\n' % (attrs) 82 83 def assert_xml_equal(self, output, expected): 84 self.assertEqual(ET.canonicalize(output), ET.canonicalize(expected)) 85 86 def test_no_uses_sdk(self): 87 """Tests inserting a uses-sdk element into a manifest.""" 88 89 manifest_input = self.manifest_tmpl % '' 90 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='28') 91 output = self.raise_min_sdk_version_test(manifest_input, '28', '28', False) 92 self.assert_xml_equal(output, expected) 93 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' 98 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='28', 99 extra='extra="foo"') 100 output = self.raise_min_sdk_version_test(manifest_input, '28', '28', False) 101 self.assert_xml_equal(output, expected) 102 103 def test_raise_min(self): 104 """Tests inserting a minSdkVersion attribute into a uses-sdk element.""" 105 106 manifest_input = self.manifest_tmpl % self.uses_sdk(min='27') 107 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='28') 108 output = self.raise_min_sdk_version_test(manifest_input, '28', '28', False) 109 self.assert_xml_equal(output, expected) 110 111 def test_raise(self): 112 """Tests raising a minSdkVersion attribute.""" 113 114 manifest_input = self.manifest_tmpl % self.uses_sdk(min='27') 115 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='28') 116 output = self.raise_min_sdk_version_test(manifest_input, '28', '28', False) 117 self.assert_xml_equal(output, expected) 118 119 def test_no_raise_min(self): 120 """Tests a minSdkVersion that doesn't need raising.""" 121 122 manifest_input = self.manifest_tmpl % self.uses_sdk(min='28') 123 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='27') 124 output = self.raise_min_sdk_version_test(manifest_input, '27', '27', False) 125 self.assert_xml_equal(output, expected) 126 127 def test_raise_codename(self): 128 """Tests raising a minSdkVersion attribute to a codename.""" 129 130 manifest_input = self.manifest_tmpl % self.uses_sdk(min='28') 131 expected = self.manifest_tmpl % self.uses_sdk(min='P', target='P') 132 output = self.raise_min_sdk_version_test(manifest_input, 'P', 'P', False) 133 self.assert_xml_equal(output, expected) 134 135 def test_no_raise_codename(self): 136 """Tests a minSdkVersion codename that doesn't need raising.""" 137 138 manifest_input = self.manifest_tmpl % self.uses_sdk(min='P') 139 expected = self.manifest_tmpl % self.uses_sdk(min='P', target='28') 140 output = self.raise_min_sdk_version_test(manifest_input, '28', '28', False) 141 self.assert_xml_equal(output, expected) 142 143 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') 148 output = self.raise_min_sdk_version_test(manifest_input, '28', '29', False) 149 self.assert_xml_equal(output, expected) 150 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') 155 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='29') 156 output = self.raise_min_sdk_version_test(manifest_input, '28', '29', False) 157 self.assert_xml_equal(output, expected) 158 159 def test_target_no_min(self): 160 """"Tests inserting targetSdkVersion when minSdkVersion exists.""" 161 162 manifest_input = self.manifest_tmpl % self.uses_sdk(target='27') 163 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='27') 164 output = self.raise_min_sdk_version_test(manifest_input, '28', '29', False) 165 self.assert_xml_equal(output, expected) 166 167 def test_no_target_no_min(self): 168 """Tests inserting targetSdkVersion when minSdkVersion does not exist.""" 169 170 manifest_input = self.manifest_tmpl % '' 171 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='29') 172 output = self.raise_min_sdk_version_test(manifest_input, '28', '29', False) 173 self.assert_xml_equal(output, expected) 174 175 def test_library_no_target(self): 176 """Tests inserting targetSdkVersion when minSdkVersion exists.""" 177 178 manifest_input = self.manifest_tmpl % self.uses_sdk(min='27') 179 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='16') 180 output = self.raise_min_sdk_version_test(manifest_input, '28', '29', True) 181 self.assert_xml_equal(output, expected) 182 183 def test_library_target_no_min(self): 184 """Tests inserting targetSdkVersion when minSdkVersion exists.""" 185 186 manifest_input = self.manifest_tmpl % self.uses_sdk(target='27') 187 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='27') 188 output = self.raise_min_sdk_version_test(manifest_input, '28', '29', True) 189 self.assert_xml_equal(output, expected) 190 191 def test_library_no_target_no_min(self): 192 """Tests inserting targetSdkVersion when minSdkVersion does not exist.""" 193 194 manifest_input = self.manifest_tmpl % '' 195 expected = self.manifest_tmpl % self.uses_sdk(min='28', target='16') 196 output = self.raise_min_sdk_version_test(manifest_input, '28', '29', True) 197 self.assert_xml_equal(output, expected) 198 199 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 207 # pylint: disable=line-too-long 208 expected = self.manifest_tmpl % ( 209 ' <!-- comment -->\n' 210 ' <uses-sdk android:minSdkVersion="28" extra="foo" android:targetSdkVersion="29"/>\n' 211 ' <application/>\n') 212 213 output = self.raise_min_sdk_version_test(manifest_input, '28', '29', False) 214 215 self.assert_xml_equal(output, expected) 216 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 222 # pylint: disable=line-too-long 223 expected = self.manifest_tmpl % ( 224 ' <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="29"/>\n' 225 ' <!-- comment -->\n') 226 227 output = self.raise_min_sdk_version_test(manifest_input, '28', '29', False) 228 229 self.assert_xml_equal(output, expected) 230 231 232class AddLoggingParentTest(unittest.TestCase): 233 """Unit tests for add_logging_parent function.""" 234 235 def assert_xml_equal(self, output, expected): 236 self.assertEqual(ET.canonicalize(output), ET.canonicalize(expected)) 237 238 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) 242 output = io.StringIO() 243 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) 266 self.assert_xml_equal(output, expected) 267 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') 273 self.assert_xml_equal(output, expected) 274 275 276class AddUsesLibrariesTest(unittest.TestCase): 277 """Unit tests for add_uses_libraries function.""" 278 279 def assert_xml_equal(self, output, expected): 280 self.assertEqual(ET.canonicalize(output), ET.canonicalize(expected)) 281 282 def run_test(self, input_manifest, new_uses_libraries): 283 doc = minidom.parseString(input_manifest) 284 manifest_fixer.add_uses_libraries(doc, new_uses_libraries, True) 285 output = io.StringIO() 286 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, []) 313 self.assert_xml_equal(output, expected) 314 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']) 322 self.assert_xml_equal(output, expected) 323 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']) 335 self.assert_xml_equal(output, expected) 336 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']) 348 self.assert_xml_equal(output, expected) 349 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']) 362 self.assert_xml_equal(output, expected) 363 364 365class AddUsesNonSdkApiTest(unittest.TestCase): 366 """Unit tests for add_uses_libraries function.""" 367 368 def assert_xml_equal(self, output, expected): 369 self.assertEqual(ET.canonicalize(output), ET.canonicalize(expected)) 370 371 def run_test(self, input_manifest): 372 doc = minidom.parseString(input_manifest) 373 manifest_fixer.add_uses_non_sdk_api(doc) 374 output = io.StringIO() 375 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) 392 self.assert_xml_equal(output, expected) 393 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) 399 self.assert_xml_equal(output, expected) 400 401 402class UseEmbeddedDexTest(unittest.TestCase): 403 """Unit tests for add_use_embedded_dex function.""" 404 405 def assert_xml_equal(self, output, expected): 406 self.assertEqual(ET.canonicalize(output), ET.canonicalize(expected)) 407 408 def run_test(self, input_manifest): 409 doc = minidom.parseString(input_manifest) 410 manifest_fixer.add_use_embedded_dex(doc) 411 output = io.StringIO() 412 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 421 def use_embedded_dex(self, value): 422 return ' android:useEmbeddedDex="%s"' % value 423 424 def test_manifest_with_undeclared_preference(self): 425 manifest_input = self.manifest_tmpl % '' 426 expected = self.manifest_tmpl % self.use_embedded_dex('true') 427 output = self.run_test(manifest_input) 428 self.assert_xml_equal(output, expected) 429 430 def test_manifest_with_use_embedded_dex(self): 431 manifest_input = self.manifest_tmpl % self.use_embedded_dex('true') 432 expected = manifest_input 433 output = self.run_test(manifest_input) 434 self.assert_xml_equal(output, expected) 435 436 def test_manifest_with_not_use_embedded_dex(self): 437 manifest_input = self.manifest_tmpl % self.use_embedded_dex('false') 438 self.assertRaises(RuntimeError, self.run_test, manifest_input) 439 440 441class AddExtractNativeLibsTest(unittest.TestCase): 442 """Unit tests for add_extract_native_libs function.""" 443 444 def assert_xml_equal(self, output, expected): 445 self.assertEqual(ET.canonicalize(output), ET.canonicalize(expected)) 446 447 def run_test(self, input_manifest, value): 448 doc = minidom.parseString(input_manifest) 449 manifest_fixer.add_extract_native_libs(doc, value) 450 output = io.StringIO() 451 manifest_fixer.write_xml(output, doc) 452 return output.getvalue() 453 454 manifest_tmpl = ( 455 '<?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') 459 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) 467 self.assert_xml_equal(output, expected) 468 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) 473 self.assert_xml_equal(output, expected) 474 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) 479 self.assert_xml_equal(output, expected) 480 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 486class AddNoCodeApplicationTest(unittest.TestCase): 487 """Unit tests for set_has_code_to_false function.""" 488 489 def assert_xml_equal(self, output, expected): 490 self.assertEqual(ET.canonicalize(output), ET.canonicalize(expected)) 491 492 def run_test(self, input_manifest): 493 doc = minidom.parseString(input_manifest) 494 manifest_fixer.set_has_code_to_false(doc) 495 output = io.StringIO() 496 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) 509 self.assert_xml_equal(output, expected) 510 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) 515 self.assert_xml_equal(output, expected) 516 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) 521 self.assert_xml_equal(output, manifest_input) 522 523 def test_has_application_has_code_true(self): 524 """ Do nothing if there's already an application element even if its 525 hasCode attribute is true. """ 526 manifest_input = self.manifest_tmpl % ' <application android:hasCode="true"/>\n' 527 output = self.run_test(manifest_input) 528 self.assert_xml_equal(output, manifest_input) 529 530 531class 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 574 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 646class 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 680if __name__ == '__main__': 681 unittest.main(verbosity=2) 682