4 # Copyright (c) 2013, 2014 Intel Corporation. All rights reserved.
5 # Use of this source code is governed by a BSD-style license that can be
6 # found in the LICENSE file.
17 def Clean(name, app_version):
18 if os.path.exists(name):
20 if options.mode == 'shared':
21 if os.path.isfile(name + '_' + app_version + '.apk'):
22 os.remove(name + '_' + app_version + '.apk')
24 if os.path.isfile(name + '_' + app_version + '_x86.apk'):
25 os.remove(name + '_' + app_version + '_x86.apk')
26 if os.path.isfile(name + '_' + app_version + '_arm.apk'):
27 os.remove(name + '_' + app_version + '_arm.apk')
30 def CompareSizeForCompressor(mode, original, ext, name, fun):
33 mode_list = ['all', 'js', 'css']
35 www_dir = os.path.join(name, 'assets', 'www')
36 if os.path.exists(www_dir):
37 size = GetFileSize(original)
38 compressed_file = os.path.join(www_dir, ext, 'test.' + ext)
39 compressed_size = GetFileSize(compressed_file)
42 fun(compressed_size < size)
44 fun(size == compressed_size)
46 print('Error: %s is not exist.' % www_dir)
49 def GetFileSize(file_path):
51 if os.path.exists(file_path):
52 size = os.path.getsize(file_path)
56 def RunCommand(command):
57 """Runs the command list, return the output."""
58 proc = subprocess.Popen(command, stdout=subprocess.PIPE,
59 stderr=subprocess.STDOUT, shell=False)
60 return proc.communicate()[0]
63 def GetResultWithOption(mode=None, manifest=None, name=None, package=None):
65 if manifest is not None:
66 manifest = '--manifest=' + manifest
68 app_url = '--app-url=http://www.intel.com'
70 name = '--name=' + name
71 if package is not None:
72 package = '--package=' + package
74 cmd = ['python', 'make_apk.py',
75 '--app-version=1.0.0',
81 return RunCommand(cmd)
84 class TestMakeApk(unittest.TestCase):
87 cls._original_dir = os.getcwd()
89 target_dir = os.path.expanduser(options.tool_path)
90 elif options.build_dir and options.target:
91 target_dir = os.path.join(options.build_dir,
94 if os.path.exists(target_dir):
95 # Prepare the test data.
96 test_src_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)),
98 test_des_dir = os.path.join(target_dir, 'test_data')
99 if not os.path.exists(test_des_dir):
100 shutil.copytree(test_src_dir, test_des_dir)
103 unittest.SkipTest('xwalk_app_template folder doesn\'t exist. '
104 'Skipping all tests in make_apk_test.py')
106 if options.mode == 'shared':
107 cls._mode = '--mode=shared'
108 elif options.mode == 'embedded':
109 cls._mode = '--mode=embedded'
110 cls.fakeNativeLibrary()
113 def tearDownClass(cls):
114 # Clean the test data.
115 if options.tool_path:
116 test_data_dir = os.path.join(os.path.expanduser(options.tool_path),
118 elif options.build_dir and options.target:
119 test_data_dir = os.path.join(options.build_dir,
121 'xwalk_app_template',
123 if os.path.exists(test_data_dir):
124 shutil.rmtree(test_data_dir)
125 cls.restoreNativeLibrary()
126 os.chdir(cls._original_dir)
129 def fakeNativeLibrary():
130 # To reduce the time consumption of make_apk test for embedded mode,
131 # replace the original native library with an empty library.
132 # Because it doesn't affect the result of test.
133 if options.mode == 'embedded':
134 native_library_dir = os.path.join('xwalk_core_library', 'libs')
135 native_library_temp_dir = 'temp'
136 shutil.copytree(native_library_dir, native_library_temp_dir)
137 for root, _, files in os.walk(native_library_dir):
138 if 'libxwalkcore.so' in files:
139 native_library_path = os.path.join(root, 'libxwalkcore.so')
140 # Remove the original library
141 os.remove(native_library_path)
142 # Create an empty library file
143 open(native_library_path, 'a').close()
146 def restoreNativeLibrary():
147 # Restore the original native library for embedded mode.
148 if options.mode == 'embedded':
149 native_library_dir = os.path.join('xwalk_core_library', 'libs')
150 native_library_temp_dir = 'temp'
151 if os.path.isdir(native_library_dir):
152 shutil.rmtree(native_library_dir)
153 shutil.move(native_library_temp_dir, native_library_dir)
157 x86_native_lib_path = os.path.join('xwalk_core_library', 'libs',
158 'x86', 'libxwalkcore.so')
159 arm_native_lib_path = os.path.join('xwalk_core_library', 'libs',
160 'armeabi-v7a', 'libxwalkcore.so')
162 if os.path.isfile(x86_native_lib_path):
163 arch_list.append('x86')
164 if os.path.isfile(arm_native_lib_path):
165 arch_list.append('arm')
168 def checkApks(self, apk_name, app_version):
169 # Check whether some files are contained in the given APK.
170 if self._mode.find('shared') != -1:
171 apk_path = '%s_%s.apk' % (apk_name, app_version)
172 self.checkApk(apk_path, '')
173 elif self._mode.find('embedded') != -1:
174 x86_apk_path = '%s_%s_x86.apk' % (apk_name, app_version)
175 if os.path.exists(x86_apk_path):
176 self.checkApk(x86_apk_path, 'x86')
177 arm_apk_path = '%s_%s_arm.apk' % (apk_name, app_version)
178 if os.path.exists(arm_apk_path):
179 self.checkApk(arm_apk_path, 'arm')
181 def checkApk(self, apk_path, arch):
182 # Check whether some files are contained in the given apk
183 # for specified arch.
184 cmd = ['jar', 'tvf', apk_path]
185 out = RunCommand(cmd)
186 common_files = ['AndroidManifest.xml', 'classes.dex']
187 for res_file in common_files:
188 self.assertTrue(out.find(res_file) != -1)
189 if self._mode.find('embedded') != -1:
190 embedded_related_files = ['icudtl.dat',
192 'device_capabilities_api.js',
193 'launch_screen_api.js',
194 'presentation_api.js']
195 for res_file in embedded_related_files:
196 self.assertTrue(out.find(res_file) != -1)
198 self.assertTrue(out.find('x86/libxwalkcore.so') != -1)
200 self.assertTrue(out.find('armeabi-v7a/libxwalkcore.so') != -1)
203 cmd = ['python', 'make_apk.py', '--app-version=1.0.0',
204 '--app-url=http://www.intel.com',
205 '--package=org.xwalk.example', self._mode]
206 out = RunCommand(cmd)
207 Clean('Example', '1.0.0')
208 self.assertIn('An APK name is required', out)
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.assertNotIn('An APK name is required', out)
215 Clean('Example', '1.0.0')
217 def testToolVersion(self):
218 cmd = ['python', 'make_apk.py', '--version']
219 out = RunCommand(cmd)
220 self.assertTrue(out.find('Crosswalk app packaging tool version') != -1)
222 def testAppDescriptionAndVersion(self):
223 cmd = ['python', 'make_apk.py', '--name=Example',
224 '--package=org.xwalk.example', '--app-version=1.0.0',
225 '--description=a sample application',
226 '--app-url=http://www.intel.com', self._mode]
228 self.addCleanup(Clean, 'Example', '1.0.0')
229 manifest = 'Example/AndroidManifest.xml'
230 with open(manifest, 'r') as content_file:
231 content = content_file.read()
232 self.assertTrue(os.path.exists(manifest))
233 self.assertTrue(content.find('description') != -1)
234 self.assertTrue(content.find('versionName') != -1)
235 self.checkApks('Example', '1.0.0')
237 def testAppVersionCode(self):
238 cmd = ['python', 'make_apk.py', '--name=Example',
239 '--package=org.xwalk.example', '--app-version=1.0.0',
240 '--description=a sample application',
241 '--app-versionCode=3',
242 '--app-url=http://www.intel.com', self._mode]
244 self.addCleanup(Clean, 'Example', '1.0.0')
245 manifest = 'Example/AndroidManifest.xml'
246 with open(manifest, 'r') as content_file:
247 content = content_file.read()
248 self.assertTrue(os.path.exists(manifest))
249 self.assertTrue(content.find('versionCode="3"') != -1)
250 self.checkApks('Example', '1.0.0')
252 def testAppVersionCodeBase(self):
253 # Arch option only works for embedded mode,
254 # so only test it for embedded mode.
255 if self._mode.find('embedded') == -1:
257 if 'x86' in self.archs():
259 versionCode = 'versionCode="60000003"'
262 versionCode = 'versionCode="20000003"'
263 cmd = ['python', 'make_apk.py', '--name=Example',
264 '--package=org.xwalk.example', '--app-version=1.0.0',
265 '--description=a sample application',
266 '--app-versionCodeBase=3',
268 '--app-url=http://www.intel.com', self._mode]
270 self.addCleanup(Clean, 'Example', '1.0.0')
271 manifest = 'Example/AndroidManifest.xml'
272 with open(manifest, 'r') as content_file:
273 content = content_file.read()
274 self.assertTrue(os.path.exists(manifest))
275 self.assertTrue(content.find(versionCode) != -1)
276 self.checkApks('Example', '1.0.0')
278 def testAppBigVersionCodeBase(self):
279 # Arch option only works for embedded mode,
280 # so only test it for embedded mode.
281 if self._mode.find('embedded') == -1:
283 if 'x86' in self.archs():
287 cmd = ['python', 'make_apk.py', '--name=Example',
288 '--package=org.xwalk.example', '--app-version=1.0.0',
289 '--description=a sample application',
290 '--app-versionCodeBase=30000000',
292 '--app-url=http://www.intel.com', self._mode]
294 self.addCleanup(Clean, 'Example', '1.0.0')
295 manifest = 'Example/AndroidManifest.xml'
296 self.assertFalse(os.path.exists(manifest))
298 def testPermissions(self):
299 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
300 '--package=org.xwalk.example', '--permissions=geolocation',
301 '--app-url=http://www.intel.com', self._mode]
303 self.addCleanup(Clean, 'Example', '1.0.0')
304 manifest = 'Example/AndroidManifest.xml'
305 with open(manifest, 'r') as content_file:
306 content = content_file.read()
307 self.assertTrue(os.path.exists(manifest))
308 self.assertTrue(content.find('ACCESS_FINE_LOCATION') != -1)
309 self.checkApks('Example', '1.0.0')
311 def testPermissionsWithError(self):
312 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
313 '--package=org.xwalk.example', '--permissions=UndefinedPermission',
314 '--app-url=http://www.intel.com', self._mode]
315 out = RunCommand(cmd)
316 self.assertTrue(out.find('related API is not supported.') != -1)
317 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
318 '--package=org.xwalk.example',
319 '--permissions=Contacts.Geolocation.Messaging',
320 '--app-url=http://www.intel.com', self._mode]
321 out = RunCommand(cmd)
322 self.assertTrue(out.find('related API is not supported.') != -1)
324 def testPackage(self):
325 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
326 '--app-url=http://www.intel.com', self._mode]
327 out = RunCommand(cmd)
328 self.assertIn('A package name is required', out)
330 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
331 '--package=org.xwalk.example',
332 '--app-url=http://www.intel.com', self._mode]
333 out = RunCommand(cmd)
334 self.assertNotIn('A package name is required', out)
335 Clean('Example', '1.0.0')
337 def testPackageWithInvalidCharacter(self):
338 package_name_error = 'package name should be started with letters'
340 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
341 '--package=org.xwalk._example',
342 '--app-url=http://www.intel.com', self._mode]
343 out = RunCommand(cmd)
344 self.assertIn(package_name_error, out)
346 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
347 '--package=org.xwalk.123example',
348 '--app-url=http://www.intel.com', self._mode]
349 out = RunCommand(cmd)
350 self.assertIn(package_name_error, out)
352 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
353 '--package=org.xwalk.example_',
354 '--app-url=http://www.intel.com', self._mode]
355 out = RunCommand(cmd)
356 self.assertNotIn(package_name_error, out)
357 Clean('Example', '1.0.0')
360 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
361 '--package=org.xwalk.example', '--app-url=http://www.intel.com',
363 out = RunCommand(cmd)
364 self.assertNotIn('You must pass either "--app-url" or',
366 self.assertNotIn('You must specify both "--app-local-path" and',
368 self.addCleanup(Clean, 'Example', '1.0.0')
369 self.checkApks('Example', '1.0.0')
370 Clean('Example', '1.0.0')
372 test_entry_root = 'test_data/entry'
373 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
374 '--package=org.xwalk.example', '--app-root=%s' % test_entry_root,
375 '--app-local-path=index.html', self._mode]
376 out = RunCommand(cmd)
377 self.assertNotIn('You must pass either "--app-url" or',
379 self.assertNotIn('You must specify both "--app-local-path" and',
381 self.checkApks('Example', '1.0.0')
383 def testEntryWithErrors(self):
384 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
385 '--package=org.xwalk.example', self._mode]
386 out = RunCommand(cmd)
387 self.addCleanup(Clean, 'Example', '1.0.0')
388 self.assertIn('You must pass either "--app-url" or',
391 self.assertFalse(os.path.exists('Example.apk'))
392 Clean('Example', '1.0.0')
394 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
395 '--package=org.xwalk.example', '--app-url=http://www.intel.com',
396 '--app-root=.', self._mode]
397 out = RunCommand(cmd)
398 self.assertIn('You must pass either "--app-url" or',
400 self.assertFalse(os.path.exists('Example.apk'))
401 Clean('Example', '1.0.0')
403 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
404 '--package=org.xwalk.example', '--app-root=./', self._mode]
405 out = RunCommand(cmd)
406 self.assertIn('You must specify both "--app-local-path" and',
408 self.assertFalse(os.path.exists('Example.apk'))
409 Clean('Example', '1.0.0')
411 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
412 '--package=org.xwalk.example', '--app-local-path=index.html',
414 out = RunCommand(cmd)
415 self.assertIn('You must specify both "--app-local-path" and',
417 self.assertFalse(os.path.exists('Example.apk'))
418 Clean('Example', '1.0.0')
420 manifest_path = os.path.join('test_data', 'manifest',
421 'manifest_app_launch_local_path.json')
422 cmd = ['python', 'make_apk.py', '--package=org.xwalk.example',
423 '--manifest=%s' % manifest_path, self._mode]
424 out = RunCommand(cmd)
426 out.find('Please make sure that the local path file') != -1)
427 self.assertFalse(os.path.exists('Example.apk'))
429 def testIconByOption(self):
430 icon = os.path.join('test_data', 'manifest', 'icons', 'icon_96.png')
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 '--icon=%s' % icon, self._mode]
435 self.addCleanup(Clean, 'Example', '1.0.0')
436 manifest = 'Example/AndroidManifest.xml'
437 with open(manifest, 'r') as content_file:
438 content = content_file.read()
439 self.assertTrue(content.find('drawable/icon_96') != -1)
440 self.checkApks('Example', '1.0.0')
442 def testIconByManifest(self):
443 manifest_path = os.path.join('test_data', 'manifest', 'manifest_icon.json')
444 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
445 '--package=org.xwalk.example', '--app-url=http://www.intel.com',
446 '--manifest=%s' % manifest_path, self._mode]
448 self.addCleanup(Clean, 'Example', '1.0.0')
449 manifest = 'Example/AndroidManifest.xml'
450 with open(manifest, 'r') as content_file:
451 content = content_file.read()
452 self.assertTrue(content.find('drawable/icon') != -1)
453 self.checkApks('Example', '1.0.0')
455 def testFullscreen(self):
456 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
457 '--package=org.xwalk.example', '--app-url=http://www.intel.com',
460 self.addCleanup(Clean, 'Example', '1.0.0')
461 theme = 'Example/res/values-v14/theme.xml'
462 with open(theme, 'r') as content_file:
463 content = content_file.read()
464 self.assertTrue(os.path.exists(theme))
467 '<item name="android:windowFullscreen">true</item>') != -1)
468 self.checkApks('Example', '1.0.0')
470 def testEnableRemoteDebugging(self):
471 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
472 '--package=org.xwalk.example', '--app-url=http://www.intel.com',
473 '--enable-remote-debugging', self._mode]
475 self.addCleanup(Clean, 'Example', '1.0.0')
476 activity = 'Example/src/org/xwalk/example/ExampleActivity.java'
477 with open(activity, 'r') as content_file:
478 content = content_file.read()
479 self.assertTrue(os.path.exists(activity))
480 self.assertTrue(content.find('setRemoteDebugging') != -1)
481 self.checkApks('Example', '1.0.0')
482 Clean('Example', '1.0.0')
483 manifest_path = os.path.join('test_data', 'manifest', 'manifest.json')
484 cmd = ['python', 'make_apk.py', '--enable-remote-debugging',
485 '--package=org.xwalk.example',
486 '--manifest=%s' % manifest_path, self._mode]
488 activity = 'Example/src/org/xwalk/example/ExampleActivity.java'
489 with open(activity, 'r') as content_file:
490 content = content_file.read()
491 self.assertTrue(os.path.exists(activity))
492 self.assertTrue(content.find('setRemoteDebugging') != -1)
493 self.checkApks('Example', '1.0.0')
495 def testKeystore(self):
496 keystore_path = os.path.join('test_data', 'keystore',
497 'xwalk-test.keystore')
498 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
499 '--package=org.xwalk.example', '--app-url=http://www.intel.com',
500 '--keystore-path=%s' % keystore_path, '--keystore-alias=xwalk-test',
501 '--keystore-passcode=xwalk-test',
502 '--keystore-alias-passcode=xwalk-test', self._mode]
504 self.addCleanup(Clean, 'Example', '1.0.0')
505 self.assertTrue(os.path.exists('Example'))
506 apk_list = ['Example.apk', 'Example_x86.apk', 'Example_arm.apk']
508 if os.path.isfile(apk):
509 cmd = ['jarsigner', '-verify', '-keystore',
510 keystore_path, '-verbose', apk]
511 out = RunCommand(cmd)
512 self.assertTrue(out.find('smk') != -1)
513 self.checkApks('Example', '1.0.0')
515 def testManifest(self):
516 manifest_path = os.path.join('test_data', 'manifest', 'manifest.json')
517 cmd = ['python', 'make_apk.py', '--package=org.xwalk.example',
518 '--manifest=%s' % manifest_path, self._mode]
520 self.addCleanup(Clean, 'Example', '1.0.0')
521 manifest = 'Example/AndroidManifest.xml'
522 with open(manifest, 'r') as content_file:
523 content = content_file.read()
524 self.assertTrue(os.path.exists(manifest))
525 self.assertTrue(content.find('android.permission.READ_CONTACTS') != -1)
526 self.assertTrue(content.find('android.permission.WRITE_CONTACTS') != -1)
528 content.find('android.permission.ACCESS_FINE_LOCATION') != -1)
529 self.assertTrue(content.find('android.permission.READ_SMS') != -1)
530 self.assertTrue(content.find('android.permission.RECEIVE_SMS') != -1)
531 self.assertTrue(content.find('android.permission.SEND_SMS') != -1)
532 self.assertTrue(content.find('android.permission.WRITE_SMS') != -1)
533 self.assertTrue(content.find('landscape') != -1)
534 theme = 'Example/res/values-v14/theme.xml'
535 with open(theme, 'r') as content_file:
536 content = content_file.read()
537 self.assertTrue(os.path.exists(theme))
540 '<item name="android:windowFullscreen">true</item>') != -1)
541 self.assertTrue(os.path.exists('Example'))
542 self.checkApks('Example', '1.0.0')
544 def testManifestWithSpecificValue(self):
545 manifest_path = os.path.join('test_data', 'manifest',
546 'manifest_app_launch_local_path.json')
547 cmd = ['python', 'make_apk.py', '--package=org.xwalk.example',
548 '--manifest=%s' % manifest_path, self._mode]
549 out = RunCommand(cmd)
550 self.addCleanup(Clean, 'Example', '1.0.0')
551 self.assertTrue(out.find('no app launch path') == -1)
552 self.checkApks('Example', '1.0.0')
554 def testManifestWithDeprecatedField(self):
555 manifest_path = os.path.join('test_data', 'manifest', 'deprecated',
556 'manifest_app_local_path.json')
557 cmd = ['python', 'make_apk.py', '--package=org.xwalk.example',
558 '--manifest=%s' % manifest_path, self._mode]
559 out = RunCommand(cmd)
560 self.addCleanup(Clean, 'Example', '1.0.0')
561 self.assertIn('WARNING: app.launch.local_path is deprecated for Crosswalk',
563 Clean('Example', '1.0.0')
565 manifest_path = os.path.join('test_data', 'manifest', 'deprecated',
566 'manifest_launch_path.json')
567 cmd = ['python', 'make_apk.py', '--package=org.xwalk.example',
568 '--manifest=%s' % manifest_path, self._mode]
569 out = RunCommand(cmd)
570 self.assertIn('WARNING: launch_path is deprecated for Crosswalk', out)
571 Clean('Example', '1.0.0')
573 manifest_path = os.path.join('test_data', 'manifest', 'deprecated',
574 'manifest_permissions.json')
575 cmd = ['python', 'make_apk.py', '--package=org.xwalk.example',
576 '--manifest=%s' % manifest_path, self._mode]
577 out = RunCommand(cmd)
578 self.assertIn('WARNING: permissions is deprecated for Crosswalk', out)
579 Clean('Example', '1.0.0')
581 manifest_path = os.path.join('test_data', 'manifest',
582 'manifest_deprecated_icon.json')
583 cmd = ['python', 'make_apk.py', '--package=org.xwalk.example',
584 '--manifest=%s' % manifest_path, self._mode]
585 out = RunCommand(cmd)
586 self.assertIn('WARNING: icons defined as dictionary form is deprecated',
588 Clean('Example', '1.0.0')
590 manifest_path = os.path.join('test_data', 'manifest', 'deprecated',
591 'manifest_description.json')
592 cmd = ['python', 'make_apk.py', '--package=org.xwalk.example',
593 '--manifest=%s' % manifest_path, self._mode]
594 out = RunCommand(cmd)
595 self.assertIn('WARNING: description is deprecated for Crosswalk', out)
596 Clean('Example', '1.0.0')
598 manifest_path = os.path.join('test_data', 'manifest', 'deprecated',
599 'manifest_deprecated_version.json')
600 cmd = ['python', 'make_apk.py', '--package=org.xwalk.example',
601 '--manifest=%s' % manifest_path, self._mode]
602 out = RunCommand(cmd)
603 self.assertIn('WARNING: version is deprecated for Crosswalk', out)
605 def testManifestWithError(self):
606 manifest_path = os.path.join('test_data', 'manifest',
607 'manifest_no_app_launch_path.json')
608 cmd = ['python', 'make_apk.py', '--package=org.xwalk.example',
609 '--manifest=%s' % manifest_path, '--verbose', self._mode]
610 out = RunCommand(cmd)
611 self.assertTrue(out.find('no app launch path') != -1)
612 manifest_path = os.path.join('test_data', 'manifest',
613 'manifest_no_name.json')
614 cmd = ['python', 'make_apk.py', '--package=org.xwalk.example',
615 '--manifest=%s' % manifest_path, '--verbose', self._mode]
616 out = RunCommand(cmd)
617 self.assertTrue(out.find('no \'name\' field') != -1)
618 manifest_path = os.path.join('test_data', 'manifest',
619 'manifest_permissions_format_error.json')
620 cmd = ['python', 'make_apk.py', '--package=org.xwalk.example',
621 '--manifest=%s' % manifest_path, '--verbose', self._mode]
622 out = RunCommand(cmd)
623 self.assertTrue(out.find('\'Permissions\' field error') != -1)
624 manifest_path = os.path.join('test_data', 'manifest',
625 'manifest_permissions_field_error.json')
626 cmd = ['python', 'make_apk.py', '--package=org.xwalk.example',
627 '--manifest=%s' % manifest_path, '--verbose', self._mode]
628 out = RunCommand(cmd)
629 self.assertTrue(out.find('\'Permissions\' field error') != -1)
630 manifest_path = os.path.join('test_data', 'manifest',
631 'manifest_not_supported_permission.json')
632 cmd = ['python', 'make_apk.py', '--package=org.xwalk.example',
633 '--manifest=%s' % manifest_path, '--verbose', self._mode]
634 out = RunCommand(cmd)
636 out.find('\'Telephony\' related API is not supported') != -1)
638 def testExtensionsWithOneExtension(self):
639 # Test with an existed extension.
640 extension_path = 'test_data/extensions/myextension'
641 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
642 '--package=org.xwalk.example', '--app-url=http://www.intel.com',
643 '--extensions=%s' % extension_path, self._mode]
645 self.addCleanup(Clean, 'Example', '1.0.0')
646 self.assertTrue(os.path.exists('Example'))
647 extensions_config_json = 'Example/assets/extensions-config.json'
648 self.assertTrue(os.path.exists(extensions_config_json))
649 with open(extensions_config_json, 'r') as content_file:
650 content = content_file.read()
652 content.find('xwalk-extensions/myextension/myextension.js'))
653 self.assertTrue(content.find('com.example.extension.MyExtension'))
654 extension_js = 'Example/assets/xwalk-extensions/myextension/myextension.js'
655 self.assertTrue(os.path.exists(extension_js))
656 extension_jar = 'Example/xwalk-extensions/myextension/myextension.jar'
657 self.assertTrue(os.path.exists(extension_jar))
658 self.checkApks('Example', '1.0.0')
660 def testExtensionsWithNonExtension(self):
661 # Test with a non-existed extension.
662 extension_path = 'test_data/extensions/myextension'
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 '--extensions=%s1' % extension_path, self._mode, '--verbose']
666 out = RunCommand(cmd)
667 error_msg = 'Error: can\'t find the extension directory'
668 self.assertTrue(out.find(error_msg) != -1)
669 self.assertTrue(out.find('Exiting with error code: 9') != -1)
671 def testExtensionWithPermissions(self):
672 test_entry_root = 'test_data/entry'
673 # Add redundant separators for test.
674 extension_path = 'test_data//extensions/contactextension/'
675 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
676 '--package=org.xwalk.example', '--app-root=%s' % test_entry_root,
677 '--app-local-path=contactextension.html',
678 '--extensions=%s' % extension_path, self._mode]
680 self.addCleanup(Clean, 'Example', '1.0.0')
681 self.assertTrue(os.path.exists('Example'))
682 manifest = 'Example/AndroidManifest.xml'
683 with open(manifest, 'r') as content_file:
684 content = content_file.read()
685 self.assertTrue(os.path.exists(manifest))
686 self.assertTrue(content.find('android.permission.WRITE_CONTACTS') != -1)
687 self.assertTrue(content.find('android.permission.READ_CONTACTS') != -1)
688 self.checkApks('Example', '1.0.0')
691 xpk_file = os.path.join('test_data', 'xpk', 'example.xpk')
692 cmd = ['python', 'make_apk.py', '--package=org.xwalk.example',
693 '--xpk=%s' % xpk_file, self._mode]
695 self.addCleanup(Clean, 'Example', '1.0.0')
696 self.assertTrue(os.path.exists('Example'))
697 self.checkApks('Example', '1.0.0')
699 def testXPKWithError(self):
700 xpk_file = os.path.join('test_data', 'xpk', 'error.xpk')
701 cmd = ['python', 'make_apk.py', '--package=org.xwalk.example',
702 '--xpk=%s' % xpk_file, self._mode]
703 out = RunCommand(cmd)
704 error_msg = 'XPK doesn\'t contain manifest file'
705 self.assertTrue(out.find(error_msg) != -1)
706 self.assertFalse(os.path.exists('Example'))
708 def testOrientation(self):
709 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
710 '--package=org.xwalk.example', '--app-url=http://www.intel.com',
711 '--orientation=landscape', self._mode]
713 self.addCleanup(Clean, 'Example', '1.0.0')
714 manifest = 'Example/AndroidManifest.xml'
715 with open(manifest, 'r') as content_file:
716 content = content_file.read()
717 self.assertTrue(os.path.exists(manifest))
718 self.assertTrue(content.find('landscape') != -1)
719 self.assertTrue(os.path.exists('Example'))
720 self.checkApks('Example', '1.0.0')
723 # Arch option only works for embedded mode,
724 # so only test it for embedded mode.
725 if self._mode.find('embedded') != -1:
726 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
727 '--package=org.xwalk.example', '--app-url=http://www.intel.com',
728 '--arch=x86', self._mode]
730 self.addCleanup(Clean, 'Example', '1.0.0')
731 if 'x86' in self.archs():
732 self.assertTrue(os.path.isfile('Example_1.0.0_x86.apk'))
733 self.checkApk('Example_1.0.0_x86.apk', 'x86')
735 self.assertFalse(os.path.isfile('Example_1.0.0_x86.apk'))
736 self.assertFalse(os.path.isfile('Example_1.0.0_arm.apk'))
737 Clean('Example', '1.0.0')
738 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
739 '--package=org.xwalk.example', '--app-url=http://www.intel.com',
740 '--arch=arm', self._mode]
742 if 'arm' in self.archs():
743 self.assertTrue(os.path.isfile('Example_1.0.0_arm.apk'))
744 self.checkApk('Example_1.0.0_arm.apk', 'arm')
746 self.assertFalse(os.path.isfile('Example_1.0.0._arm.apk'))
747 self.assertFalse(os.path.isfile('Example_1.0.0_x86.apk'))
748 Clean('Example', '1.0.0')
749 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
750 '--package=org.xwalk.example', '--app-url=http://www.intel.com',
753 if 'arm' in self.archs():
754 self.assertTrue(os.path.isfile('Example_1.0.0_arm.apk'))
755 self.checkApk('Example_1.0.0_arm.apk', 'arm')
757 self.assertFalse(os.path.isfile('Example_1.0.0._arm.apk'))
758 if 'x86' in self.archs():
759 self.assertTrue(os.path.isfile('Example_1.0.0_x86.apk'))
760 self.checkApk('Example_1.0.0_x86.apk', 'x86')
762 self.assertFalse(os.path.isfile('Example_1.0.0._x86.apk'))
763 Clean('Example', '1.0.0')
764 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
765 '--package=org.xwalk.example', '--app-url=http://www.intel.com',
766 '--arch=undefined', self._mode]
767 out = RunCommand(cmd)
768 error_msg = 'invalid choice: \'undefined\''
769 self.assertTrue(out.find(error_msg) != -1)
771 def testVerbose(self):
772 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
773 '--package=org.xwalk.example', '--app-url=http://www.intel.com',
774 '--verbose', self._mode]
775 result = RunCommand(cmd)
776 self.addCleanup(Clean, 'Example', '1.0.0')
777 self.assertTrue(result.find('aapt') != -1)
778 self.assertTrue(result.find('crunch') != -1)
779 self.assertTrue(result.find('apkbuilder') != -1)
780 self.assertTrue(os.path.exists('Example'))
781 self.checkApks('Example', '1.0.0')
783 def executeCommandAndVerifyResult(self, exec_file):
784 # Test all of supported options with empty 'mode' option.
785 icon_path = './template/res/drawable-xhdpi/crosswalk.png'
786 extension_path = 'test_data/extensions/myextension'
789 if exec_file.find("make_apk.py") != -1:
791 icon = '--icon=%s' % icon_path
792 cmd = ['python', '%s' % exec_file,
793 '--app-version=1.0.0',
794 '--app-url=http://www.intel.com',
796 '--description=a sample application',
797 '--enable-remote-debugging',
798 '--extensions=%s' % extension_path,
803 '--orientation=landscape',
804 '--package=org.xwalk.example',
805 '--permissions=geolocation']
807 self.addCleanup(Clean, 'Example', '1.0.0')
808 activity = 'Example/src/org/xwalk/example/ExampleActivity.java'
809 with open(activity, 'r') as content_file:
810 content = content_file.read()
811 self.assertTrue(os.path.exists(activity))
812 # Test remote debugging option.
813 self.assertTrue(content.find('setRemoteDebugging') != -1)
814 # Test keep screen on option
815 self.assertTrue(content.find('FLAG_KEEP_SCREEN_ON') != -1)
817 manifest = 'Example/AndroidManifest.xml'
818 with open(manifest, 'r') as content_file:
819 content = content_file.read()
820 self.assertTrue(os.path.exists(manifest))
821 # Test permission option.
822 self.assertTrue(content.find('ACCESS_FINE_LOCATION') != -1)
823 # Test description option.
824 self.assertTrue(content.find('description') != -1)
825 # Test app version option.
826 self.assertTrue(content.find('versionName') != -1)
827 # Test orientation option.
828 self.assertTrue(content.find('landscape') != -1)
829 # Test fullscreen option
830 theme = 'Example/res/values-v14/theme.xml'
831 with open(theme, 'r') as content_file:
832 content = content_file.read()
833 self.assertTrue(os.path.exists(theme))
836 '<item name="android:windowFullscreen">true</item>') != -1)
837 # Test extensions option.
838 extensions_config_json = 'Example/assets/extensions-config.json'
839 self.assertTrue(os.path.exists(extensions_config_json))
840 with open(extensions_config_json, 'r') as content_file:
841 content = content_file.read()
842 js_file_name = 'xwalk-extensions/myextension/myextension.js'
843 self.assertTrue(content.find(js_file_name))
844 self.assertTrue(content.find('com.example.extension.MyExtension'))
845 extension_js = 'Example/assets/xwalk-extensions/myextension/myextension.js'
846 self.assertTrue(os.path.exists(extension_js))
847 extension_jar = 'Example/xwalk-extensions/myextension/myextension.jar'
848 self.assertTrue(os.path.exists(extension_jar))
850 def testEmptyMode(self):
851 self.executeCommandAndVerifyResult('make_apk.py')
853 def testCustomizeFile(self):
854 cmd = ['python', 'make_apk.py',
855 '--app-url=http://www.intel.com',
856 '--app-version=1.0.0',
858 '--package=org.xwalk.example',
861 manifest = 'Example/AndroidManifest.xml'
862 if not os.path.exists(manifest):
863 print 'The \'%s\' was not generated, please check it.' % manifest
866 self.executeCommandAndVerifyResult('customize.py')
868 def testLaunchScreen(self):
869 # Prepare launch screen resources.
870 launch_screen_path = os.path.join('test_data', 'launchScreen')
871 orientations = ['default', 'portrait', 'landscape']
872 dimensions = ['0_75', '1', '1_5', '2']
873 img_types = ['img', 'bg']
874 for orientation in orientations:
875 for dimension in dimensions:
876 for img_type in img_types:
877 name = orientation + '_' + img_type + '_' + dimension
878 path_tmp = os.path.join(launch_screen_path, name)
879 _file = open(path_tmp,'w+')
883 manifest_path = os.path.join('test_data', 'launchScreen',
884 'manifest_deprecated_launch_screen.json')
885 cmd = ['python', 'make_apk.py', '--package=org.xwalk.example',
886 '--manifest=%s' % manifest_path, self._mode]
887 out = RunCommand(cmd)
889 out.find('WARNING: launch_screen is deprecated for Crosswalk') != -1)
890 Clean('Example', '1.0.0')
891 manifest_path = os.path.join('test_data', 'launchScreen', 'manifest.json')
892 cmd = ['python', 'make_apk.py', '--package=org.xwalk.example',
893 '--manifest=%s' % manifest_path, self._mode]
896 theme_path = os.path.join('Example', 'res', 'values-v14', 'theme.xml')
897 self.assertTrue(os.path.exists(theme_path))
898 with open(theme_path, 'r') as content_file:
899 content = content_file.read()
900 self.assertTrue(content.find('@drawable/launchscreen_bg') != -1)
901 # Check launchscreen_bg.xml
902 launch_screen_bg_path = os.path.join(
903 "Example", 'res', 'drawable', 'launchscreen_bg.xml')
904 self.assertTrue(os.path.exists(launch_screen_bg_path))
905 with open(launch_screen_bg_path, 'r') as content_file:
906 content = content_file.read()
907 self.assertTrue(content.find('@drawable/launchscreen_bg_img') != -1)
908 # Check resource images
909 for orientation in orientations:
910 for dimension in dimensions:
911 drawable = 'drawable'
912 if orientation == 'portrait':
913 drawable = drawable + '-port'
914 elif orientation == 'landscape':
915 drawable = drawable + '-land'
916 if dimension == '0_75':
917 drawable = drawable + '-ldpi'
918 elif dimension == '1':
919 drawable = drawable + '-mdpi'
920 elif dimension == '1_5':
921 drawable = drawable + '-hdpi'
922 elif dimension == '2':
923 drawable = drawable + '-xhdpi'
924 # Check background image
925 bg_drawable = os.path.join(
926 "Example", 'res', drawable, 'launchscreen_bg_img')
927 self.assertTrue(os.path.exists(bg_drawable))
928 with open(bg_drawable, 'r') as content_file:
929 content = content_file.read()
930 name = orientation + '_' + 'bg' + '_' + dimension
931 self.assertTrue(content == name)
932 # Check foreground image
933 fg_drawable = os.path.join(
934 "Example", 'res', drawable, 'launchscreen_img')
935 self.assertTrue(os.path.exists(fg_drawable))
936 with open(fg_drawable, 'r') as content_file:
937 content = content_file.read()
938 name = orientation + '_' + 'img' + '_' + dimension
939 self.assertTrue(content == name)
940 self.checkApks('Example', '1.0.0')
941 Clean('Example', '1.0.0')
943 def testTargetDir(self):
944 test_option = ['./', '../', '~/']
945 for option in test_option:
946 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
947 '--package=org.xwalk.example', '--app-url=http://www.intel.com',
948 '--target-dir=%s' % option, self._mode]
950 self.addCleanup(Clean, os.path.expanduser('%sExample' % option), '1.0.0')
951 if self._mode.find('shared') != -1:
952 apk_path = os.path.expanduser('%sExample_1.0.0.apk' % option)
953 self.assertTrue(os.path.exists(apk_path))
954 self.checkApk(apk_path, '')
955 elif self._mode.find('embedded') != -1:
956 for arch in self.archs():
957 apk_path = os.path.expanduser('%sExample_1.0.0_%s.apk'
959 self.assertTrue(os.path.exists(apk_path))
960 self.checkApk(apk_path, arch)
962 def testCompressor(self):
963 app_root = os.path.join('test_data', 'compressor')
964 css_folder = os.path.join('test_data', 'compressor', 'css')
965 css_file = os.path.join(css_folder, 'test.css')
966 js_folder = os.path.join('test_data', 'compressor', 'js')
967 js_file = os.path.join(js_folder, 'test.js')
968 fun = self.assertTrue
971 cmd = ['python', 'customize.py',
973 '--package=org.xwalk.example',
975 '--app-root=%s' % app_root]
977 CompareSizeForCompressor('all', css_file, 'css', name, fun)
978 CompareSizeForCompressor('all', js_file, 'js', name, fun)
980 cmd = ['python', 'customize.py',
982 '--package=org.xwalk.example',
983 '--app-root=%s' % app_root,
986 CompareSizeForCompressor('all', css_file, 'css', name, fun)
987 CompareSizeForCompressor('all', js_file, 'js', name, fun)
989 cmd = ['python', 'customize.py',
991 '--package=org.xwalk.example',
993 '--app-root=%s' % app_root]
995 CompareSizeForCompressor('js', js_file, 'js', name, fun)
997 cmd = ['python', 'customize.py',
999 '--package=org.xwalk.example',
1001 '--app-root=%s' % app_root]
1003 CompareSizeForCompressor('css', css_file, 'css', name, fun)
1005 cmd = ['python', 'customize.py',
1007 '--package=org.xwalk.example',
1008 '--app-root=%s' % app_root]
1010 CompareSizeForCompressor(None, css_file, 'css', name, fun)
1011 CompareSizeForCompressor(None, js_file, 'js', name, fun)
1013 cmd = ['python', 'customize.py',
1015 '--package=org.xwalk.example',
1016 '--app-root=%s' % app_root,
1017 '--compressor=other']
1019 CompareSizeForCompressor(None, css_file, 'css', name, fun)
1020 CompareSizeForCompressor(None, js_file, 'js', name, fun)
1022 Clean(name, '1.0.0')
1025 def VerifyResultInXMLFile(self, xml_path, piece_content):
1026 self.assertTrue(os.path.exists(xml_path))
1027 with open(xml_path, 'r') as content_file:
1028 content = content_file.read()
1030 self.assertIn(piece_content, content)
1031 Clean('Example', '1.0.0')
1034 def testAppNameWithNonASCII(self):
1035 xml_path = 'Example/AndroidManifest.xml'
1036 piece_content = 'android:label="%s"' % '你好'
1037 cmd = ['python', 'make_apk.py', '--name=你好', '--app-version=1.0.0',
1038 '--package=org.xwalk.example', '--app-url=http://www.intel.com']
1040 self.VerifyResultInXMLFile(xml_path, piece_content)
1042 manifest_path = os.path.join('test_data', 'manifest', 'invalidchars',
1043 'manifest_with_chinese_name.json')
1044 cmd = ['python', 'make_apk.py', '--package=org.xwalk.example',
1045 '--manifest=%s' % manifest_path]
1047 self.VerifyResultInXMLFile(xml_path, piece_content)
1050 def testDescriptionWithDBCS(self):
1051 xml_path = 'Example/res/values/strings.xml'
1052 piece_content = '<string name="description">%s</string>' % '你好'
1053 cmd = ['python', 'make_apk.py', '--name=hello', '--app-version=1.0.0',
1054 '--package=org.xwalk.example', '--app-url=http://www.intel.com',
1057 self.VerifyResultInXMLFile(xml_path, piece_content)
1059 manifest_path = os.path.join('test_data', 'manifest',
1060 'manifest_description_dbcs.json')
1061 cmd = ['python', 'make_apk.py', '--package=org.xwalk.example',
1062 '--manifest=%s' % manifest_path]
1064 piece_content = '"description">%s</string>' % '你好 a sample description'
1065 self.VerifyResultInXMLFile(xml_path, piece_content)
1068 def SuiteWithModeOption():
1069 # Gather all the tests for the specified mode option.
1070 test_suite = unittest.TestSuite()
1071 test_suite.addTest(TestMakeApk('testAppBigVersionCodeBase'))
1072 test_suite.addTest(TestMakeApk('testAppVersionCode'))
1073 test_suite.addTest(TestMakeApk('testAppVersionCodeBase'))
1074 test_suite.addTest(TestMakeApk('testAppDescriptionAndVersion'))
1075 test_suite.addTest(TestMakeApk('testArch'))
1076 test_suite.addTest(TestMakeApk('testEnableRemoteDebugging'))
1077 test_suite.addTest(TestMakeApk('testEntry'))
1078 test_suite.addTest(TestMakeApk('testEntryWithErrors'))
1079 test_suite.addTest(TestMakeApk('testExtensionsWithOneExtension'))
1080 test_suite.addTest(TestMakeApk('testExtensionsWithNonExtension'))
1081 test_suite.addTest(TestMakeApk('testExtensionWithPermissions'))
1082 test_suite.addTest(TestMakeApk('testFullscreen'))
1083 test_suite.addTest(TestMakeApk('testIconByOption'))
1084 test_suite.addTest(TestMakeApk('testIconByManifest'))
1085 test_suite.addTest(TestMakeApk('testKeystore'))
1086 test_suite.addTest(TestMakeApk('testManifest'))
1087 test_suite.addTest(TestMakeApk('testManifestWithDeprecatedField'))
1088 test_suite.addTest(TestMakeApk('testManifestWithError'))
1089 test_suite.addTest(TestMakeApk('testName'))
1090 test_suite.addTest(TestMakeApk('testOrientation'))
1091 test_suite.addTest(TestMakeApk('testPackage'))
1092 test_suite.addTest(TestMakeApk('testPackageWithInvalidCharacter'))
1093 test_suite.addTest(TestMakeApk('testPermissions'))
1094 test_suite.addTest(TestMakeApk('testPermissionsWithError'))
1095 test_suite.addTest(TestMakeApk('testXPK'))
1096 test_suite.addTest(TestMakeApk('testXPKWithError'))
1097 test_suite.addTest(TestMakeApk('testTargetDir'))
1098 test_suite.addTest(TestMakeApk('testLaunchScreen'))
1102 def SuiteWithEmptyModeOption():
1103 # Gather all the tests for empty mode option.
1104 test_suite = unittest.TestSuite()
1105 test_suite.addTest(TestMakeApk('testAppNameWithNonASCII'))
1106 test_suite.addTest(TestMakeApk('testCompressor'))
1107 test_suite.addTest(TestMakeApk('testCustomizeFile'))
1108 test_suite.addTest(TestMakeApk('testDescriptionWithDBCS'))
1109 test_suite.addTest(TestMakeApk('testEmptyMode'))
1110 test_suite.addTest(TestMakeApk('testToolVersion'))
1111 test_suite.addTest(TestMakeApk('testVerbose'))
1115 def TestSuiteRun(test_runner, suite):
1116 results = test_runner.run(suite)
1117 return results.wasSuccessful()
1120 if __name__ == '__main__':
1121 parser = optparse.OptionParser()
1122 info = ('The build directory for xwalk.'
1123 'Such as: --build-dir=src/out')
1124 parser.add_option('--build-dir', help=info)
1125 info = ('The build target for xwalk.'
1126 'Such as: --target=Release')
1127 parser.add_option('--target', help=info)
1128 info = ('The path of package tool.')
1129 parser.add_option('--tool-path', help=info)
1130 info = ('The packaging mode for xwalk. Such as: --mode=embedded.'
1131 'Please refer the detail to the option of make_apk.py.')
1132 parser.add_option('--mode', help=info)
1133 options, dummy = parser.parse_args()
1134 if len(sys.argv) == 1:
1139 mode_suite = SuiteWithModeOption()
1140 empty_mode_suite = SuiteWithEmptyModeOption()
1141 runner = unittest.TextTestRunner(verbosity=2)
1142 if options.build_dir or options.target:
1143 warnings.warn(('"--build-dir" and "--target" will be deprecated soon, '
1144 'please leverage "--tool-path" instead.'),
1148 test_result = TestSuiteRun(runner, mode_suite)
1150 # Run tests in both embedded and shared mode
1151 # when the mode option isn't specified.
1152 options.mode = 'embedded'
1153 print 'Run tests in embedded mode.'
1154 test_result = TestSuiteRun(runner, mode_suite)
1155 options.mode = 'shared'
1156 print 'Run tests in shared mode.'
1157 test_result = TestSuiteRun(runner, mode_suite) and test_result
1159 print 'Run test without \'--mode\' option.'
1160 test_result = TestSuiteRun(runner, empty_mode_suite) and test_result