Upstream version 6.35.131.0
[platform/framework/web/crosswalk.git] / src / xwalk / app / tools / android / make_apk_test.py
1 #!/usr/bin/env python
2
3 # Copyright (c) 2013, 2014 Intel Corporation. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
6
7 import optparse
8 import os
9 import shutil
10 import subprocess
11 import sys
12 import unittest
13 import warnings
14
15 def Clean(name, app_version):
16   if os.path.exists(name):
17     shutil.rmtree(name)
18   if options.mode == 'shared':
19     if os.path.isfile(name + '_' + app_version + '.apk'):
20       os.remove(name + '_' + app_version + '.apk')
21   else:
22     if os.path.isfile(name + '_' + app_version + '_x86.apk'):
23       os.remove(name + '_' + app_version + '_x86.apk')
24     if os.path.isfile(name + '_' + app_version + '_arm.apk'):
25       os.remove(name + '_' + app_version + '_arm.apk')
26
27
28 def RunCommand(command):
29   """Runs the command list, return the output."""
30   proc = subprocess.Popen(command, stdout=subprocess.PIPE,
31                           stderr=subprocess.STDOUT, shell=False)
32   return proc.communicate()[0]
33
34
35 class TestMakeApk(unittest.TestCase):
36   @classmethod
37   def setUpClass(cls):
38     cls._original_dir = os.getcwd()
39     if options.tool_path:
40       target_dir = os.path.expanduser(options.tool_path)
41     elif options.build_dir and options.target:
42       target_dir = os.path.join(options.build_dir,
43                                 options.target,
44                                 'xwalk_app_template')
45     if os.path.exists(target_dir):
46       # Prepare the test data.
47       test_src_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)),
48                                   'test_data')
49       test_des_dir = os.path.join(target_dir, 'test_data')
50       if not os.path.exists(test_des_dir):
51         shutil.copytree(test_src_dir, test_des_dir)
52       os.chdir(target_dir)
53     else:
54       unittest.SkipTest('xwalk_app_template folder doesn\'t exist. '
55                         'Skipping all tests in make_apk_test.py')
56     cls._mode = ''
57     if options.mode == 'shared':
58       cls._mode = '--mode=shared'
59     elif options.mode == 'embedded':
60       cls._mode = '--mode=embedded'
61     cls.fakeNativeLibrary()
62
63   @classmethod
64   def tearDownClass(cls):
65     # Clean the test data.
66     if options.tool_path:
67       test_data_dir = os.path.join(os.path.expanduser(options.tool_path),
68                                    'test_data')
69     elif options.build_dir and options.target:
70       test_data_dir = os.path.join(options.build_dir,
71                                    options.target,
72                                    'xwalk_app_template',
73                                    'test_data')
74     if os.path.exists(test_data_dir):
75       shutil.rmtree(test_data_dir)
76     cls.restoreNativeLibrary()
77     os.chdir(cls._original_dir)
78
79   @staticmethod
80   def fakeNativeLibrary():
81     # To reduce the time consumption of make_apk test for embedded mode,
82     # replace the original native library with an empty library.
83     # Because it doesn't affect the result of test.
84     if options.mode == 'embedded':
85       native_library_dir = 'native_libs'
86       native_library_temp_dir = 'temp'
87       shutil.copytree(native_library_dir, native_library_temp_dir)
88       for root, _, files in os.walk(native_library_dir):
89         if 'libxwalkcore.so' in files:
90           native_library_path = os.path.join(root, 'libxwalkcore.so')
91           # Remove the original library
92           os.remove(native_library_path)
93           # Create an empty library file
94           open(native_library_path, 'a').close()
95
96   @staticmethod
97   def restoreNativeLibrary():
98     # Restore the original native library for embedded mode.
99     if options.mode == 'embedded':
100       native_library_dir = 'native_libs'
101       native_library_temp_dir = 'temp'
102       if os.path.exists(native_library_dir):
103         shutil.rmtree(native_library_dir)
104       shutil.move(native_library_temp_dir, native_library_dir)
105
106   @staticmethod
107   def archs():
108     x86_native_lib_path = os.path.join('native_libs', 'x86', 'libs',
109                                        'x86', 'libxwalkcore.so')
110     arm_native_lib_path = os.path.join('native_libs', 'armeabi-v7a', 'libs',
111                                        'armeabi-v7a', 'libxwalkcore.so')
112     arch_list = []
113     if os.path.isfile(x86_native_lib_path):
114       arch_list.append('x86')
115     if os.path.isfile(arm_native_lib_path):
116       arch_list.append('arm')
117     return arch_list
118
119   def checkApks(self, apk_name, app_version):
120     # Check whether some files are contained in the given APK.
121     if self._mode.find('shared') != -1:
122       apk_path = '%s_%s.apk' % (apk_name, app_version)
123       self.checkApk(apk_path, '')
124     elif self._mode.find('embedded') != -1:
125       x86_apk_path = '%s_%s_x86.apk' % (apk_name, app_version)
126       if os.path.exists(x86_apk_path):
127         self.checkApk(x86_apk_path, 'x86')
128       arm_apk_path = '%s_%s_arm.apk' % (apk_name, app_version)
129       if os.path.exists(arm_apk_path):
130         self.checkApk(arm_apk_path, 'arm')
131
132   def checkApk(self, apk_path, arch):
133     # Check whether some files are contained in the given apk
134     # for specified arch.
135     cmd = ['jar', 'tvf', apk_path]
136     out = RunCommand(cmd)
137     common_files = ['AndroidManifest.xml', 'classes.dex']
138     for res_file in common_files:
139       self.assertTrue(out.find(res_file) != -1)
140     if self._mode.find('embedded') != -1:
141       embedded_related_files = ['icudtl.dat',
142                                 'xwalk.pak',
143                                 'device_capabilities_api.js',
144                                 'launch_screen_api.js',
145                                 'presentation_api.js',
146                                 'screen_orientation_api.js']
147       for res_file in embedded_related_files:
148         self.assertTrue(out.find(res_file) != -1)
149     if arch == 'x86':
150       self.assertTrue(out.find('x86/libxwalkcore.so') != -1)
151     elif arch == 'arm':
152       self.assertTrue(out.find('armeabi-v7a/libxwalkcore.so') != -1)
153
154   def testName(self):
155     cmd = ['python', 'make_apk.py', '--app-version=1.0.0',
156            '--package=org.xwalk.example', self._mode]
157     out = RunCommand(cmd)
158     Clean('Example', '1.0.0')
159     self.assertTrue(out.find('The APK name is required!') != -1)
160     cmd = ['python', 'make_apk.py', '--name="Test Example"',
161            '--app-version=1.0.0',
162            '--package=org.xwalk.example', self._mode]
163     out = RunCommand(cmd)
164     Clean('Test Example', '1.0.0')
165     self.assertTrue(out.find('The APK name is required!') == -1)
166     # The following invalid chars verification is too heavy for embedded mode,
167     # and the result of verification should be the same between shared mode
168     # and embedded mode. So only do the verification in the shared mode.
169     if self._mode.find('shared') != -1:
170       invalid_chars = '\/:.*?"<>|-'
171       for c in invalid_chars:
172         invalid_name = '--name=Example' + c
173         cmd = ['python', 'make_apk.py', invalid_name,
174                '--app-version=1.0.0', '--package=org.xwalk.example',
175                '--app-url=http://www.intel.com', self._mode]
176         out = RunCommand(cmd)
177         Clean('Example_', '1.0.0')
178         self.assertTrue(out.find('Illegal character') != -1)
179
180   def testToolVersion(self):
181     cmd = ['python', 'make_apk.py', '--version']
182     out = RunCommand(cmd)
183     self.assertTrue(out.find('Crosswalk app packaging tool version') != -1)
184
185   def testAppDescriptionAndVersion(self):
186     cmd = ['python', 'make_apk.py', '--name=Example',
187            '--package=org.xwalk.example', '--app-version=1.0.0',
188            '--description=a sample application',
189            '--app-url=http://www.intel.com', self._mode]
190     RunCommand(cmd)
191     self.addCleanup(Clean, 'Example', '1.0.0')
192     manifest = 'Example/AndroidManifest.xml'
193     with open(manifest, 'r') as content_file:
194       content = content_file.read()
195     self.assertTrue(os.path.exists(manifest))
196     self.assertTrue(content.find('description') != -1)
197     self.assertTrue(content.find('versionName') != -1)
198     self.checkApks('Example', '1.0.0')
199
200   def testAppVersionCode(self):
201     cmd = ['python', 'make_apk.py', '--name=Example',
202            '--package=org.xwalk.example', '--app-version=1.0.0',
203            '--description=a sample application',
204            '--app-versionCode=3',
205            '--app-url=http://www.intel.com', self._mode]
206     RunCommand(cmd)
207     self.addCleanup(Clean, 'Example', '1.0.0')
208     manifest = 'Example/AndroidManifest.xml'
209     with open(manifest, 'r') as content_file:
210       content = content_file.read()
211     self.assertTrue(os.path.exists(manifest))
212     self.assertTrue(content.find('versionCode="3"') != -1)
213     self.checkApks('Example', '1.0.0')
214
215   def testAppVersionCodeBase(self):
216     # Arch option only works for embedded mode,
217     # so only test it for embedded mode.
218     if self._mode.find('embedded') == -1:
219       return
220     if 'x86' in self.archs():
221       arch = '--arch=x86'
222       versionCode = 'versionCode="60000003"'
223     else:
224       arch = '--arch=arm'
225       versionCode = 'versionCode="20000003"'
226     cmd = ['python', 'make_apk.py', '--name=Example',
227            '--package=org.xwalk.example', '--app-version=1.0.0',
228            '--description=a sample application',
229            '--app-versionCodeBase=3',
230            arch,
231            '--app-url=http://www.intel.com', self._mode]
232     RunCommand(cmd)
233     self.addCleanup(Clean, 'Example', '1.0.0')
234     manifest = 'Example/AndroidManifest.xml'
235     with open(manifest, 'r') as content_file:
236       content = content_file.read()
237     self.assertTrue(os.path.exists(manifest))
238     self.assertTrue(content.find(versionCode) != -1)
239     self.checkApks('Example', '1.0.0')
240
241   def testAppBigVersionCodeBase(self):
242     # Arch option only works for embedded mode,
243     # so only test it for embedded mode.
244     if self._mode.find('embedded') == -1:
245       return
246     if 'x86' in self.archs():
247       arch = '--arch=x86'
248     else:
249       arch = '--arch=arm'
250     cmd = ['python', 'make_apk.py', '--name=Example',
251            '--package=org.xwalk.example', '--app-version=1.0.0',
252            '--description=a sample application',
253            '--app-versionCodeBase=30000000',
254            arch,
255            '--app-url=http://www.intel.com', self._mode]
256     RunCommand(cmd)
257     self.addCleanup(Clean, 'Example', '1.0.0')
258     manifest = 'Example/AndroidManifest.xml'
259     self.assertFalse(os.path.exists(manifest))
260
261   def testPermissions(self):
262     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
263            '--package=org.xwalk.example', '--permissions=geolocation',
264            '--app-url=http://www.intel.com', self._mode]
265     RunCommand(cmd)
266     self.addCleanup(Clean, 'Example', '1.0.0')
267     manifest = 'Example/AndroidManifest.xml'
268     with open(manifest, 'r') as content_file:
269       content = content_file.read()
270     self.assertTrue(os.path.exists(manifest))
271     self.assertTrue(content.find('ACCESS_FINE_LOCATION') != -1)
272     self.checkApks('Example', '1.0.0')
273
274   def testPermissionsWithError(self):
275     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
276            '--package=org.xwalk.example', '--permissions=UndefinedPermission',
277            '--app-url=http://www.intel.com', self._mode]
278     out = RunCommand(cmd)
279     self.assertTrue(out.find('related API is not supported.') != -1)
280     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
281            '--package=org.xwalk.example',
282            '--permissions=Contacts.Geolocation.Messaging',
283            '--app-url=http://www.intel.com', self._mode]
284     out = RunCommand(cmd)
285     self.assertTrue(out.find('related API is not supported.') != -1)
286
287   def testPackage(self):
288     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
289            self._mode]
290     out = RunCommand(cmd)
291     self.addCleanup(Clean, 'Example', '1.0.0')
292     self.assertTrue(out.find('The package name is required!') != -1)
293     Clean('Example', '1.0.0')
294     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
295            '--package=org.xwalk.example', self._mode]
296     out = RunCommand(cmd)
297     self.assertTrue(out.find('The package name is required!') == -1)
298
299   def testEntry(self):
300     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
301            '--package=org.xwalk.example', '--app-url=http://www.intel.com',
302            self._mode]
303     out = RunCommand(cmd)
304     self.addCleanup(Clean, 'Example', '1.0.0')
305     self.assertTrue(out.find('The entry is required.') == -1)
306     self.checkApks('Example', '1.0.0')
307     Clean('Example', '1.0.0')
308
309     test_entry_root = 'test_data/entry'
310     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
311            '--package=org.xwalk.example', '--app-root=%s' % test_entry_root,
312            '--app-local-path=index.html', self._mode]
313     out = RunCommand(cmd)
314     self.assertTrue(out.find('The entry is required.') == -1)
315     self.checkApks('Example', '1.0.0')
316
317   def testEntryWithErrors(self):
318     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
319            '--package=org.xwalk.example', self._mode]
320     out = RunCommand(cmd)
321     self.addCleanup(Clean, 'Example', '1.0.0')
322     self.assertTrue(out.find('The entry is required.') != -1)
323     self.assertFalse(os.path.exists('Example.apk'))
324     Clean('Example', '1.0.0')
325
326     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
327            '--package=org.xwalk.example', '--app-url=http://www.intel.com',
328            '--app-root=.', self._mode]
329     out = RunCommand(cmd)
330     self.assertTrue(out.find('The entry is required.') != -1)
331     self.assertFalse(os.path.exists('Example.apk'))
332     Clean('Example', '1.0.0')
333
334     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
335            '--package=org.xwalk.example', '--app-root=./', self._mode]
336     out = RunCommand(cmd)
337     self.assertTrue(out.find('The entry is required.') != -1)
338     self.assertFalse(os.path.exists('Example.apk'))
339     Clean('Example', '1.0.0')
340
341     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
342            '--package=org.xwalk.example', '--app-local-path=index.html',
343            self._mode]
344     out = RunCommand(cmd)
345     self.assertTrue(out.find('The entry is required.') != -1)
346     self.assertFalse(os.path.exists('Example.apk'))
347     Clean('Example', '1.0.0')
348
349     manifest_path = os.path.join('test_data', 'manifest',
350                                  'manifest_app_launch_local_path.json')
351     cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path, self._mode]
352     out = RunCommand(cmd)
353     self.assertTrue(out.find('Please make sure that the local path file') != -1)
354     self.assertFalse(os.path.exists('Example.apk'))
355
356   def testIconByOption(self):
357     icon = os.path.join('test_data', 'manifest', 'icons', 'icon_96.png')
358     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
359            '--package=org.xwalk.example', '--app-url=http://www.intel.com',
360            '--icon=%s' % icon, self._mode]
361     RunCommand(cmd)
362     self.addCleanup(Clean, 'Example', '1.0.0')
363     manifest = 'Example/AndroidManifest.xml'
364     with open(manifest, 'r') as content_file:
365       content = content_file.read()
366     self.assertTrue(content.find('drawable/icon_96') != -1)
367     self.checkApks('Example', '1.0.0')
368
369   def testIconByManifest(self):
370     manifest_path = os.path.join('test_data', 'manifest', 'manifest_icon.json')
371     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
372            '--package=org.xwalk.example', '--app-url=http://www.intel.com',
373            '--manifest=%s' % manifest_path, self._mode]
374     RunCommand(cmd)
375     self.addCleanup(Clean, 'Example', '1.0.0')
376     manifest = 'Example/AndroidManifest.xml'
377     with open(manifest, 'r') as content_file:
378       content = content_file.read()
379     self.assertTrue(content.find('drawable/icon') != -1)
380     self.checkApks('Example', '1.0.0')
381
382   def testFullscreen(self):
383     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
384            '--package=org.xwalk.example', '--app-url=http://www.intel.com',
385            '-f', self._mode]
386     RunCommand(cmd)
387     self.addCleanup(Clean, 'Example', '1.0.0')
388     theme = 'Example/res/values/theme.xml'
389     with open(theme, 'r') as content_file:
390       content = content_file.read()
391     self.assertTrue(os.path.exists(theme))
392     self.assertTrue(
393         content.find(
394             '<item name="android:windowFullscreen">true</item>') != -1)
395     self.checkApks('Example', '1.0.0')
396
397   def testEnableRemoteDebugging(self):
398     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
399            '--package=org.xwalk.example', '--app-url=http://www.intel.com',
400            '--enable-remote-debugging', self._mode]
401     RunCommand(cmd)
402     self.addCleanup(Clean, 'Example', '1.0.0')
403     activity = 'Example/src/org/xwalk/example/ExampleActivity.java'
404     with open(activity, 'r') as content_file:
405       content = content_file.read()
406     self.assertTrue(os.path.exists(activity))
407     self.assertTrue(content.find('setRemoteDebugging') != -1)
408     self.checkApks('Example', '1.0.0')
409     Clean('Example', '1.0.0')
410     manifest_path = os.path.join('test_data', 'manifest', 'manifest.json')
411     cmd = ['python', 'make_apk.py', '--enable-remote-debugging',
412            '--manifest=%s' % manifest_path, self._mode]
413     RunCommand(cmd)
414     activity = 'Example/src/org/xwalk/example/ExampleActivity.java'
415     with open(activity, 'r') as content_file:
416       content = content_file.read()
417     self.assertTrue(os.path.exists(activity))
418     self.assertTrue(content.find('setRemoteDebugging') != -1)
419     self.checkApks('Example', '1.0.0')
420
421   def testKeystore(self):
422     keystore_path = os.path.join('test_data', 'keystore', 'xwalk-test.keystore')
423     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
424            '--package=org.xwalk.example', '--app-url=http://www.intel.com',
425            '--keystore-path=%s' % keystore_path, '--keystore-alias=xwalk-test',
426            '--keystore-passcode=xwalk-test', self._mode]
427     RunCommand(cmd)
428     self.addCleanup(Clean, 'Example', '1.0.0')
429     self.assertTrue(os.path.exists('Example'))
430     apk_list = ['Example.apk', 'Example_x86.apk', 'Example_arm.apk']
431     for apk in apk_list:
432       if os.path.isfile(apk):
433         cmd = ['jarsigner', '-verify', '-keystore',
434                keystore_path, '-verbose', apk]
435         out = RunCommand(cmd)
436         self.assertTrue(out.find('smk') != -1)
437     self.checkApks('Example', '1.0.0')
438
439   def testManifest(self):
440     manifest_path = os.path.join('test_data', 'manifest', 'manifest.json')
441     cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path, self._mode]
442     RunCommand(cmd)
443     self.addCleanup(Clean, 'Example', '1.0.0')
444     manifest = 'Example/AndroidManifest.xml'
445     with open(manifest, 'r') as content_file:
446       content = content_file.read()
447     self.assertTrue(os.path.exists(manifest))
448     self.assertTrue(content.find('android.permission.READ_CONTACTS') != -1)
449     self.assertTrue(content.find('android.permission.WRITE_CONTACTS') != -1)
450     self.assertTrue(
451         content.find('android.permission.ACCESS_FINE_LOCATION') != -1)
452     self.assertTrue(content.find('android.permission.READ_SMS') != -1)
453     self.assertTrue(content.find('android.permission.RECEIVE_SMS') != -1)
454     self.assertTrue(content.find('android.permission.SEND_SMS') != -1)
455     self.assertTrue(content.find('android.permission.WRITE_SMS') != -1)
456     theme = 'Example/res/values/theme.xml'
457     with open(theme, 'r') as content_file:
458       content = content_file.read()
459     self.assertTrue(os.path.exists(theme))
460     self.assertTrue(
461         content.find(
462             '<item name="android:windowFullscreen">true</item>') != -1)
463     self.assertTrue(os.path.exists('Example'))
464     self.checkApks('Example', '1.0.0')
465
466   def testManifestWithSpecificValue(self):
467     manifest_path = os.path.join('test_data', 'manifest',
468                                  'manifest_app_launch_local_path.json')
469     cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path, self._mode]
470     out = RunCommand(cmd)
471     self.addCleanup(Clean, 'Example', '1.0.0')
472     self.assertTrue(out.find('no app launch path') == -1)
473     self.checkApks('Example', '1.0.0')
474
475   def testManifestWithError(self):
476     manifest_path = os.path.join('test_data', 'manifest',
477                                  'manifest_no_app_launch_path.json')
478     cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path,
479            '--verbose', self._mode]
480     out = RunCommand(cmd)
481     self.assertTrue(out.find('no app launch path') != -1)
482     manifest_path = os.path.join('test_data', 'manifest',
483                                  'manifest_no_name.json')
484     cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path,
485            '--verbose', self._mode]
486     out = RunCommand(cmd)
487     self.assertTrue(out.find('no \'name\' field') != -1)
488     manifest_path = os.path.join('test_data', 'manifest',
489                                  'manifest_no_version.json')
490     cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path,
491            '--verbose', self._mode]
492     out = RunCommand(cmd)
493     self.assertTrue(out.find('no \'version\' field') != -1)
494     manifest_path = os.path.join('test_data', 'manifest',
495                                  'manifest_permissions_format_error.json')
496     cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path,
497            '--verbose', self._mode]
498     out = RunCommand(cmd)
499     self.assertTrue(out.find('\'Permissions\' field error') != -1)
500     manifest_path = os.path.join('test_data', 'manifest',
501                                  'manifest_permissions_field_error.json')
502     cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path,
503            '--verbose', self._mode]
504     out = RunCommand(cmd)
505     self.assertTrue(out.find('\'Permissions\' field error') != -1)
506     manifest_path = os.path.join('test_data', 'manifest',
507                                  'manifest_not_supported_permission.json')
508     cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path,
509            '--verbose', self._mode]
510     out = RunCommand(cmd)
511     self.assertTrue(
512         out.find('\'Telephony\' related API is not supported') != -1)
513
514   def testExtensionsWithOneExtension(self):
515     # Test with an existed extension.
516     extension_path = 'test_data/extensions/myextension'
517     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
518            '--package=org.xwalk.example', '--app-url=http://www.intel.com',
519            '--extensions=%s' % extension_path, self._mode]
520     RunCommand(cmd)
521     self.addCleanup(Clean, 'Example', '1.0.0')
522     self.assertTrue(os.path.exists('Example'))
523     extensions_config_json = 'Example/assets/extensions-config.json'
524     self.assertTrue(os.path.exists(extensions_config_json))
525     with open(extensions_config_json, 'r') as content_file:
526       content = content_file.read()
527     self.assertTrue(content.find('xwalk-extensions/myextension/myextension.js'))
528     self.assertTrue(content.find('com.example.extension.MyExtension'))
529     extension_js = 'Example/assets/xwalk-extensions/myextension/myextension.js'
530     self.assertTrue(os.path.exists(extension_js))
531     extension_jar = 'Example/xwalk-extensions/myextension/myextension.jar'
532     self.assertTrue(os.path.exists(extension_jar))
533     self.checkApks('Example', '1.0.0')
534
535   def testExtensionsWithNonExtension(self):
536     # Test with a non-existed extension.
537     extension_path = 'test_data/extensions/myextension'
538     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
539            '--package=org.xwalk.example', '--app-url=http://www.intel.com',
540            '--extensions=%s1' % extension_path, self._mode, '--verbose']
541     out = RunCommand(cmd)
542     error_msg = 'Error: can\'t find the extension directory'
543     self.assertTrue(out.find(error_msg) != -1)
544     self.assertTrue(out.find('Exiting with error code: 9') != -1)
545
546   def testExtensionWithPermissions(self):
547     test_entry_root = 'test_data/entry'
548     # Add redundant separators for test.
549     extension_path = 'test_data//extensions/contactextension/'
550     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
551            '--package=org.xwalk.example', '--app-root=%s' % test_entry_root,
552            '--app-local-path=contactextension.html',
553            '--extensions=%s' % extension_path, self._mode]
554     RunCommand(cmd)
555     self.addCleanup(Clean, 'Example', '1.0.0')
556     self.assertTrue(os.path.exists('Example'))
557     manifest = 'Example/AndroidManifest.xml'
558     with open(manifest, 'r') as content_file:
559       content = content_file.read()
560     self.assertTrue(os.path.exists(manifest))
561     self.assertTrue(content.find('android.permission.WRITE_CONTACTS') != -1)
562     self.assertTrue(content.find('android.permission.READ_CONTACTS') != -1)
563     self.checkApks('Example', '1.0.0')
564
565   def testXPK(self):
566     xpk_file = os.path.join('test_data', 'xpk', 'example.xpk')
567     cmd = ['python', 'make_apk.py', '--xpk=%s' % xpk_file, self._mode]
568     RunCommand(cmd)
569     self.addCleanup(Clean, 'Example', '1.0.0')
570     self.assertTrue(os.path.exists('Example'))
571     self.checkApks('Example', '1.0.0')
572
573   def testXPKWithError(self):
574     xpk_file = os.path.join('test_data', 'xpk', 'error.xpk')
575     cmd = ['python', 'make_apk.py', '--xpk=%s' % xpk_file, self._mode]
576     out = RunCommand(cmd)
577     error_msg = 'XPK doesn\'t contain manifest file'
578     self.assertTrue(out.find(error_msg) != -1)
579     self.assertFalse(os.path.exists('Example'))
580
581   def testOrientation(self):
582     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
583            '--package=org.xwalk.example', '--app-url=http://www.intel.com',
584            '--orientation=landscape', self._mode]
585     RunCommand(cmd)
586     self.addCleanup(Clean, 'Example', '1.0.0')
587     manifest = 'Example/AndroidManifest.xml'
588     with open(manifest, 'r') as content_file:
589       content = content_file.read()
590     self.assertTrue(os.path.exists(manifest))
591     self.assertTrue(content.find('landscape') != -1)
592     self.assertTrue(os.path.exists('Example'))
593     self.checkApks('Example', '1.0.0')
594
595   def testArch(self):
596     # Arch option only works for embedded mode,
597     # so only test it for embedded mode.
598     if self._mode.find('embedded') != -1:
599       cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
600              '--package=org.xwalk.example', '--app-url=http://www.intel.com',
601              '--arch=x86', self._mode]
602       RunCommand(cmd)
603       self.addCleanup(Clean, 'Example', '1.0.0')
604       if 'x86' in self.archs():
605         self.assertTrue(os.path.isfile('Example_1.0.0_x86.apk'))
606         self.checkApk('Example_1.0.0_x86.apk', 'x86')
607       else:
608         self.assertFalse(os.path.isfile('Example_1.0.0_x86.apk'))
609       self.assertFalse(os.path.isfile('Example_1.0.0_arm.apk'))
610       Clean('Example', '1.0.0')
611       cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
612              '--package=org.xwalk.example', '--app-url=http://www.intel.com',
613              '--arch=arm', self._mode]
614       RunCommand(cmd)
615       if 'arm' in self.archs():
616         self.assertTrue(os.path.isfile('Example_1.0.0_arm.apk'))
617         self.checkApk('Example_1.0.0_arm.apk', 'arm')
618       else:
619         self.assertFalse(os.path.isfile('Example_1.0.0._arm.apk'))
620       self.assertFalse(os.path.isfile('Example_1.0.0_x86.apk'))
621
622   def testVerbose(self):
623     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
624            '--package=org.xwalk.example', '--app-url=http://www.intel.com',
625            '--verbose', self._mode]
626     result = RunCommand(cmd)
627     self.addCleanup(Clean, 'Example', '1.0.0')
628     self.assertTrue(result.find('aapt') != -1)
629     self.assertTrue(result.find('crunch') != -1)
630     self.assertTrue(result.find('apkbuilder') != -1)
631     self.assertTrue(os.path.exists('Example'))
632     self.checkApks('Example', '1.0.0')
633
634   def executeCommandAndVerifyResult(self, exec_file):
635     # Test all of supported options with empty 'mode' option.
636     icon_path = './app_src/res/drawable-xhdpi/crosswalk.png'
637     extension_path = 'test_data/extensions/myextension'
638     arch = ''
639     icon = ''
640     if exec_file.find("make_apk.py") != -1:
641       arch = '--arch=x86'
642       icon = '--icon=%s' % icon_path
643     cmd = ['python', '%s' % exec_file,
644            '--app-version=1.0.0',
645            '--app-url=http://www.intel.com',
646            '%s' % arch,
647            '--description=a sample application',
648            '--enable-remote-debugging',
649            '--extensions=%s' % extension_path,
650            '--fullscreen',
651            '--keep-screen-on',
652            '%s' % icon,
653            '--name=Example',
654            '--orientation=landscape',
655            '--package=org.xwalk.example',
656            '--permissions=geolocation']
657     RunCommand(cmd)
658     self.addCleanup(Clean, 'Example', '1.0.0')
659     activity = 'Example/src/org/xwalk/example/ExampleActivity.java'
660     with open(activity, 'r') as content_file:
661       content = content_file.read()
662     self.assertTrue(os.path.exists(activity))
663     # Test remote debugging option.
664     self.assertTrue(content.find('setRemoteDebugging') != -1)
665     # Test keep screen on option
666     self.assertTrue(content.find('FLAG_KEEP_SCREEN_ON') != -1)
667
668     manifest = 'Example/AndroidManifest.xml'
669     with open(manifest, 'r') as content_file:
670       content = content_file.read()
671     self.assertTrue(os.path.exists(manifest))
672     # Test permission option.
673     self.assertTrue(content.find('ACCESS_FINE_LOCATION') != -1)
674     # Test description option.
675     self.assertTrue(content.find('description') != -1)
676     # Test app version option.
677     self.assertTrue(content.find('versionName') != -1)
678     # Test orientation option.
679     self.assertTrue(content.find('landscape') != -1)
680     # Test fullscreen option
681     theme = 'Example/res/values/theme.xml'
682     with open(theme, 'r') as content_file:
683       content = content_file.read()
684     self.assertTrue(os.path.exists(theme))
685     self.assertTrue(
686         content.find(
687             '<item name="android:windowFullscreen">true</item>') != -1)
688     # Test extensions option.
689     extensions_config_json = 'Example/assets/extensions-config.json'
690     self.assertTrue(os.path.exists(extensions_config_json))
691     with open(extensions_config_json, 'r') as content_file:
692       content = content_file.read()
693       js_file_name = 'xwalk-extensions/myextension/myextension.js'
694       self.assertTrue(content.find(js_file_name))
695       self.assertTrue(content.find('com.example.extension.MyExtension'))
696     extension_js = 'Example/assets/xwalk-extensions/myextension/myextension.js'
697     self.assertTrue(os.path.exists(extension_js))
698     extension_jar = 'Example/xwalk-extensions/myextension/myextension.jar'
699     self.assertTrue(os.path.exists(extension_jar))
700
701   def testEmptyMode(self):
702     self.executeCommandAndVerifyResult('make_apk.py')
703
704   def testCustomizeFile(self):
705     cmd = ['python', 'make_apk.py',
706            '--app-url=http://www.intel.com',
707            '--app-version=1.0.0',
708            '--name=Example',
709            '--package=org.xwalk.example',
710            '--verbose']
711     RunCommand(cmd)
712     manifest = 'Example/AndroidManifest.xml'
713     if not os.path.exists(manifest):
714       print 'The \'%s\' was not generated, please check it.' % manifest
715       sys.exit(1)
716
717     self.executeCommandAndVerifyResult('customize.py')
718
719
720   def testTargetDir(self):
721     test_option = ['./', '../', '~/']
722     for option in test_option:
723       cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
724              '--package=org.xwalk.example', '--app-url=http://www.intel.com',
725              '--target-dir=%s' % option, self._mode]
726       RunCommand(cmd)
727       self.addCleanup(Clean, os.path.expanduser('%sExample' % option), '1.0.0')
728       if self._mode.find('shared') != -1:
729         apk_path = os.path.expanduser('%sExample_1.0.0.apk' % option)
730         self.assertTrue(os.path.exists(apk_path))
731         self.checkApk(apk_path, '')
732       elif self._mode.find('embedded') != -1:
733         for arch in self.archs():
734           apk_path = os.path.expanduser('%sExample_1.0.0_%s.apk'
735                                         % (option, arch))
736           self.assertTrue(os.path.exists(apk_path))
737           self.checkApk(apk_path, arch)
738
739
740 def SuiteWithModeOption():
741   # Gather all the tests for the specified mode option.
742   test_suite = unittest.TestSuite()
743   test_suite.addTest(TestMakeApk('testAppBigVersionCodeBase'))
744   test_suite.addTest(TestMakeApk('testAppVersionCode'))
745   test_suite.addTest(TestMakeApk('testAppVersionCodeBase'))
746   test_suite.addTest(TestMakeApk('testAppDescriptionAndVersion'))
747   test_suite.addTest(TestMakeApk('testArch'))
748   test_suite.addTest(TestMakeApk('testEnableRemoteDebugging'))
749   test_suite.addTest(TestMakeApk('testEntry'))
750   test_suite.addTest(TestMakeApk('testEntryWithErrors'))
751   test_suite.addTest(TestMakeApk('testExtensionsWithOneExtension'))
752   test_suite.addTest(TestMakeApk('testExtensionsWithNonExtension'))
753   test_suite.addTest(TestMakeApk('testExtensionWithPermissions'))
754   test_suite.addTest(TestMakeApk('testFullscreen'))
755   test_suite.addTest(TestMakeApk('testIconByOption'))
756   test_suite.addTest(TestMakeApk('testIconByManifest'))
757   test_suite.addTest(TestMakeApk('testKeystore'))
758   test_suite.addTest(TestMakeApk('testManifest'))
759   test_suite.addTest(TestMakeApk('testManifestWithError'))
760   test_suite.addTest(TestMakeApk('testName'))
761   test_suite.addTest(TestMakeApk('testOrientation'))
762   test_suite.addTest(TestMakeApk('testPackage'))
763   test_suite.addTest(TestMakeApk('testPermissions'))
764   test_suite.addTest(TestMakeApk('testPermissionsWithError'))
765   test_suite.addTest(TestMakeApk('testXPK'))
766   test_suite.addTest(TestMakeApk('testXPKWithError'))
767   test_suite.addTest(TestMakeApk('testTargetDir'))
768   return test_suite
769
770
771 def SuiteWithEmptyModeOption():
772   # Gather all the tests for empty mode option.
773   test_suite = unittest.TestSuite()
774   test_suite.addTest(TestMakeApk('testCustomizeFile'))
775   test_suite.addTest(TestMakeApk('testEmptyMode'))
776   test_suite.addTest(TestMakeApk('testToolVersion'))
777   test_suite.addTest(TestMakeApk('testVerbose'))
778   return test_suite
779
780
781 def TestSuiteRun(test_runner, suite):
782   results = test_runner.run(suite)
783   return results.wasSuccessful()
784
785
786 if __name__ == '__main__':
787   parser = optparse.OptionParser()
788   info = ('The build directory for xwalk.'
789           'Such as: --build-dir=src/out')
790   parser.add_option('--build-dir', help=info)
791   info = ('The build target for xwalk.'
792           'Such as: --target=Release')
793   parser.add_option('--target', help=info)
794   info = ('The path of package tool.')
795   parser.add_option('--tool-path', help=info)
796   info = ('The packaging mode for xwalk. Such as: --mode=embedded.'
797           'Please refer the detail to the option of make_apk.py.')
798   parser.add_option('--mode', help=info)
799   options, dummy = parser.parse_args()
800   if len(sys.argv) == 1:
801     parser.print_help()
802     sys.exit(1)
803
804   del sys.argv[1:]
805   mode_suite = SuiteWithModeOption()
806   empty_mode_suite = SuiteWithEmptyModeOption()
807   runner = unittest.TextTestRunner(verbosity=2)
808   if options.build_dir or options.target:
809     warnings.warn(('"--build-dir" and "--target" will be deprecated soon, '
810                    'please leverage "--tool-path" instead.'),
811                   Warning)
812   test_result = True
813   if options.mode:
814     test_result = TestSuiteRun(runner, mode_suite)
815   else:
816     # Run tests in both embedded and shared mode
817     # when the mode option isn't specified.
818     options.mode = 'embedded'
819     print 'Run tests in embedded mode.'
820     test_result = TestSuiteRun(runner, mode_suite)
821     options.mode = 'shared'
822     print 'Run tests in shared mode.'
823     test_result = TestSuiteRun(runner, mode_suite) and test_result
824     options.mode = ''
825     print 'Run test without \'--mode\' option.'
826     test_result = TestSuiteRun(runner, empty_mode_suite) and test_result
827   if not test_result:
828     sys.exit(1)