• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
19 import sys
20 import unittest
21 from xml.dom import minidom
22 
23 import manifest_check
24 
25 sys.dont_write_bytecode = True
26 
27 
28 def uses_library_xml(name, attr=''):
29     return '<uses-library android:name="%s"%s />' % (name, attr)
30 
31 
32 def required_xml(value):
33     return ' android:required="%s"' % ('true' if value else 'false')
34 
35 
36 def uses_library_apk(name, sfx=''):
37     return "uses-library%s:'%s'" % (sfx, name)
38 
39 
40 def required_apk(value):
41     return '' if value else '-not-required'
42 
43 
44 class EnforceUsesLibrariesTest(unittest.TestCase):
45     """Unit tests for add_extract_native_libs function."""
46 
47     def run_test(self, xml, apk, uses_libraries=[], optional_uses_libraries=[],
48                  missing_optional_uses_libraries=[]): #pylint: disable=dangerous-default-value
49         doc = minidom.parseString(xml)
50         try:
51             relax = False
52             manifest_check.enforce_uses_libraries(
53                 doc, uses_libraries, optional_uses_libraries, missing_optional_uses_libraries,
54                 relax, False, 'path/to/X/AndroidManifest.xml')
55             manifest_check.enforce_uses_libraries(apk, uses_libraries,
56                                                   optional_uses_libraries,
57                                                   missing_optional_uses_libraries,
58                                                   relax, True,
59                                                   'path/to/X/X.apk')
60             return True
61         except manifest_check.ManifestMismatchError:
62             return False
63 
64     xml_tmpl = (
65         '<?xml version="1.0" encoding="utf-8"?>\n<manifest '
66         'xmlns:android="http://schemas.android.com/apk/res/android">\n    '
67         '<application>\n    %s\n    </application>\n</manifest>\n')
68 
69     apk_tmpl = (
70         "package: name='com.google.android.something' versionCode='100'\n"
71         "sdkVersion:'29'\n"
72         "targetSdkVersion:'29'\n"
73         "uses-permission: name='android.permission.ACCESS_NETWORK_STATE'\n"
74         '%s\n'
75         "densities: '160' '240' '320' '480' '640' '65534")
76 
77     def test_uses_library(self):
78         xml = self.xml_tmpl % (uses_library_xml('foo'))
79         apk = self.apk_tmpl % (uses_library_apk('foo'))
80         matches = self.run_test(xml, apk, uses_libraries=['foo'])
81         self.assertTrue(matches)
82 
83     def test_uses_library_required(self):
84         xml = self.xml_tmpl % (uses_library_xml('foo', required_xml(True)))
85         apk = self.apk_tmpl % (uses_library_apk('foo', required_apk(True)))
86         matches = self.run_test(xml, apk, uses_libraries=['foo'])
87         self.assertTrue(matches)
88 
89     def test_optional_uses_library(self):
90         xml = self.xml_tmpl % (uses_library_xml('foo', required_xml(False)))
91         apk = self.apk_tmpl % (uses_library_apk('foo', required_apk(False)))
92         matches = self.run_test(xml, apk, optional_uses_libraries=['foo'])
93         self.assertTrue(matches)
94 
95     def test_expected_uses_library(self):
96         xml = self.xml_tmpl % (uses_library_xml('foo', required_xml(False)))
97         apk = self.apk_tmpl % (uses_library_apk('foo', required_apk(False)))
98         matches = self.run_test(xml, apk, uses_libraries=['foo'])
99         self.assertFalse(matches)
100 
101     def test_expected_optional_uses_library(self):
102         xml = self.xml_tmpl % (uses_library_xml('foo'))
103         apk = self.apk_tmpl % (uses_library_apk('foo'))
104         matches = self.run_test(xml, apk, optional_uses_libraries=['foo'])
105         self.assertFalse(matches)
106 
107     def test_expected_missing_optional_uses_library(self):
108         xml = self.xml_tmpl % (
109             uses_library_xml('foo') + uses_library_xml('missing') + uses_library_xml('bar'))
110         apk = self.apk_tmpl % (
111             uses_library_apk('foo') + uses_library_apk('missing') + uses_library_apk('bar'))
112         matches = self.run_test(xml, apk, optional_uses_libraries=['foo', 'bar'],
113                                 missing_optional_uses_libraries=['missing'])
114         self.assertFalse(matches)
115 
116     def test_missing_uses_library(self):
117         xml = self.xml_tmpl % ('')
118         apk = self.apk_tmpl % ('')
119         matches = self.run_test(xml, apk, uses_libraries=['foo'])
120         self.assertFalse(matches)
121 
122     def test_missing_optional_uses_library(self):
123         xml = self.xml_tmpl % ('')
124         apk = self.apk_tmpl % ('')
125         matches = self.run_test(xml, apk, optional_uses_libraries=['foo'])
126         self.assertFalse(matches)
127 
128     def test_extra_uses_library(self):
129         xml = self.xml_tmpl % (uses_library_xml('foo'))
130         apk = self.apk_tmpl % (uses_library_xml('foo'))
131         matches = self.run_test(xml, apk)
132         self.assertFalse(matches)
133 
134     def test_extra_optional_uses_library(self):
135         xml = self.xml_tmpl % (uses_library_xml('foo', required_xml(False)))
136         apk = self.apk_tmpl % (uses_library_apk('foo', required_apk(False)))
137         matches = self.run_test(xml, apk)
138         self.assertFalse(matches)
139 
140     def test_multiple_uses_library(self):
141         xml = self.xml_tmpl % ('\n'.join(
142             [uses_library_xml('foo'),
143              uses_library_xml('bar')]))
144         apk = self.apk_tmpl % ('\n'.join(
145             [uses_library_apk('foo'),
146              uses_library_apk('bar')]))
147         matches = self.run_test(xml, apk, uses_libraries=['foo', 'bar'])
148         self.assertTrue(matches)
149 
150     def test_multiple_optional_uses_library(self):
151         xml = self.xml_tmpl % ('\n'.join([
152             uses_library_xml('foo', required_xml(False)),
153             uses_library_xml('bar', required_xml(False))
154         ]))
155         apk = self.apk_tmpl % ('\n'.join([
156             uses_library_apk('foo', required_apk(False)),
157             uses_library_apk('bar', required_apk(False))
158         ]))
159         matches = self.run_test(
160             xml, apk, optional_uses_libraries=['foo', 'bar'])
161         self.assertTrue(matches)
162 
163     def test_order_uses_library(self):
164         xml = self.xml_tmpl % ('\n'.join(
165             [uses_library_xml('foo'),
166              uses_library_xml('bar')]))
167         apk = self.apk_tmpl % ('\n'.join(
168             [uses_library_apk('foo'),
169              uses_library_apk('bar')]))
170         matches = self.run_test(xml, apk, uses_libraries=['bar', 'foo'])
171         self.assertFalse(matches)
172 
173     def test_order_optional_uses_library(self):
174         xml = self.xml_tmpl % ('\n'.join([
175             uses_library_xml('foo', required_xml(False)),
176             uses_library_xml('bar', required_xml(False))
177         ]))
178         apk = self.apk_tmpl % ('\n'.join([
179             uses_library_apk('foo', required_apk(False)),
180             uses_library_apk('bar', required_apk(False))
181         ]))
182         matches = self.run_test(
183             xml, apk, optional_uses_libraries=['bar', 'foo'])
184         self.assertFalse(matches)
185 
186     def test_duplicate_uses_library(self):
187         xml = self.xml_tmpl % ('\n'.join(
188             [uses_library_xml('foo'),
189              uses_library_xml('foo')]))
190         apk = self.apk_tmpl % ('\n'.join(
191             [uses_library_apk('foo'),
192              uses_library_apk('foo')]))
193         matches = self.run_test(xml, apk, uses_libraries=['foo'])
194         self.assertTrue(matches)
195 
196     def test_duplicate_optional_uses_library(self):
197         xml = self.xml_tmpl % ('\n'.join([
198             uses_library_xml('foo', required_xml(False)),
199             uses_library_xml('foo', required_xml(False))
200         ]))
201         apk = self.apk_tmpl % ('\n'.join([
202             uses_library_apk('foo', required_apk(False)),
203             uses_library_apk('foo', required_apk(False))
204         ]))
205         matches = self.run_test(xml, apk, optional_uses_libraries=['foo'])
206         self.assertTrue(matches)
207 
208     def test_mixed(self):
209         xml = self.xml_tmpl % ('\n'.join([
210             uses_library_xml('foo'),
211             uses_library_xml('bar', required_xml(False))
212         ]))
213         apk = self.apk_tmpl % ('\n'.join([
214             uses_library_apk('foo'),
215             uses_library_apk('bar', required_apk(False))
216         ]))
217         matches = self.run_test(
218             xml, apk, uses_libraries=['foo'], optional_uses_libraries=['bar'])
219         self.assertTrue(matches)
220 
221     def test_mixed_with_namespace(self):
222         xml = self.xml_tmpl % ('\n'.join([
223             uses_library_xml('foo'),
224             uses_library_xml('bar', required_xml(False))
225         ]))
226         apk = self.apk_tmpl % ('\n'.join([
227             uses_library_apk('foo'),
228             uses_library_apk('bar', required_apk(False))
229         ]))
230         matches = self.run_test(
231             xml,
232             apk,
233             uses_libraries=['//x/y/z:foo'],
234             optional_uses_libraries=['//x/y/z:bar'])
235         self.assertTrue(matches)
236 
237 
238 class ExtractTargetSdkVersionTest(unittest.TestCase):
239 
240     def run_test(self, xml, apk, version):
241         doc = minidom.parseString(xml)
242         v = manifest_check.extract_target_sdk_version(doc, is_apk=False)
243         self.assertEqual(v, version)
244         v = manifest_check.extract_target_sdk_version(apk, is_apk=True)
245         self.assertEqual(v, version)
246 
247     xml_tmpl = (
248         '<?xml version="1.0" encoding="utf-8"?>\n<manifest '
249         'xmlns:android="http://schemas.android.com/apk/res/android">\n    '
250         '<uses-sdk android:minSdkVersion="28" android:targetSdkVersion="%s" '
251         '/>\n</manifest>\n')
252 
253     apk_tmpl = (
254         "package: name='com.google.android.something' versionCode='100'\n"
255         "sdkVersion:'28'\n"
256         "targetSdkVersion:'%s'\n"
257         "uses-permission: name='android.permission.ACCESS_NETWORK_STATE'\n")
258 
259     def test_targert_sdk_version_28(self):
260         xml = self.xml_tmpl % '28'
261         apk = self.apk_tmpl % '28'
262         self.run_test(xml, apk, '28')
263 
264     def test_targert_sdk_version_29(self):
265         xml = self.xml_tmpl % '29'
266         apk = self.apk_tmpl % '29'
267         self.run_test(xml, apk, '29')
268 
269 
270 if __name__ == '__main__':
271     unittest.main(verbosity=2)
272