Upstream version 6.34.113.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 = ['xwalk.pak',
142                                 'device_capabilities_api.js',
143                                 'launch_screen_api.js',
144                                 'presentation_api.js',
145                                 'screen_orientation_api.js']
146       for res_file in embedded_related_files:
147         self.assertTrue(out.find(res_file) != -1)
148     if arch == 'x86':
149       self.assertTrue(out.find('x86/libxwalkcore.so') != -1)
150     elif arch == 'arm':
151       self.assertTrue(out.find('armeabi-v7a/libxwalkcore.so') != -1)
152
153   def testName(self):
154     cmd = ['python', 'make_apk.py', '--app-version=1.0.0',
155            '--package=org.xwalk.example', self._mode]
156     out = RunCommand(cmd)
157     self.assertTrue(out.find('The APK name is required!') != -1)
158     Clean('Example', '1.0.0')
159     cmd = ['python', 'make_apk.py', '--name="Test Example"',
160            '--app-version=1.0.0',
161            '--package=org.xwalk.example', self._mode]
162     out = RunCommand(cmd)
163     self.assertTrue(out.find('The APK name is required!') == -1)
164     Clean('Test Example', '1.0.0')
165     # The following invalid chars verification is too heavy for embedded mode,
166     # and the result of verification should be the same between shared mode
167     # and embedded mode. So only do the verification in the shared mode.
168     if self._mode.find('shared') != -1:
169       invalid_chars = '\/:.*?"<>|-'
170       for c in invalid_chars:
171         invalid_name = '--name=Example' + c
172         cmd = ['python', 'make_apk.py', invalid_name,
173                '--app-version=1.0.0', '--package=org.xwalk.example',
174                '--app-url=http://www.intel.com', self._mode]
175         out = RunCommand(cmd)
176         self.assertTrue(out.find('Illegal character') != -1)
177         Clean('Example_', '1.0.0')
178
179   def testToolVersion(self):
180     cmd = ['python', 'make_apk.py', '--version']
181     out = RunCommand(cmd)
182     self.assertTrue(out.find('Crosswalk app packaging tool version') != -1)
183
184   def testAppDescriptionAndVersion(self):
185     cmd = ['python', 'make_apk.py', '--name=Example',
186            '--package=org.xwalk.example', '--app-version=1.0.0',
187            '--description=a sample application',
188            '--app-url=http://www.intel.com', self._mode]
189     RunCommand(cmd)
190     manifest = 'Example/AndroidManifest.xml'
191     with open(manifest, 'r') as content_file:
192       content = content_file.read()
193     self.assertTrue(os.path.exists(manifest))
194     self.assertTrue(content.find('description') != -1)
195     self.assertTrue(content.find('versionName') != -1)
196     self.checkApks('Example', '1.0.0')
197     Clean('Example', '1.0.0')
198
199   def testAppVersionCode(self):
200     cmd = ['python', 'make_apk.py', '--name=Example',
201            '--package=org.xwalk.example', '--app-version=1.0.0',
202            '--description=a sample application',
203            '--app-versionCode=3',
204            '--app-url=http://www.intel.com', self._mode]
205     RunCommand(cmd)
206     manifest = 'Example/AndroidManifest.xml'
207     with open(manifest, 'r') as content_file:
208       content = content_file.read()
209     self.assertTrue(os.path.exists(manifest))
210     self.assertTrue(content.find('versionCode="3"') != -1)
211     self.checkApks('Example', '1.0.0')
212     Clean('Example', '1.0.0')
213
214   def testAppVersionCodeBase(self):
215     # Arch option only works for embedded mode,
216     # so only test it for embedded mode.
217     if self._mode.find('embedded') == -1:
218       return
219     if 'x86' in self.archs():
220       arch = '--arch=x86'
221       versionCode = 'versionCode="60000003"'
222     else:
223       arch = '--arch=arm'
224       versionCode = 'versionCode="20000003"'
225     cmd = ['python', 'make_apk.py', '--name=Example',
226            '--package=org.xwalk.example', '--app-version=1.0.0',
227            '--description=a sample application',
228            '--app-versionCodeBase=3',
229            arch,
230            '--app-url=http://www.intel.com', self._mode]
231     RunCommand(cmd)
232     manifest = 'Example/AndroidManifest.xml'
233     with open(manifest, 'r') as content_file:
234       content = content_file.read()
235     self.assertTrue(os.path.exists(manifest))
236     self.assertTrue(content.find(versionCode) != -1)
237     self.checkApks('Example', '1.0.0')
238     Clean('Example', '1.0.0')
239
240   def testAppBigVersionCodeBase(self):
241     # Arch option only works for embedded mode,
242     # so only test it for embedded mode.
243     if self._mode.find('embedded') == -1:
244       return
245     if 'x86' in self.archs():
246       arch = '--arch=x86'
247     else:
248       arch = '--arch=arm'
249     cmd = ['python', 'make_apk.py', '--name=Example',
250            '--package=org.xwalk.example', '--app-version=1.0.0',
251            '--description=a sample application',
252            '--app-versionCodeBase=30000000',
253            arch,
254            '--app-url=http://www.intel.com', self._mode]
255     RunCommand(cmd)
256     manifest = 'Example/AndroidManifest.xml'
257     self.assertFalse(os.path.exists(manifest))
258     Clean('Example', '1.0.0')
259
260   def testPermissions(self):
261     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
262            '--package=org.xwalk.example', '--permissions=geolocation',
263            '--app-url=http://www.intel.com', self._mode]
264     RunCommand(cmd)
265     manifest = 'Example/AndroidManifest.xml'
266     with open(manifest, 'r') as content_file:
267       content = content_file.read()
268     self.assertTrue(os.path.exists(manifest))
269     self.assertTrue(content.find('ACCESS_FINE_LOCATION') != -1)
270     self.checkApks('Example', '1.0.0')
271     Clean('Example', '1.0.0')
272
273   def testPermissionsWithError(self):
274     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
275            '--package=org.xwalk.example', '--permissions=UndefinedPermission',
276            '--app-url=http://www.intel.com', self._mode]
277     out = RunCommand(cmd)
278     self.assertTrue(out.find('related API is not supported.') != -1)
279     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
280            '--package=org.xwalk.example',
281            '--permissions=Contacts.Geolocation.Messaging',
282            '--app-url=http://www.intel.com', self._mode]
283     out = RunCommand(cmd)
284     self.assertTrue(out.find('related API is not supported.') != -1)
285
286   def testPackage(self):
287     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
288            self._mode]
289     out = RunCommand(cmd)
290     self.assertTrue(out.find('The package name is required!') != -1)
291     Clean('Example', '1.0.0')
292     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
293            '--package=org.xwalk.example', self._mode]
294     out = RunCommand(cmd)
295     self.assertTrue(out.find('The package name is required!') == -1)
296     Clean('Example', '1.0.0')
297
298   def testEntry(self):
299     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
300            '--package=org.xwalk.example', '--app-url=http://www.intel.com',
301            self._mode]
302     out = RunCommand(cmd)
303     self.assertTrue(out.find('The entry is required.') == -1)
304     self.checkApks('Example', '1.0.0')
305     Clean('Example', '1.0.0')
306
307     test_entry_root = 'test_data/entry'
308     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
309            '--package=org.xwalk.example', '--app-root=%s' % test_entry_root,
310            '--app-local-path=index.html', self._mode]
311     out = RunCommand(cmd)
312     self.assertTrue(out.find('The entry is required.') == -1)
313     self.checkApks('Example', '1.0.0')
314     Clean('Example', '1.0.0')
315
316   def testEntryWithErrors(self):
317     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
318            '--package=org.xwalk.example', self._mode]
319     out = RunCommand(cmd)
320     self.assertTrue(out.find('The entry is required.') != -1)
321     self.assertFalse(os.path.exists('Example.apk'))
322     Clean('Example', '1.0.0')
323
324     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
325            '--package=org.xwalk.example', '--app-url=http://www.intel.com',
326            '--app-root=.', self._mode]
327     out = RunCommand(cmd)
328     self.assertTrue(out.find('The entry is required.') != -1)
329     self.assertFalse(os.path.exists('Example.apk'))
330     Clean('Example', '1.0.0')
331
332     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
333            '--package=org.xwalk.example', '--app-root=./', self._mode]
334     out = RunCommand(cmd)
335     self.assertTrue(out.find('The entry is required.') != -1)
336     self.assertFalse(os.path.exists('Example.apk'))
337     Clean('Example', '1.0.0')
338
339     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
340            '--package=org.xwalk.example', '--app-local-path=index.html',
341            self._mode]
342     out = RunCommand(cmd)
343     self.assertTrue(out.find('The entry is required.') != -1)
344     self.assertFalse(os.path.exists('Example.apk'))
345     Clean('Example', '1.0.0')
346
347     manifest_path = os.path.join('test_data', 'manifest',
348                                  'manifest_app_launch_local_path.json')
349     cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path, self._mode]
350     out = RunCommand(cmd)
351     self.assertTrue(out.find('Please make sure that the local path file') != -1)
352     self.assertFalse(os.path.exists('Example.apk'))
353     Clean('Example', '1.0.0')
354
355   def testIcon(self):
356     manifest_path = os.path.join('test_data', 'manifest', 'manifest_icon.json')
357     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
358            '--package=org.xwalk.example', '--app-url=http://www.intel.com',
359            '--manifest=%s' % manifest_path, self._mode]
360     RunCommand(cmd)
361     manifest = 'Example/AndroidManifest.xml'
362     with open(manifest, 'r') as content_file:
363       content = content_file.read()
364     self.assertTrue(content.find('drawable/icon') != -1)
365     self.checkApks('Example', '1.0.0')
366     Clean('Example', '1.0.0')
367
368   def testFullscreen(self):
369     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
370            '--package=org.xwalk.example', '--app-url=http://www.intel.com',
371            '-f', self._mode]
372     RunCommand(cmd)
373     theme = 'Example/res/values/theme.xml'
374     with open(theme, 'r') as content_file:
375       content = content_file.read()
376     self.assertTrue(os.path.exists(theme))
377     self.assertTrue(
378         content.find(
379             '<item name="android:windowFullscreen">true</item>') != -1)
380     self.checkApks('Example', '1.0.0')
381     Clean('Example', '1.0.0')
382
383   def testEnableRemoteDebugging(self):
384     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
385            '--package=org.xwalk.example', '--app-url=http://www.intel.com',
386            '--enable-remote-debugging', self._mode]
387     RunCommand(cmd)
388     activity = 'Example/src/org/xwalk/example/ExampleActivity.java'
389     with open(activity, 'r') as content_file:
390       content = content_file.read()
391     self.assertTrue(os.path.exists(activity))
392     self.assertTrue(content.find('setRemoteDebugging') != -1)
393     self.checkApks('Example', '1.0.0')
394     Clean('Example', '1.0.0')
395     manifest_path = os.path.join('test_data', 'manifest', 'manifest.json')
396     cmd = ['python', 'make_apk.py', '--enable-remote-debugging',
397            '--manifest=%s' % manifest_path, self._mode]
398     RunCommand(cmd)
399     activity = 'Example/src/org/xwalk/example/ExampleActivity.java'
400     with open(activity, 'r') as content_file:
401       content = content_file.read()
402     self.assertTrue(os.path.exists(activity))
403     self.assertTrue(content.find('setRemoteDebugging') != -1)
404     self.checkApks('Example', '1.0.0')
405     Clean('Example', '1.0.0')
406
407   def testKeystore(self):
408     keystore_path = os.path.join('test_data', 'keystore', 'xwalk-test.keystore')
409     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
410            '--package=org.xwalk.example', '--app-url=http://www.intel.com',
411            '--keystore-path=%s' % keystore_path, '--keystore-alias=xwalk-test',
412            '--keystore-passcode=xwalk-test', self._mode]
413     RunCommand(cmd)
414     self.assertTrue(os.path.exists('Example'))
415     apk_list = ['Example.apk', 'Example_x86.apk', 'Example_arm.apk']
416     for apk in apk_list:
417       if os.path.isfile(apk):
418         cmd = ['jarsigner', '-verify', '-keystore',
419                keystore_path, '-verbose', apk]
420         out = RunCommand(cmd)
421         self.assertTrue(out.find('smk') != -1)
422     self.checkApks('Example', '1.0.0')
423     Clean('Example', '1.0.0')
424
425   def testManifest(self):
426     manifest_path = os.path.join('test_data', 'manifest', 'manifest.json')
427     cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path, self._mode]
428     RunCommand(cmd)
429     manifest = 'Example/AndroidManifest.xml'
430     with open(manifest, 'r') as content_file:
431       content = content_file.read()
432     self.assertTrue(os.path.exists(manifest))
433     self.assertTrue(content.find('android.permission.READ_CONTACTS') != -1)
434     self.assertTrue(content.find('android.permission.WRITE_CONTACTS') != -1)
435     self.assertTrue(
436         content.find('android.permission.ACCESS_FINE_LOCATION') != -1)
437     self.assertTrue(content.find('android.permission.READ_SMS') != -1)
438     self.assertTrue(content.find('android.permission.RECEIVE_SMS') != -1)
439     self.assertTrue(content.find('android.permission.SEND_SMS') != -1)
440     self.assertTrue(content.find('android.permission.WRITE_SMS') != -1)
441     theme = 'Example/res/values/theme.xml'
442     with open(theme, 'r') as content_file:
443       content = content_file.read()
444     self.assertTrue(os.path.exists(theme))
445     self.assertTrue(
446         content.find(
447             '<item name="android:windowFullscreen">true</item>') != -1)
448     self.assertTrue(os.path.exists('Example'))
449     self.checkApks('Example', '1.0.0')
450     Clean('Example', '1.0.0')
451
452   def testManifestWithSpecificValue(self):
453     manifest_path = os.path.join('test_data', 'manifest',
454                                  'manifest_app_launch_local_path.json')
455     cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path, self._mode]
456     out = RunCommand(cmd)
457     self.assertTrue(out.find('no app launch path') == -1)
458     self.checkApks('Example', '1.0.0')
459     Clean('Example', '1.0.0')
460
461   def testManifestWithError(self):
462     manifest_path = os.path.join('test_data', 'manifest',
463                                  'manifest_no_app_launch_path.json')
464     cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path,
465            '--verbose', self._mode]
466     out = RunCommand(cmd)
467     self.assertTrue(out.find('no app launch path') != -1)
468     manifest_path = os.path.join('test_data', 'manifest',
469                                  'manifest_no_name.json')
470     cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path,
471            '--verbose', self._mode]
472     out = RunCommand(cmd)
473     self.assertTrue(out.find('no \'name\' field') != -1)
474     manifest_path = os.path.join('test_data', 'manifest',
475                                  'manifest_no_version.json')
476     cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path,
477            '--verbose', self._mode]
478     out = RunCommand(cmd)
479     self.assertTrue(out.find('no \'version\' field') != -1)
480     manifest_path = os.path.join('test_data', 'manifest',
481                                  'manifest_permissions_format_error.json')
482     cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path,
483            '--verbose', self._mode]
484     out = RunCommand(cmd)
485     self.assertTrue(out.find('\'Permissions\' field error') != -1)
486     manifest_path = os.path.join('test_data', 'manifest',
487                                  'manifest_permissions_field_error.json')
488     cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path,
489            '--verbose', self._mode]
490     out = RunCommand(cmd)
491     self.assertTrue(out.find('\'Permissions\' field error') != -1)
492     manifest_path = os.path.join('test_data', 'manifest',
493                                  'manifest_not_supported_permission.json')
494     cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path,
495            '--verbose', self._mode]
496     out = RunCommand(cmd)
497     self.assertTrue(
498         out.find('\'Telephony\' related API is not supported') != -1)
499
500   def testExtensionsWithOneExtension(self):
501     # Test with an existed extension.
502     extension_path = 'test_data/extensions/myextension'
503     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
504            '--package=org.xwalk.example', '--app-url=http://www.intel.com',
505            '--extensions=%s' % extension_path, self._mode]
506     RunCommand(cmd)
507     self.assertTrue(os.path.exists('Example'))
508     extensions_config_json = 'Example/assets/extensions-config.json'
509     self.assertTrue(os.path.exists(extensions_config_json))
510     with open(extensions_config_json, 'r') as content_file:
511       content = content_file.read()
512     self.assertTrue(content.find('xwalk-extensions/myextension/myextension.js'))
513     self.assertTrue(content.find('com.example.extension.MyExtension'))
514     extension_js = 'Example/assets/xwalk-extensions/myextension/myextension.js'
515     self.assertTrue(os.path.exists(extension_js))
516     extension_jar = 'Example/xwalk-extensions/myextension/myextension.jar'
517     self.assertTrue(os.path.exists(extension_jar))
518     self.checkApks('Example', '1.0.0')
519     Clean('Example', '1.0.0')
520
521   def testExtensionsWithNonExtension(self):
522     # Test with a non-existed extension.
523     extension_path = 'test_data/extensions/myextension'
524     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
525            '--package=org.xwalk.example', '--app-url=http://www.intel.com',
526            '--extensions=%s1' % extension_path, self._mode, '--verbose']
527     out = RunCommand(cmd)
528     error_msg = 'Error: can\'t find the extension directory'
529     self.assertTrue(out.find(error_msg) != -1)
530     self.assertTrue(out.find('Exiting with error code: 9') != -1)
531
532   def testExtensionWithPermissions(self):
533     test_entry_root = 'test_data/entry'
534     # Add redundant separators for test.
535     extension_path = 'test_data//extensions/contactextension/'
536     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
537            '--package=org.xwalk.example', '--app-root=%s' % test_entry_root,
538            '--app-local-path=contactextension.html',
539            '--extensions=%s' % extension_path, self._mode]
540     RunCommand(cmd)
541     self.assertTrue(os.path.exists('Example'))
542     manifest = 'Example/AndroidManifest.xml'
543     with open(manifest, 'r') as content_file:
544       content = content_file.read()
545     self.assertTrue(os.path.exists(manifest))
546     self.assertTrue(content.find('android.permission.WRITE_CONTACTS') != -1)
547     self.assertTrue(content.find('android.permission.READ_CONTACTS') != -1)
548     self.checkApks('Example', '1.0.0')
549     Clean('Example', '1.0.0')
550
551   def testXPK(self):
552     xpk_file = os.path.join('test_data', 'xpk', 'example.xpk')
553     cmd = ['python', 'make_apk.py', '--xpk=%s' % xpk_file, self._mode]
554     RunCommand(cmd)
555     self.assertTrue(os.path.exists('Example'))
556     self.checkApks('Example', '1.0.0')
557     Clean('Example', '1.0.0')
558
559   def testXPKWithError(self):
560     xpk_file = os.path.join('test_data', 'xpk', 'error.xpk')
561     cmd = ['python', 'make_apk.py', '--xpk=%s' % xpk_file, self._mode]
562     out = RunCommand(cmd)
563     error_msg = 'XPK doesn\'t contain manifest file'
564     self.assertTrue(out.find(error_msg) != -1)
565     self.assertFalse(os.path.exists('Example'))
566
567   def testOrientation(self):
568     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
569            '--package=org.xwalk.example', '--app-url=http://www.intel.com',
570            '--orientation=landscape', self._mode]
571     RunCommand(cmd)
572     manifest = 'Example/AndroidManifest.xml'
573     with open(manifest, 'r') as content_file:
574       content = content_file.read()
575     self.assertTrue(os.path.exists(manifest))
576     self.assertTrue(content.find('landscape') != -1)
577     self.assertTrue(os.path.exists('Example'))
578     self.checkApks('Example', '1.0.0')
579     Clean('Example', '1.0.0')
580
581   def testArch(self):
582     # Arch option only works for embedded mode,
583     # so only test it for embedded mode.
584     if self._mode.find('embedded') != -1:
585       cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
586              '--package=org.xwalk.example', '--app-url=http://www.intel.com',
587              '--arch=x86', self._mode]
588       RunCommand(cmd)
589       if 'x86' in self.archs():
590         self.assertTrue(os.path.isfile('Example_1.0.0_x86.apk'))
591         self.checkApk('Example_1.0.0_x86.apk', 'x86')
592       else:
593         self.assertFalse(os.path.isfile('Example_1.0.0_x86.apk'))
594       self.assertFalse(os.path.isfile('Example_1.0.0_arm.apk'))
595       Clean('Example', '1.0.0')
596       cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
597              '--package=org.xwalk.example', '--app-url=http://www.intel.com',
598              '--arch=arm', self._mode]
599       RunCommand(cmd)
600       if 'arm' in self.archs():
601         self.assertTrue(os.path.isfile('Example_1.0.0_arm.apk'))
602         self.checkApk('Example_1.0.0_arm.apk', 'arm')
603       else:
604         self.assertFalse(os.path.isfile('Example_1.0.0._arm.apk'))
605       self.assertFalse(os.path.isfile('Example_1.0.0_x86.apk'))
606       Clean('Example', '1.0.0')
607
608   def testVerbose(self):
609     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
610            '--package=org.xwalk.example', '--app-url=http://www.intel.com',
611            '--verbose', self._mode]
612     result = RunCommand(cmd)
613     self.assertTrue(result.find('aapt') != -1)
614     self.assertTrue(result.find('crunch') != -1)
615     self.assertTrue(result.find('apkbuilder') != -1)
616     self.assertTrue(os.path.exists('Example'))
617     self.checkApks('Example', '1.0.0')
618     Clean('Example', '1.0.0')
619
620   def executeCommandAndVerifyResult(self, exec_file):
621     # Test all of supported options with empty 'mode' option.
622     icon_path = './app_src/res/drawable-xhdpi/crosswalk.png'
623     extension_path = 'test_data/extensions/myextension'
624     arch = ''
625     icon = ''
626     if exec_file.find("make_apk.py") != -1:
627       arch = '--arch=x86'
628       icon = '--icon=%s' % icon_path
629     cmd = ['python', '%s' % exec_file,
630            '--app-version=1.0.0',
631            '--app-url=http://www.intel.com',
632            '%s' % arch,
633            '--description=a sample application',
634            '--enable-remote-debugging',
635            '--extensions=%s' % extension_path,
636            '--fullscreen',
637            '%s' % icon,
638            '--name=Example',
639            '--orientation=landscape',
640            '--package=org.xwalk.example',
641            '--permissions=geolocation']
642     RunCommand(cmd)
643     activity = 'Example/src/org/xwalk/example/ExampleActivity.java'
644     with open(activity, 'r') as content_file:
645       content = content_file.read()
646     self.assertTrue(os.path.exists(activity))
647     # Test remote debugging option.
648     self.assertTrue(content.find('setRemoteDebugging') != -1)
649
650     manifest = 'Example/AndroidManifest.xml'
651     with open(manifest, 'r') as content_file:
652       content = content_file.read()
653     self.assertTrue(os.path.exists(manifest))
654     # Test permission option.
655     self.assertTrue(content.find('ACCESS_FINE_LOCATION') != -1)
656     # Test description option.
657     self.assertTrue(content.find('description') != -1)
658     # Test app version option.
659     self.assertTrue(content.find('versionName') != -1)
660     # Test orientation option.
661     self.assertTrue(content.find('landscape') != -1)
662     # Test fullscreen option
663     theme = 'Example/res/values/theme.xml'
664     with open(theme, 'r') as content_file:
665       content = content_file.read()
666     self.assertTrue(os.path.exists(theme))
667     self.assertTrue(
668         content.find(
669             '<item name="android:windowFullscreen">true</item>') != -1)
670     # Test extensions option.
671     extensions_config_json = 'Example/assets/extensions-config.json'
672     self.assertTrue(os.path.exists(extensions_config_json))
673     with open(extensions_config_json, 'r') as content_file:
674       content = content_file.read()
675       js_file_name = 'xwalk-extensions/myextension/myextension.js'
676       self.assertTrue(content.find(js_file_name))
677       self.assertTrue(content.find('com.example.extension.MyExtension'))
678     extension_js = 'Example/assets/xwalk-extensions/myextension/myextension.js'
679     self.assertTrue(os.path.exists(extension_js))
680     extension_jar = 'Example/xwalk-extensions/myextension/myextension.jar'
681     self.assertTrue(os.path.exists(extension_jar))
682     # Test arch option.
683     if 'x86' in self.archs():
684       self.assertTrue(os.path.isfile('Example_1.0.0_x86.apk'))
685       self.checkApk('Example_1.0.0_x86.apk', 'x86')
686     else:
687       self.assertFalse(os.path.isfile('Example_1.0.0_x86.apk'))
688     self.assertFalse(os.path.isfile('Example_1.0.0_arm.apk'))
689     Clean('Example', '1.0.0')
690
691   def testEmptyMode(self):
692     self.executeCommandAndVerifyResult('make_apk.py')
693
694   def testCustomizeFile(self):
695     cmd = ['python', 'make_apk.py',
696            '--app-url=http://www.intel.com',
697            '--app-version=1.0.0',
698            '--name=Example',
699            '--package=org.xwalk.example',
700            '--verbose']
701     RunCommand(cmd)
702     manifest = 'Example/AndroidManifest.xml'
703     if not os.path.exists(manifest):
704       print 'The \'%s\' was not generated, please check it.' % manifest
705       sys.exit(1)
706
707     self.executeCommandAndVerifyResult('customize.py')
708
709
710   def testTargetDir(self):
711     test_option = ['./', '../', '~/']
712     for option in test_option:
713       cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
714              '--package=org.xwalk.example', '--app-url=http://www.intel.com',
715              '--target-dir=%s' % option, self._mode]
716       RunCommand(cmd)
717       if self._mode.find('shared') != -1:
718         apk_path = os.path.expanduser('%sExample_1.0.0.apk' % option)
719         self.assertTrue(os.path.exists(apk_path))
720         self.checkApk(apk_path, '')
721       elif self._mode.find('embedded') != -1:
722         for arch in self.archs():
723           apk_path = os.path.expanduser('%sExample_1.0.0_%s.apk'
724                                         % (option, arch))
725           self.assertTrue(os.path.exists(apk_path))
726           self.checkApk(apk_path, arch)
727       Clean(os.path.expanduser('%sExample' % option), '1.0.0')
728
729
730 def SuiteWithModeOption():
731   # Gather all the tests for the specified mode option.
732   test_suite = unittest.TestSuite()
733   test_suite.addTest(TestMakeApk('testAppBigVersionCodeBase'))
734   test_suite.addTest(TestMakeApk('testAppVersionCode'))
735   test_suite.addTest(TestMakeApk('testAppVersionCodeBase'))
736   test_suite.addTest(TestMakeApk('testAppDescriptionAndVersion'))
737   test_suite.addTest(TestMakeApk('testArch'))
738   test_suite.addTest(TestMakeApk('testEnableRemoteDebugging'))
739   test_suite.addTest(TestMakeApk('testEntry'))
740   test_suite.addTest(TestMakeApk('testEntryWithErrors'))
741   test_suite.addTest(TestMakeApk('testExtensionsWithOneExtension'))
742   test_suite.addTest(TestMakeApk('testExtensionsWithNonExtension'))
743   test_suite.addTest(TestMakeApk('testExtensionWithPermissions'))
744   test_suite.addTest(TestMakeApk('testFullscreen'))
745   test_suite.addTest(TestMakeApk('testIcon'))
746   test_suite.addTest(TestMakeApk('testKeystore'))
747   test_suite.addTest(TestMakeApk('testManifest'))
748   test_suite.addTest(TestMakeApk('testManifestWithError'))
749   test_suite.addTest(TestMakeApk('testName'))
750   test_suite.addTest(TestMakeApk('testOrientation'))
751   test_suite.addTest(TestMakeApk('testPackage'))
752   test_suite.addTest(TestMakeApk('testPermissions'))
753   test_suite.addTest(TestMakeApk('testPermissionsWithError'))
754   test_suite.addTest(TestMakeApk('testXPK'))
755   test_suite.addTest(TestMakeApk('testXPKWithError'))
756   test_suite.addTest(TestMakeApk('testTargetDir'))
757   return test_suite
758
759
760 def SuiteWithEmptyModeOption():
761   # Gather all the tests for empty mode option.
762   test_suite = unittest.TestSuite()
763   test_suite.addTest(TestMakeApk('testCustomizeFile'))
764   test_suite.addTest(TestMakeApk('testEmptyMode'))
765   test_suite.addTest(TestMakeApk('testToolVersion'))
766   test_suite.addTest(TestMakeApk('testVerbose'))
767   return test_suite
768
769
770 def TestSuiteRun(test_runner, suite):
771   results = test_runner.run(suite)
772   return results.wasSuccessful()
773
774
775 if __name__ == '__main__':
776   parser = optparse.OptionParser()
777   info = ('The build directory for xwalk.'
778           'Such as: --build-dir=src/out')
779   parser.add_option('--build-dir', help=info)
780   info = ('The build target for xwalk.'
781           'Such as: --target=Release')
782   parser.add_option('--target', help=info)
783   info = ('The path of package tool.')
784   parser.add_option('--tool-path', help=info)
785   info = ('The packaging mode for xwalk. Such as: --mode=embedded.'
786           'Please refer the detail to the option of make_apk.py.')
787   parser.add_option('--mode', help=info)
788   options, dummy = parser.parse_args()
789   if len(sys.argv) == 1:
790     parser.print_help()
791     sys.exit(1)
792
793   del sys.argv[1:]
794   mode_suite = SuiteWithModeOption()
795   empty_mode_suite = SuiteWithEmptyModeOption()
796   runner = unittest.TextTestRunner(verbosity=2)
797   if options.build_dir or options.target:
798     warnings.warn(('"--build-dir" and "--target" will be deprecated soon, '
799                    'please leverage "--tool-path" instead.'),
800                   Warning)
801   test_result = True
802   if options.mode:
803     test_result = TestSuiteRun(runner, mode_suite)
804   else:
805     # Run tests in both embedded and shared mode
806     # when the mode option isn't specified.
807     options.mode = 'embedded'
808     print 'Run tests in embedded mode.'
809     test_result = TestSuiteRun(runner, mode_suite)
810     options.mode = 'shared'
811     print 'Run tests in shared mode.'
812     test_result = TestSuiteRun(runner, mode_suite) and test_result
813     print 'Run test without \'--mode\' option.'
814     test_result = TestSuiteRun(runner, empty_mode_suite) and test_result
815   if not test_result:
816     sys.exit(1)