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 sys
20import unittest
21from xml.dom import minidom
22
23import manifest_check
24
25sys.dont_write_bytecode = True
26
27
28def uses_library(name, attr=''):
29  return '<uses-library android:name="%s"%s />' % (name, attr)
30
31
32def required(value):
33  return ' android:required="%s"' % ('true' if value else 'false')
34
35
36class EnforceUsesLibrariesTest(unittest.TestCase):
37  """Unit tests for add_extract_native_libs function."""
38
39  def run_test(self, input_manifest, uses_libraries=None, optional_uses_libraries=None):
40    doc = minidom.parseString(input_manifest)
41    try:
42      manifest_check.enforce_uses_libraries(doc, uses_libraries, optional_uses_libraries)
43      return True
44    except manifest_check.ManifestMismatchError:
45      return False
46
47  manifest_tmpl = (
48      '<?xml version="1.0" encoding="utf-8"?>\n'
49      '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n'
50      '    <application>\n'
51      '    %s\n'
52      '    </application>\n'
53      '</manifest>\n')
54
55  def test_uses_library(self):
56    manifest_input = self.manifest_tmpl % (uses_library('foo'))
57    matches = self.run_test(manifest_input, uses_libraries=['foo'])
58    self.assertTrue(matches)
59
60  def test_uses_library_required(self):
61    manifest_input = self.manifest_tmpl % (uses_library('foo', required(True)))
62    matches = self.run_test(manifest_input, uses_libraries=['foo'])
63    self.assertTrue(matches)
64
65  def test_optional_uses_library(self):
66    manifest_input = self.manifest_tmpl % (uses_library('foo', required(False)))
67    matches = self.run_test(manifest_input, optional_uses_libraries=['foo'])
68    self.assertTrue(matches)
69
70  def test_expected_uses_library(self):
71    manifest_input = self.manifest_tmpl % (uses_library('foo', required(False)))
72    matches = self.run_test(manifest_input, uses_libraries=['foo'])
73    self.assertFalse(matches)
74
75  def test_expected_optional_uses_library(self):
76    manifest_input = self.manifest_tmpl % (uses_library('foo'))
77    matches = self.run_test(manifest_input, optional_uses_libraries=['foo'])
78    self.assertFalse(matches)
79
80  def test_missing_uses_library(self):
81    manifest_input = self.manifest_tmpl % ('')
82    matches = self.run_test(manifest_input, uses_libraries=['foo'])
83    self.assertFalse(matches)
84
85  def test_missing_optional_uses_library(self):
86    manifest_input = self.manifest_tmpl % ('')
87    matches = self.run_test(manifest_input, optional_uses_libraries=['foo'])
88    self.assertFalse(matches)
89
90  def test_extra_uses_library(self):
91    manifest_input = self.manifest_tmpl % (uses_library('foo'))
92    matches = self.run_test(manifest_input)
93    self.assertFalse(matches)
94
95  def test_extra_optional_uses_library(self):
96    manifest_input = self.manifest_tmpl % (uses_library('foo', required(False)))
97    matches = self.run_test(manifest_input)
98    self.assertFalse(matches)
99
100  def test_multiple_uses_library(self):
101    manifest_input = self.manifest_tmpl % ('\n'.join([uses_library('foo'),
102                                                      uses_library('bar')]))
103    matches = self.run_test(manifest_input, uses_libraries=['foo', 'bar'])
104    self.assertTrue(matches)
105
106  def test_multiple_optional_uses_library(self):
107    manifest_input = self.manifest_tmpl % ('\n'.join([uses_library('foo', required(False)),
108                                                      uses_library('bar', required(False))]))
109    matches = self.run_test(manifest_input, optional_uses_libraries=['foo', 'bar'])
110    self.assertTrue(matches)
111
112  def test_order_uses_library(self):
113    manifest_input = self.manifest_tmpl % ('\n'.join([uses_library('foo'),
114                                                      uses_library('bar')]))
115    matches = self.run_test(manifest_input, uses_libraries=['bar', 'foo'])
116    self.assertFalse(matches)
117
118  def test_order_optional_uses_library(self):
119    manifest_input = self.manifest_tmpl % ('\n'.join([uses_library('foo', required(False)),
120                                                      uses_library('bar', required(False))]))
121    matches = self.run_test(manifest_input, optional_uses_libraries=['bar', 'foo'])
122    self.assertFalse(matches)
123
124  def test_duplicate_uses_library(self):
125    manifest_input = self.manifest_tmpl % ('\n'.join([uses_library('foo'),
126                                                      uses_library('foo')]))
127    matches = self.run_test(manifest_input, uses_libraries=['foo'])
128    self.assertTrue(matches)
129
130  def test_duplicate_optional_uses_library(self):
131    manifest_input = self.manifest_tmpl % ('\n'.join([uses_library('foo', required(False)),
132                                                      uses_library('foo', required(False))]))
133    matches = self.run_test(manifest_input, optional_uses_libraries=['foo'])
134    self.assertTrue(matches)
135
136  def test_mixed(self):
137    manifest_input = self.manifest_tmpl % ('\n'.join([uses_library('foo'),
138                                                      uses_library('bar', required(False))]))
139    matches = self.run_test(manifest_input, uses_libraries=['foo'],
140                            optional_uses_libraries=['bar'])
141    self.assertTrue(matches)
142
143
144class ExtractTargetSdkVersionTest(unittest.TestCase):
145  def test_target_sdk_version(self):
146    manifest = (
147      '<?xml version="1.0" encoding="utf-8"?>\n'
148      '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n'
149      '    <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="29" />\n'
150      '</manifest>\n')
151    doc = minidom.parseString(manifest)
152    target_sdk_version = manifest_check.extract_target_sdk_version(doc)
153    self.assertEqual(target_sdk_version, '29')
154
155  def test_min_sdk_version(self):
156    manifest = (
157      '<?xml version="1.0" encoding="utf-8"?>\n'
158      '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n'
159      '    <uses-sdk android:minSdkVersion="28" />\n'
160      '</manifest>\n')
161    doc = minidom.parseString(manifest)
162    target_sdk_version = manifest_check.extract_target_sdk_version(doc)
163    self.assertEqual(target_sdk_version, '28')
164
165if __name__ == '__main__':
166  unittest.main(verbosity=2)
167