blob: 3be7a30bf1adefa3334705b19bd6855e7dac062d [file] [log] [blame]
Colin Cross72119102019-05-20 13:14:18 -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#
17"""Unit tests for manifest_fixer.py."""
18
19import sys
20import unittest
21from xml.dom import minidom
22
23import manifest_check
24
25sys.dont_write_bytecode = True
26
27
Ulya Trafimovich0aba2522021-03-03 16:38:37 +000028def uses_library_xml(name, attr=''):
Spandan Dasf8807422021-08-25 20:01:17 +000029 return '<uses-library android:name="%s"%s />' % (name, attr)
Colin Cross72119102019-05-20 13:14:18 -070030
31
Ulya Trafimovich0aba2522021-03-03 16:38:37 +000032def required_xml(value):
Spandan Dasf8807422021-08-25 20:01:17 +000033 return ' android:required="%s"' % ('true' if value else 'false')
Colin Cross72119102019-05-20 13:14:18 -070034
35
Ulya Trafimovich0aba2522021-03-03 16:38:37 +000036def uses_library_apk(name, sfx=''):
Spandan Dasf8807422021-08-25 20:01:17 +000037 return "uses-library%s:'%s'" % (sfx, name)
Ulya Trafimovich0aba2522021-03-03 16:38:37 +000038
39
40def required_apk(value):
Spandan Dasf8807422021-08-25 20:01:17 +000041 return '' if value else '-not-required'
Ulya Trafimovich0aba2522021-03-03 16:38:37 +000042
43
Colin Cross72119102019-05-20 13:14:18 -070044class EnforceUsesLibrariesTest(unittest.TestCase):
Spandan Dasf8807422021-08-25 20:01:17 +000045 """Unit tests for add_extract_native_libs function."""
Colin Cross72119102019-05-20 13:14:18 -070046
Spandan Dasf8807422021-08-25 20:01:17 +000047 def run_test(self, xml, apk, uses_libraries=[], optional_uses_libraries=[]): #pylint: disable=dangerous-default-value
48 doc = minidom.parseString(xml)
49 try:
50 relax = False
51 manifest_check.enforce_uses_libraries(
52 doc, uses_libraries, optional_uses_libraries, relax, False,
53 'path/to/X/AndroidManifest.xml')
54 manifest_check.enforce_uses_libraries(apk, uses_libraries,
55 optional_uses_libraries,
56 relax, True,
57 'path/to/X/X.apk')
58 return True
59 except manifest_check.ManifestMismatchError:
60 return False
Colin Cross72119102019-05-20 13:14:18 -070061
Spandan Dasf8807422021-08-25 20:01:17 +000062 xml_tmpl = (
63 '<?xml version="1.0" encoding="utf-8"?>\n<manifest '
64 'xmlns:android="http://schemas.android.com/apk/res/android">\n '
65 '<application>\n %s\n </application>\n</manifest>\n')
Colin Cross72119102019-05-20 13:14:18 -070066
Spandan Dasf8807422021-08-25 20:01:17 +000067 apk_tmpl = (
68 "package: name='com.google.android.something' versionCode='100'\n"
69 "sdkVersion:'29'\n"
70 "targetSdkVersion:'29'\n"
71 "uses-permission: name='android.permission.ACCESS_NETWORK_STATE'\n"
72 '%s\n'
73 "densities: '160' '240' '320' '480' '640' '65534")
Ulya Trafimovich0aba2522021-03-03 16:38:37 +000074
Spandan Dasf8807422021-08-25 20:01:17 +000075 def test_uses_library(self):
76 xml = self.xml_tmpl % (uses_library_xml('foo'))
77 apk = self.apk_tmpl % (uses_library_apk('foo'))
78 matches = self.run_test(xml, apk, uses_libraries=['foo'])
79 self.assertTrue(matches)
Colin Cross72119102019-05-20 13:14:18 -070080
Spandan Dasf8807422021-08-25 20:01:17 +000081 def test_uses_library_required(self):
82 xml = self.xml_tmpl % (uses_library_xml('foo', required_xml(True)))
83 apk = self.apk_tmpl % (uses_library_apk('foo', required_apk(True)))
84 matches = self.run_test(xml, apk, uses_libraries=['foo'])
85 self.assertTrue(matches)
Colin Cross72119102019-05-20 13:14:18 -070086
Spandan Dasf8807422021-08-25 20:01:17 +000087 def test_optional_uses_library(self):
88 xml = self.xml_tmpl % (uses_library_xml('foo', required_xml(False)))
89 apk = self.apk_tmpl % (uses_library_apk('foo', required_apk(False)))
90 matches = self.run_test(xml, apk, optional_uses_libraries=['foo'])
91 self.assertTrue(matches)
Colin Cross72119102019-05-20 13:14:18 -070092
Spandan Dasf8807422021-08-25 20:01:17 +000093 def test_expected_uses_library(self):
94 xml = self.xml_tmpl % (uses_library_xml('foo', required_xml(False)))
95 apk = self.apk_tmpl % (uses_library_apk('foo', required_apk(False)))
96 matches = self.run_test(xml, apk, uses_libraries=['foo'])
97 self.assertFalse(matches)
Colin Cross72119102019-05-20 13:14:18 -070098
Spandan Dasf8807422021-08-25 20:01:17 +000099 def test_expected_optional_uses_library(self):
100 xml = self.xml_tmpl % (uses_library_xml('foo'))
101 apk = self.apk_tmpl % (uses_library_apk('foo'))
102 matches = self.run_test(xml, apk, optional_uses_libraries=['foo'])
103 self.assertFalse(matches)
Colin Cross72119102019-05-20 13:14:18 -0700104
Spandan Dasf8807422021-08-25 20:01:17 +0000105 def test_missing_uses_library(self):
106 xml = self.xml_tmpl % ('')
107 apk = self.apk_tmpl % ('')
108 matches = self.run_test(xml, apk, uses_libraries=['foo'])
109 self.assertFalse(matches)
Colin Cross72119102019-05-20 13:14:18 -0700110
Spandan Dasf8807422021-08-25 20:01:17 +0000111 def test_missing_optional_uses_library(self):
112 xml = self.xml_tmpl % ('')
113 apk = self.apk_tmpl % ('')
114 matches = self.run_test(xml, apk, optional_uses_libraries=['foo'])
115 self.assertFalse(matches)
Colin Cross72119102019-05-20 13:14:18 -0700116
Spandan Dasf8807422021-08-25 20:01:17 +0000117 def test_extra_uses_library(self):
118 xml = self.xml_tmpl % (uses_library_xml('foo'))
119 apk = self.apk_tmpl % (uses_library_xml('foo'))
120 matches = self.run_test(xml, apk)
121 self.assertFalse(matches)
Colin Cross72119102019-05-20 13:14:18 -0700122
Spandan Dasf8807422021-08-25 20:01:17 +0000123 def test_extra_optional_uses_library(self):
124 xml = self.xml_tmpl % (uses_library_xml('foo', required_xml(False)))
125 apk = self.apk_tmpl % (uses_library_apk('foo', required_apk(False)))
126 matches = self.run_test(xml, apk)
127 self.assertFalse(matches)
Colin Cross72119102019-05-20 13:14:18 -0700128
Spandan Dasf8807422021-08-25 20:01:17 +0000129 def test_multiple_uses_library(self):
130 xml = self.xml_tmpl % ('\n'.join(
131 [uses_library_xml('foo'),
132 uses_library_xml('bar')]))
133 apk = self.apk_tmpl % ('\n'.join(
134 [uses_library_apk('foo'),
135 uses_library_apk('bar')]))
136 matches = self.run_test(xml, apk, uses_libraries=['foo', 'bar'])
137 self.assertTrue(matches)
Colin Cross72119102019-05-20 13:14:18 -0700138
Spandan Dasf8807422021-08-25 20:01:17 +0000139 def test_multiple_optional_uses_library(self):
140 xml = self.xml_tmpl % ('\n'.join([
141 uses_library_xml('foo', required_xml(False)),
142 uses_library_xml('bar', required_xml(False))
143 ]))
144 apk = self.apk_tmpl % ('\n'.join([
145 uses_library_apk('foo', required_apk(False)),
146 uses_library_apk('bar', required_apk(False))
147 ]))
148 matches = self.run_test(
149 xml, apk, optional_uses_libraries=['foo', 'bar'])
150 self.assertTrue(matches)
Colin Cross72119102019-05-20 13:14:18 -0700151
Spandan Dasf8807422021-08-25 20:01:17 +0000152 def test_order_uses_library(self):
153 xml = self.xml_tmpl % ('\n'.join(
154 [uses_library_xml('foo'),
155 uses_library_xml('bar')]))
156 apk = self.apk_tmpl % ('\n'.join(
157 [uses_library_apk('foo'),
158 uses_library_apk('bar')]))
159 matches = self.run_test(xml, apk, uses_libraries=['bar', 'foo'])
160 self.assertFalse(matches)
Colin Cross72119102019-05-20 13:14:18 -0700161
Spandan Dasf8807422021-08-25 20:01:17 +0000162 def test_order_optional_uses_library(self):
163 xml = self.xml_tmpl % ('\n'.join([
164 uses_library_xml('foo', required_xml(False)),
165 uses_library_xml('bar', required_xml(False))
166 ]))
167 apk = self.apk_tmpl % ('\n'.join([
168 uses_library_apk('foo', required_apk(False)),
169 uses_library_apk('bar', required_apk(False))
170 ]))
171 matches = self.run_test(
172 xml, apk, optional_uses_libraries=['bar', 'foo'])
173 self.assertFalse(matches)
Colin Cross72119102019-05-20 13:14:18 -0700174
Spandan Dasf8807422021-08-25 20:01:17 +0000175 def test_duplicate_uses_library(self):
176 xml = self.xml_tmpl % ('\n'.join(
177 [uses_library_xml('foo'),
178 uses_library_xml('foo')]))
179 apk = self.apk_tmpl % ('\n'.join(
180 [uses_library_apk('foo'),
181 uses_library_apk('foo')]))
182 matches = self.run_test(xml, apk, uses_libraries=['foo'])
183 self.assertTrue(matches)
Colin Cross72119102019-05-20 13:14:18 -0700184
Spandan Dasf8807422021-08-25 20:01:17 +0000185 def test_duplicate_optional_uses_library(self):
186 xml = self.xml_tmpl % ('\n'.join([
187 uses_library_xml('foo', required_xml(False)),
188 uses_library_xml('foo', required_xml(False))
189 ]))
190 apk = self.apk_tmpl % ('\n'.join([
191 uses_library_apk('foo', required_apk(False)),
192 uses_library_apk('foo', required_apk(False))
193 ]))
194 matches = self.run_test(xml, apk, optional_uses_libraries=['foo'])
195 self.assertTrue(matches)
Colin Cross72119102019-05-20 13:14:18 -0700196
Spandan Dasf8807422021-08-25 20:01:17 +0000197 def test_mixed(self):
198 xml = self.xml_tmpl % ('\n'.join([
199 uses_library_xml('foo'),
200 uses_library_xml('bar', required_xml(False))
201 ]))
202 apk = self.apk_tmpl % ('\n'.join([
203 uses_library_apk('foo'),
204 uses_library_apk('bar', required_apk(False))
205 ]))
206 matches = self.run_test(
207 xml, apk, uses_libraries=['foo'], optional_uses_libraries=['bar'])
208 self.assertTrue(matches)
Colin Cross72119102019-05-20 13:14:18 -0700209
Spandan Dasf8807422021-08-25 20:01:17 +0000210 def test_mixed_with_namespace(self):
211 xml = self.xml_tmpl % ('\n'.join([
212 uses_library_xml('foo'),
213 uses_library_xml('bar', required_xml(False))
214 ]))
215 apk = self.apk_tmpl % ('\n'.join([
216 uses_library_apk('foo'),
217 uses_library_apk('bar', required_apk(False))
218 ]))
219 matches = self.run_test(
220 xml,
221 apk,
222 uses_libraries=['//x/y/z:foo'],
223 optional_uses_libraries=['//x/y/z:bar'])
224 self.assertTrue(matches)
Ulya Trafimovich1b513452021-07-20 14:27:32 +0100225
Colin Cross72119102019-05-20 13:14:18 -0700226
227class ExtractTargetSdkVersionTest(unittest.TestCase):
Colin Cross72119102019-05-20 13:14:18 -0700228
Spandan Dasf8807422021-08-25 20:01:17 +0000229 def run_test(self, xml, apk, version):
230 doc = minidom.parseString(xml)
231 v = manifest_check.extract_target_sdk_version(doc, is_apk=False)
232 self.assertEqual(v, version)
233 v = manifest_check.extract_target_sdk_version(apk, is_apk=True)
234 self.assertEqual(v, version)
Ulya Trafimovich0aba2522021-03-03 16:38:37 +0000235
Spandan Dasf8807422021-08-25 20:01:17 +0000236 xml_tmpl = (
237 '<?xml version="1.0" encoding="utf-8"?>\n<manifest '
238 'xmlns:android="http://schemas.android.com/apk/res/android">\n '
239 '<uses-sdk android:minSdkVersion="28" android:targetSdkVersion="%s" '
240 '/>\n</manifest>\n')
Ulya Trafimovich0aba2522021-03-03 16:38:37 +0000241
Spandan Dasf8807422021-08-25 20:01:17 +0000242 apk_tmpl = (
243 "package: name='com.google.android.something' versionCode='100'\n"
244 "sdkVersion:'28'\n"
245 "targetSdkVersion:'%s'\n"
246 "uses-permission: name='android.permission.ACCESS_NETWORK_STATE'\n")
Ulya Trafimovich0aba2522021-03-03 16:38:37 +0000247
Spandan Dasf8807422021-08-25 20:01:17 +0000248 def test_targert_sdk_version_28(self):
249 xml = self.xml_tmpl % '28'
250 apk = self.apk_tmpl % '28'
251 self.run_test(xml, apk, '28')
252
253 def test_targert_sdk_version_29(self):
254 xml = self.xml_tmpl % '29'
255 apk = self.apk_tmpl % '29'
256 self.run_test(xml, apk, '29')
257
Colin Cross72119102019-05-20 13:14:18 -0700258
259if __name__ == '__main__':
Spandan Dasf8807422021-08-25 20:01:17 +0000260 unittest.main(verbosity=2)