Upstream version 8.36.156.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 from customize import ReplaceSpaceWithUnderscore
16
17
18 def Clean(name, app_version):
19   if os.path.exists(name):
20     shutil.rmtree(name)
21   if options.mode == 'shared':
22     if os.path.isfile(name + '_' + app_version + '.apk'):
23       os.remove(name + '_' + app_version + '.apk')
24   else:
25     if os.path.isfile(name + '_' + app_version + '_x86.apk'):
26       os.remove(name + '_' + app_version + '_x86.apk')
27     if os.path.isfile(name + '_' + app_version + '_arm.apk'):
28       os.remove(name + '_' + app_version + '_arm.apk')
29
30
31 def CompareSizeForCompressor(mode, original, ext, name, fun):
32   size = 0
33   compressed_size = 0
34   mode_list = ['all', 'js', 'css']
35
36   www_dir = os.path.join(name, 'assets', 'www')
37   if os.path.exists(www_dir):
38     size = GetFileSize(original)
39     compressed_file = os.path.join(www_dir, ext, 'test.' + ext)
40     compressed_size = GetFileSize(compressed_file)
41
42     if mode in mode_list:
43       fun(compressed_size < size)
44     else:
45       fun(size == compressed_size)
46   else:
47     print('Error: %s is not exist.' % www_dir)
48
49
50 def GetFileSize(file_path):
51   size = 0
52   if os.path.exists(file_path):
53     size = os.path.getsize(file_path)
54   return size
55
56
57 def RunCommand(command):
58   """Runs the command list, return the output."""
59   proc = subprocess.Popen(command, stdout=subprocess.PIPE,
60                           stderr=subprocess.STDOUT, shell=False)
61   return proc.communicate()[0]
62
63
64 def GetResultWithOption(mode=None, manifest=None, name=None, package=None):
65   app_url = None
66   if manifest is not None:
67     manifest = '--manifest=' + manifest
68   else:
69     app_url = '--app-url=http://www.intel.com'
70   if name is not None:
71     name = '--name=' + name
72   if package is not None:
73     package = '--package=' + package
74
75   cmd = ['python', 'make_apk.py',
76          '--app-version=1.0.0',
77          '%s' % manifest,
78          '%s' % name,
79          '%s' % package,
80          '%s' % app_url,
81          '%s' % mode]
82   return RunCommand(cmd)
83
84
85 class TestMakeApk(unittest.TestCase):
86   @classmethod
87   def setUpClass(cls):
88     cls._original_dir = os.getcwd()
89     if options.tool_path:
90       target_dir = os.path.expanduser(options.tool_path)
91     elif options.build_dir and options.target:
92       target_dir = os.path.join(options.build_dir,
93                                 options.target,
94                                 'xwalk_app_template')
95     if os.path.exists(target_dir):
96       # Prepare the test data.
97       test_src_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)),
98                                   'test_data')
99       test_des_dir = os.path.join(target_dir, 'test_data')
100       if not os.path.exists(test_des_dir):
101         shutil.copytree(test_src_dir, test_des_dir)
102       os.chdir(target_dir)
103     else:
104       unittest.SkipTest('xwalk_app_template folder doesn\'t exist. '
105                         'Skipping all tests in make_apk_test.py')
106     cls._mode = ''
107     if options.mode == 'shared':
108       cls._mode = '--mode=shared'
109     elif options.mode == 'embedded':
110       cls._mode = '--mode=embedded'
111     cls.fakeNativeLibrary()
112
113   @classmethod
114   def tearDownClass(cls):
115     # Clean the test data.
116     if options.tool_path:
117       test_data_dir = os.path.join(os.path.expanduser(options.tool_path),
118                                    'test_data')
119     elif options.build_dir and options.target:
120       test_data_dir = os.path.join(options.build_dir,
121                                    options.target,
122                                    'xwalk_app_template',
123                                    'test_data')
124     if os.path.exists(test_data_dir):
125       shutil.rmtree(test_data_dir)
126     cls.restoreNativeLibrary()
127     os.chdir(cls._original_dir)
128
129   @staticmethod
130   def fakeNativeLibrary():
131     # To reduce the time consumption of make_apk test for embedded mode,
132     # replace the original native library with an empty library.
133     # Because it doesn't affect the result of test.
134     if options.mode == 'embedded':
135       native_library_dir = 'native_libs'
136       native_library_temp_dir = 'temp'
137       shutil.copytree(native_library_dir, native_library_temp_dir)
138       for root, _, files in os.walk(native_library_dir):
139         if 'libxwalkcore.so' in files:
140           native_library_path = os.path.join(root, 'libxwalkcore.so')
141           # Remove the original library
142           os.remove(native_library_path)
143           # Create an empty library file
144           open(native_library_path, 'a').close()
145
146   @staticmethod
147   def restoreNativeLibrary():
148     # Restore the original native library for embedded mode.
149     if options.mode == 'embedded':
150       native_library_dir = 'native_libs'
151       native_library_temp_dir = 'temp'
152       if os.path.exists(native_library_dir):
153         shutil.rmtree(native_library_dir)
154       shutil.move(native_library_temp_dir, native_library_dir)
155
156   @staticmethod
157   def archs():
158     x86_native_lib_path = os.path.join('native_libs', 'x86', 'libs',
159                                        'x86', 'libxwalkcore.so')
160     arm_native_lib_path = os.path.join('native_libs', 'armeabi-v7a', 'libs',
161                                        'armeabi-v7a', 'libxwalkcore.so')
162     arch_list = []
163     if os.path.isfile(x86_native_lib_path):
164       arch_list.append('x86')
165     if os.path.isfile(arm_native_lib_path):
166       arch_list.append('arm')
167     return arch_list
168
169   def checkApks(self, apk_name, app_version):
170     # Check whether some files are contained in the given APK.
171     if self._mode.find('shared') != -1:
172       apk_path = '%s_%s.apk' % (apk_name, app_version)
173       self.checkApk(apk_path, '')
174     elif self._mode.find('embedded') != -1:
175       x86_apk_path = '%s_%s_x86.apk' % (apk_name, app_version)
176       if os.path.exists(x86_apk_path):
177         self.checkApk(x86_apk_path, 'x86')
178       arm_apk_path = '%s_%s_arm.apk' % (apk_name, app_version)
179       if os.path.exists(arm_apk_path):
180         self.checkApk(arm_apk_path, 'arm')
181
182   def checkApk(self, apk_path, arch):
183     # Check whether some files are contained in the given apk
184     # for specified arch.
185     cmd = ['jar', 'tvf', apk_path]
186     out = RunCommand(cmd)
187     common_files = ['AndroidManifest.xml', 'classes.dex']
188     for res_file in common_files:
189       self.assertTrue(out.find(res_file) != -1)
190     if self._mode.find('embedded') != -1:
191       embedded_related_files = ['icudtl.dat',
192                                 'xwalk.pak',
193                                 'device_capabilities_api.js',
194                                 'launch_screen_api.js',
195                                 'presentation_api.js']
196       for res_file in embedded_related_files:
197         self.assertTrue(out.find(res_file) != -1)
198     if arch == 'x86':
199       self.assertTrue(out.find('x86/libxwalkcore.so') != -1)
200     elif arch == 'arm':
201       self.assertTrue(out.find('armeabi-v7a/libxwalkcore.so') != -1)
202
203   def testName(self):
204     cmd = ['python', 'make_apk.py', '--app-version=1.0.0',
205            '--package=org.xwalk.example', self._mode]
206     out = RunCommand(cmd)
207     Clean('Example', '1.0.0')
208     self.assertTrue(out.find('The APK name is required!') != -1)
209
210     cmd = ['python', 'make_apk.py', '--name=Test_Example',
211            '--app-version=1.0.0', '--app-url=http://www.intel.com',
212            '--package=org.xwalk.example', self._mode]
213     out = RunCommand(cmd)
214     self.assertTrue(out.find('The APK name is required!') == -1)
215     Clean('Test_Example', '1.0.0')
216
217     invalid_chars = '\/:.*?"<>|-'
218     for c in invalid_chars:
219       invalid_name = '--name=Example' + c
220       cmd = ['python', 'make_apk.py', invalid_name,
221              '--app-version=1.0.0', '--package=org.xwalk.example',
222              '--app-url=http://www.intel.com', self._mode]
223       out = RunCommand(cmd)
224       self.assertTrue(out.find('invalid characters') != -1)
225
226   def testToolVersion(self):
227     cmd = ['python', 'make_apk.py', '--version']
228     out = RunCommand(cmd)
229     self.assertTrue(out.find('Crosswalk app packaging tool version') != -1)
230
231   def testAppDescriptionAndVersion(self):
232     cmd = ['python', 'make_apk.py', '--name=Example',
233            '--package=org.xwalk.example', '--app-version=1.0.0',
234            '--description=a sample application',
235            '--app-url=http://www.intel.com', self._mode]
236     RunCommand(cmd)
237     self.addCleanup(Clean, 'Example', '1.0.0')
238     manifest = 'Example/AndroidManifest.xml'
239     with open(manifest, 'r') as content_file:
240       content = content_file.read()
241     self.assertTrue(os.path.exists(manifest))
242     self.assertTrue(content.find('description') != -1)
243     self.assertTrue(content.find('versionName') != -1)
244     self.checkApks('Example', '1.0.0')
245
246   def testAppVersionCode(self):
247     cmd = ['python', 'make_apk.py', '--name=Example',
248            '--package=org.xwalk.example', '--app-version=1.0.0',
249            '--description=a sample application',
250            '--app-versionCode=3',
251            '--app-url=http://www.intel.com', self._mode]
252     RunCommand(cmd)
253     self.addCleanup(Clean, 'Example', '1.0.0')
254     manifest = 'Example/AndroidManifest.xml'
255     with open(manifest, 'r') as content_file:
256       content = content_file.read()
257     self.assertTrue(os.path.exists(manifest))
258     self.assertTrue(content.find('versionCode="3"') != -1)
259     self.checkApks('Example', '1.0.0')
260
261   def testAppVersionCodeBase(self):
262     # Arch option only works for embedded mode,
263     # so only test it for embedded mode.
264     if self._mode.find('embedded') == -1:
265       return
266     if 'x86' in self.archs():
267       arch = '--arch=x86'
268       versionCode = 'versionCode="60000003"'
269     else:
270       arch = '--arch=arm'
271       versionCode = 'versionCode="20000003"'
272     cmd = ['python', 'make_apk.py', '--name=Example',
273            '--package=org.xwalk.example', '--app-version=1.0.0',
274            '--description=a sample application',
275            '--app-versionCodeBase=3',
276            arch,
277            '--app-url=http://www.intel.com', self._mode]
278     RunCommand(cmd)
279     self.addCleanup(Clean, 'Example', '1.0.0')
280     manifest = 'Example/AndroidManifest.xml'
281     with open(manifest, 'r') as content_file:
282       content = content_file.read()
283     self.assertTrue(os.path.exists(manifest))
284     self.assertTrue(content.find(versionCode) != -1)
285     self.checkApks('Example', '1.0.0')
286
287   def testAppBigVersionCodeBase(self):
288     # Arch option only works for embedded mode,
289     # so only test it for embedded mode.
290     if self._mode.find('embedded') == -1:
291       return
292     if 'x86' in self.archs():
293       arch = '--arch=x86'
294     else:
295       arch = '--arch=arm'
296     cmd = ['python', 'make_apk.py', '--name=Example',
297            '--package=org.xwalk.example', '--app-version=1.0.0',
298            '--description=a sample application',
299            '--app-versionCodeBase=30000000',
300            arch,
301            '--app-url=http://www.intel.com', self._mode]
302     RunCommand(cmd)
303     self.addCleanup(Clean, 'Example', '1.0.0')
304     manifest = 'Example/AndroidManifest.xml'
305     self.assertFalse(os.path.exists(manifest))
306
307   def testPermissions(self):
308     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
309            '--package=org.xwalk.example', '--permissions=geolocation',
310            '--app-url=http://www.intel.com', self._mode]
311     RunCommand(cmd)
312     self.addCleanup(Clean, 'Example', '1.0.0')
313     manifest = 'Example/AndroidManifest.xml'
314     with open(manifest, 'r') as content_file:
315       content = content_file.read()
316     self.assertTrue(os.path.exists(manifest))
317     self.assertTrue(content.find('ACCESS_FINE_LOCATION') != -1)
318     self.checkApks('Example', '1.0.0')
319
320   def testPermissionsWithError(self):
321     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
322            '--package=org.xwalk.example', '--permissions=UndefinedPermission',
323            '--app-url=http://www.intel.com', self._mode]
324     out = RunCommand(cmd)
325     self.assertTrue(out.find('related API is not supported.') != -1)
326     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
327            '--package=org.xwalk.example',
328            '--permissions=Contacts.Geolocation.Messaging',
329            '--app-url=http://www.intel.com', self._mode]
330     out = RunCommand(cmd)
331     self.assertTrue(out.find('related API is not supported.') != -1)
332
333   def testPackage(self):
334     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
335            self._mode]
336     out = RunCommand(cmd)
337     self.addCleanup(Clean, 'Example', '1.0.0')
338     self.assertTrue(out.find('The package name is required!') != -1)
339     Clean('Example', '1.0.0')
340     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
341            '--package=org.xwalk.example', self._mode]
342     out = RunCommand(cmd)
343     self.assertTrue(out.find('The package name is required!') == -1)
344
345   def testEntry(self):
346     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
347            '--package=org.xwalk.example', '--app-url=http://www.intel.com',
348            self._mode]
349     out = RunCommand(cmd)
350     self.addCleanup(Clean, 'Example', '1.0.0')
351     self.assertTrue(out.find('The entry is required.') == -1)
352     self.checkApks('Example', '1.0.0')
353     Clean('Example', '1.0.0')
354
355     test_entry_root = 'test_data/entry'
356     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
357            '--package=org.xwalk.example', '--app-root=%s' % test_entry_root,
358            '--app-local-path=index.html', self._mode]
359     out = RunCommand(cmd)
360     self.assertTrue(out.find('The entry is required.') == -1)
361     self.checkApks('Example', '1.0.0')
362
363   def testEntryWithErrors(self):
364     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
365            '--package=org.xwalk.example', self._mode]
366     out = RunCommand(cmd)
367     self.addCleanup(Clean, 'Example', '1.0.0')
368     self.assertTrue(out.find('The entry is required.') != -1)
369     self.assertFalse(os.path.exists('Example.apk'))
370     Clean('Example', '1.0.0')
371
372     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
373            '--package=org.xwalk.example', '--app-url=http://www.intel.com',
374            '--app-root=.', self._mode]
375     out = RunCommand(cmd)
376     self.assertTrue(out.find('The entry is required.') != -1)
377     self.assertFalse(os.path.exists('Example.apk'))
378     Clean('Example', '1.0.0')
379
380     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
381            '--package=org.xwalk.example', '--app-root=./', self._mode]
382     out = RunCommand(cmd)
383     self.assertTrue(out.find('The entry is required.') != -1)
384     self.assertFalse(os.path.exists('Example.apk'))
385     Clean('Example', '1.0.0')
386
387     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
388            '--package=org.xwalk.example', '--app-local-path=index.html',
389            self._mode]
390     out = RunCommand(cmd)
391     self.assertTrue(out.find('The entry is required.') != -1)
392     self.assertFalse(os.path.exists('Example.apk'))
393     Clean('Example', '1.0.0')
394
395     manifest_path = os.path.join('test_data', 'manifest',
396                                  'manifest_app_launch_local_path.json')
397     cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path,
398            self._mode]
399     out = RunCommand(cmd)
400     self.assertTrue(
401         out.find('Please make sure that the local path file') != -1)
402     self.assertFalse(os.path.exists('Example.apk'))
403
404   def testIconByOption(self):
405     icon = os.path.join('test_data', 'manifest', 'icons', 'icon_96.png')
406     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
407            '--package=org.xwalk.example', '--app-url=http://www.intel.com',
408            '--icon=%s' % icon, self._mode]
409     RunCommand(cmd)
410     self.addCleanup(Clean, 'Example', '1.0.0')
411     manifest = 'Example/AndroidManifest.xml'
412     with open(manifest, 'r') as content_file:
413       content = content_file.read()
414     self.assertTrue(content.find('drawable/icon_96') != -1)
415     self.checkApks('Example', '1.0.0')
416
417   def testIconByManifest(self):
418     manifest_path = os.path.join('test_data', 'manifest', 'manifest_icon.json')
419     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
420            '--package=org.xwalk.example', '--app-url=http://www.intel.com',
421            '--manifest=%s' % manifest_path, self._mode]
422     RunCommand(cmd)
423     self.addCleanup(Clean, 'Example', '1.0.0')
424     manifest = 'Example/AndroidManifest.xml'
425     with open(manifest, 'r') as content_file:
426       content = content_file.read()
427     self.assertTrue(content.find('drawable/icon') != -1)
428     self.checkApks('Example', '1.0.0')
429
430   def testFullscreen(self):
431     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
432            '--package=org.xwalk.example', '--app-url=http://www.intel.com',
433            '-f', self._mode]
434     RunCommand(cmd)
435     self.addCleanup(Clean, 'Example', '1.0.0')
436     theme = 'Example/res/values/theme.xml'
437     with open(theme, 'r') as content_file:
438       content = content_file.read()
439     self.assertTrue(os.path.exists(theme))
440     self.assertTrue(
441         content.find(
442             '<item name="android:windowFullscreen">true</item>') != -1)
443     self.checkApks('Example', '1.0.0')
444
445   def testEnableRemoteDebugging(self):
446     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
447            '--package=org.xwalk.example', '--app-url=http://www.intel.com',
448            '--enable-remote-debugging', self._mode]
449     RunCommand(cmd)
450     self.addCleanup(Clean, 'Example', '1.0.0')
451     activity = 'Example/src/org/xwalk/example/ExampleActivity.java'
452     with open(activity, 'r') as content_file:
453       content = content_file.read()
454     self.assertTrue(os.path.exists(activity))
455     self.assertTrue(content.find('setRemoteDebugging') != -1)
456     self.checkApks('Example', '1.0.0')
457     Clean('Example', '1.0.0')
458     manifest_path = os.path.join('test_data', 'manifest', 'manifest.json')
459     cmd = ['python', 'make_apk.py', '--enable-remote-debugging',
460            '--manifest=%s' % manifest_path, self._mode]
461     RunCommand(cmd)
462     activity = 'Example/src/org/xwalk/example/ExampleActivity.java'
463     with open(activity, 'r') as content_file:
464       content = content_file.read()
465     self.assertTrue(os.path.exists(activity))
466     self.assertTrue(content.find('setRemoteDebugging') != -1)
467     self.checkApks('Example', '1.0.0')
468
469   def testKeystore(self):
470     keystore_path = os.path.join('test_data', 'keystore',
471                                  'xwalk-test.keystore')
472     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
473            '--package=org.xwalk.example', '--app-url=http://www.intel.com',
474            '--keystore-path=%s' % keystore_path, '--keystore-alias=xwalk-test',
475            '--keystore-passcode=xwalk-test', self._mode]
476     RunCommand(cmd)
477     self.addCleanup(Clean, 'Example', '1.0.0')
478     self.assertTrue(os.path.exists('Example'))
479     apk_list = ['Example.apk', 'Example_x86.apk', 'Example_arm.apk']
480     for apk in apk_list:
481       if os.path.isfile(apk):
482         cmd = ['jarsigner', '-verify', '-keystore',
483                keystore_path, '-verbose', apk]
484         out = RunCommand(cmd)
485         self.assertTrue(out.find('smk') != -1)
486     self.checkApks('Example', '1.0.0')
487
488   def testManifest(self):
489     manifest_path = os.path.join('test_data', 'manifest', 'manifest.json')
490     cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path,
491            self._mode]
492     RunCommand(cmd)
493     self.addCleanup(Clean, 'Example', '1.0.0')
494     manifest = 'Example/AndroidManifest.xml'
495     with open(manifest, 'r') as content_file:
496       content = content_file.read()
497     self.assertTrue(os.path.exists(manifest))
498     self.assertTrue(content.find('android.permission.READ_CONTACTS') != -1)
499     self.assertTrue(content.find('android.permission.WRITE_CONTACTS') != -1)
500     self.assertTrue(
501         content.find('android.permission.ACCESS_FINE_LOCATION') != -1)
502     self.assertTrue(content.find('android.permission.READ_SMS') != -1)
503     self.assertTrue(content.find('android.permission.RECEIVE_SMS') != -1)
504     self.assertTrue(content.find('android.permission.SEND_SMS') != -1)
505     self.assertTrue(content.find('android.permission.WRITE_SMS') != -1)
506     theme = 'Example/res/values/theme.xml'
507     with open(theme, 'r') as content_file:
508       content = content_file.read()
509     self.assertTrue(os.path.exists(theme))
510     self.assertTrue(
511         content.find(
512             '<item name="android:windowFullscreen">true</item>') != -1)
513     self.assertTrue(os.path.exists('Example'))
514     self.checkApks('Example', '1.0.0')
515
516   def testManifestWithSpecificValue(self):
517     manifest_path = os.path.join('test_data', 'manifest',
518                                  'manifest_app_launch_local_path.json')
519     cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path,
520            self._mode]
521     out = RunCommand(cmd)
522     self.addCleanup(Clean, 'Example', '1.0.0')
523     self.assertTrue(out.find('no app launch path') == -1)
524     self.checkApks('Example', '1.0.0')
525
526   def testManifestWithError(self):
527     manifest_path = os.path.join('test_data', 'manifest',
528                                  'manifest_no_app_launch_path.json')
529     cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path,
530            '--verbose', self._mode]
531     out = RunCommand(cmd)
532     self.assertTrue(out.find('no app launch path') != -1)
533     manifest_path = os.path.join('test_data', 'manifest',
534                                  'manifest_no_name.json')
535     cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path,
536            '--verbose', self._mode]
537     out = RunCommand(cmd)
538     self.assertTrue(out.find('no \'name\' field') != -1)
539     manifest_path = os.path.join('test_data', 'manifest',
540                                  'manifest_no_version.json')
541     cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path,
542            '--verbose', self._mode]
543     out = RunCommand(cmd)
544     self.assertTrue(out.find('no \'version\' field') != -1)
545     manifest_path = os.path.join('test_data', 'manifest',
546                                  'manifest_permissions_format_error.json')
547     cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path,
548            '--verbose', self._mode]
549     out = RunCommand(cmd)
550     self.assertTrue(out.find('\'Permissions\' field error') != -1)
551     manifest_path = os.path.join('test_data', 'manifest',
552                                  'manifest_permissions_field_error.json')
553     cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path,
554            '--verbose', self._mode]
555     out = RunCommand(cmd)
556     self.assertTrue(out.find('\'Permissions\' field error') != -1)
557     manifest_path = os.path.join('test_data', 'manifest',
558                                  'manifest_not_supported_permission.json')
559     cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path,
560            '--verbose', self._mode]
561     out = RunCommand(cmd)
562     self.assertTrue(
563         out.find('\'Telephony\' related API is not supported') != -1)
564
565   def testExtensionsWithOneExtension(self):
566     # Test with an existed extension.
567     extension_path = 'test_data/extensions/myextension'
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            '--extensions=%s' % extension_path, self._mode]
571     RunCommand(cmd)
572     self.addCleanup(Clean, 'Example', '1.0.0')
573     self.assertTrue(os.path.exists('Example'))
574     extensions_config_json = 'Example/assets/extensions-config.json'
575     self.assertTrue(os.path.exists(extensions_config_json))
576     with open(extensions_config_json, 'r') as content_file:
577       content = content_file.read()
578     self.assertTrue(
579         content.find('xwalk-extensions/myextension/myextension.js'))
580     self.assertTrue(content.find('com.example.extension.MyExtension'))
581     extension_js = 'Example/assets/xwalk-extensions/myextension/myextension.js'
582     self.assertTrue(os.path.exists(extension_js))
583     extension_jar = 'Example/xwalk-extensions/myextension/myextension.jar'
584     self.assertTrue(os.path.exists(extension_jar))
585     self.checkApks('Example', '1.0.0')
586
587   def testExtensionsWithNonExtension(self):
588     # Test with a non-existed extension.
589     extension_path = 'test_data/extensions/myextension'
590     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
591            '--package=org.xwalk.example', '--app-url=http://www.intel.com',
592            '--extensions=%s1' % extension_path, self._mode, '--verbose']
593     out = RunCommand(cmd)
594     error_msg = 'Error: can\'t find the extension directory'
595     self.assertTrue(out.find(error_msg) != -1)
596     self.assertTrue(out.find('Exiting with error code: 9') != -1)
597
598   def testExtensionWithPermissions(self):
599     test_entry_root = 'test_data/entry'
600     # Add redundant separators for test.
601     extension_path = 'test_data//extensions/contactextension/'
602     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
603            '--package=org.xwalk.example', '--app-root=%s' % test_entry_root,
604            '--app-local-path=contactextension.html',
605            '--extensions=%s' % extension_path, self._mode]
606     RunCommand(cmd)
607     self.addCleanup(Clean, 'Example', '1.0.0')
608     self.assertTrue(os.path.exists('Example'))
609     manifest = 'Example/AndroidManifest.xml'
610     with open(manifest, 'r') as content_file:
611       content = content_file.read()
612     self.assertTrue(os.path.exists(manifest))
613     self.assertTrue(content.find('android.permission.WRITE_CONTACTS') != -1)
614     self.assertTrue(content.find('android.permission.READ_CONTACTS') != -1)
615     self.checkApks('Example', '1.0.0')
616
617   def testXPK(self):
618     xpk_file = os.path.join('test_data', 'xpk', 'example.xpk')
619     cmd = ['python', 'make_apk.py', '--xpk=%s' % xpk_file, self._mode]
620     RunCommand(cmd)
621     self.addCleanup(Clean, 'Example', '1.0.0')
622     self.assertTrue(os.path.exists('Example'))
623     self.checkApks('Example', '1.0.0')
624
625   def testXPKWithError(self):
626     xpk_file = os.path.join('test_data', 'xpk', 'error.xpk')
627     cmd = ['python', 'make_apk.py', '--xpk=%s' % xpk_file, self._mode]
628     out = RunCommand(cmd)
629     error_msg = 'XPK doesn\'t contain manifest file'
630     self.assertTrue(out.find(error_msg) != -1)
631     self.assertFalse(os.path.exists('Example'))
632
633   def testOrientation(self):
634     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
635            '--package=org.xwalk.example', '--app-url=http://www.intel.com',
636            '--orientation=landscape', self._mode]
637     RunCommand(cmd)
638     self.addCleanup(Clean, 'Example', '1.0.0')
639     manifest = 'Example/AndroidManifest.xml'
640     with open(manifest, 'r') as content_file:
641       content = content_file.read()
642     self.assertTrue(os.path.exists(manifest))
643     self.assertTrue(content.find('landscape') != -1)
644     self.assertTrue(os.path.exists('Example'))
645     self.checkApks('Example', '1.0.0')
646
647   def testArch(self):
648     # Arch option only works for embedded mode,
649     # so only test it for embedded mode.
650     if self._mode.find('embedded') != -1:
651       cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
652              '--package=org.xwalk.example', '--app-url=http://www.intel.com',
653              '--arch=x86', self._mode]
654       RunCommand(cmd)
655       self.addCleanup(Clean, 'Example', '1.0.0')
656       if 'x86' in self.archs():
657         self.assertTrue(os.path.isfile('Example_1.0.0_x86.apk'))
658         self.checkApk('Example_1.0.0_x86.apk', 'x86')
659       else:
660         self.assertFalse(os.path.isfile('Example_1.0.0_x86.apk'))
661       self.assertFalse(os.path.isfile('Example_1.0.0_arm.apk'))
662       Clean('Example', '1.0.0')
663       cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
664              '--package=org.xwalk.example', '--app-url=http://www.intel.com',
665              '--arch=arm', self._mode]
666       RunCommand(cmd)
667       if 'arm' in self.archs():
668         self.assertTrue(os.path.isfile('Example_1.0.0_arm.apk'))
669         self.checkApk('Example_1.0.0_arm.apk', 'arm')
670       else:
671         self.assertFalse(os.path.isfile('Example_1.0.0._arm.apk'))
672       self.assertFalse(os.path.isfile('Example_1.0.0_x86.apk'))
673       Clean('Example', '1.0.0')
674       cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
675              '--package=org.xwalk.example', '--app-url=http://www.intel.com',
676              self._mode]
677       RunCommand(cmd)
678       if 'arm' in self.archs():
679         self.assertTrue(os.path.isfile('Example_1.0.0_arm.apk'))
680         self.checkApk('Example_1.0.0_arm.apk', 'arm')
681       else:
682         self.assertFalse(os.path.isfile('Example_1.0.0._arm.apk'))
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       Clean('Example', '1.0.0')
689       cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
690              '--package=org.xwalk.example', '--app-url=http://www.intel.com',
691              '--arch=undefined', self._mode]
692       out = RunCommand(cmd)
693       error_msg = 'invalid choice: \'undefined\''
694       self.assertTrue(out.find(error_msg) != -1)
695
696   def testVerbose(self):
697     cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
698            '--package=org.xwalk.example', '--app-url=http://www.intel.com',
699            '--verbose', self._mode]
700     result = RunCommand(cmd)
701     self.addCleanup(Clean, 'Example', '1.0.0')
702     self.assertTrue(result.find('aapt') != -1)
703     self.assertTrue(result.find('crunch') != -1)
704     self.assertTrue(result.find('apkbuilder') != -1)
705     self.assertTrue(os.path.exists('Example'))
706     self.checkApks('Example', '1.0.0')
707
708   def executeCommandAndVerifyResult(self, exec_file):
709     # Test all of supported options with empty 'mode' option.
710     icon_path = './app_src/res/drawable-xhdpi/crosswalk.png'
711     extension_path = 'test_data/extensions/myextension'
712     arch = ''
713     icon = ''
714     if exec_file.find("make_apk.py") != -1:
715       arch = '--arch=x86'
716       icon = '--icon=%s' % icon_path
717     cmd = ['python', '%s' % exec_file,
718            '--app-version=1.0.0',
719            '--app-url=http://www.intel.com',
720            '%s' % arch,
721            '--description=a sample application',
722            '--enable-remote-debugging',
723            '--extensions=%s' % extension_path,
724            '--fullscreen',
725            '--keep-screen-on',
726            '%s' % icon,
727            '--name=Example',
728            '--orientation=landscape',
729            '--package=org.xwalk.example',
730            '--permissions=geolocation']
731     RunCommand(cmd)
732     self.addCleanup(Clean, 'Example', '1.0.0')
733     activity = 'Example/src/org/xwalk/example/ExampleActivity.java'
734     with open(activity, 'r') as content_file:
735       content = content_file.read()
736     self.assertTrue(os.path.exists(activity))
737     # Test remote debugging option.
738     self.assertTrue(content.find('setRemoteDebugging') != -1)
739     # Test keep screen on option
740     self.assertTrue(content.find('FLAG_KEEP_SCREEN_ON') != -1)
741
742     manifest = 'Example/AndroidManifest.xml'
743     with open(manifest, 'r') as content_file:
744       content = content_file.read()
745     self.assertTrue(os.path.exists(manifest))
746     # Test permission option.
747     self.assertTrue(content.find('ACCESS_FINE_LOCATION') != -1)
748     # Test description option.
749     self.assertTrue(content.find('description') != -1)
750     # Test app version option.
751     self.assertTrue(content.find('versionName') != -1)
752     # Test orientation option.
753     self.assertTrue(content.find('landscape') != -1)
754     # Test fullscreen option
755     theme = 'Example/res/values/theme.xml'
756     with open(theme, 'r') as content_file:
757       content = content_file.read()
758     self.assertTrue(os.path.exists(theme))
759     self.assertTrue(
760         content.find(
761             '<item name="android:windowFullscreen">true</item>') != -1)
762     # Test extensions option.
763     extensions_config_json = 'Example/assets/extensions-config.json'
764     self.assertTrue(os.path.exists(extensions_config_json))
765     with open(extensions_config_json, 'r') as content_file:
766       content = content_file.read()
767       js_file_name = 'xwalk-extensions/myextension/myextension.js'
768       self.assertTrue(content.find(js_file_name))
769       self.assertTrue(content.find('com.example.extension.MyExtension'))
770     extension_js = 'Example/assets/xwalk-extensions/myextension/myextension.js'
771     self.assertTrue(os.path.exists(extension_js))
772     extension_jar = 'Example/xwalk-extensions/myextension/myextension.jar'
773     self.assertTrue(os.path.exists(extension_jar))
774
775   def testEmptyMode(self):
776     self.executeCommandAndVerifyResult('make_apk.py')
777
778   def testCustomizeFile(self):
779     cmd = ['python', 'make_apk.py',
780            '--app-url=http://www.intel.com',
781            '--app-version=1.0.0',
782            '--name=Example',
783            '--package=org.xwalk.example',
784            '--verbose']
785     RunCommand(cmd)
786     manifest = 'Example/AndroidManifest.xml'
787     if not os.path.exists(manifest):
788       print 'The \'%s\' was not generated, please check it.' % manifest
789       sys.exit(1)
790
791     self.executeCommandAndVerifyResult('customize.py')
792
793   def testLaunchScreen(self):
794     # Prepare launch screen resources.
795     launch_screen_path = os.path.join('test_data', 'launchScreen')
796     orientations = ['default', 'portrait', 'landscape']
797     dimensions = ['0_75', '1', '1_5', '2']
798     img_types = ['img', 'bg']
799     for orientation in orientations:
800       for dimension in dimensions:
801         for img_type in img_types:
802           name = orientation + '_' + img_type + '_' + dimension
803           path_tmp = os.path.join(launch_screen_path, name)
804           _file = open(path_tmp,'w+')
805           _file.write(name)
806           _file.close()
807     # Run Test.
808     manifest_path = os.path.join('test_data', 'launchScreen', 'manifest.json')
809     cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path, self._mode]
810     RunCommand(cmd)
811     # Check theme.xml.
812     theme_path = os.path.join('Example', 'res', 'values', 'theme.xml')
813     self.assertTrue(os.path.exists(theme_path))
814     with open(theme_path, 'r') as content_file:
815       content = content_file.read()
816     self.assertTrue(content.find('@drawable/launchscreen_bg') != -1)
817     # Check launchscreen_bg.xml
818     launch_screen_bg_path = os.path.join(
819         "Example", 'res', 'drawable', 'launchscreen_bg.xml')
820     self.assertTrue(os.path.exists(launch_screen_bg_path))
821     with open(launch_screen_bg_path, 'r') as content_file:
822       content = content_file.read()
823     self.assertTrue(content.find('@drawable/launchscreen_bg_img') != -1)
824     # Check resource images
825     for orientation in orientations:
826       for dimension in dimensions:
827         drawable = 'drawable'
828         if orientation == 'portrait':
829           drawable = drawable + '-port'
830         elif orientation == 'landscape':
831           drawable = drawable + '-land'
832         if dimension == '0_75':
833           drawable = drawable + '-ldpi'
834         elif dimension == '1':
835           drawable = drawable + '-mdpi'
836         elif dimension == '1_5':
837           drawable = drawable + '-hdpi'
838         elif dimension == '2':
839           drawable = drawable + '-xhdpi'
840         # Check background image
841         bg_drawable = os.path.join(
842             "Example", 'res', drawable, 'launchscreen_bg_img')
843         self.assertTrue(os.path.exists(bg_drawable))
844         with open(bg_drawable, 'r') as content_file:
845           content = content_file.read()
846         name = orientation + '_' + 'bg' + '_' + dimension
847         self.assertTrue(content == name)
848         # Check foreground image
849         fg_drawable = os.path.join(
850             "Example", 'res', drawable, 'launchscreen_img')
851         self.assertTrue(os.path.exists(fg_drawable))
852         with open(fg_drawable, 'r') as content_file:
853           content = content_file.read()
854         name = orientation + '_' + 'img' + '_' + dimension
855         self.assertTrue(content == name)
856     self.checkApks('Example', '1.0.0')
857     Clean('Example', '1.0.0')
858
859   def testTargetDir(self):
860     test_option = ['./', '../', '~/']
861     for option in test_option:
862       cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
863              '--package=org.xwalk.example', '--app-url=http://www.intel.com',
864              '--target-dir=%s' % option, self._mode]
865       RunCommand(cmd)
866       self.addCleanup(Clean, os.path.expanduser('%sExample' % option), '1.0.0')
867       if self._mode.find('shared') != -1:
868         apk_path = os.path.expanduser('%sExample_1.0.0.apk' % option)
869         self.assertTrue(os.path.exists(apk_path))
870         self.checkApk(apk_path, '')
871       elif self._mode.find('embedded') != -1:
872         for arch in self.archs():
873           apk_path = os.path.expanduser('%sExample_1.0.0_%s.apk'
874                                         % (option, arch))
875           self.assertTrue(os.path.exists(apk_path))
876           self.checkApk(apk_path, arch)
877
878   def testCompressor(self):
879     app_root = os.path.join('test_data', 'compressor')
880     css_folder = os.path.join('test_data', 'compressor', 'css')
881     css_file = os.path.join(css_folder, 'test.css')
882     js_folder = os.path.join('test_data', 'compressor', 'js')
883     js_file = os.path.join(js_folder, 'test.js')
884     fun = self.assertTrue
885     name = 'Example'
886
887     cmd = ['python', 'customize.py',
888            '--name=%s' % name,
889            '--compressor',
890            '--app-root=%s' % app_root]
891     RunCommand(cmd)
892     CompareSizeForCompressor('all', css_file, 'css', name, fun)
893     CompareSizeForCompressor('all', js_file, 'js', name, fun)
894
895     cmd = ['python', 'customize.py',
896            '--name=%s' % name,
897            '--app-root=%s' % app_root,
898            '--compressor']
899     RunCommand(cmd)
900     CompareSizeForCompressor('all', css_file, 'css', name, fun)
901     CompareSizeForCompressor('all', js_file, 'js', name, fun)
902
903     cmd = ['python', 'customize.py',
904            '--name=%s' % name,
905            '--compressor=js',
906            '--app-root=%s' % app_root]
907     RunCommand(cmd)
908     CompareSizeForCompressor('js', js_file, 'js', name, fun)
909
910     cmd = ['python', 'customize.py',
911            '--name=%s' % name,
912            '--compressor=css',
913            '--app-root=%s' % app_root]
914     RunCommand(cmd)
915     CompareSizeForCompressor('css', css_file, 'css', name, fun)
916
917     cmd = ['python', 'customize.py',
918            '--name=%s' % name,
919            '--app-root=%s' % app_root]
920     RunCommand(cmd)
921     CompareSizeForCompressor(None, css_file, 'css', name, fun)
922     CompareSizeForCompressor(None, js_file, 'js', name, fun)
923
924     cmd = ['python', 'customize.py',
925            '--name=%s' % name,
926            '--app-root=%s' % app_root,
927            '--compressor=other']
928     RunCommand(cmd)
929     CompareSizeForCompressor(None, css_file, 'css', name, fun)
930     CompareSizeForCompressor(None, js_file, 'js', name, fun)
931
932     Clean(name, '1.0.0')
933
934   def testInvalidCharacter(self):
935     version = '1.0.0'
936     start_with_letters = ' should be started with letters'
937     app_name_error = 'app name' + start_with_letters
938     package_name_error = 'package name' + start_with_letters
939     parse_error = 'parser error in manifest.json file'
940     directory = os.path.join('test_data', 'manifest', 'invalidchars')
941
942     manifest_path = os.path.join(directory, 'manifest_with_space_name.json')
943     result = GetResultWithOption(self._mode, manifest_path)
944     self.assertTrue(result.find(app_name_error) != -1)
945
946     manifest_path = os.path.join(directory, 'manifest_with_chinese_name.json')
947     result = GetResultWithOption(self._mode, manifest_path)
948     self.assertTrue(result.find(app_name_error) != -1)
949
950     manifest_path = os.path.join(directory, 'manifest_parse_error.json')
951     result = GetResultWithOption(self._mode, manifest_path)
952     self.assertTrue(result.find(parse_error) != -1)
953
954     manifest_path = os.path.join(directory, 'manifest_with_invalid_name.json')
955     result = GetResultWithOption(self._mode, manifest_path)
956     self.assertTrue(result.find(app_name_error) != -1)
957
958     manifest_path = os.path.join(directory, 'manifest_contain_space_name.json')
959     result = GetResultWithOption(self._mode, manifest_path)
960     self.assertTrue(result.find(app_name_error) == -1)
961
962     package = 'org.xwalk.example'
963     name = '_hello'
964     result = GetResultWithOption(self._mode, name=name, package=package)
965     self.assertTrue(result.find(app_name_error) != -1)
966
967     name = '123hello'
968     result = GetResultWithOption(self._mode, name=name, package=package)
969     self.assertTrue(result.find(app_name_error) != -1)
970
971     name = 'hello_'
972     result = GetResultWithOption(self._mode, name=name, package=package)
973     self.assertTrue(result.find(app_name_error) == -1)
974     Clean(name, version)
975
976     name = 'xwalk'
977     package = 'org.xwalk._example'
978     result = GetResultWithOption(self._mode, name=name, package=package)
979     self.assertTrue(result.find(package_name_error) != -1)
980
981     package = 'org.xwalk.123example'
982     result = GetResultWithOption(self._mode, name=name, package=package)
983     self.assertTrue(result.find(package_name_error) != -1)
984
985     package = 'org.xwalk.example_'
986     result = GetResultWithOption(self._mode, name=name, package=package)
987     self.assertTrue(result.find(package_name_error) == -1)
988     Clean(name, version)
989
990
991   def VerifyResultForAppNameWithSpace(self, manifest=None, name=None,
992                                       package=None):
993     version = '1.0.0'
994     GetResultWithOption(manifest=manifest, name=name, package=package)
995     if name is None:
996       name = 'app name '
997     replaced_name = ReplaceSpaceWithUnderscore(name)
998     manifest = replaced_name + '/AndroidManifest.xml'
999     with open(manifest, 'r') as content_file:
1000       content = content_file.read()
1001     self.assertTrue(os.path.exists(manifest))
1002     self.assertTrue(name in content)
1003     Clean(replaced_name, version)
1004
1005
1006   def testAppNameWithSpace(self):
1007     name = 'app name'
1008     package = 'org.xwalk.app_name'
1009
1010     self.VerifyResultForAppNameWithSpace(name=name, package=package)
1011
1012     name = 'app name '
1013     self.VerifyResultForAppNameWithSpace(name=name, package=package)
1014
1015     directory = os.path.join('test_data', 'manifest', 'invalidchars')
1016     manifest_path = os.path.join(directory, 'manifest_contain_space_name.json')
1017     self.VerifyResultForAppNameWithSpace(manifest=manifest_path)
1018
1019
1020 def SuiteWithModeOption():
1021   # Gather all the tests for the specified mode option.
1022   test_suite = unittest.TestSuite()
1023   test_suite.addTest(TestMakeApk('testAppBigVersionCodeBase'))
1024   test_suite.addTest(TestMakeApk('testAppVersionCode'))
1025   test_suite.addTest(TestMakeApk('testAppVersionCodeBase'))
1026   test_suite.addTest(TestMakeApk('testAppDescriptionAndVersion'))
1027   test_suite.addTest(TestMakeApk('testArch'))
1028   test_suite.addTest(TestMakeApk('testEnableRemoteDebugging'))
1029   test_suite.addTest(TestMakeApk('testEntry'))
1030   test_suite.addTest(TestMakeApk('testEntryWithErrors'))
1031   test_suite.addTest(TestMakeApk('testExtensionsWithOneExtension'))
1032   test_suite.addTest(TestMakeApk('testExtensionsWithNonExtension'))
1033   test_suite.addTest(TestMakeApk('testExtensionWithPermissions'))
1034   test_suite.addTest(TestMakeApk('testFullscreen'))
1035   test_suite.addTest(TestMakeApk('testIconByOption'))
1036   test_suite.addTest(TestMakeApk('testIconByManifest'))
1037   test_suite.addTest(TestMakeApk('testInvalidCharacter'))
1038   test_suite.addTest(TestMakeApk('testKeystore'))
1039   test_suite.addTest(TestMakeApk('testManifest'))
1040   test_suite.addTest(TestMakeApk('testManifestWithError'))
1041   test_suite.addTest(TestMakeApk('testName'))
1042   test_suite.addTest(TestMakeApk('testOrientation'))
1043   test_suite.addTest(TestMakeApk('testPackage'))
1044   test_suite.addTest(TestMakeApk('testPermissions'))
1045   test_suite.addTest(TestMakeApk('testPermissionsWithError'))
1046   test_suite.addTest(TestMakeApk('testXPK'))
1047   test_suite.addTest(TestMakeApk('testXPKWithError'))
1048   test_suite.addTest(TestMakeApk('testTargetDir'))
1049   test_suite.addTest(TestMakeApk('testLaunchScreen'))
1050   return test_suite
1051
1052
1053 def SuiteWithEmptyModeOption():
1054   # Gather all the tests for empty mode option.
1055   test_suite = unittest.TestSuite()
1056   test_suite.addTest(TestMakeApk('testAppNameWithSpace'))
1057   test_suite.addTest(TestMakeApk('testCompressor'))
1058   test_suite.addTest(TestMakeApk('testCustomizeFile'))
1059   test_suite.addTest(TestMakeApk('testEmptyMode'))
1060   test_suite.addTest(TestMakeApk('testToolVersion'))
1061   test_suite.addTest(TestMakeApk('testVerbose'))
1062   return test_suite
1063
1064
1065 def TestSuiteRun(test_runner, suite):
1066   results = test_runner.run(suite)
1067   return results.wasSuccessful()
1068
1069
1070 if __name__ == '__main__':
1071   parser = optparse.OptionParser()
1072   info = ('The build directory for xwalk.'
1073           'Such as: --build-dir=src/out')
1074   parser.add_option('--build-dir', help=info)
1075   info = ('The build target for xwalk.'
1076           'Such as: --target=Release')
1077   parser.add_option('--target', help=info)
1078   info = ('The path of package tool.')
1079   parser.add_option('--tool-path', help=info)
1080   info = ('The packaging mode for xwalk. Such as: --mode=embedded.'
1081           'Please refer the detail to the option of make_apk.py.')
1082   parser.add_option('--mode', help=info)
1083   options, dummy = parser.parse_args()
1084   if len(sys.argv) == 1:
1085     parser.print_help()
1086     sys.exit(1)
1087
1088   del sys.argv[1:]
1089   mode_suite = SuiteWithModeOption()
1090   empty_mode_suite = SuiteWithEmptyModeOption()
1091   runner = unittest.TextTestRunner(verbosity=2)
1092   if options.build_dir or options.target:
1093     warnings.warn(('"--build-dir" and "--target" will be deprecated soon, '
1094                    'please leverage "--tool-path" instead.'),
1095                   Warning)
1096   test_result = True
1097   if options.mode:
1098     test_result = TestSuiteRun(runner, mode_suite)
1099   else:
1100     # Run tests in both embedded and shared mode
1101     # when the mode option isn't specified.
1102     options.mode = 'embedded'
1103     print 'Run tests in embedded mode.'
1104     test_result = TestSuiteRun(runner, mode_suite)
1105     options.mode = 'shared'
1106     print 'Run tests in shared mode.'
1107     test_result = TestSuiteRun(runner, mode_suite) and test_result
1108     options.mode = ''
1109     print 'Run test without \'--mode\' option.'
1110     test_result = TestSuiteRun(runner, empty_mode_suite) and test_result
1111   if not test_result:
1112     sys.exit(1)