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.
15 from customize import ReplaceSpaceWithUnderscore
18 def Clean(name, app_version):
19 if os.path.exists(name):
21 if options.mode == 'shared':
22 if os.path.isfile(name + '_' + app_version + '.apk'):
23 os.remove(name + '_' + app_version + '.apk')
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')
31 def CompareSizeForCompressor(mode, original, ext, name, fun):
34 mode_list = ['all', 'js', 'css']
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)
43 fun(compressed_size < size)
45 fun(size == compressed_size)
47 print('Error: %s is not exist.' % www_dir)
50 def GetFileSize(file_path):
52 if os.path.exists(file_path):
53 size = os.path.getsize(file_path)
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]
64 def GetResultWithOption(mode=None, manifest=None, name=None, package=None):
66 if manifest is not None:
67 manifest = '--manifest=' + manifest
69 app_url = '--app-url=http://www.intel.com'
71 name = '--name=' + name
72 if package is not None:
73 package = '--package=' + package
75 cmd = ['python', 'make_apk.py',
76 '--app-version=1.0.0',
82 return RunCommand(cmd)
85 class TestMakeApk(unittest.TestCase):
88 cls._original_dir = os.getcwd()
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,
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__)),
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)
104 unittest.SkipTest('xwalk_app_template folder doesn\'t exist. '
105 'Skipping all tests in make_apk_test.py')
107 if options.mode == 'shared':
108 cls._mode = '--mode=shared'
109 elif options.mode == 'embedded':
110 cls._mode = '--mode=embedded'
111 cls.fakeNativeLibrary()
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),
119 elif options.build_dir and options.target:
120 test_data_dir = os.path.join(options.build_dir,
122 'xwalk_app_template',
124 if os.path.exists(test_data_dir):
125 shutil.rmtree(test_data_dir)
126 cls.restoreNativeLibrary()
127 os.chdir(cls._original_dir)
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()
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)
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')
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')
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')
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',
193 'device_capabilities_api.js',
194 'launch_screen_api.js',
195 'presentation_api.js',
196 'screen_orientation_api.js']
197 for res_file in embedded_related_files:
198 self.assertTrue(out.find(res_file) != -1)
200 self.assertTrue(out.find('x86/libxwalkcore.so') != -1)
202 self.assertTrue(out.find('armeabi-v7a/libxwalkcore.so') != -1)
205 cmd = ['python', 'make_apk.py', '--app-version=1.0.0',
206 '--package=org.xwalk.example', self._mode]
207 out = RunCommand(cmd)
208 Clean('Example', '1.0.0')
209 self.assertTrue(out.find('The APK name is required!') != -1)
211 cmd = ['python', 'make_apk.py', '--name=Test_Example',
212 '--app-version=1.0.0', '--app-url=http://www.intel.com',
213 '--package=org.xwalk.example', self._mode]
214 out = RunCommand(cmd)
215 self.assertTrue(out.find('The APK name is required!') == -1)
216 Clean('Test_Example', '1.0.0')
218 invalid_chars = '\/:.*?"<>|-'
219 for c in invalid_chars:
220 invalid_name = '--name=Example' + c
221 cmd = ['python', 'make_apk.py', invalid_name,
222 '--app-version=1.0.0', '--package=org.xwalk.example',
223 '--app-url=http://www.intel.com', self._mode]
224 out = RunCommand(cmd)
225 self.assertTrue(out.find('invalid characters') != -1)
227 def testToolVersion(self):
228 cmd = ['python', 'make_apk.py', '--version']
229 out = RunCommand(cmd)
230 self.assertTrue(out.find('Crosswalk app packaging tool version') != -1)
232 def testAppDescriptionAndVersion(self):
233 cmd = ['python', 'make_apk.py', '--name=Example',
234 '--package=org.xwalk.example', '--app-version=1.0.0',
235 '--description=a sample application',
236 '--app-url=http://www.intel.com', self._mode]
238 self.addCleanup(Clean, 'Example', '1.0.0')
239 manifest = 'Example/AndroidManifest.xml'
240 with open(manifest, 'r') as content_file:
241 content = content_file.read()
242 self.assertTrue(os.path.exists(manifest))
243 self.assertTrue(content.find('description') != -1)
244 self.assertTrue(content.find('versionName') != -1)
245 self.checkApks('Example', '1.0.0')
247 def testAppVersionCode(self):
248 cmd = ['python', 'make_apk.py', '--name=Example',
249 '--package=org.xwalk.example', '--app-version=1.0.0',
250 '--description=a sample application',
251 '--app-versionCode=3',
252 '--app-url=http://www.intel.com', self._mode]
254 self.addCleanup(Clean, 'Example', '1.0.0')
255 manifest = 'Example/AndroidManifest.xml'
256 with open(manifest, 'r') as content_file:
257 content = content_file.read()
258 self.assertTrue(os.path.exists(manifest))
259 self.assertTrue(content.find('versionCode="3"') != -1)
260 self.checkApks('Example', '1.0.0')
262 def testAppVersionCodeBase(self):
263 # Arch option only works for embedded mode,
264 # so only test it for embedded mode.
265 if self._mode.find('embedded') == -1:
267 if 'x86' in self.archs():
269 versionCode = 'versionCode="60000003"'
272 versionCode = 'versionCode="20000003"'
273 cmd = ['python', 'make_apk.py', '--name=Example',
274 '--package=org.xwalk.example', '--app-version=1.0.0',
275 '--description=a sample application',
276 '--app-versionCodeBase=3',
278 '--app-url=http://www.intel.com', self._mode]
280 self.addCleanup(Clean, 'Example', '1.0.0')
281 manifest = 'Example/AndroidManifest.xml'
282 with open(manifest, 'r') as content_file:
283 content = content_file.read()
284 self.assertTrue(os.path.exists(manifest))
285 self.assertTrue(content.find(versionCode) != -1)
286 self.checkApks('Example', '1.0.0')
288 def testAppBigVersionCodeBase(self):
289 # Arch option only works for embedded mode,
290 # so only test it for embedded mode.
291 if self._mode.find('embedded') == -1:
293 if 'x86' in self.archs():
297 cmd = ['python', 'make_apk.py', '--name=Example',
298 '--package=org.xwalk.example', '--app-version=1.0.0',
299 '--description=a sample application',
300 '--app-versionCodeBase=30000000',
302 '--app-url=http://www.intel.com', self._mode]
304 self.addCleanup(Clean, 'Example', '1.0.0')
305 manifest = 'Example/AndroidManifest.xml'
306 self.assertFalse(os.path.exists(manifest))
308 def testPermissions(self):
309 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
310 '--package=org.xwalk.example', '--permissions=geolocation',
311 '--app-url=http://www.intel.com', self._mode]
313 self.addCleanup(Clean, 'Example', '1.0.0')
314 manifest = 'Example/AndroidManifest.xml'
315 with open(manifest, 'r') as content_file:
316 content = content_file.read()
317 self.assertTrue(os.path.exists(manifest))
318 self.assertTrue(content.find('ACCESS_FINE_LOCATION') != -1)
319 self.checkApks('Example', '1.0.0')
321 def testPermissionsWithError(self):
322 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
323 '--package=org.xwalk.example', '--permissions=UndefinedPermission',
324 '--app-url=http://www.intel.com', self._mode]
325 out = RunCommand(cmd)
326 self.assertTrue(out.find('related API is not supported.') != -1)
327 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
328 '--package=org.xwalk.example',
329 '--permissions=Contacts.Geolocation.Messaging',
330 '--app-url=http://www.intel.com', self._mode]
331 out = RunCommand(cmd)
332 self.assertTrue(out.find('related API is not supported.') != -1)
334 def testPackage(self):
335 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
337 out = RunCommand(cmd)
338 self.addCleanup(Clean, 'Example', '1.0.0')
339 self.assertTrue(out.find('The package name is required!') != -1)
340 Clean('Example', '1.0.0')
341 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
342 '--package=org.xwalk.example', self._mode]
343 out = RunCommand(cmd)
344 self.assertTrue(out.find('The package name is required!') == -1)
347 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
348 '--package=org.xwalk.example', '--app-url=http://www.intel.com',
350 out = RunCommand(cmd)
351 self.addCleanup(Clean, 'Example', '1.0.0')
352 self.assertTrue(out.find('The entry is required.') == -1)
353 self.checkApks('Example', '1.0.0')
354 Clean('Example', '1.0.0')
356 test_entry_root = 'test_data/entry'
357 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
358 '--package=org.xwalk.example', '--app-root=%s' % test_entry_root,
359 '--app-local-path=index.html', self._mode]
360 out = RunCommand(cmd)
361 self.assertTrue(out.find('The entry is required.') == -1)
362 self.checkApks('Example', '1.0.0')
364 def testEntryWithErrors(self):
365 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
366 '--package=org.xwalk.example', self._mode]
367 out = RunCommand(cmd)
368 self.addCleanup(Clean, 'Example', '1.0.0')
369 self.assertTrue(out.find('The entry is required.') != -1)
370 self.assertFalse(os.path.exists('Example.apk'))
371 Clean('Example', '1.0.0')
373 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
374 '--package=org.xwalk.example', '--app-url=http://www.intel.com',
375 '--app-root=.', self._mode]
376 out = RunCommand(cmd)
377 self.assertTrue(out.find('The entry is required.') != -1)
378 self.assertFalse(os.path.exists('Example.apk'))
379 Clean('Example', '1.0.0')
381 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
382 '--package=org.xwalk.example', '--app-root=./', self._mode]
383 out = RunCommand(cmd)
384 self.assertTrue(out.find('The entry is required.') != -1)
385 self.assertFalse(os.path.exists('Example.apk'))
386 Clean('Example', '1.0.0')
388 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
389 '--package=org.xwalk.example', '--app-local-path=index.html',
391 out = RunCommand(cmd)
392 self.assertTrue(out.find('The entry is required.') != -1)
393 self.assertFalse(os.path.exists('Example.apk'))
394 Clean('Example', '1.0.0')
396 manifest_path = os.path.join('test_data', 'manifest',
397 'manifest_app_launch_local_path.json')
398 cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path,
400 out = RunCommand(cmd)
402 out.find('Please make sure that the local path file') != -1)
403 self.assertFalse(os.path.exists('Example.apk'))
405 def testIconByOption(self):
406 icon = os.path.join('test_data', 'manifest', 'icons', 'icon_96.png')
407 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
408 '--package=org.xwalk.example', '--app-url=http://www.intel.com',
409 '--icon=%s' % icon, self._mode]
411 self.addCleanup(Clean, 'Example', '1.0.0')
412 manifest = 'Example/AndroidManifest.xml'
413 with open(manifest, 'r') as content_file:
414 content = content_file.read()
415 self.assertTrue(content.find('drawable/icon_96') != -1)
416 self.checkApks('Example', '1.0.0')
418 def testIconByManifest(self):
419 manifest_path = os.path.join('test_data', 'manifest', 'manifest_icon.json')
420 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
421 '--package=org.xwalk.example', '--app-url=http://www.intel.com',
422 '--manifest=%s' % manifest_path, self._mode]
424 self.addCleanup(Clean, 'Example', '1.0.0')
425 manifest = 'Example/AndroidManifest.xml'
426 with open(manifest, 'r') as content_file:
427 content = content_file.read()
428 self.assertTrue(content.find('drawable/icon') != -1)
429 self.checkApks('Example', '1.0.0')
431 def testFullscreen(self):
432 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
433 '--package=org.xwalk.example', '--app-url=http://www.intel.com',
436 self.addCleanup(Clean, 'Example', '1.0.0')
437 theme = 'Example/res/values/theme.xml'
438 with open(theme, 'r') as content_file:
439 content = content_file.read()
440 self.assertTrue(os.path.exists(theme))
443 '<item name="android:windowFullscreen">true</item>') != -1)
444 self.checkApks('Example', '1.0.0')
446 def testEnableRemoteDebugging(self):
447 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
448 '--package=org.xwalk.example', '--app-url=http://www.intel.com',
449 '--enable-remote-debugging', self._mode]
451 self.addCleanup(Clean, 'Example', '1.0.0')
452 activity = 'Example/src/org/xwalk/example/ExampleActivity.java'
453 with open(activity, 'r') as content_file:
454 content = content_file.read()
455 self.assertTrue(os.path.exists(activity))
456 self.assertTrue(content.find('setRemoteDebugging') != -1)
457 self.checkApks('Example', '1.0.0')
458 Clean('Example', '1.0.0')
459 manifest_path = os.path.join('test_data', 'manifest', 'manifest.json')
460 cmd = ['python', 'make_apk.py', '--enable-remote-debugging',
461 '--manifest=%s' % manifest_path, self._mode]
463 activity = 'Example/src/org/xwalk/example/ExampleActivity.java'
464 with open(activity, 'r') as content_file:
465 content = content_file.read()
466 self.assertTrue(os.path.exists(activity))
467 self.assertTrue(content.find('setRemoteDebugging') != -1)
468 self.checkApks('Example', '1.0.0')
470 def testKeystore(self):
471 keystore_path = os.path.join('test_data', 'keystore',
472 'xwalk-test.keystore')
473 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
474 '--package=org.xwalk.example', '--app-url=http://www.intel.com',
475 '--keystore-path=%s' % keystore_path, '--keystore-alias=xwalk-test',
476 '--keystore-passcode=xwalk-test', self._mode]
478 self.addCleanup(Clean, 'Example', '1.0.0')
479 self.assertTrue(os.path.exists('Example'))
480 apk_list = ['Example.apk', 'Example_x86.apk', 'Example_arm.apk']
482 if os.path.isfile(apk):
483 cmd = ['jarsigner', '-verify', '-keystore',
484 keystore_path, '-verbose', apk]
485 out = RunCommand(cmd)
486 self.assertTrue(out.find('smk') != -1)
487 self.checkApks('Example', '1.0.0')
489 def testManifest(self):
490 manifest_path = os.path.join('test_data', 'manifest', 'manifest.json')
491 cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path,
494 self.addCleanup(Clean, 'Example', '1.0.0')
495 manifest = 'Example/AndroidManifest.xml'
496 with open(manifest, 'r') as content_file:
497 content = content_file.read()
498 self.assertTrue(os.path.exists(manifest))
499 self.assertTrue(content.find('android.permission.READ_CONTACTS') != -1)
500 self.assertTrue(content.find('android.permission.WRITE_CONTACTS') != -1)
502 content.find('android.permission.ACCESS_FINE_LOCATION') != -1)
503 self.assertTrue(content.find('android.permission.READ_SMS') != -1)
504 self.assertTrue(content.find('android.permission.RECEIVE_SMS') != -1)
505 self.assertTrue(content.find('android.permission.SEND_SMS') != -1)
506 self.assertTrue(content.find('android.permission.WRITE_SMS') != -1)
507 theme = 'Example/res/values/theme.xml'
508 with open(theme, 'r') as content_file:
509 content = content_file.read()
510 self.assertTrue(os.path.exists(theme))
513 '<item name="android:windowFullscreen">true</item>') != -1)
514 self.assertTrue(os.path.exists('Example'))
515 self.checkApks('Example', '1.0.0')
517 def testManifestWithSpecificValue(self):
518 manifest_path = os.path.join('test_data', 'manifest',
519 'manifest_app_launch_local_path.json')
520 cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path,
522 out = RunCommand(cmd)
523 self.addCleanup(Clean, 'Example', '1.0.0')
524 self.assertTrue(out.find('no app launch path') == -1)
525 self.checkApks('Example', '1.0.0')
527 def testManifestWithError(self):
528 manifest_path = os.path.join('test_data', 'manifest',
529 'manifest_no_app_launch_path.json')
530 cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path,
531 '--verbose', self._mode]
532 out = RunCommand(cmd)
533 self.assertTrue(out.find('no app launch path') != -1)
534 manifest_path = os.path.join('test_data', 'manifest',
535 'manifest_no_name.json')
536 cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path,
537 '--verbose', self._mode]
538 out = RunCommand(cmd)
539 self.assertTrue(out.find('no \'name\' field') != -1)
540 manifest_path = os.path.join('test_data', 'manifest',
541 'manifest_no_version.json')
542 cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path,
543 '--verbose', self._mode]
544 out = RunCommand(cmd)
545 self.assertTrue(out.find('no \'version\' field') != -1)
546 manifest_path = os.path.join('test_data', 'manifest',
547 'manifest_permissions_format_error.json')
548 cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path,
549 '--verbose', self._mode]
550 out = RunCommand(cmd)
551 self.assertTrue(out.find('\'Permissions\' field error') != -1)
552 manifest_path = os.path.join('test_data', 'manifest',
553 'manifest_permissions_field_error.json')
554 cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path,
555 '--verbose', self._mode]
556 out = RunCommand(cmd)
557 self.assertTrue(out.find('\'Permissions\' field error') != -1)
558 manifest_path = os.path.join('test_data', 'manifest',
559 'manifest_not_supported_permission.json')
560 cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path,
561 '--verbose', self._mode]
562 out = RunCommand(cmd)
564 out.find('\'Telephony\' related API is not supported') != -1)
566 def testExtensionsWithOneExtension(self):
567 # Test with an existed extension.
568 extension_path = 'test_data/extensions/myextension'
569 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
570 '--package=org.xwalk.example', '--app-url=http://www.intel.com',
571 '--extensions=%s' % extension_path, self._mode]
573 self.addCleanup(Clean, 'Example', '1.0.0')
574 self.assertTrue(os.path.exists('Example'))
575 extensions_config_json = 'Example/assets/extensions-config.json'
576 self.assertTrue(os.path.exists(extensions_config_json))
577 with open(extensions_config_json, 'r') as content_file:
578 content = content_file.read()
580 content.find('xwalk-extensions/myextension/myextension.js'))
581 self.assertTrue(content.find('com.example.extension.MyExtension'))
582 extension_js = 'Example/assets/xwalk-extensions/myextension/myextension.js'
583 self.assertTrue(os.path.exists(extension_js))
584 extension_jar = 'Example/xwalk-extensions/myextension/myextension.jar'
585 self.assertTrue(os.path.exists(extension_jar))
586 self.checkApks('Example', '1.0.0')
588 def testExtensionsWithNonExtension(self):
589 # Test with a non-existed extension.
590 extension_path = 'test_data/extensions/myextension'
591 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
592 '--package=org.xwalk.example', '--app-url=http://www.intel.com',
593 '--extensions=%s1' % extension_path, self._mode, '--verbose']
594 out = RunCommand(cmd)
595 error_msg = 'Error: can\'t find the extension directory'
596 self.assertTrue(out.find(error_msg) != -1)
597 self.assertTrue(out.find('Exiting with error code: 9') != -1)
599 def testExtensionWithPermissions(self):
600 test_entry_root = 'test_data/entry'
601 # Add redundant separators for test.
602 extension_path = 'test_data//extensions/contactextension/'
603 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
604 '--package=org.xwalk.example', '--app-root=%s' % test_entry_root,
605 '--app-local-path=contactextension.html',
606 '--extensions=%s' % extension_path, self._mode]
608 self.addCleanup(Clean, 'Example', '1.0.0')
609 self.assertTrue(os.path.exists('Example'))
610 manifest = 'Example/AndroidManifest.xml'
611 with open(manifest, 'r') as content_file:
612 content = content_file.read()
613 self.assertTrue(os.path.exists(manifest))
614 self.assertTrue(content.find('android.permission.WRITE_CONTACTS') != -1)
615 self.assertTrue(content.find('android.permission.READ_CONTACTS') != -1)
616 self.checkApks('Example', '1.0.0')
619 xpk_file = os.path.join('test_data', 'xpk', 'example.xpk')
620 cmd = ['python', 'make_apk.py', '--xpk=%s' % xpk_file, self._mode]
622 self.addCleanup(Clean, 'Example', '1.0.0')
623 self.assertTrue(os.path.exists('Example'))
624 self.checkApks('Example', '1.0.0')
626 def testXPKWithError(self):
627 xpk_file = os.path.join('test_data', 'xpk', 'error.xpk')
628 cmd = ['python', 'make_apk.py', '--xpk=%s' % xpk_file, self._mode]
629 out = RunCommand(cmd)
630 error_msg = 'XPK doesn\'t contain manifest file'
631 self.assertTrue(out.find(error_msg) != -1)
632 self.assertFalse(os.path.exists('Example'))
634 def testOrientation(self):
635 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
636 '--package=org.xwalk.example', '--app-url=http://www.intel.com',
637 '--orientation=landscape', self._mode]
639 self.addCleanup(Clean, 'Example', '1.0.0')
640 manifest = 'Example/AndroidManifest.xml'
641 with open(manifest, 'r') as content_file:
642 content = content_file.read()
643 self.assertTrue(os.path.exists(manifest))
644 self.assertTrue(content.find('landscape') != -1)
645 self.assertTrue(os.path.exists('Example'))
646 self.checkApks('Example', '1.0.0')
649 # Arch option only works for embedded mode,
650 # so only test it for embedded mode.
651 if self._mode.find('embedded') != -1:
652 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
653 '--package=org.xwalk.example', '--app-url=http://www.intel.com',
654 '--arch=x86', self._mode]
656 self.addCleanup(Clean, 'Example', '1.0.0')
657 if 'x86' in self.archs():
658 self.assertTrue(os.path.isfile('Example_1.0.0_x86.apk'))
659 self.checkApk('Example_1.0.0_x86.apk', 'x86')
661 self.assertFalse(os.path.isfile('Example_1.0.0_x86.apk'))
662 self.assertFalse(os.path.isfile('Example_1.0.0_arm.apk'))
663 Clean('Example', '1.0.0')
664 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
665 '--package=org.xwalk.example', '--app-url=http://www.intel.com',
666 '--arch=arm', self._mode]
668 if 'arm' in self.archs():
669 self.assertTrue(os.path.isfile('Example_1.0.0_arm.apk'))
670 self.checkApk('Example_1.0.0_arm.apk', 'arm')
672 self.assertFalse(os.path.isfile('Example_1.0.0._arm.apk'))
673 self.assertFalse(os.path.isfile('Example_1.0.0_x86.apk'))
674 Clean('Example', '1.0.0')
675 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
676 '--package=org.xwalk.example', '--app-url=http://www.intel.com',
679 if 'arm' in self.archs():
680 self.assertTrue(os.path.isfile('Example_1.0.0_arm.apk'))
681 self.checkApk('Example_1.0.0_arm.apk', 'arm')
683 self.assertFalse(os.path.isfile('Example_1.0.0._arm.apk'))
684 if 'x86' in self.archs():
685 self.assertTrue(os.path.isfile('Example_1.0.0_x86.apk'))
686 self.checkApk('Example_1.0.0_x86.apk', 'x86')
688 self.assertFalse(os.path.isfile('Example_1.0.0._x86.apk'))
689 Clean('Example', '1.0.0')
690 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
691 '--package=org.xwalk.example', '--app-url=http://www.intel.com',
692 '--arch=undefined', self._mode]
693 out = RunCommand(cmd)
694 error_msg = 'invalid choice: \'undefined\''
695 self.assertTrue(out.find(error_msg) != -1)
697 def testVerbose(self):
698 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
699 '--package=org.xwalk.example', '--app-url=http://www.intel.com',
700 '--verbose', self._mode]
701 result = RunCommand(cmd)
702 self.addCleanup(Clean, 'Example', '1.0.0')
703 self.assertTrue(result.find('aapt') != -1)
704 self.assertTrue(result.find('crunch') != -1)
705 self.assertTrue(result.find('apkbuilder') != -1)
706 self.assertTrue(os.path.exists('Example'))
707 self.checkApks('Example', '1.0.0')
709 def executeCommandAndVerifyResult(self, exec_file):
710 # Test all of supported options with empty 'mode' option.
711 icon_path = './app_src/res/drawable-xhdpi/crosswalk.png'
712 extension_path = 'test_data/extensions/myextension'
715 if exec_file.find("make_apk.py") != -1:
717 icon = '--icon=%s' % icon_path
718 cmd = ['python', '%s' % exec_file,
719 '--app-version=1.0.0',
720 '--app-url=http://www.intel.com',
722 '--description=a sample application',
723 '--enable-remote-debugging',
724 '--extensions=%s' % extension_path,
729 '--orientation=landscape',
730 '--package=org.xwalk.example',
731 '--permissions=geolocation']
733 self.addCleanup(Clean, 'Example', '1.0.0')
734 activity = 'Example/src/org/xwalk/example/ExampleActivity.java'
735 with open(activity, 'r') as content_file:
736 content = content_file.read()
737 self.assertTrue(os.path.exists(activity))
738 # Test remote debugging option.
739 self.assertTrue(content.find('setRemoteDebugging') != -1)
740 # Test keep screen on option
741 self.assertTrue(content.find('FLAG_KEEP_SCREEN_ON') != -1)
743 manifest = 'Example/AndroidManifest.xml'
744 with open(manifest, 'r') as content_file:
745 content = content_file.read()
746 self.assertTrue(os.path.exists(manifest))
747 # Test permission option.
748 self.assertTrue(content.find('ACCESS_FINE_LOCATION') != -1)
749 # Test description option.
750 self.assertTrue(content.find('description') != -1)
751 # Test app version option.
752 self.assertTrue(content.find('versionName') != -1)
753 # Test orientation option.
754 self.assertTrue(content.find('landscape') != -1)
755 # Test fullscreen option
756 theme = 'Example/res/values/theme.xml'
757 with open(theme, 'r') as content_file:
758 content = content_file.read()
759 self.assertTrue(os.path.exists(theme))
762 '<item name="android:windowFullscreen">true</item>') != -1)
763 # Test extensions option.
764 extensions_config_json = 'Example/assets/extensions-config.json'
765 self.assertTrue(os.path.exists(extensions_config_json))
766 with open(extensions_config_json, 'r') as content_file:
767 content = content_file.read()
768 js_file_name = 'xwalk-extensions/myextension/myextension.js'
769 self.assertTrue(content.find(js_file_name))
770 self.assertTrue(content.find('com.example.extension.MyExtension'))
771 extension_js = 'Example/assets/xwalk-extensions/myextension/myextension.js'
772 self.assertTrue(os.path.exists(extension_js))
773 extension_jar = 'Example/xwalk-extensions/myextension/myextension.jar'
774 self.assertTrue(os.path.exists(extension_jar))
776 def testEmptyMode(self):
777 self.executeCommandAndVerifyResult('make_apk.py')
779 def testCustomizeFile(self):
780 cmd = ['python', 'make_apk.py',
781 '--app-url=http://www.intel.com',
782 '--app-version=1.0.0',
784 '--package=org.xwalk.example',
787 manifest = 'Example/AndroidManifest.xml'
788 if not os.path.exists(manifest):
789 print 'The \'%s\' was not generated, please check it.' % manifest
792 self.executeCommandAndVerifyResult('customize.py')
794 def testLaunchScreen(self):
795 # Prepare launch screen resources.
796 launch_screen_path = os.path.join('test_data', 'launchScreen')
797 orientations = ['default', 'portrait', 'landscape']
798 dimensions = ['0_75', '1', '1_5', '2']
799 img_types = ['img', 'bg']
800 for orientation in orientations:
801 for dimension in dimensions:
802 for img_type in img_types:
803 name = orientation + '_' + img_type + '_' + dimension
804 path_tmp = os.path.join(launch_screen_path, name)
805 _file = open(path_tmp,'w+')
809 manifest_path = os.path.join('test_data', 'launchScreen', 'manifest.json')
810 cmd = ['python', 'make_apk.py', '--manifest=%s' % manifest_path, self._mode]
813 theme_path = os.path.join('Example', 'res', 'values', 'theme.xml')
814 self.assertTrue(os.path.exists(theme_path))
815 with open(theme_path, 'r') as content_file:
816 content = content_file.read()
817 self.assertTrue(content.find('@drawable/launchscreen_bg') != -1)
818 # Check launchscreen_bg.xml
819 launch_screen_bg_path = os.path.join(
820 "Example", 'res', 'drawable', 'launchscreen_bg.xml')
821 self.assertTrue(os.path.exists(launch_screen_bg_path))
822 with open(launch_screen_bg_path, 'r') as content_file:
823 content = content_file.read()
824 self.assertTrue(content.find('@drawable/launchscreen_bg_img') != -1)
825 # Check resource images
826 for orientation in orientations:
827 for dimension in dimensions:
828 drawable = 'drawable'
829 if orientation == 'portrait':
830 drawable = drawable + '-port'
831 elif orientation == 'landscape':
832 drawable = drawable + '-land'
833 if dimension == '0_75':
834 drawable = drawable + '-ldpi'
835 elif dimension == '1':
836 drawable = drawable + '-mdpi'
837 elif dimension == '1_5':
838 drawable = drawable + '-hdpi'
839 elif dimension == '2':
840 drawable = drawable + '-xhdpi'
841 # Check background image
842 bg_drawable = os.path.join(
843 "Example", 'res', drawable, 'launchscreen_bg_img')
844 self.assertTrue(os.path.exists(bg_drawable))
845 with open(bg_drawable, 'r') as content_file:
846 content = content_file.read()
847 name = orientation + '_' + 'bg' + '_' + dimension
848 self.assertTrue(content == name)
849 # Check foreground image
850 fg_drawable = os.path.join(
851 "Example", 'res', drawable, 'launchscreen_img')
852 self.assertTrue(os.path.exists(fg_drawable))
853 with open(fg_drawable, 'r') as content_file:
854 content = content_file.read()
855 name = orientation + '_' + 'img' + '_' + dimension
856 self.assertTrue(content == name)
857 self.checkApks('Example', '1.0.0')
858 Clean('Example', '1.0.0')
860 def testTargetDir(self):
861 test_option = ['./', '../', '~/']
862 for option in test_option:
863 cmd = ['python', 'make_apk.py', '--name=Example', '--app-version=1.0.0',
864 '--package=org.xwalk.example', '--app-url=http://www.intel.com',
865 '--target-dir=%s' % option, self._mode]
867 self.addCleanup(Clean, os.path.expanduser('%sExample' % option), '1.0.0')
868 if self._mode.find('shared') != -1:
869 apk_path = os.path.expanduser('%sExample_1.0.0.apk' % option)
870 self.assertTrue(os.path.exists(apk_path))
871 self.checkApk(apk_path, '')
872 elif self._mode.find('embedded') != -1:
873 for arch in self.archs():
874 apk_path = os.path.expanduser('%sExample_1.0.0_%s.apk'
876 self.assertTrue(os.path.exists(apk_path))
877 self.checkApk(apk_path, arch)
879 def testCompressor(self):
880 app_root = os.path.join('test_data', 'compressor')
881 css_folder = os.path.join('test_data', 'compressor', 'css')
882 css_file = os.path.join(css_folder, 'test.css')
883 js_folder = os.path.join('test_data', 'compressor', 'js')
884 js_file = os.path.join(js_folder, 'test.js')
885 fun = self.assertTrue
888 cmd = ['python', 'customize.py',
891 '--app-root=%s' % app_root]
893 CompareSizeForCompressor('all', css_file, 'css', name, fun)
894 CompareSizeForCompressor('all', js_file, 'js', name, fun)
896 cmd = ['python', 'customize.py',
898 '--app-root=%s' % app_root,
901 CompareSizeForCompressor('all', css_file, 'css', name, fun)
902 CompareSizeForCompressor('all', js_file, 'js', name, fun)
904 cmd = ['python', 'customize.py',
907 '--app-root=%s' % app_root]
909 CompareSizeForCompressor('js', js_file, 'js', name, fun)
911 cmd = ['python', 'customize.py',
914 '--app-root=%s' % app_root]
916 CompareSizeForCompressor('css', css_file, 'css', name, fun)
918 cmd = ['python', 'customize.py',
920 '--app-root=%s' % app_root]
922 CompareSizeForCompressor(None, css_file, 'css', name, fun)
923 CompareSizeForCompressor(None, js_file, 'js', name, fun)
925 cmd = ['python', 'customize.py',
927 '--app-root=%s' % app_root,
928 '--compressor=other']
930 CompareSizeForCompressor(None, css_file, 'css', name, fun)
931 CompareSizeForCompressor(None, js_file, 'js', name, fun)
935 def testInvalidCharacter(self):
937 start_with_letters = ' should be started with letters'
938 app_name_error = 'app name' + start_with_letters
939 package_name_error = 'package name' + start_with_letters
940 parse_error = 'parser error in manifest.json file'
941 directory = os.path.join('test_data', 'manifest', 'invalidchars')
943 manifest_path = os.path.join(directory, 'manifest_with_space_name.json')
944 result = GetResultWithOption(self._mode, manifest_path)
945 self.assertTrue(result.find(app_name_error) != -1)
947 manifest_path = os.path.join(directory, 'manifest_with_chinese_name.json')
948 result = GetResultWithOption(self._mode, manifest_path)
949 self.assertTrue(result.find(app_name_error) != -1)
951 manifest_path = os.path.join(directory, 'manifest_parse_error.json')
952 result = GetResultWithOption(self._mode, manifest_path)
953 self.assertTrue(result.find(parse_error) != -1)
955 manifest_path = os.path.join(directory, 'manifest_with_invalid_name.json')
956 result = GetResultWithOption(self._mode, manifest_path)
957 self.assertTrue(result.find(app_name_error) != -1)
959 manifest_path = os.path.join(directory, 'manifest_contain_space_name.json')
960 result = GetResultWithOption(self._mode, manifest_path)
961 self.assertTrue(result.find(app_name_error) == -1)
963 package = 'org.xwalk.example'
965 result = GetResultWithOption(self._mode, name=name, package=package)
966 self.assertTrue(result.find(app_name_error) != -1)
969 result = GetResultWithOption(self._mode, name=name, package=package)
970 self.assertTrue(result.find(app_name_error) != -1)
973 result = GetResultWithOption(self._mode, name=name, package=package)
974 self.assertTrue(result.find(app_name_error) == -1)
978 package = 'org.xwalk._example'
979 result = GetResultWithOption(self._mode, name=name, package=package)
980 self.assertTrue(result.find(package_name_error) != -1)
982 package = 'org.xwalk.123example'
983 result = GetResultWithOption(self._mode, name=name, package=package)
984 self.assertTrue(result.find(package_name_error) != -1)
986 package = 'org.xwalk.example_'
987 result = GetResultWithOption(self._mode, name=name, package=package)
988 self.assertTrue(result.find(package_name_error) == -1)
992 def VerifyResultForAppNameWithSpace(self, manifest=None, name=None,
995 GetResultWithOption(manifest=manifest, name=name, package=package)
998 replaced_name = ReplaceSpaceWithUnderscore(name)
999 manifest = replaced_name + '/AndroidManifest.xml'
1000 with open(manifest, 'r') as content_file:
1001 content = content_file.read()
1002 self.assertTrue(os.path.exists(manifest))
1003 self.assertTrue(name in content)
1004 Clean(replaced_name, version)
1007 def testAppNameWithSpace(self):
1009 package = 'org.xwalk.app_name'
1011 self.VerifyResultForAppNameWithSpace(name=name, package=package)
1014 self.VerifyResultForAppNameWithSpace(name=name, package=package)
1016 directory = os.path.join('test_data', 'manifest', 'invalidchars')
1017 manifest_path = os.path.join(directory, 'manifest_contain_space_name.json')
1018 self.VerifyResultForAppNameWithSpace(manifest=manifest_path)
1021 def SuiteWithModeOption():
1022 # Gather all the tests for the specified mode option.
1023 test_suite = unittest.TestSuite()
1024 test_suite.addTest(TestMakeApk('testAppBigVersionCodeBase'))
1025 test_suite.addTest(TestMakeApk('testAppVersionCode'))
1026 test_suite.addTest(TestMakeApk('testAppVersionCodeBase'))
1027 test_suite.addTest(TestMakeApk('testAppDescriptionAndVersion'))
1028 test_suite.addTest(TestMakeApk('testArch'))
1029 test_suite.addTest(TestMakeApk('testEnableRemoteDebugging'))
1030 test_suite.addTest(TestMakeApk('testEntry'))
1031 test_suite.addTest(TestMakeApk('testEntryWithErrors'))
1032 test_suite.addTest(TestMakeApk('testExtensionsWithOneExtension'))
1033 test_suite.addTest(TestMakeApk('testExtensionsWithNonExtension'))
1034 test_suite.addTest(TestMakeApk('testExtensionWithPermissions'))
1035 test_suite.addTest(TestMakeApk('testFullscreen'))
1036 test_suite.addTest(TestMakeApk('testIconByOption'))
1037 test_suite.addTest(TestMakeApk('testIconByManifest'))
1038 test_suite.addTest(TestMakeApk('testInvalidCharacter'))
1039 test_suite.addTest(TestMakeApk('testKeystore'))
1040 test_suite.addTest(TestMakeApk('testManifest'))
1041 test_suite.addTest(TestMakeApk('testManifestWithError'))
1042 test_suite.addTest(TestMakeApk('testName'))
1043 test_suite.addTest(TestMakeApk('testOrientation'))
1044 test_suite.addTest(TestMakeApk('testPackage'))
1045 test_suite.addTest(TestMakeApk('testPermissions'))
1046 test_suite.addTest(TestMakeApk('testPermissionsWithError'))
1047 test_suite.addTest(TestMakeApk('testXPK'))
1048 test_suite.addTest(TestMakeApk('testXPKWithError'))
1049 test_suite.addTest(TestMakeApk('testTargetDir'))
1050 test_suite.addTest(TestMakeApk('testLaunchScreen'))
1054 def SuiteWithEmptyModeOption():
1055 # Gather all the tests for empty mode option.
1056 test_suite = unittest.TestSuite()
1057 test_suite.addTest(TestMakeApk('testAppNameWithSpace'))
1058 test_suite.addTest(TestMakeApk('testCompressor'))
1059 test_suite.addTest(TestMakeApk('testCustomizeFile'))
1060 test_suite.addTest(TestMakeApk('testEmptyMode'))
1061 test_suite.addTest(TestMakeApk('testToolVersion'))
1062 test_suite.addTest(TestMakeApk('testVerbose'))
1066 def TestSuiteRun(test_runner, suite):
1067 results = test_runner.run(suite)
1068 return results.wasSuccessful()
1071 if __name__ == '__main__':
1072 parser = optparse.OptionParser()
1073 info = ('The build directory for xwalk.'
1074 'Such as: --build-dir=src/out')
1075 parser.add_option('--build-dir', help=info)
1076 info = ('The build target for xwalk.'
1077 'Such as: --target=Release')
1078 parser.add_option('--target', help=info)
1079 info = ('The path of package tool.')
1080 parser.add_option('--tool-path', help=info)
1081 info = ('The packaging mode for xwalk. Such as: --mode=embedded.'
1082 'Please refer the detail to the option of make_apk.py.')
1083 parser.add_option('--mode', help=info)
1084 options, dummy = parser.parse_args()
1085 if len(sys.argv) == 1:
1090 mode_suite = SuiteWithModeOption()
1091 empty_mode_suite = SuiteWithEmptyModeOption()
1092 runner = unittest.TextTestRunner(verbosity=2)
1093 if options.build_dir or options.target:
1094 warnings.warn(('"--build-dir" and "--target" will be deprecated soon, '
1095 'please leverage "--tool-path" instead.'),
1099 test_result = TestSuiteRun(runner, mode_suite)
1101 # Run tests in both embedded and shared mode
1102 # when the mode option isn't specified.
1103 options.mode = 'embedded'
1104 print 'Run tests in embedded mode.'
1105 test_result = TestSuiteRun(runner, mode_suite)
1106 options.mode = 'shared'
1107 print 'Run tests in shared mode.'
1108 test_result = TestSuiteRun(runner, mode_suite) and test_result
1110 print 'Run test without \'--mode\' option.'
1111 test_result = TestSuiteRun(runner, empty_mode_suite) and test_result