blob: 62d0474e15a065679c0d89999a9030a20b066083 [file] [log] [blame]
Damien Martin-Guillerezf88f4d82015-09-25 13:56:55 +00001# Copyright 2015 The Bazel Authors. All rights reserved.
Alex Humeskyb46c6352015-05-26 22:23:13 +00002#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15"""This file contains unit tests for the merge_manifests script."""
16
17import re
18import unittest
19import xml.dom.minidom
20
21from tools.android import merge_manifests
22
23FIRST_MANIFEST = """<?xml version='1.0' encoding='utf-8'?>
24<manifest
25 xmlns:android="http://schemas.android.com/apk/res/android"
26 package="com.google.android.apps.testapp"
27 android:versionCode="70"
28 android:versionName="1.0">
29 <uses-sdk android:minSdkVersion="10"/>
30 <uses-feature android:name="android.hardware.nfc" android:required="true" />
31 <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
32 <application
33 android:icon="@drawable/icon"
34 android:name="com.google.android.apps.testapp.TestApplication"
35 android:theme="@style/Theme.Test"
36 android:label="@string/app_name">
37 <!-- START LIBRARIES (Maintain Alphabetic order) -->
38 <!-- NFC extras -->
39 <uses-library android:name="com.google.android.nfc_extras" android:required="false"/>
40 <!-- END LIBRARIES -->
41 <!-- START ACTIVITIES (Maintain Alphabetic order) -->
42 <!-- Entry point activity - navigation and title bar. -->
43 <activity
44 android:name=".entrypoint.EntryPointActivityGroup"
45 android:screenOrientation="portrait"
46 android:launchMode="singleTop"/>
47 <activity android:name=".ui.topup.TopUpActivity" />
48 <service android:name=".nfcevent.NfcEventService" />
49 <receiver
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +000050 android:name="com.receiver.TestReceiver"
51 android:process="@string/receiver_service_name">
Alex Humeskyb46c6352015-05-26 22:23:13 +000052 <!-- Receive the actual message -->
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +000053 <intent-filter>
54 <action
55 android:name="android.intent.action.USER_PRESENT"/>
56 </intent-filter>
Alex Humeskyb46c6352015-05-26 22:23:13 +000057 </receiver>
58 <provider
59 android:name=".dataaccess.persistence.ContentProvider"
60 android:authorities="com.google.android.apps.testapp"
61 android:exported="false" />
62 </application>
63</manifest>
64"""
65
66SECOND_MANIFEST = """<?xml version='1.0' encoding='utf-8'?>
67<manifest xmlns:android="http://schemas.android.com/apk/res/android"
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +000068 package="com.google.android.apps.testapp2"
69 android:versionCode="1"
70 android:versionName="1.0">
Alex Humeskyb46c6352015-05-26 22:23:13 +000071 <permission android:name="com.google.android.apps.foo.C2D_MESSAGE"
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +000072 android:protectionLevel="signature" />
Alex Humeskyb46c6352015-05-26 22:23:13 +000073 <uses-sdk android:minSdkVersion="5" />
74 <uses-feature android:name="android.hardware.nfc" android:required="true" />
75 <uses-permission android:name="android.permission.READ_LOGS" />
76 <uses-permission android:name="android.permission.INTERNET" />
77 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
78 <!-- Comment for permission android.permission.GET_ACCOUNTS.
79 This is just to make sure the comment is being merged correctly.
80 -->
81 <uses-permission android:name="android.permission.GET_ACCOUNTS" />
82 <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
83
84 <application
85 android:icon="@drawable/icon"
86 android:name="com.google.android.apps.testapp.TestApplication2"
87 android:theme="@style/Theme.Test2"
88 android:label="@string/app_name"
89 android:backupAgent="FooBar">
90 <activity android:name=".ui.home.HomeActivity"
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +000091 android:label="@string/app_name" >
Alex Humeskyb46c6352015-05-26 22:23:13 +000092 <intent-filter>
93 <action android:name="android.intent.action.MAIN"/>
94 <category android:name="android.intent.category.LAUNCHER"/>
95 </intent-filter>
96 </activity>
97 <activity android:name=".TestActivity2"></activity>
98 <activity android:name=".PreviewActivity"></activity>
99 <activity android:name=".ShowTextActivity" android:excludeFromRecents="true"></activity>
100 <activity android:name=".ShowStringListActivity"
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000101 android:excludeFromRecents="true"
102 android:parentActivityName=".ui.home.HomeActivity">
Alex Humeskyb46c6352015-05-26 22:23:13 +0000103 </activity>
104 <service android:name=".TestService">
105 <meta-data android:name="param" android:value="value"/>
106 </service>
107 <service android:name=".nfcevent.NfcEventService" />
108 <receiver android:name=".ConnectivityReceiver" android:enabled="false" >
109 <intent-filter>
110 <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
111 </intent-filter>
112 </receiver>
113 <activity-alias android:name="BarFoo" android:targetActivity=".FooBar" />
114 <provider
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000115 android:name="some.package.with.inner.class$AnInnerClass" />
Alex Humeskyb46c6352015-05-26 22:23:13 +0000116 <provider
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000117 android:name="${packageName}"
118 android:authorities="${packageName}.${packageName}"
119 android:exported="false" />
Alex Humeskyb46c6352015-05-26 22:23:13 +0000120 <provider
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000121 android:name="${packageName}.PlaceHolderProviderName"
122 android:authorities="PlaceHolderProviderAuthorities.${packageName}"
123 android:exported="false" />
Alex Humeskyb46c6352015-05-26 22:23:13 +0000124 <activity
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000125 android:name="activityPrefix.${packageName}.activitySuffix">
Alex Humeskyb46c6352015-05-26 22:23:13 +0000126 <intent-filter>
127 <action android:name="actionPrefix.${packageName}.actionSuffix" />
128 </intent-filter>
129 </activity>
130 </application>
131</manifest>
132"""
133
134THIRD_MANIFEST = """<?xml version='1.0' encoding='utf-8'?>
135<manifest xmlns:android="http://schemas.android.com/apk/res/android"
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000136 package="com.google.android.apps.testapp3"
137 android:versionCode="3"
138 android:versionName="1.30">
Alex Humeskyb46c6352015-05-26 22:23:13 +0000139 <uses-sdk android:minSdkVersion="14" />
140 <uses-feature android:name="android.hardware.nfc" android:required="true" />
141 <uses-permission android:name="android.permission.READ_LOGS" />
142 <uses-permission android:name="android.permission.INTERNET" />
143 <application>
144 <activity android:name=".ui.home.HomeActivity"
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000145 android:label="@string/app_name" >
Alex Humeskyb46c6352015-05-26 22:23:13 +0000146 <intent-filter>
147 <action android:name="android.intent.action.MAIN"/>
148 <category android:name="android.intent.category.LAUNCHER"/>
149 </intent-filter>
150 </activity>
151 <activity android:name="TestActivity"></activity>
152 <service android:name=".TestService" />
153 <receiver android:name=".ConnectivityReceiver" android:enabled="true" >
154 <intent-filter>
155 <action android:name="android.net.conn.CONNECTIVITY_CHANGER" />
156 </intent-filter>
157 </receiver>
158 </application>
159</manifest>
160"""
161
162MANUALLY_MERGED = """<?xml version='1.0' encoding='utf-8'?>
163<manifest
164 xmlns:android="http://schemas.android.com/apk/res/android"
165 package="com.google.android.apps.testapp"
166 android:versionCode="70"
167 android:versionName="1.0">
168 <!-- *** WARNING *** DO NOT EDIT! THIS IS GENERATED MANIFEST BY MERGE_MANIFEST TOOL.
169 Merger manifest:
170 FIRST_MANIFEST
171 Mergee manifests:
172 SECOND_MANIFEST
173 THIRD_MANIFEST
174 -->
175 <uses-sdk android:minSdkVersion="10"/>
176 <uses-feature android:name="android.hardware.nfc" android:required="true" />
177 <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000178 <!-- Merged from file: SECOND_MANIFEST -->
179 <permission android:name="com.google.android.apps.foo.C2D_MESSAGE" android:protectionLevel="signature" />
180 <!-- Merged from file: SECOND_MANIFEST -->
181 <uses-permission android:name="android.permission.INTERNET" />
182 <!-- Merged from file: SECOND_MANIFEST -->
183 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
184 <!-- Merged from file: SECOND_MANIFEST -->
185 <!-- Comment for permission android.permission.GET_ACCOUNTS.
186 This is just to make sure the comment is being merged correctly.
187 -->
188 <uses-permission android:name="android.permission.GET_ACCOUNTS" />
Alex Humeskyb46c6352015-05-26 22:23:13 +0000189 <application
190 android:icon="@drawable/icon"
191 android:name="com.google.android.apps.testapp.TestApplication"
192 android:theme="@style/Theme.Test"
193 android:label="@string/app_name">
194 <!-- START LIBRARIES (Maintain Alphabetic order) -->
195 <!-- NFC extras -->
196 <uses-library android:name="com.google.android.nfc_extras" android:required="false"/>
197 <!-- END LIBRARIES -->
198 <!-- START ACTIVITIES (Maintain Alphabetic order) -->
199 <!-- Entry point activity - navigation and title bar. -->
200 <activity
201 android:name="com.google.android.apps.testapp.entrypoint.EntryPointActivityGroup"
202 android:screenOrientation="portrait"
203 android:launchMode="singleTop"/>
204 <activity android:name="com.google.android.apps.testapp.ui.topup.TopUpActivity" />
205 <service android:name="com.google.android.apps.testapp.nfcevent.NfcEventService" />
206 <receiver
207 android:name="com.receiver.TestReceiver"
208 android:process="@string/receiver_service_name">
209 <!-- Receive the actual message -->
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000210 <intent-filter>
211 <action
212 android:name="android.intent.action.USER_PRESENT"/>
213 </intent-filter>
Alex Humeskyb46c6352015-05-26 22:23:13 +0000214 </receiver>
215 <provider android:authorities="com.google.android.apps.testapp" android:exported="false"
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000216 android:name="com.google.android.apps.testapp.dataaccess.persistence.ContentProvider"/>
Alex Humeskyb46c6352015-05-26 22:23:13 +0000217 <!-- Merged from file: SECOND_MANIFEST -->
218 <activity android:label="@string/app_name" android:name="com.google.android.apps.testapp2.ui.home.HomeActivity">
219 <intent-filter>
220 <action android:name="android.intent.action.MAIN"/>
221 <category android:name="android.intent.category.LAUNCHER"/>
222 </intent-filter>
223 </activity>
224 <!-- Merged from file: SECOND_MANIFEST -->
225 <activity android:name="com.google.android.apps.testapp2.TestActivity2"></activity>
226 <!-- Merged from file: SECOND_MANIFEST -->
227 <activity android:name="com.google.android.apps.testapp2.PreviewActivity"></activity>
228 <!-- Merged from file: SECOND_MANIFEST -->
229 <activity android:name="com.google.android.apps.testapp2.ShowTextActivity"
230 android:excludeFromRecents="true"></activity>
231 <!-- Merged from file: SECOND_MANIFEST -->
232 <activity android:name="com.google.android.apps.testapp2.ShowStringListActivity"
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000233 android:excludeFromRecents="true"
234 android:parentActivityName="com.google.android.apps.testapp2.ui.home.HomeActivity">
Alex Humeskyb46c6352015-05-26 22:23:13 +0000235 </activity>
236 <!-- Merged from file: SECOND_MANIFEST -->
237 <activity
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000238 android:name="activityPrefix.com.google.android.apps.testapp.activitySuffix">
Alex Humeskyb46c6352015-05-26 22:23:13 +0000239 <intent-filter>
240 <action android:name="actionPrefix.com.google.android.apps.testapp.actionSuffix" />
241 </intent-filter>
242 </activity>
243 <!-- Merged from file: SECOND_MANIFEST -->
244 <provider
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000245 android:name="some.package.with.inner.class$AnInnerClass" />
Alex Humeskyb46c6352015-05-26 22:23:13 +0000246 <!-- Merged from file: SECOND_MANIFEST -->
247 <provider
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000248 android:name="com.google.android.apps.testapp"
249 android:authorities="com.google.android.apps.testapp.com.google.android.apps.testapp"
250 android:exported="false" />
Alex Humeskyb46c6352015-05-26 22:23:13 +0000251 <!-- Merged from file: SECOND_MANIFEST -->
252 <provider
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000253 android:name="com.google.android.apps.testapp.PlaceHolderProviderName"
254 android:authorities="PlaceHolderProviderAuthorities.com.google.android.apps.testapp"
255 android:exported="false" />
Alex Humeskyb46c6352015-05-26 22:23:13 +0000256 <!-- Merged from file: SECOND_MANIFEST -->
257 <receiver android:name="com.google.android.apps.testapp2.ConnectivityReceiver"
258 android:enabled="false" >
259 <intent-filter>
260 <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
261 </intent-filter>
262 </receiver>
263 <!-- Merged from file: SECOND_MANIFEST -->
264 <service android:name="com.google.android.apps.testapp2.TestService">
265 <meta-data android:name="param" android:value="value"/>
266 </service>
267 <!-- Merged from file: SECOND_MANIFEST -->
268 <service android:name="com.google.android.apps.testapp2.nfcevent.NfcEventService"/>
269 <!-- Merged from file: THIRD_MANIFEST -->
270 <activity android:label="@string/app_name" android:name="com.google.android.apps.testapp3.ui.home.HomeActivity">
271 <intent-filter>
272 <action android:name="android.intent.action.MAIN"/>
273 <category android:name="android.intent.category.LAUNCHER"/>
274 </intent-filter>
275 </activity>
276 <!-- Merged from file: THIRD_MANIFEST -->
277 <activity android:name="com.google.android.apps.testapp3.TestActivity"/>
278 <!-- Merged from file: THIRD_MANIFEST -->
279 <receiver android:enabled="true"
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000280 android:name="com.google.android.apps.testapp3.ConnectivityReceiver">
281 <intent-filter>
282 <action android:name="android.net.conn.CONNECTIVITY_CHANGER"/>
283 </intent-filter>
284 </receiver>
285 <!-- Merged from file: THIRD_MANIFEST -->
286 <service android:name="com.google.android.apps.testapp3.TestService"/>
287 <!-- Merged from file: SECOND_MANIFEST -->
Alex Humeskyb46c6352015-05-26 22:23:13 +0000288 <activity-alias android:name="com.google.android.apps.testapp2.BarFoo"
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000289 android:targetActivity="com.google.android.apps.testapp2.FooBar"/>
Alex Humeskyb46c6352015-05-26 22:23:13 +0000290 </application>
Alex Humeskyb46c6352015-05-26 22:23:13 +0000291</manifest>
292"""
293
294
295ALIAS_MANIFEST = """<?xml version='1.0' encoding='utf-8'?>
296<manifest
297 xmlns:android="http://schemas.android.com/apk/res/android"
298 package="com.google.android.apps.testapp"
299 android:versionCode="70"
300 android:versionName="1.0">
301 <uses-sdk android:minSdkVersion="10"/>
302 <uses-feature android:name="android.hardware.nfc" android:required="true" />
303 <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
304 <application
305 android:icon="@drawable/icon"
306 android:name="com.google.android.apps.testapp.TestApplication"
307 android:theme="@style/Theme.Test"
308 android:label="@string/app_name">
309 <activity-alias android:name="com.google.foo.should.not.be.first"
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000310 android:targetActivity=".entrypoint.EntryPointActivityGroup"/>
Alex Humeskyb46c6352015-05-26 22:23:13 +0000311 <!-- START LIBRARIES (Maintain Alphabetic order) -->
312 <!-- NFC extras -->
313 <uses-library android:name="com.google.android.nfc_extras" android:required="false"/>
314 <!-- END LIBRARIES -->
315 <!-- START ACTIVITIES (Maintain Alphabetic order) -->
316 <!-- Entry point activity - navigation and title bar. -->
317 <activity
318 android:name=".entrypoint.EntryPointActivityGroup"
319 android:screenOrientation="portrait"
320 android:launchMode="singleTop"/>
321 <activity android:name=".ui.topup.TopUpActivity" />
322 <service android:name=".nfcevent.NfcEventService" />
323 <receiver
324 android:name="com.receiver.TestReceiver"
325 android:process="@string/receiver_service_name">
326 <!-- Receive the actual message -->
327 <intent-filter>
328 <action
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000329 android:name="android.intent.action.USER_PRESENT"/>
Alex Humeskyb46c6352015-05-26 22:23:13 +0000330 </intent-filter>
331 </receiver>
332 <provider
333 android:name=".dataaccess.persistence.ContentProvider"
334 android:authorities="com.google.android.apps.testapp"
335 android:exported="false" />
336 </application>
337</manifest>
338"""
339
340
341# This case exists when a library manifest relies on
342# dependent manifests to provide required elements, i.e. a <application>
343INVALID_MERGER_MANIFEST = """
344<manifest xmlns:android="http://schemas.android.com/apk/res/android"
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000345 package="com.google.android.invalid"
346 android:versionCode="9100000"
347 android:versionName="9.1.0.0x">
Alex Humeskyb46c6352015-05-26 22:23:13 +0000348 <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
349</manifest>
350"""
351
352
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000353INVALID_MERGEE_MANIFEST = """
354<manifest xmlns:android="http://schemas.android.com/apk/res/android"
355 package="com.google.android.invalid"
356 android:versionCode="9100000"
357 android:versionName="9.1.0.0x">
358 <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
359 <permission android:name="com.google.android.apps.foo.C2D_MESSAGE" android:protectionLevel="signature"/>
360 <uses-feature android:name="android.hardware.nfc" android:required="true"/>
361</manifest>
362"""
363
Alex Humeskyb46c6352015-05-26 22:23:13 +0000364VALID_MANIFEST = """
365<manifest
366 android:versionCode="9100000"
367 android:versionName="9.1.0.0x"
368 package="com.google.android.invalid"
369 xmlns:android="http://schemas.android.com/apk/res/android">
370 <!-- *** WARNING *** DO NOT EDIT! THIS IS GENERATED MANIFEST BY MERGE_MANIFEST TOOL.
371 Merger manifest:
372 INVALID_MANIFEST
373 Mergee manifests:
374 SECOND_MANIFEST
375 -->
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000376 <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21"/>
377 <!-- Merged from file: SECOND_MANIFEST -->
378 <permission android:name="com.google.android.apps.foo.C2D_MESSAGE" android:protectionLevel="signature"/>
379 <!-- Merged from file: SECOND_MANIFEST -->
380 <uses-feature android:name="android.hardware.nfc" android:required="true"/>
Alex Humeskyb46c6352015-05-26 22:23:13 +0000381 <application
382 android:backupAgent="com.google.android.apps.testapp2.FooBar"
383 android:icon="@drawable/icon"
384 android:label="@string/app_name"
385 android:name="com.google.android.apps.testapp.TestApplication2"
386 android:theme="@style/Theme.Test2">
387 <activity
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000388 android:name="com.google.android.apps.testapp2.TestActivity2"/>
Alex Humeskyb46c6352015-05-26 22:23:13 +0000389 <activity
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000390 android:name="com.google.android.apps.testapp2.PreviewActivity"/>
Alex Humeskyb46c6352015-05-26 22:23:13 +0000391 <activity android:excludeFromRecents="true"
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000392 android:name="com.google.android.apps.testapp2.ShowTextActivity"/>
Alex Humeskyb46c6352015-05-26 22:23:13 +0000393 <activity android:excludeFromRecents="true"
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000394 android:name="com.google.android.apps.testapp2.ShowStringListActivity"
395 android:parentActivityName="com.google.android.apps.testapp2.ui.home.HomeActivity">
Alex Humeskyb46c6352015-05-26 22:23:13 +0000396 </activity>
397 <service
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000398 android:name="com.google.android.apps.testapp2.TestService">
Alex Humeskyb46c6352015-05-26 22:23:13 +0000399 <meta-data android:name="param"
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000400 android:value="value"/>
Alex Humeskyb46c6352015-05-26 22:23:13 +0000401 </service>
402 <service
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000403 android:name="com.google.android.apps.testapp2.nfcevent.NfcEventService"/>
Alex Humeskyb46c6352015-05-26 22:23:13 +0000404 <receiver
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000405 android:enabled="false"
406 android:name="com.google.android.apps.testapp2.ConnectivityReceiver">
Alex Humeskyb46c6352015-05-26 22:23:13 +0000407 <intent-filter>
408 <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
409 </intent-filter>
410 </receiver>
411 <provider android:name="some.package.with.inner.class$AnInnerClass"/>
412 <provider
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000413 android:authorities="com.google.android.invalid.com.google.android.invalid"
414 android:exported="false" android:name="com.google.android.invalid"/>
Alex Humeskyb46c6352015-05-26 22:23:13 +0000415 <provider android:authorities="PlaceHolderProviderAuthorities.com.google.android.invalid"
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000416 android:exported="false"
417 android:name="com.google.android.invalid.PlaceHolderProviderName"/>
Alex Humeskyb46c6352015-05-26 22:23:13 +0000418 <activity android:name="activityPrefix.com.google.android.invalid.activitySuffix">
419 <intent-filter>
420 <action android:name="actionPrefix.com.google.android.invalid.actionSuffix"/>
421 </intent-filter>
422 </activity>
423 <!-- Merged from file: SECOND_MANIFEST -->
424 <activity android:label="@string/app_name"
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000425 android:name="com.google.android.apps.testapp2.ui.home.HomeActivity">
Alex Humeskyb46c6352015-05-26 22:23:13 +0000426 <intent-filter>
427 <action android:name="android.intent.action.MAIN"/>
428 <category android:name="android.intent.category.LAUNCHER"/>
429 </intent-filter>
430 </activity>
431 <activity-alias
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000432 android:name="com.google.android.apps.testapp2.BarFoo"
433 android:targetActivity="com.google.android.apps.testapp2.FooBar"/>
Alex Humeskyb46c6352015-05-26 22:23:13 +0000434 </application>
Alex Humeskyb46c6352015-05-26 22:23:13 +0000435</manifest>
436"""
437
Googler7576acc2016-08-25 21:33:55 +0000438MANIFEST_WITHOUT_EXTRA_NAMESPACE = """
439<manifest xmlns:android="http://schemas.android.com/apk/res/android"
440 package="com.google.android.test"
441 android:versionCode="1"
442 android:versionName="1.0.0.0">
443 <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
444 <application>
445 <activity android:name=".ui.home.HomeActivity"
446 android:label="@string/app_name" >
447 <intent-filter>
448 <action android:name="android.intent.action.MAIN"/>
449 <category android:name="android.intent.category.LAUNCHER"/>
450 </intent-filter>
451 </activity>
452 </application>
453</manifest>
454"""
455
456MANIFEST_WITH_EXTRA_NAMESPACE = """
457<manifest
458 xmlns:android="http://schemas.android.com/apk/res/android"
459 xmlns:tools="http://schemas.android.com/tools"
460 package="com.google.android.library">
461 <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
462 <application>
463 <service android:name=".nfcevent.NfcEventService"
464 android:exported="true"
465 tools:replace="exported" />
466 </application>
467</manifest>
468"""
469
470MERGED_MANIFEST_WITH_EXTRA_NAMESPACE = """
471<manifest xmlns:android="http://schemas.android.com/apk/res/android"
472 xmlns:tools="http://schemas.android.com/tools"
473 package="com.google.android.test"
474 android:versionCode="1"
475 android:versionName="1.0.0.0">
476 <!-- *** WARNING *** DO NOT EDIT! THIS IS GENERATED MANIFEST BY MERGE_MANIFEST TOOL.
477 Merger manifest:
478 MANIFEST_WITHOUT_EXTRA_NAMESPACE
479 Mergee manifests:
480 MANIFEST_WITH_EXTRA_NAMESPACE
481 -->
482 <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
483 <application>
484 <activity android:name="com.google.android.test.ui.home.HomeActivity"
485 android:label="@string/app_name" >
486 <intent-filter>
487 <action android:name="android.intent.action.MAIN"/>
488 <category android:name="android.intent.category.LAUNCHER"/>
489 </intent-filter>
490 </activity>
491 <!-- Merged from file: MANIFEST_WITH_EXTRA_NAMESPACE -->
492 <service android:exported="true" android:name="com.google.android.library.nfcevent.NfcEventService" tools:replace="exported"/>
493 </application>
494</manifest>
495"""
496
497MANIFEST_WITH_CONFLICTING_NAMESPACE = """
498<manifest xmlns:android="http://schemas.android.com/apk/res/android"
499 xmlns:tools="not_tools"
500 package="com.google.android.test"
501 android:versionCode="1"
502 android:versionName="1.0.0.0">
503 <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
504 <application>
505 <activity android:name=".ui.home.HomeActivity"
506 android:label="@string/app_name" >
507 <intent-filter>
508 <action android:name="android.intent.action.MAIN"/>
509 <category android:name="android.intent.category.LAUNCHER"/>
510 </intent-filter>
511 </activity>
512 </application>
513</manifest>
514"""
515
Alex Humeskyb46c6352015-05-26 22:23:13 +0000516
517def Reformat(string):
518 """Reformat for comparison."""
519 string = re.compile(r'^[ \t]*\n?', re.MULTILINE).sub('', string)
520 return string
521
522
523class MergeManifestsTest(unittest.TestCase):
524 """Unit tests for the MergeManifest class."""
525
526 def testMerge(self):
527 self.maxDiff = None
528 merger = merge_manifests.MergeManifests(
529 (FIRST_MANIFEST, 'FIRST_MANIFEST'),
530 [(SECOND_MANIFEST, 'SECOND_MANIFEST'),
531 (THIRD_MANIFEST, 'THIRD_MANIFEST')],
532 ['android.permission.READ_LOGS'])
533 result = merger.Merge()
534 expected = xml.dom.minidom.parseString(MANUALLY_MERGED).toprettyxml()
535 self.assertEquals(Reformat(expected), Reformat(result))
536
537 def testReformat(self):
538 text = ' a\n b\n\n\n \t c'
539 expected = 'a\nb\nc'
540 self.assertEquals(expected, Reformat(text))
541
542 def testValidateAndWarnPermissions(self):
543 permissions = ['android.permission.VIBRATE', 'android.permission.LAUGH']
544 warnings = merge_manifests._ValidateAndWarnPermissions(permissions)
545 self.assertTrue('android.permission.VIBRATE' not in warnings)
546 self.assertTrue('android.permission.LAUGH' in warnings)
547
548 def testExcludeAllPermissions(self):
549 merger = merge_manifests.MergeManifests(
550 (FIRST_MANIFEST, 'FIRST_MANIFEST'),
551 [(SECOND_MANIFEST, 'SECOND_MANIFEST'),
552 (THIRD_MANIFEST, 'THIRD_MANIFEST')],
553 ['all'])
554 result = merger.Merge()
555 self.assertFalse('android.permission.READ_LOGS' in result)
556 self.assertFalse('android.permission.INTERNET' in result)
557 self.assertTrue('android.permission.ACCESS_COARSE_LOCATION' in result)
558
559 def testUndefinedArgumentPlaceholder(self):
560 bad_manifest = SECOND_MANIFEST.replace(
561 '${packageName}', '${unknownPlaceHolder}')
562 merger = merge_manifests.MergeManifests(
563 (FIRST_MANIFEST, 'FIRST_MANIFEST'),
564 [(bad_manifest, 'invalidManifest'),
565 (THIRD_MANIFEST, 'THIRD_MANIFEST')])
566 try:
567 merger.Merge()
568 self.fail('merging manifests with unknown placeholders didn\'t fail')
569 except merge_manifests.UndefinedPlaceholderException:
570 pass
571
572 def testActivityAliasesAreAlwaysLast(self):
573 merger = merge_manifests.MergeManifests(
574 (FIRST_MANIFEST, 'FIRST_MANIFEST'),
575 [(SECOND_MANIFEST, 'SECOND_MANIFEST'),
576 (ALIAS_MANIFEST, 'THIRD_MANIFEST')],
577 ['all'])
578 result = merger.Merge()
579 last_occurence_of_activity = result.rfind('<activity ')
580 first_occurence_of_alias = result.find('<activity-alias ')
581 self.assertLess(last_occurence_of_activity, first_occurence_of_alias,
582 msg='First activity-alias is not after the last activity!')
583
584 def testMergeToCreateValidManifest(self):
585 self.maxDiff = None
586 merger = merge_manifests.MergeManifests(
587 (INVALID_MERGER_MANIFEST, 'INVALID_MANIFEST'),
588 [(SECOND_MANIFEST, 'SECOND_MANIFEST')],
589 ['all'])
590 result = merger.Merge()
591 expected = xml.dom.minidom.parseString(VALID_MANIFEST).toprettyxml()
592 self.assertEquals(Reformat(expected), Reformat(result))
593
Andrew Pellegrini4ec251b2016-06-21 21:15:01 +0000594 def testMergeWithNoApplication(self):
595 merger = merge_manifests.MergeManifests(
596 (INVALID_MERGER_MANIFEST, 'INVALID_MERGER_MANIFEST'),
597 [(INVALID_MERGEE_MANIFEST, 'INVALID_MERGEE_MANIFEST')],
598 ['all'])
599 merger.Merge()
Alex Humeskyb46c6352015-05-26 22:23:13 +0000600
Googler7576acc2016-08-25 21:33:55 +0000601 def testMergeWithNamespaces(self):
602 self.maxDiff = None
603 merger = merge_manifests.MergeManifests(
604 (MANIFEST_WITHOUT_EXTRA_NAMESPACE, 'MANIFEST_WITHOUT_EXTRA_NAMESPACE'),
605 [(MANIFEST_WITH_EXTRA_NAMESPACE, 'MANIFEST_WITH_EXTRA_NAMESPACE')],
606 ['all'])
607 result = merger.Merge()
608 expected = xml.dom.minidom.parseString(
609 MERGED_MANIFEST_WITH_EXTRA_NAMESPACE).toprettyxml()
610 # Make sure the result is valid xml (not missing xmlns declarations)
611 result_reparsed = xml.dom.minidom.parseString(result).toprettyxml()
612 self.assertEquals(Reformat(expected), Reformat(result_reparsed))
613
614 def testMergeConflictingNamespaces(self):
615 self.maxDiff = None
616 merger = merge_manifests.MergeManifests(
617 (MANIFEST_WITH_CONFLICTING_NAMESPACE,
618 'MANIFEST_WITH_CONFLICTING_NAMESPACE'),
619 [(MANIFEST_WITH_EXTRA_NAMESPACE, 'MANIFEST_WITH_EXTRA_NAMESPACE')],
620 ['all'])
621 with self.assertRaisesRegexp(merge_manifests.MalformedManifestException,
622 'different values for namespace xmlns:tools'):
623 merger.Merge()
624
625
Alex Humeskyb46c6352015-05-26 22:23:13 +0000626if __name__ == '__main__':
627 unittest.main()
628