manifest_fixer_test.py 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681
  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. import io
  19. import sys
  20. import unittest
  21. from xml.dom import minidom
  22. import xml.etree.ElementTree as ET
  23. import manifest_fixer
  24. sys.dont_write_bytecode = True
  25. class CompareVersionGtTest(unittest.TestCase):
  26. """Unit tests for compare_version_gt function."""
  27. def test_sdk(self):
  28. """Test comparing sdk versions."""
  29. self.assertTrue(manifest_fixer.compare_version_gt('28', '27'))
  30. self.assertFalse(manifest_fixer.compare_version_gt('27', '28'))
  31. self.assertFalse(manifest_fixer.compare_version_gt('28', '28'))
  32. def test_codename(self):
  33. """Test comparing codenames."""
  34. self.assertTrue(manifest_fixer.compare_version_gt('Q', 'P'))
  35. self.assertFalse(manifest_fixer.compare_version_gt('P', 'Q'))
  36. self.assertFalse(manifest_fixer.compare_version_gt('Q', 'Q'))
  37. def test_sdk_codename(self):
  38. """Test comparing sdk versions with codenames."""
  39. self.assertTrue(manifest_fixer.compare_version_gt('Q', '28'))
  40. self.assertFalse(manifest_fixer.compare_version_gt('28', 'Q'))
  41. def test_compare_numeric(self):
  42. """Test that numbers are compared in numeric and not lexicographic order."""
  43. self.assertTrue(manifest_fixer.compare_version_gt('18', '8'))
  44. class RaiseMinSdkVersionTest(unittest.TestCase):
  45. """Unit tests for raise_min_sdk_version function."""
  46. def raise_min_sdk_version_test(self, input_manifest, min_sdk_version,
  47. target_sdk_version, library):
  48. doc = minidom.parseString(input_manifest)
  49. manifest_fixer.raise_min_sdk_version(doc, min_sdk_version,
  50. target_sdk_version, library)
  51. output = io.StringIO()
  52. manifest_fixer.write_xml(output, doc)
  53. return output.getvalue()
  54. manifest_tmpl = (
  55. '<?xml version="1.0" encoding="utf-8"?>\n'
  56. '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n'
  57. '%s'
  58. '</manifest>\n')
  59. # pylint: disable=redefined-builtin
  60. def uses_sdk(self, min=None, target=None, extra=''):
  61. attrs = ''
  62. if min:
  63. attrs += ' android:minSdkVersion="%s"' % (min)
  64. if target:
  65. attrs += ' android:targetSdkVersion="%s"' % (target)
  66. if extra:
  67. attrs += ' ' + extra
  68. return ' <uses-sdk%s/>\n' % (attrs)
  69. def assert_xml_equal(self, output, expected):
  70. self.assertEqual(ET.canonicalize(output), ET.canonicalize(expected))
  71. def test_no_uses_sdk(self):
  72. """Tests inserting a uses-sdk element into a manifest."""
  73. manifest_input = self.manifest_tmpl % ''
  74. expected = self.manifest_tmpl % self.uses_sdk(min='28', target='28')
  75. output = self.raise_min_sdk_version_test(manifest_input, '28', '28', False)
  76. self.assert_xml_equal(output, expected)
  77. def test_no_min(self):
  78. """Tests inserting a minSdkVersion attribute into a uses-sdk element."""
  79. manifest_input = self.manifest_tmpl % ' <uses-sdk extra="foo"/>\n'
  80. expected = self.manifest_tmpl % self.uses_sdk(min='28', target='28',
  81. extra='extra="foo"')
  82. output = self.raise_min_sdk_version_test(manifest_input, '28', '28', False)
  83. self.assert_xml_equal(output, expected)
  84. def test_raise_min(self):
  85. """Tests inserting a minSdkVersion attribute into a uses-sdk element."""
  86. manifest_input = self.manifest_tmpl % self.uses_sdk(min='27')
  87. expected = self.manifest_tmpl % self.uses_sdk(min='28', target='28')
  88. output = self.raise_min_sdk_version_test(manifest_input, '28', '28', False)
  89. self.assert_xml_equal(output, expected)
  90. def test_raise(self):
  91. """Tests raising a minSdkVersion attribute."""
  92. manifest_input = self.manifest_tmpl % self.uses_sdk(min='27')
  93. expected = self.manifest_tmpl % self.uses_sdk(min='28', target='28')
  94. output = self.raise_min_sdk_version_test(manifest_input, '28', '28', False)
  95. self.assert_xml_equal(output, expected)
  96. def test_no_raise_min(self):
  97. """Tests a minSdkVersion that doesn't need raising."""
  98. manifest_input = self.manifest_tmpl % self.uses_sdk(min='28')
  99. expected = self.manifest_tmpl % self.uses_sdk(min='28', target='27')
  100. output = self.raise_min_sdk_version_test(manifest_input, '27', '27', False)
  101. self.assert_xml_equal(output, expected)
  102. def test_raise_codename(self):
  103. """Tests raising a minSdkVersion attribute to a codename."""
  104. manifest_input = self.manifest_tmpl % self.uses_sdk(min='28')
  105. expected = self.manifest_tmpl % self.uses_sdk(min='P', target='P')
  106. output = self.raise_min_sdk_version_test(manifest_input, 'P', 'P', False)
  107. self.assert_xml_equal(output, expected)
  108. def test_no_raise_codename(self):
  109. """Tests a minSdkVersion codename that doesn't need raising."""
  110. manifest_input = self.manifest_tmpl % self.uses_sdk(min='P')
  111. expected = self.manifest_tmpl % self.uses_sdk(min='P', target='28')
  112. output = self.raise_min_sdk_version_test(manifest_input, '28', '28', False)
  113. self.assert_xml_equal(output, expected)
  114. def test_target(self):
  115. """Tests an existing targetSdkVersion is preserved."""
  116. manifest_input = self.manifest_tmpl % self.uses_sdk(min='26', target='27')
  117. expected = self.manifest_tmpl % self.uses_sdk(min='28', target='27')
  118. output = self.raise_min_sdk_version_test(manifest_input, '28', '29', False)
  119. self.assert_xml_equal(output, expected)
  120. def test_no_target(self):
  121. """Tests inserting targetSdkVersion when minSdkVersion exists."""
  122. manifest_input = self.manifest_tmpl % self.uses_sdk(min='27')
  123. expected = self.manifest_tmpl % self.uses_sdk(min='28', target='29')
  124. output = self.raise_min_sdk_version_test(manifest_input, '28', '29', False)
  125. self.assert_xml_equal(output, expected)
  126. def test_target_no_min(self):
  127. """"Tests inserting targetSdkVersion when minSdkVersion exists."""
  128. manifest_input = self.manifest_tmpl % self.uses_sdk(target='27')
  129. expected = self.manifest_tmpl % self.uses_sdk(min='28', target='27')
  130. output = self.raise_min_sdk_version_test(manifest_input, '28', '29', False)
  131. self.assert_xml_equal(output, expected)
  132. def test_no_target_no_min(self):
  133. """Tests inserting targetSdkVersion when minSdkVersion does not exist."""
  134. manifest_input = self.manifest_tmpl % ''
  135. expected = self.manifest_tmpl % self.uses_sdk(min='28', target='29')
  136. output = self.raise_min_sdk_version_test(manifest_input, '28', '29', False)
  137. self.assert_xml_equal(output, expected)
  138. def test_library_no_target(self):
  139. """Tests inserting targetSdkVersion when minSdkVersion exists."""
  140. manifest_input = self.manifest_tmpl % self.uses_sdk(min='27')
  141. expected = self.manifest_tmpl % self.uses_sdk(min='28', target='16')
  142. output = self.raise_min_sdk_version_test(manifest_input, '28', '29', True)
  143. self.assert_xml_equal(output, expected)
  144. def test_library_target_no_min(self):
  145. """Tests inserting targetSdkVersion when minSdkVersion exists."""
  146. manifest_input = self.manifest_tmpl % self.uses_sdk(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', True)
  149. self.assert_xml_equal(output, expected)
  150. def test_library_no_target_no_min(self):
  151. """Tests inserting targetSdkVersion when minSdkVersion does not exist."""
  152. manifest_input = self.manifest_tmpl % ''
  153. expected = self.manifest_tmpl % self.uses_sdk(min='28', target='16')
  154. output = self.raise_min_sdk_version_test(manifest_input, '28', '29', True)
  155. self.assert_xml_equal(output, expected)
  156. def test_extra(self):
  157. """Tests that extra attributes and elements are maintained."""
  158. manifest_input = self.manifest_tmpl % (
  159. ' <!-- comment -->\n'
  160. ' <uses-sdk android:minSdkVersion="27" extra="foo"/>\n'
  161. ' <application/>\n')
  162. # pylint: disable=line-too-long
  163. expected = self.manifest_tmpl % (
  164. ' <!-- comment -->\n'
  165. ' <uses-sdk android:minSdkVersion="28" extra="foo" android:targetSdkVersion="29"/>\n'
  166. ' <application/>\n')
  167. output = self.raise_min_sdk_version_test(manifest_input, '28', '29', False)
  168. self.assert_xml_equal(output, expected)
  169. def test_indent(self):
  170. """Tests that an inserted element copies the existing indentation."""
  171. manifest_input = self.manifest_tmpl % ' <!-- comment -->\n'
  172. # pylint: disable=line-too-long
  173. expected = self.manifest_tmpl % (
  174. ' <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="29"/>\n'
  175. ' <!-- comment -->\n')
  176. output = self.raise_min_sdk_version_test(manifest_input, '28', '29', False)
  177. self.assert_xml_equal(output, expected)
  178. class AddLoggingParentTest(unittest.TestCase):
  179. """Unit tests for add_logging_parent function."""
  180. def assert_xml_equal(self, output, expected):
  181. self.assertEqual(ET.canonicalize(output), ET.canonicalize(expected))
  182. def add_logging_parent_test(self, input_manifest, logging_parent=None):
  183. doc = minidom.parseString(input_manifest)
  184. if logging_parent:
  185. manifest_fixer.add_logging_parent(doc, logging_parent)
  186. output = io.StringIO()
  187. manifest_fixer.write_xml(output, doc)
  188. return output.getvalue()
  189. manifest_tmpl = (
  190. '<?xml version="1.0" encoding="utf-8"?>\n'
  191. '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n'
  192. '%s'
  193. '</manifest>\n')
  194. def uses_logging_parent(self, logging_parent=None):
  195. attrs = ''
  196. if logging_parent:
  197. meta_text = ('<meta-data android:name="android.content.pm.LOGGING_PARENT" '
  198. 'android:value="%s"/>\n') % (logging_parent)
  199. attrs += ' <application>\n %s </application>\n' % (meta_text)
  200. return attrs
  201. def test_no_logging_parent(self):
  202. """Tests manifest_fixer with no logging_parent."""
  203. manifest_input = self.manifest_tmpl % ''
  204. expected = self.manifest_tmpl % self.uses_logging_parent()
  205. output = self.add_logging_parent_test(manifest_input)
  206. self.assert_xml_equal(output, expected)
  207. def test_logging_parent(self):
  208. """Tests manifest_fixer with no logging_parent."""
  209. manifest_input = self.manifest_tmpl % ''
  210. expected = self.manifest_tmpl % self.uses_logging_parent('FOO')
  211. output = self.add_logging_parent_test(manifest_input, 'FOO')
  212. self.assert_xml_equal(output, expected)
  213. class AddUsesLibrariesTest(unittest.TestCase):
  214. """Unit tests for add_uses_libraries function."""
  215. def assert_xml_equal(self, output, expected):
  216. self.assertEqual(ET.canonicalize(output), ET.canonicalize(expected))
  217. def run_test(self, input_manifest, new_uses_libraries):
  218. doc = minidom.parseString(input_manifest)
  219. manifest_fixer.add_uses_libraries(doc, new_uses_libraries, True)
  220. output = io.StringIO()
  221. manifest_fixer.write_xml(output, doc)
  222. return output.getvalue()
  223. manifest_tmpl = (
  224. '<?xml version="1.0" encoding="utf-8"?>\n'
  225. '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n'
  226. ' <application>\n'
  227. '%s'
  228. ' </application>\n'
  229. '</manifest>\n')
  230. def uses_libraries(self, name_required_pairs):
  231. ret = ''
  232. for name, required in name_required_pairs:
  233. ret += (
  234. ' <uses-library android:name="%s" android:required="%s"/>\n'
  235. ) % (name, required)
  236. return ret
  237. def test_empty(self):
  238. """Empty new_uses_libraries must not touch the manifest."""
  239. manifest_input = self.manifest_tmpl % self.uses_libraries([
  240. ('foo', 'true'),
  241. ('bar', 'false')])
  242. expected = manifest_input
  243. output = self.run_test(manifest_input, [])
  244. self.assert_xml_equal(output, expected)
  245. def test_not_overwrite(self):
  246. """new_uses_libraries must not overwrite existing tags."""
  247. manifest_input = self.manifest_tmpl % self.uses_libraries([
  248. ('foo', 'true'),
  249. ('bar', 'false')])
  250. expected = manifest_input
  251. output = self.run_test(manifest_input, ['foo', 'bar'])
  252. self.assert_xml_equal(output, expected)
  253. def test_add(self):
  254. """New names are added with 'required:true'."""
  255. manifest_input = self.manifest_tmpl % self.uses_libraries([
  256. ('foo', 'true'),
  257. ('bar', 'false')])
  258. expected = self.manifest_tmpl % self.uses_libraries([
  259. ('foo', 'true'),
  260. ('bar', 'false'),
  261. ('baz', 'true'),
  262. ('qux', 'true')])
  263. output = self.run_test(manifest_input, ['bar', 'baz', 'qux'])
  264. self.assert_xml_equal(output, expected)
  265. def test_no_application(self):
  266. """When there is no <application> tag, the tag is added."""
  267. manifest_input = (
  268. '<?xml version="1.0" encoding="utf-8"?>\n'
  269. '<manifest xmlns:android='
  270. '"http://schemas.android.com/apk/res/android">\n'
  271. '</manifest>\n')
  272. expected = self.manifest_tmpl % self.uses_libraries([
  273. ('foo', 'true'),
  274. ('bar', 'true')])
  275. output = self.run_test(manifest_input, ['foo', 'bar'])
  276. self.assert_xml_equal(output, expected)
  277. def test_empty_application(self):
  278. """Even when here is an empty <application/> tag, the libs are added."""
  279. manifest_input = (
  280. '<?xml version="1.0" encoding="utf-8"?>\n'
  281. '<manifest xmlns:android='
  282. '"http://schemas.android.com/apk/res/android">\n'
  283. ' <application/>\n'
  284. '</manifest>\n')
  285. expected = self.manifest_tmpl % self.uses_libraries([
  286. ('foo', 'true'),
  287. ('bar', 'true')])
  288. output = self.run_test(manifest_input, ['foo', 'bar'])
  289. self.assert_xml_equal(output, expected)
  290. class AddUsesNonSdkApiTest(unittest.TestCase):
  291. """Unit tests for add_uses_libraries function."""
  292. def assert_xml_equal(self, output, expected):
  293. self.assertEqual(ET.canonicalize(output), ET.canonicalize(expected))
  294. def run_test(self, input_manifest):
  295. doc = minidom.parseString(input_manifest)
  296. manifest_fixer.add_uses_non_sdk_api(doc)
  297. output = io.StringIO()
  298. manifest_fixer.write_xml(output, doc)
  299. return output.getvalue()
  300. manifest_tmpl = (
  301. '<?xml version="1.0" encoding="utf-8"?>\n'
  302. '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n'
  303. ' <application%s/>\n'
  304. '</manifest>\n')
  305. def uses_non_sdk_api(self, value):
  306. return ' android:usesNonSdkApi="true"' if value else ''
  307. def test_set_true(self):
  308. """Empty new_uses_libraries must not touch the manifest."""
  309. manifest_input = self.manifest_tmpl % self.uses_non_sdk_api(False)
  310. expected = self.manifest_tmpl % self.uses_non_sdk_api(True)
  311. output = self.run_test(manifest_input)
  312. self.assert_xml_equal(output, expected)
  313. def test_already_set(self):
  314. """new_uses_libraries must not overwrite existing tags."""
  315. manifest_input = self.manifest_tmpl % self.uses_non_sdk_api(True)
  316. expected = manifest_input
  317. output = self.run_test(manifest_input)
  318. self.assert_xml_equal(output, expected)
  319. class UseEmbeddedDexTest(unittest.TestCase):
  320. """Unit tests for add_use_embedded_dex function."""
  321. def assert_xml_equal(self, output, expected):
  322. self.assertEqual(ET.canonicalize(output), ET.canonicalize(expected))
  323. def run_test(self, input_manifest):
  324. doc = minidom.parseString(input_manifest)
  325. manifest_fixer.add_use_embedded_dex(doc)
  326. output = io.StringIO()
  327. manifest_fixer.write_xml(output, doc)
  328. return output.getvalue()
  329. manifest_tmpl = (
  330. '<?xml version="1.0" encoding="utf-8"?>\n'
  331. '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n'
  332. ' <application%s/>\n'
  333. '</manifest>\n')
  334. def use_embedded_dex(self, value):
  335. return ' android:useEmbeddedDex="%s"' % value
  336. def test_manifest_with_undeclared_preference(self):
  337. manifest_input = self.manifest_tmpl % ''
  338. expected = self.manifest_tmpl % self.use_embedded_dex('true')
  339. output = self.run_test(manifest_input)
  340. self.assert_xml_equal(output, expected)
  341. def test_manifest_with_use_embedded_dex(self):
  342. manifest_input = self.manifest_tmpl % self.use_embedded_dex('true')
  343. expected = manifest_input
  344. output = self.run_test(manifest_input)
  345. self.assert_xml_equal(output, expected)
  346. def test_manifest_with_not_use_embedded_dex(self):
  347. manifest_input = self.manifest_tmpl % self.use_embedded_dex('false')
  348. self.assertRaises(RuntimeError, self.run_test, manifest_input)
  349. class AddExtractNativeLibsTest(unittest.TestCase):
  350. """Unit tests for add_extract_native_libs function."""
  351. def assert_xml_equal(self, output, expected):
  352. self.assertEqual(ET.canonicalize(output), ET.canonicalize(expected))
  353. def run_test(self, input_manifest, value):
  354. doc = minidom.parseString(input_manifest)
  355. manifest_fixer.add_extract_native_libs(doc, value)
  356. output = io.StringIO()
  357. manifest_fixer.write_xml(output, doc)
  358. return output.getvalue()
  359. manifest_tmpl = (
  360. '<?xml version="1.0" encoding="utf-8"?>\n'
  361. '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n'
  362. ' <application%s/>\n'
  363. '</manifest>\n')
  364. def extract_native_libs(self, value):
  365. return ' android:extractNativeLibs="%s"' % value
  366. def test_set_true(self):
  367. manifest_input = self.manifest_tmpl % ''
  368. expected = self.manifest_tmpl % self.extract_native_libs('true')
  369. output = self.run_test(manifest_input, True)
  370. self.assert_xml_equal(output, expected)
  371. def test_set_false(self):
  372. manifest_input = self.manifest_tmpl % ''
  373. expected = self.manifest_tmpl % self.extract_native_libs('false')
  374. output = self.run_test(manifest_input, False)
  375. self.assert_xml_equal(output, expected)
  376. def test_match(self):
  377. manifest_input = self.manifest_tmpl % self.extract_native_libs('true')
  378. expected = manifest_input
  379. output = self.run_test(manifest_input, True)
  380. self.assert_xml_equal(output, expected)
  381. def test_conflict(self):
  382. manifest_input = self.manifest_tmpl % self.extract_native_libs('true')
  383. self.assertRaises(RuntimeError, self.run_test, manifest_input, False)
  384. class AddNoCodeApplicationTest(unittest.TestCase):
  385. """Unit tests for set_has_code_to_false function."""
  386. def assert_xml_equal(self, output, expected):
  387. self.assertEqual(ET.canonicalize(output), ET.canonicalize(expected))
  388. def run_test(self, input_manifest):
  389. doc = minidom.parseString(input_manifest)
  390. manifest_fixer.set_has_code_to_false(doc)
  391. output = io.StringIO()
  392. manifest_fixer.write_xml(output, doc)
  393. return output.getvalue()
  394. manifest_tmpl = (
  395. '<?xml version="1.0" encoding="utf-8"?>\n'
  396. '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n'
  397. '%s'
  398. '</manifest>\n')
  399. def test_no_application(self):
  400. manifest_input = self.manifest_tmpl % ''
  401. expected = self.manifest_tmpl % ' <application android:hasCode="false"/>\n'
  402. output = self.run_test(manifest_input)
  403. self.assert_xml_equal(output, expected)
  404. def test_has_application_no_has_code(self):
  405. manifest_input = self.manifest_tmpl % ' <application/>\n'
  406. expected = self.manifest_tmpl % ' <application android:hasCode="false"/>\n'
  407. output = self.run_test(manifest_input)
  408. self.assert_xml_equal(output, expected)
  409. def test_has_application_has_code_false(self):
  410. """ Do nothing if there's already an application elemeent. """
  411. manifest_input = self.manifest_tmpl % ' <application android:hasCode="false"/>\n'
  412. output = self.run_test(manifest_input)
  413. self.assert_xml_equal(output, manifest_input)
  414. def test_has_application_has_code_true(self):
  415. """ Do nothing if there's already an application element even if its
  416. hasCode attribute is true. """
  417. manifest_input = self.manifest_tmpl % ' <application android:hasCode="true"/>\n'
  418. output = self.run_test(manifest_input)
  419. self.assert_xml_equal(output, manifest_input)
  420. class AddTestOnlyApplicationTest(unittest.TestCase):
  421. """Unit tests for set_test_only_flag_to_true function."""
  422. def assert_xml_equal(self, output, expected):
  423. self.assertEqual(ET.canonicalize(output), ET.canonicalize(expected))
  424. def run_test(self, input_manifest):
  425. doc = minidom.parseString(input_manifest)
  426. manifest_fixer.set_test_only_flag_to_true(doc)
  427. output = io.StringIO()
  428. manifest_fixer.write_xml(output, doc)
  429. return output.getvalue()
  430. manifest_tmpl = (
  431. '<?xml version="1.0" encoding="utf-8"?>\n'
  432. '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n'
  433. '%s'
  434. '</manifest>\n')
  435. def test_no_application(self):
  436. manifest_input = self.manifest_tmpl % ''
  437. expected = self.manifest_tmpl % ' <application android:testOnly="true"/>\n'
  438. output = self.run_test(manifest_input)
  439. self.assert_xml_equal(output, expected)
  440. def test_has_application_no_test_only(self):
  441. manifest_input = self.manifest_tmpl % ' <application/>\n'
  442. expected = self.manifest_tmpl % ' <application android:testOnly="true"/>\n'
  443. output = self.run_test(manifest_input)
  444. self.assert_xml_equal(output, expected)
  445. def test_has_application_test_only_true(self):
  446. """ If there's already an application element."""
  447. manifest_input = self.manifest_tmpl % ' <application android:testOnly="true"/>\n'
  448. output = self.run_test(manifest_input)
  449. self.assert_xml_equal(output, manifest_input)
  450. def test_has_application_test_only_false(self):
  451. """ If there's already an application element with the testOnly attribute as false."""
  452. manifest_input = self.manifest_tmpl % ' <application android:testOnly="false"/>\n'
  453. output = self.run_test(manifest_input)
  454. self.assert_xml_equal(output, manifest_input)
  455. class SetMaxSdkVersionTest(unittest.TestCase):
  456. """Unit tests for set_max_sdk_version function."""
  457. def assert_xml_equal(self, output, expected):
  458. self.assertEqual(ET.canonicalize(output), ET.canonicalize(expected))
  459. def run_test(self, input_manifest, max_sdk_version):
  460. doc = minidom.parseString(input_manifest)
  461. manifest_fixer.set_max_sdk_version(doc, max_sdk_version)
  462. output = io.StringIO()
  463. manifest_fixer.write_xml(output, doc)
  464. return output.getvalue()
  465. manifest_tmpl = (
  466. '<?xml version="1.0" encoding="utf-8"?>\n'
  467. '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n'
  468. '%s'
  469. '</manifest>\n')
  470. def permission(self, max=None):
  471. if max is None:
  472. return ' <permission/>'
  473. return ' <permission android:maxSdkVersion="%s"/>\n' % max
  474. def uses_permission(self, max=None):
  475. if max is None:
  476. return ' <uses-permission/>'
  477. return ' <uses-permission android:maxSdkVersion="%s"/>\n' % max
  478. def test_permission_no_max_sdk_version(self):
  479. """Tests if permission has no maxSdkVersion attribute"""
  480. manifest_input = self.manifest_tmpl % self.permission()
  481. expected = self.manifest_tmpl % self.permission()
  482. output = self.run_test(manifest_input, '9000')
  483. self.assert_xml_equal(output, expected)
  484. def test_permission_max_sdk_version_changed(self):
  485. """Tests if permission maxSdkVersion attribute is set to current"""
  486. manifest_input = self.manifest_tmpl % self.permission('current')
  487. expected = self.manifest_tmpl % self.permission(9000)
  488. output = self.run_test(manifest_input, '9000')
  489. self.assert_xml_equal(output, expected)
  490. def test_permission_max_sdk_version_not_changed(self):
  491. """Tests if permission maxSdkVersion attribute is not set to current"""
  492. manifest_input = self.manifest_tmpl % self.permission(30)
  493. expected = self.manifest_tmpl % self.permission(30)
  494. output = self.run_test(manifest_input, '9000')
  495. self.assert_xml_equal(output, expected)
  496. def test_uses_permission_no_max_sdk_version(self):
  497. """Tests if uses-permission has no maxSdkVersion attribute"""
  498. manifest_input = self.manifest_tmpl % self.uses_permission()
  499. expected = self.manifest_tmpl % self.uses_permission()
  500. output = self.run_test(manifest_input, '9000')
  501. self.assert_xml_equal(output, expected)
  502. def test_uses_permission_max_sdk_version_changed(self):
  503. """Tests if uses-permission maxSdkVersion attribute is set to current"""
  504. manifest_input = self.manifest_tmpl % self.uses_permission('current')
  505. expected = self.manifest_tmpl % self.uses_permission(9000)
  506. output = self.run_test(manifest_input, '9000')
  507. self.assert_xml_equal(output, expected)
  508. def test_uses_permission_max_sdk_version_not_changed(self):
  509. """Tests if uses-permission maxSdkVersion attribute is not set to current"""
  510. manifest_input = self.manifest_tmpl % self.uses_permission(30)
  511. expected = self.manifest_tmpl % self.uses_permission(30)
  512. output = self.run_test(manifest_input, '9000')
  513. self.assert_xml_equal(output, expected)
  514. class OverrideDefaultVersionTest(unittest.TestCase):
  515. """Unit tests for override_default_version function."""
  516. def assert_xml_equal(self, output, expected):
  517. self.assertEqual(ET.canonicalize(output), ET.canonicalize(expected))
  518. def run_test(self, input_manifest, version):
  519. doc = minidom.parseString(input_manifest)
  520. manifest_fixer.override_placeholder_version(doc, version)
  521. output = io.StringIO()
  522. manifest_fixer.write_xml(output, doc)
  523. return output.getvalue()
  524. manifest_tmpl = (
  525. '<?xml version="1.0" encoding="utf-8"?>\n'
  526. '<manifest xmlns:android="http://schemas.android.com/apk/res/android" '
  527. 'android:versionCode="%s">\n'
  528. '</manifest>\n')
  529. def test_doesnt_override_existing_version(self):
  530. """Tests that an existing version is not overridden"""
  531. manifest_input = self.manifest_tmpl % '12345'
  532. expected = manifest_input
  533. output = self.run_test(manifest_input, '67890')
  534. self.assert_xml_equal(output, expected)
  535. def test_overrides_default_version(self):
  536. """Tests that a default version is overridden"""
  537. manifest_input = self.manifest_tmpl % '0'
  538. expected = self.manifest_tmpl % '67890'
  539. output = self.run_test(manifest_input, '67890')
  540. self.assert_xml_equal(output, expected)
  541. if __name__ == '__main__':
  542. unittest.main(verbosity=2)