How to use shrinker method in fast-check-monorepo

Best JavaScript code snippet using fast-check-monorepo

run_on_as_app.py

Source:run_on_as_app.py Github

copy

Full Screen

1#!/usr/bin/env python2# Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file3# for details. All rights reserved. Use of this source code is governed by a4# BSD-style license that can be found in the LICENSE file.5import apk_masseur6import apk_utils7import golem8import gradle9import jdk10import json11import os12import optparse13import shutil14import signal15import subprocess16import sys17import time18import utils19import zipfile20from xml.dom import minidom21from datetime import datetime22import as_utils23import update_prebuilds_in_android24import download_all_benchmark_dependencies25SHRINKERS = ['r8', 'r8-full', 'r8-nolib', 'r8-nolib-full', 'pg']26WORKING_DIR = os.path.join(utils.BUILD, 'opensource_apps')27GRADLE_USER_HOME = '.gradle_user_home'28if ('R8_BENCHMARK_DIR' in os.environ29 and os.path.isdir(os.environ['R8_BENCHMARK_DIR'])):30 WORKING_DIR = os.environ['R8_BENCHMARK_DIR']31class Repo(object):32 def __init__(self, fields):33 self.__dict__ = fields34 # If there is only one app in this repository, then give the app the same35 # name as the repository, if it does not already have one.36 if len(self.apps) == 1:37 app = self.apps[0]38 if not app.name:39 app.name = self.name40class App(object):41 def __init__(self, fields):42 module = fields.get('module', 'app')43 defaults = {44 'archives_base_name': module,45 'build_dir': 'build',46 'compile_sdk': None,47 'dir': None,48 'flavor': None,49 'has_instrumentation_tests': False,50 'main_dex_rules': None,51 'module': module,52 'min_sdk': None,53 'name': None,54 'releaseTarget': None,55 'signed_apk_name': None,56 'skip': False,57 'has_lint_task': True58 }59 self.__dict__ = dict(defaults.items() + fields.items())60# For running on Golem all third-party repositories are bundled as an x20-61# dependency and then copied to WORKING_DIR. To update the app-bundle use62# 'run_on_as_app_x20_packager.py'.63# For showing benchmark data, also include the app in appSegmentBenchmarks in64# the file <golem_repo>/config/r8/benchmarks.dart.65APP_REPOSITORIES = [66 # ...67 # Repo({68 # 'name': ...,69 # 'url': ...,70 # 'revision': ...,71 # 'apps': [72 # {73 # 'id': ...,74 # 'dir': ...,75 # 'module': ... (default app)76 # 'name': ...,77 # 'archives_base_name': ... (default same as module)78 # 'flavor': ... (default no flavor)79 # 'releaseTarget': ... (default <module>:assemble<flavor>Release80 # },81 # ...82 # ]83 # }),84 # ...85 Repo({86 'name': 'android-suite',87 'url': 'https://github.com/christofferqa/android-suite',88 'revision': '46c96f214711cf6cdcb72cc0c94520ef418e3739',89 'apps': [90 App({91 'id': 'com.numix.calculator',92 'dir': 'Calculator',93 'name': 'numix-calculator',94 'has_instrumentation_tests': True,95 'has_lint_task': False96 })97 ]98 }),99 Repo({100 'name': 'AnExplorer',101 'url': 'https://github.com/christofferqa/AnExplorer',102 'revision': '365927477b8eab4052a1882d5e358057ae3dee4d',103 'apps': [104 App({105 'id': 'dev.dworks.apps.anexplorer.pro',106 'flavor': 'googleMobilePro',107 'signed_apk_name': 'AnExplorer-googleMobileProRelease-4.0.3.apk',108 'min_sdk': 17109 })110 ]111 }),112 Repo({113 'name': 'AntennaPod',114 'url': 'https://github.com/christofferqa/AntennaPod.git',115 'revision': '77e94f4783a16abe9cc5b78dc2d2b2b1867d8c06',116 'apps': [117 App({118 'id': 'de.danoeh.antennapod',119 'flavor': 'play',120 'min_sdk': 14,121 'compile_sdk': 26122 })123 ]124 }),125 Repo({126 'name': 'applymapping',127 'url': 'https://github.com/mkj-gram/applymapping',128 'revision': 'e3ae14b8c16fa4718e5dea8f7ad00937701b3c48',129 'apps': [130 App({131 'id': 'com.example.applymapping',132 'has_instrumentation_tests': True133 })134 ]135 }),136 Repo({137 'name': 'apps-android-wikipedia',138 'url': 'https://github.com/christofferqa/apps-android-wikipedia',139 'revision': '686e8aa5682af8e6a905054b935dd2daa57e63ee',140 'apps': [141 App({142 'id': 'org.wikipedia',143 'flavor': 'prod',144 'signed_apk_name': 'app-prod-universal-release.apk'145 })146 ]147 }),148 Repo({149 'name': 'chanu',150 'url': 'https://github.com/mkj-gram/chanu.git',151 'revision': '6e53458f167b6d78398da60c20fd0da01a232617',152 'apps': [153 App({154 'id': 'com.chanapps.four.activity',155 'has_lint_task': False156 })157 ]158 }),159 Repo({160 'name': 'friendlyeats-android',161 'url': 'https://github.com/christofferqa/friendlyeats-android.git',162 'revision': '10091fa0ec37da12e66286559ad1b6098976b07b',163 'apps': [164 App({165 'id': 'com.google.firebase.example.fireeats'166 })167 ]168 }),169 Repo({170 'name': 'googlesamples',171 'url': 'https://github.com/christofferqa/android-sunflower.git',172 'revision': 'df0a082a0bcbeae253817e13daca3c7a7c54f67a',173 'apps': [174 App({175 'id': 'com.google.samples.apps.sunflower',176 'name': 'android-sunflower',177 'min_sdk': 19,178 'compile_sdk': 28179 })180 ]181 }),182 Repo({183 'name': 'Instabug-Android',184 'url': 'https://github.com/christofferqa/Instabug-Android.git',185 'revision': 'b8df78c96630a6537fbc07787b4990afc030cc0f',186 'apps': [187 App({188 'id': 'com.example.instabug'189 })190 ]191 }),192 Repo({193 'name': 'iosched',194 'url': 'https://github.com/christofferqa/iosched.git',195 'revision': '581cbbe2253711775dbccb753cdb53e7e506cb02',196 'apps': [197 App({198 'id': 'com.google.samples.apps.iosched',199 'module': 'mobile',200 'min_sdk': 21,201 'compile_sdk': 29,202 'has_lint_task': False203 })204 ]205 }),206 Repo({207 'name': 'KISS',208 'url': 'https://github.com/christofferqa/KISS',209 'revision': '093da9ee0512e67192f62951c45a07a616fc3224',210 'apps': [211 App({212 'id': 'fr.neamar.kiss'213 })214 ]215 }),216 Repo({217 'name': 'materialistic',218 'url': 'https://github.com/christofferqa/materialistic',219 'revision': '2b2b2ee25ce9e672d5aab1dc90a354af1522b1d9',220 'apps': [221 App({222 'id': 'io.github.hidroh.materialistic'223 })224 ]225 }),226 Repo({227 'name': 'Minimal-Todo',228 'url': 'https://github.com/christofferqa/Minimal-Todo',229 'revision': '9d8c73746762cd376b718858ec1e8783ca07ba7c',230 'apps': [231 App({232 'id': 'com.avjindersinghsekhon.minimaltodo'233 })234 ]235 }),236 Repo({237 'name': 'muzei',238 'url': 'https://github.com/sgjesse/muzei.git',239 'revision': 'a1f1d9b119faa0db09b6bbffe2318c4ec3679418',240 'apps': [241 App({242 'id': 'net.nurik.roman.muzei',243 'module': 'main',244 'archives_base_name': 'muzei',245 'compile_sdk': 28,246 })247 ]248 }),249 Repo({250 'name': 'NewPipe',251 'url': 'https://github.com/christofferqa/NewPipe',252 'revision': 'ed543099c7823be00f15d9340f94bdb7cb37d1e6',253 'apps': [254 App({255 'id': 'org.schabi.newpipe',256 'has_lint_task': False257 })258 ]259 }),260 Repo({261 'name': 'rover-android',262 'url': 'https://github.com/mkj-gram/rover-android.git',263 'revision': 'a5e155a1ed7d19b1cecd9a7b075e2852623a06bf',264 'apps': [265 App({266 'id': 'io.rover.app.debug',267 'module': 'debug-app'268 })269 ]270 }),271 Repo({272 'name': 'santa-tracker-android',273 'url': 'https://github.com/christofferqa/santa-tracker-android.git',274 'revision': '8dee74be7d9ee33c69465a07088c53087d24a6dd',275 'apps': [276 App({277 'id': 'com.google.android.apps.santatracker',278 'module': 'santa-tracker',279 'min_sdk': 21,280 'compile_sdk': 28281 })282 ]283 }),284 Repo({285 'name': 'Signal-Android',286 'url': 'https://github.com/mkj-gram/Signal-Android.git',287 'revision': 'cd542cab9bf860e71504ecb1caaf0a8476ba3989',288 'apps': [289 App({290 'id': 'org.thoughtcrime.securesms',291 'module': '',292 'flavor': 'play',293 'main_dex_rules': 'multidex-config.pro',294 'signed_apk_name': 'Signal-play-release-4.32.7.apk'295 })296 ]297 }),298 Repo({299 'name': 'Simple-Calendar',300 'url': 'https://github.com/christofferqa/Simple-Calendar',301 'revision': '82dad8c203eea5a0f0ddb513506d8f1de986ef2b',302 'apps': [303 App({304 'id': 'com.simplemobiletools.calendar.pro',305 'signed_apk_name': 'calendar-release.apk',306 'has_lint_task': False307 })308 ]309 }),310 Repo({311 'name': 'Simple-Camera',312 'url': 'https://github.com/jsjeon/Simple-Camera',313 'revision': '451fe188ab123e6956413b42e89839b44c05ac14',314 'apps': [315 App({316 'id': 'com.simplemobiletools.camera.pro',317 'signed_apk_name': 'camera-release.apk',318 'has_lint_task': False319 })320 ]321 }),322 Repo({323 'name': 'Simple-File-Manager',324 'url': 'https://github.com/jsjeon/Simple-File-Manager',325 'revision': '282b57d9e73f4d250cc844d8d73fd223509a141e',326 'apps': [327 App({328 'id': 'com.simplemobiletools.filemanager.pro',329 'signed_apk_name': 'file-manager-release.apk',330 'has_lint_task': False331 })332 ]333 }),334 Repo({335 'name': 'Simple-Gallery',336 'url': 'https://github.com/jsjeon/Simple-Gallery',337 'revision': '679125601eee7e057dfdfecd7bea6c4a6ac73ef9',338 'apps': [339 App({340 'id': 'com.simplemobiletools.gallery.pro',341 'signed_apk_name': 'gallery-release.apk',342 'has_lint_task': False343 })344 ]345 }),346 Repo({347 'name': 'sqldelight',348 'url': 'https://github.com/christofferqa/sqldelight.git',349 'revision': '2e67a1126b6df05e4119d1e3a432fde51d76cdc8',350 'apps': [351 App({352 'id': 'com.example.sqldelight.hockey',353 'module': 'sample/android',354 'archives_base_name': 'android',355 'min_sdk': 14,356 'compile_sdk': 28357 })358 ]359 }),360 Repo({361 'name': 'tachiyomi',362 'url': 'https://github.com/sgjesse/tachiyomi.git',363 'revision': 'b15d2fe16864645055af6a745a62cc5566629798',364 'apps': [365 App({366 'id': 'eu.kanade.tachiyomi',367 'flavor': 'dev',368 'min_sdk': 16,369 'has_lint_task': False370 })371 ]372 }),373 Repo({374 'name': 'tivi',375 'url': 'https://github.com/sgjesse/tivi.git',376 'revision': '25c52e3593e7c98da4e537b49b29f6f67f88754d',377 'apps': [378 App({379 'id': 'app.tivi',380 'min_sdk': 23,381 'compile_sdk': 28,382 'has_lint_task': False383 })384 ]385 }),386 Repo({387 'name': 'Tusky',388 'url': 'https://github.com/mkj-gram/Tusky.git',389 'revision': 'e7fbd190fb53bf9fde72253b816920cb6fe34518',390 'apps': [391 App({392 'id': 'com.keylesspalace.tusky',393 'flavor': 'blue'394 })395 ]396 }),397 Repo({398 'name': 'Vungle-Android-SDK',399 'url': 'https://github.com/mkj-gram/Vungle-Android-SDK.git',400 'revision': '138d3f18c027b61b195c98911f1c5ab7d87ad18b',401 'apps': [402 App({403 'id': 'com.publisher.vungle.sample',404 'skip': True, # TODO(b/144058031)405 })406 ]407 })408]409def signal_handler(signum, frame):410 subprocess.call(['pkill', 'java'])411 raise Exception('Got killed by %s' % signum)412class EnsureNoGradleAlive(object):413 def __init__(self, active):414 self.active = active415 def __enter__(self):416 if self.active:417 # If we timeout and get a sigterm we should still kill all java418 signal.signal(signal.SIGTERM, signal_handler)419 print 'Running with wrapper that will kill java after'420 def __exit__(self, *_):421 if self.active:422 subprocess.call(['pkill', 'java'])423def GetAllApps():424 apps = []425 for repo in APP_REPOSITORIES:426 for app in repo.apps:427 apps.append((app, repo))428 return apps429def GetAllAppNames():430 return [app.name for (app, repo) in GetAllApps()]431def GetAppWithName(query):432 for (app, repo) in GetAllApps():433 if app.name == query:434 return (app, repo)435 assert False436def ComputeSizeOfDexFilesInApk(apk):437 dex_size = 0438 z = zipfile.ZipFile(apk, 'r')439 for filename in z.namelist():440 if filename.endswith('.dex'):441 dex_size += z.getinfo(filename).file_size442 return dex_size443def ExtractMarker(apk, temp_dir, options):444 r8_jar = os.path.join(temp_dir, 'r8.jar')445 r8lib_jar = os.path.join(temp_dir, 'r8lib.jar')446 # Use the copy of r8.jar or r8lib.jar if one is there.447 if os.path.isfile(r8_jar):448 cmd = [jdk.GetJavaExecutable(), '-ea', '-jar', r8_jar, 'extractmarker', apk]449 elif os.path.isfile(r8lib_jar):450 cmd = [jdk.GetJavaExecutable(), '-ea', '-cp', r8lib_jar,451 'com.android.tools.r8.ExtractMarker', apk]452 else:453 script = os.path.join(utils.TOOLS_DIR, 'extractmarker.py')454 cmd = ['python', script, apk]455 utils.PrintCmd(cmd, quiet=options.quiet)456 stdout = subprocess.check_output(cmd)457 # Return the last line.458 lines = stdout.strip().splitlines()459 assert len(lines) >= 1460 return lines[-1]461def CheckIsBuiltWithExpectedR8(apk, temp_dir, shrinker, options):462 marker_raw = ExtractMarker(apk, temp_dir, options)463 # Marker should be a string on the following format (no whitespace):464 # ~~R8{"compilation-mode":"release",465 # "min-api":16,466 # "pg-map-id":"767707e",467 # "sha-1":"7111a35bae6d5185dcfb338d61074aca8426c006",468 # "version":"1.5.14-dev"}469 if not marker_raw.startswith('~~R8'):470 raise Exception(471 'Expected marker to start with \'~~R8\' (was: {})'.format(marker_raw))472 marker = json.loads(marker_raw[4:])473 if options.hash:474 actual_hash = marker.get('sha-1')475 if actual_hash != options.hash:476 raise Exception(477 'Expected APK to be built with R8 version {} (was: {})'.format(478 expected_hash, marker_raw))479 return True480 expected_version = (481 options.version482 if options.version483 else utils.getR8Version(484 os.path.join(485 temp_dir,486 'r8lib.jar' if IsMinifiedR8(shrinker) else 'r8.jar')))487 actual_version = marker.get('version')488 if actual_version != expected_version:489 raise Exception(490 'Expected APK to be built with R8 version {} (was: {})'.format(491 expected_version, marker_raw))492 return True493def IsR8(shrinker):494 return 'r8' in shrinker495def IsR8FullMode(shrinker):496 return shrinker == 'r8-full' or shrinker == 'r8-nolib-full'497def IsLoggingEnabledFor(app, options):498 if options.no_logging:499 return False500 if options.app_logging_filter and app.name not in options.app_logging_filter:501 return False502 return True503def IsMinifiedR8(shrinker):504 return 'nolib' not in shrinker505def IsTrackedByGit(file):506 return subprocess.check_output(['git', 'ls-files', file]).strip() != ''507def GitClone(repo, checkout_dir, quiet):508 result = subprocess.check_output(509 ['git', 'clone', repo.url, checkout_dir]).strip()510 head_rev = utils.get_HEAD_sha1_for_checkout(checkout_dir)511 if repo.revision == head_rev:512 return result513 warn('Target revision is not head in {}.'.format(checkout_dir))514 with utils.ChangedWorkingDirectory(checkout_dir, quiet=quiet):515 subprocess.check_output(['git', 'reset', '--hard', repo.revision])516 return result517def GitCheckout(file):518 return subprocess.check_output(['git', 'checkout', file]).strip()519def InstallApkOnEmulator(apk_dest, options):520 cmd = ['adb', '-s', options.emulator_id, 'install', '-r', '-d', apk_dest]521 if options.quiet:522 with open(os.devnull, 'w') as devnull:523 subprocess.check_call(cmd, stdout=devnull)524 else:525 subprocess.check_call(cmd)526def PercentageDiffAsString(before, after):527 if after < before:528 return '-' + str(round((1.0 - after / before) * 100)) + '%'529 else:530 return '+' + str(round((after - before) / before * 100)) + '%'531def UninstallApkOnEmulator(app, options):532 process = subprocess.Popen(533 ['adb', '-s', options.emulator_id, 'uninstall', app.id],534 stdout=subprocess.PIPE, stderr=subprocess.PIPE)535 stdout, stderr = process.communicate()536 if stdout.strip() == 'Success':537 # Successfully uninstalled538 return539 if 'Unknown package: {}'.format(app.id) in stderr:540 # Application not installed541 return542 raise Exception(543 'Unexpected result from `adb uninstall {}\nStdout: {}\nStderr: {}'.format(544 app.id, stdout, stderr))545def WaitForEmulator(options):546 stdout = subprocess.check_output(['adb', 'devices'])547 if '{}\tdevice'.format(options.emulator_id) in stdout:548 return True549 print('Emulator \'{}\' not connected; waiting for connection'.format(550 options.emulator_id))551 time_waited = 0552 while True:553 time.sleep(10)554 time_waited += 10555 stdout = subprocess.check_output(['adb', 'devices'])556 if '{}\tdevice'.format(options.emulator_id) not in stdout:557 print('... still waiting for connection')558 if time_waited >= 5 * 60:559 return False560 else:561 return True562def GetResultsForApp(app, repo, options, temp_dir):563 # Checkout and build in the build directory.564 repo_name = repo.name565 repo_checkout_dir = os.path.join(WORKING_DIR, repo_name)566 result = {}567 if not os.path.exists(repo_checkout_dir) and not options.golem:568 with utils.ChangedWorkingDirectory(WORKING_DIR, quiet=options.quiet):569 GitClone(repo, repo_checkout_dir, options.quiet)570 checkout_rev = utils.get_HEAD_sha1_for_checkout(repo_checkout_dir)571 if repo.revision != checkout_rev:572 msg = 'Checkout is not target revision for {} in {}.'.format(573 app.name, repo_checkout_dir)574 if options.ignore_versions:575 warn(msg)576 else:577 raise Exception(msg)578 result['status'] = 'success'579 app_checkout_dir = (os.path.join(repo_checkout_dir, app.dir)580 if app.dir else repo_checkout_dir)581 result_per_shrinker = BuildAppWithSelectedShrinkers(582 app, repo, options, app_checkout_dir, temp_dir)583 for shrinker, shrinker_result in result_per_shrinker.iteritems():584 result[shrinker] = shrinker_result585 return result586def BuildAppWithSelectedShrinkers(587 app, repo, options, checkout_dir, temp_dir):588 result_per_shrinker = {}589 with utils.ChangedWorkingDirectory(checkout_dir, quiet=options.quiet):590 for shrinker in options.shrinker:591 apk_dest = None592 result = {}593 proguard_config_file = None594 if not options.r8_compilation_steps_only:595 try:596 out_dir = os.path.join(checkout_dir, 'out', shrinker)597 (apk_dest, profile_dest_dir, res_proguard_config_file) = \598 BuildAppWithShrinker(599 app, repo, shrinker, checkout_dir, out_dir, temp_dir,600 options)601 proguard_config_file = res_proguard_config_file602 dex_size = ComputeSizeOfDexFilesInApk(apk_dest)603 result['apk_dest'] = apk_dest604 result['build_status'] = 'success'605 result['dex_size'] = dex_size606 result['profile_dest_dir'] = profile_dest_dir607 profile = as_utils.ParseProfileReport(profile_dest_dir)608 result['profile'] = {609 task_name:duration for task_name, duration in profile.iteritems()610 if as_utils.IsGradleCompilerTask(task_name, shrinker)}611 except Exception as e:612 warn('Failed to build {} with {}'.format(app.name, shrinker))613 if e:614 print('Error: ' + str(e))615 result['build_status'] = 'failed'616 if result.get('build_status') == 'success':617 if options.monkey:618 result['monkey_status'] = 'success' if RunMonkey(619 app, options, apk_dest) else 'failed'620 if (result.get('build_status') == 'success'621 or options.r8_compilation_steps_only):622 if 'r8' in shrinker and options.r8_compilation_steps > 1:623 result['recompilation_results'] = \624 ComputeRecompilationResults(625 app, repo, options, checkout_dir, temp_dir, shrinker,626 proguard_config_file)627 if result.get('build_status') == 'success':628 if options.run_tests and app.has_instrumentation_tests:629 result['instrumentation_test_results'] = \630 ComputeInstrumentationTestResults(631 app, options, checkout_dir, out_dir, shrinker)632 result_per_shrinker[shrinker] = result633 if len(options.apps) > 1:634 print('')635 LogResultsForApp(app, result_per_shrinker, options)636 print('')637 return result_per_shrinker638def BuildAppWithShrinker(639 app, repo, shrinker, checkout_dir, out_dir, temp_dir, options,640 keepRuleSynthesisForRecompilation=False):641 print('[{}] Building {} with {}{}'.format(642 datetime.now().strftime("%H:%M:%S"),643 app.name,644 shrinker,645 ' for recompilation' if keepRuleSynthesisForRecompilation else ''))646 print('To compile locally: '647 'tools/run_on_as_app.py --shrinker {} --r8-compilation-steps {} '648 '--app {} {}'.format(649 shrinker,650 options.r8_compilation_steps,651 app.name,652 '--r8-compilation-steps-only'653 if options.r8_compilation_steps_only else ''))654 print('HINT: use --shrinker r8-nolib --no-build if you have a local R8.jar')655 # Add settings.gradle file if it is not present to prevent gradle from finding656 # the settings.gradle file in the r8 root when apps are placed under657 # $R8/build.658 as_utils.add_settings_gradle(checkout_dir, app.name)659 # Add 'r8.jar' to top-level build.gradle.660 as_utils.add_r8_dependency(checkout_dir, temp_dir, IsMinifiedR8(shrinker))661 archives_base_name = app.archives_base_name662 if not os.path.exists(out_dir):663 os.makedirs(out_dir)664 # Set -printconfiguration in Proguard rules.665 proguard_config_dest = os.path.abspath(666 os.path.join(out_dir, 'proguard-rules.pro'))667 as_utils.SetPrintConfigurationDirective(668 app, checkout_dir, proguard_config_dest)669 env_vars = {}670 env_vars['JAVA_HOME'] = jdk.GetJdk8Home()671 env_vars['ANDROID_HOME'] = utils.getAndroidHome()672 if not options.disable_assertions:673 env_vars['JAVA_OPTS'] = '-ea:com.android.tools.r8...'674 release_target = app.releaseTarget675 if not release_target:676 app_module = app.module.replace('/', ':')677 app_flavor = (app.flavor.capitalize() if app.flavor else '') + 'Release'678 release_target = app_module + ':' + 'assemble' + app_flavor679 # Build using gradle.680 args = [release_target,681 '-g=' + os.path.join(checkout_dir, GRADLE_USER_HOME),682 '-Pandroid.enableR8=' + str(IsR8(shrinker)).lower(),683 '-Pandroid.enableR8.fullMode=' + str(IsR8FullMode(shrinker)).lower()]684 if app.has_lint_task:685 args.extend(['-x', app_module + ':lintVital' + app_flavor])686 if options.bot:687 args.extend(['--console=plain', '--info'])688 # Warm up gradle if pre_runs > 0. For posterity we generate the same sequence689 # as the benchmarking at https://github.com/madsager/santa-tracker-android.690 for i in range(0, options.gradle_pre_runs):691 if i == 0:692 utils.RunGradlew(693 ["--stop"],694 env_vars=env_vars,695 quiet=options.quiet,696 logging=IsLoggingEnabledFor(app, options),697 use_daemon=options.use_daemon)698 utils.RunGradlew(699 args,700 env_vars=env_vars,701 quiet=options.quiet,702 clean=i > 0,703 use_daemon=options.use_daemon,704 logging=IsLoggingEnabledFor(app, options))705 if keepRuleSynthesisForRecompilation:706 args.append('-Dcom.android.tools.r8.keepRuleSynthesisForRecompilation=true')707 if options.gradle_flags:708 args.extend(options.gradle_flags.split(' '))709 args.append('--profile')710 stdout = utils.RunGradlew(711 args,712 env_vars=env_vars,713 quiet=options.quiet,714 use_daemon=options.use_daemon,715 logging=IsLoggingEnabledFor(app, options))716 apk_base_name = (archives_base_name717 + (('-' + app.flavor) if app.flavor else '') + '-release')718 signed_apk_name = (719 app.signed_apk_name720 if app.signed_apk_name721 else apk_base_name + '.apk')722 unsigned_apk_name = apk_base_name + '-unsigned.apk'723 build_dir = os.path.join(app.module, app.build_dir)724 build_output_apks = os.path.join(build_dir, 'outputs', 'apk')725 if app.flavor:726 build_output_apks = os.path.join(build_output_apks, app.flavor, 'release')727 else:728 build_output_apks = os.path.join(build_output_apks, 'release')729 signed_apk = os.path.join(build_output_apks, signed_apk_name)730 unsigned_apk = os.path.join(build_output_apks, unsigned_apk_name)731 assert os.path.isfile(signed_apk) or os.path.isfile(unsigned_apk), (732 "Expected a file to be present at {} or {}, found: {}\n"733 "Standard out from compilation: {}".format(734 signed_apk,735 unsigned_apk,736 ', '.join(737 as_utils.ListFiles(build_dir, lambda x : x.endswith('.apk'))),738 stdout))739 if options.sign_apks and not os.path.isfile(signed_apk):740 assert os.path.isfile(unsigned_apk)741 if options.sign_apks:742 apk_utils.sign_with_apksigner(743 unsigned_apk,744 signed_apk,745 options.keystore,746 options.keystore_password,747 quiet=options.quiet,748 logging=IsLoggingEnabledFor(app, options))749 if os.path.isfile(signed_apk):750 apk_dest = os.path.join(out_dir, signed_apk_name)751 as_utils.MoveFile(signed_apk, apk_dest, quiet=options.quiet)752 else:753 apk_dest = os.path.join(out_dir, unsigned_apk_name)754 as_utils.MoveFile(unsigned_apk, apk_dest, quiet=options.quiet)755 assert ('r8' not in shrinker756 or CheckIsBuiltWithExpectedR8(apk_dest, temp_dir, shrinker, options))757 profile_dest_dir = os.path.join(out_dir, 'profile')758 as_utils.MoveProfileReportTo(profile_dest_dir, stdout, quiet=options.quiet)759 # Ensure that the gradle daemon is stopped if we are running with it.760 if options.use_daemon:761 utils.RunGradlew(['--stop', '-g=' + os.path.join(checkout_dir, GRADLE_USER_HOME)])762 return (apk_dest, profile_dest_dir, proguard_config_dest)763def ComputeInstrumentationTestResults(764 app, options, checkout_dir, out_dir, shrinker):765 args = ['connectedAndroidTest',766 '-Pandroid.enableR8=' + str(IsR8(shrinker)).lower(),767 '-Pandroid.enableR8.fullMode=' + str(IsR8FullMode(shrinker)).lower()]768 env_vars = { 'ANDROID_SERIAL': options.emulator_id }769 stdout = utils.RunGradlew(770 args,771 env_vars=env_vars,772 quiet=options.quiet,773 fail=False,774 logging=IsLoggingEnabledFor(app, options),775 use_daemon=options.use_daemon)776 xml_test_result_dest = os.path.join(out_dir, 'test_result')777 as_utils.MoveXMLTestResultFileTo(778 xml_test_result_dest, stdout, quiet=options.quiet)779 with open(xml_test_result_dest, 'r') as f:780 xml_test_result_contents = f.read()781 xml_document = minidom.parseString(xml_test_result_contents)782 testsuite_element = xml_document.documentElement783 return {784 'xml_test_result_dest': xml_test_result_dest,785 'tests': int(testsuite_element.getAttribute('tests')),786 'failures': int(testsuite_element.getAttribute('failures')),787 'errors': int(testsuite_element.getAttribute('errors')),788 'skipped': int(testsuite_element.getAttribute('skipped'))789 }790def ComputeRecompilationResults(791 app, repo, options, checkout_dir, temp_dir, shrinker, proguard_config_file):792 recompilation_results = []793 # Build app with gradle using -D...keepRuleSynthesisForRecompilation=true.794 out_dir = os.path.join(checkout_dir, 'out', shrinker + '-1')795 (apk_dest, profile_dest_dir, ext_proguard_config_file) = \796 BuildAppWithShrinker(797 app, repo, shrinker, checkout_dir, out_dir,798 temp_dir, options, keepRuleSynthesisForRecompilation=True)799 recompilation_result = {800 'apk_dest': apk_dest,801 'build_status': 'success',802 'dex_size': ComputeSizeOfDexFilesInApk(apk_dest),803 'monkey_status': 'skipped'804 }805 recompilation_results.append(recompilation_result)806 # Sanity check that keep rules have changed. If we are only doing807 # recompilation, the passed in proguard_config_file is None.808 if proguard_config_file:809 with open(ext_proguard_config_file) as new:810 with open(proguard_config_file) as old:811 assert(812 sum(1 for line in new813 if line.strip() and '-printconfiguration' not in line)814 >815 sum(1 for line in old816 if line.strip() and '-printconfiguration' not in line))817 # Extract min-sdk and target-sdk818 (min_sdk, compile_sdk) = \819 as_utils.GetMinAndCompileSdk(app, checkout_dir, apk_dest)820 # Now rebuild generated apk.821 previous_apk = apk_dest822 # We may need main dex rules when re-compiling with R8 as standalone.823 main_dex_rules = None824 if app.main_dex_rules:825 main_dex_rules = os.path.join(checkout_dir, app.main_dex_rules)826 for i in range(1, options.r8_compilation_steps):827 try:828 recompiled_apk_dest = os.path.join(829 checkout_dir, 'out', shrinker, 'app-release-{}.apk'.format(i))830 if not os.path.exists(os.path.dirname(recompiled_apk_dest)):831 os.makedirs(os.path.dirname(recompiled_apk_dest))832 RebuildAppWithShrinker(833 app, previous_apk, recompiled_apk_dest,834 ext_proguard_config_file, shrinker, min_sdk, compile_sdk,835 options, temp_dir, main_dex_rules)836 recompilation_result = {837 'apk_dest': recompiled_apk_dest,838 'build_status': 'success',839 'dex_size': ComputeSizeOfDexFilesInApk(recompiled_apk_dest)840 }841 if options.monkey:842 recompilation_result['monkey_status'] = 'success' if RunMonkey(843 app, options, recompiled_apk_dest) else 'failed'844 recompilation_results.append(recompilation_result)845 previous_apk = recompiled_apk_dest846 except Exception as e:847 warn('Failed to recompile {} with {}'.format(848 app.name, shrinker))849 recompilation_results.append({ 'build_status': 'failed' })850 break851 return recompilation_results852def RebuildAppWithShrinker(853 app, apk, apk_dest, proguard_config_file, shrinker, min_sdk, compile_sdk,854 options, temp_dir, main_dex_rules):855 assert 'r8' in shrinker856 assert apk_dest.endswith('.apk')857 print('Rebuilding {} with {}'.format(app.name, shrinker))858 # Compile given APK with shrinker to temporary zip file.859 android_jar = utils.get_android_jar(compile_sdk)860 r8_jar = os.path.join(861 temp_dir, 'r8lib.jar' if IsMinifiedR8(shrinker) else 'r8.jar')862 zip_dest = apk_dest[:-4] + '.zip'863 # TODO(christofferqa): Entry point should be CompatProguard if the shrinker864 # is 'r8'.865 entry_point = 'com.android.tools.r8.R8'866 cmd = ([jdk.GetJavaExecutable()] +867 (['-ea:com.android.tools.r8...']868 if not options.disable_assertions869 else []) +870 ['-cp', r8_jar, entry_point,871 '--release', '--min-api', str(min_sdk),872 '--pg-conf', proguard_config_file,873 '--lib', android_jar,874 '--output', zip_dest,875 apk])876 for android_optional_jar in utils.get_android_optional_jars(compile_sdk):877 cmd.append('--lib')878 cmd.append(android_optional_jar)879 if main_dex_rules:880 cmd.append('--main-dex-rules')881 cmd.append(main_dex_rules)882 utils.RunCmd(883 cmd, quiet=options.quiet, logging=IsLoggingEnabledFor(app, options))884 # Make a copy of the given APK, move the newly generated dex files into the885 # copied APK, and then sign the APK.886 apk_masseur.masseur(887 apk, dex=zip_dest, resources='META-INF/services/*', out=apk_dest,888 quiet=options.quiet, logging=IsLoggingEnabledFor(app, options),889 keystore=options.keystore)890def RunMonkey(app, options, apk_dest):891 if not WaitForEmulator(options):892 return False893 UninstallApkOnEmulator(app, options)894 InstallApkOnEmulator(apk_dest, options)895 number_of_events_to_generate = options.monkey_events896 # Intentionally using a constant seed such that the monkey generates the same897 # event sequence for each shrinker.898 random_seed = 42899 cmd = ['adb', '-s', options.emulator_id, 'shell', 'monkey', '-p', app.id,900 '-s', str(random_seed), str(number_of_events_to_generate)]901 try:902 stdout = utils.RunCmd(903 cmd, quiet=options.quiet, logging=IsLoggingEnabledFor(app, options))904 succeeded = (905 'Events injected: {}'.format(number_of_events_to_generate) in stdout)906 except subprocess.CalledProcessError as e:907 succeeded = False908 UninstallApkOnEmulator(app, options)909 return succeeded910def LogResultsForApps(result_per_shrinker_per_app, options):911 print('')912 app_errors = 0913 for (app, result_per_shrinker) in result_per_shrinker_per_app:914 app_errors += (1 if LogResultsForApp(app, result_per_shrinker, options)915 else 0)916 return app_errors917def LogResultsForApp(app, result_per_shrinker, options):918 if options.print_dexsegments:919 LogSegmentsForApp(app, result_per_shrinker, options)920 return False921 else:922 return LogComparisonResultsForApp(app, result_per_shrinker, options)923def LogSegmentsForApp(app, result_per_shrinker, options):924 for shrinker in SHRINKERS:925 if shrinker not in result_per_shrinker:926 continue927 result = result_per_shrinker[shrinker];928 benchmark_name = '{}-{}'.format(options.print_dexsegments, app.name)929 utils.print_dexsegments(benchmark_name, [result.get('apk_dest')])930 duration = sum(result.get('profile').values())931 print('%s-Total(RunTimeRaw): %s ms' % (benchmark_name, duration * 1000))932 print('%s-Total(CodeSize): %s' % (benchmark_name, result.get('dex_size')))933def LogComparisonResultsForApp(app, result_per_shrinker, options):934 print(app.name + ':')935 app_error = False936 if result_per_shrinker.get('status', 'success') != 'success':937 error_message = result_per_shrinker.get('error_message')938 print(' skipped ({})'.format(error_message))939 return940 proguard_result = result_per_shrinker.get('pg', {})941 proguard_dex_size = float(proguard_result.get('dex_size', -1))942 proguard_duration = sum(proguard_result.get('profile', {}).values())943 for shrinker in SHRINKERS:944 if shrinker not in result_per_shrinker:945 continue946 result = result_per_shrinker.get(shrinker)947 build_status = result.get('build_status')948 if build_status != 'success' and build_status is not None:949 app_error = True950 warn(' {}: {}'.format(shrinker, build_status))951 continue952 print(' {}:'.format(shrinker))953 dex_size = result.get('dex_size')954 msg = ' dex size: {}'.format(dex_size)955 if dex_size != proguard_dex_size and proguard_dex_size >= 0:956 msg = '{} ({}, {})'.format(957 msg, dex_size - proguard_dex_size,958 PercentageDiffAsString(proguard_dex_size, dex_size))959 success(msg) if dex_size < proguard_dex_size else warn(msg)960 else:961 print(msg)962 profile = result.get('profile')963 if profile:964 duration = sum(profile.values())965 msg = ' performance: {}s'.format(duration)966 if duration != proguard_duration and proguard_duration > 0:967 msg = '{} ({}s, {})'.format(968 msg, duration - proguard_duration,969 PercentageDiffAsString(proguard_duration, duration))970 success(msg) if duration < proguard_duration else warn(msg)971 else:972 print(msg)973 if len(profile) >= 2:974 for task_name, task_duration in profile.iteritems():975 print(' {}: {}s'.format(task_name, task_duration))976 if options.monkey:977 monkey_status = result.get('monkey_status')978 if monkey_status != 'success':979 app_error = True980 warn(' monkey: {}'.format(monkey_status))981 else:982 success(' monkey: {}'.format(monkey_status))983 recompilation_results = result.get('recompilation_results', [])984 i = 0985 for recompilation_result in recompilation_results:986 build_status = recompilation_result.get('build_status')987 if build_status != 'success':988 app_error = True989 print(' recompilation #{}: {}'.format(i, build_status))990 else:991 dex_size = recompilation_result.get('dex_size')992 print(' recompilation #{}'.format(i))993 print(' dex size: {}'.format(dex_size))994 if options.monkey:995 monkey_status = recompilation_result.get('monkey_status')996 msg = ' monkey: {}'.format(monkey_status)997 if monkey_status == 'success':998 success(msg)999 elif monkey_status == 'skipped':1000 print(msg)1001 else:1002 warn(msg)1003 i += 11004 if options.run_tests and 'instrumentation_test_results' in result:1005 instrumentation_test_results = \1006 result.get('instrumentation_test_results')1007 succeeded = (1008 instrumentation_test_results.get('failures')1009 + instrumentation_test_results.get('errors')1010 + instrumentation_test_results.get('skipped')) == 01011 if succeeded:1012 success(' tests: succeeded')1013 else:1014 app_error = True1015 warn(1016 ' tests: failed (failures: {}, errors: {}, skipped: {})'1017 .format(1018 instrumentation_test_results.get('failures'),1019 instrumentation_test_results.get('errors'),1020 instrumentation_test_results.get('skipped')))1021 return app_error1022def ParseOptions(argv):1023 result = optparse.OptionParser()1024 result.add_option('--app',1025 help='What app to run on',1026 choices=GetAllAppNames(),1027 action='append')1028 result.add_option('--bot',1029 help='Running on bot, use third_party dependency.',1030 default=False,1031 action='store_true')1032 result.add_option('--disable-assertions', '--disable_assertions',1033 help='Disable assertions when compiling',1034 default=False,1035 action='store_true')1036 result.add_option('--download-only', '--download_only',1037 help='Whether to download apps without any compilation',1038 default=False,1039 action='store_true')1040 result.add_option('--emulator-id', '--emulator_id',1041 help='Id of the emulator to use',1042 default='emulator-5554')1043 result.add_option('--golem',1044 help='Running on golem, do not download',1045 default=False,1046 action='store_true')1047 result.add_option('--gradle-flags', '--gradle_flags',1048 help='Flags to pass in to gradle')1049 result.add_option('--gradle-pre-runs', '--gradle_pre_runs',1050 help='Do rounds of compilations to warm up gradle',1051 default=0,1052 type=int)1053 result.add_option('--hash',1054 help='The version of R8 to use')1055 result.add_option('--ignore-versions', '--ignore_versions',1056 help='Allow checked-out app to differ in revision from '1057 'pinned',1058 default=False,1059 action='store_true')1060 result.add_option('--keystore',1061 help='Path to app.keystore',1062 default=os.path.join(utils.TOOLS_DIR, 'debug.keystore'))1063 result.add_option('--keystore-password', '--keystore_password',1064 help='Password for app.keystore',1065 default='android')1066 result.add_option('--app-logging-filter', '--app_logging_filter',1067 help='The apps for which to turn on logging',1068 action='append')1069 result.add_option('--monkey',1070 help='Whether to install and run app(s) with monkey',1071 default=False,1072 action='store_true')1073 result.add_option('--monkey-events', '--monkey_events',1074 help='Number of events that the monkey should trigger',1075 default=250,1076 type=int)1077 result.add_option('--no-build', '--no_build',1078 help='Run without building ToT first (only when using ToT)',1079 default=False,1080 action='store_true')1081 result.add_option('--no-logging', '--no_logging',1082 help='Disable logging except for errors',1083 default=False,1084 action='store_true')1085 result.add_option('--print-dexsegments',1086 metavar='BENCHMARKNAME',1087 help='Print the sizes of individual dex segments as ' +1088 '\'<BENCHMARKNAME>-<APP>-<segment>(CodeSize): '1089 '<bytes>\'')1090 result.add_option('--quiet',1091 help='Disable verbose logging',1092 default=False,1093 action='store_true')1094 result.add_option('--r8-compilation-steps', '--r8_compilation_steps',1095 help='Number of times R8 should be run on each app',1096 default=2,1097 type=int)1098 result.add_option('--r8-compilation-steps-only', '--r8_compilation_steps_only',1099 help='Specify to only run compilation steps',1100 default=False,1101 action='store_true')1102 result.add_option('--run-tests', '--run_tests',1103 help='Whether to run instrumentation tests',1104 default=False,1105 action='store_true')1106 result.add_option('--sign-apks', '--sign_apks',1107 help='Whether the APKs should be signed',1108 default=False,1109 action='store_true')1110 result.add_option('--shrinker',1111 help='The shrinkers to use (by default, all are run)',1112 action='append')1113 result.add_option('--use-daemon', '--use_daemon',1114 help='Whether to use a gradle daemon',1115 default=False,1116 action='store_true')1117 result.add_option('--version',1118 help='The version of R8 to use (e.g., 1.4.51)')1119 (options, args) = result.parse_args(argv)1120 if options.app:1121 options.apps = [(app, repo) for (app, repo) in GetAllApps()1122 if app.name in options.app]1123 del options.app1124 else:1125 options.apps = GetAllApps()1126 if options.app_logging_filter:1127 for app_name in options.app_logging_filter:1128 assert any(app.name == app_name for (app, repo) in options.apps)1129 if options.shrinker:1130 for shrinker in options.shrinker:1131 assert shrinker in SHRINKERS1132 else:1133 options.shrinker = [shrinker for shrinker in SHRINKERS]1134 if options.hash or options.version:1135 # No need to build R8 if a specific version should be used.1136 options.no_build = True1137 if 'r8-nolib' in options.shrinker:1138 warn('Skipping shrinker r8-nolib because a specific version '1139 + 'of r8 was specified')1140 options.shrinker.remove('r8-nolib')1141 if 'r8-nolib-full' in options.shrinker:1142 warn('Skipping shrinker r8-nolib-full because a specific version '1143 + 'of r8 was specified')1144 options.shrinker.remove('r8-nolib-full')1145 assert not options.r8_compilation_steps_only \1146 or options.r8_compilation_steps > 11147 return (options, args)1148def clone_repositories(quiet):1149 # Clone repositories into WORKING_DIR.1150 with utils.ChangedWorkingDirectory(WORKING_DIR):1151 for repo in APP_REPOSITORIES:1152 repo_dir = os.path.join(WORKING_DIR, repo.name)1153 if not os.path.exists(repo_dir):1154 GitClone(repo, repo_dir, quiet)1155def main(argv):1156 (options, args) = ParseOptions(argv)1157 if options.bot:1158 utils.DownloadFromGoogleCloudStorage(utils.OPENSOURCE_APPS_SHA_FILE)1159 utils.DownloadFromGoogleCloudStorage(utils.ANDROID_SDK + '.tar.gz.sha1',1160 bucket='r8-deps-internal',1161 auth=True)1162 if os.path.exists(WORKING_DIR):1163 shutil.rmtree(WORKING_DIR)1164 shutil.copytree(utils.OPENSOURCE_APPS_FOLDER, WORKING_DIR)1165 os.environ[utils.ANDROID_HOME_ENVIROMENT_NAME] = os.path.join(1166 utils.ANDROID_SDK)1167 os.environ[utils.ANDROID_TOOLS_VERSION_ENVIRONMENT_NAME] = '28.0.3'1168 # TODO(b/141081520): Set to True once fixed.1169 options.no_logging = False1170 # TODO(b/141081520): Remove logging filter once fixed.1171 options.app_logging_filter = ['sqldelight']1172 options.shrinker = ['r8', 'r8-full']1173 print(options.shrinker)1174 if options.golem:1175 golem.link_third_party()1176 if os.path.exists(WORKING_DIR):1177 shutil.rmtree(WORKING_DIR)1178 shutil.copytree(utils.OPENSOURCE_APPS_FOLDER, WORKING_DIR)1179 os.environ[utils.ANDROID_HOME_ENVIROMENT_NAME] = os.path.join(1180 utils.ANDROID_SDK)1181 os.environ[utils.ANDROID_TOOLS_VERSION_ENVIRONMENT_NAME] = '28.0.3'1182 options.disable_assertions = True1183 options.ignore_versions = True1184 options.no_build = True1185 options.r8_compilation_steps = 11186 options.quiet = True1187 options.gradle_pre_runs = 21188 options.use_daemon = True1189 options.no_logging = True1190 if not os.path.exists(WORKING_DIR):1191 os.makedirs(WORKING_DIR)1192 if options.download_only:1193 clone_repositories(options.quiet)1194 return1195 with utils.TempDir() as temp_dir:1196 if not (options.no_build or options.golem):1197 gradle.RunGradle(['r8', '-Pno_internal'])1198 build_r8lib = False1199 for shrinker in options.shrinker:1200 if IsMinifiedR8(shrinker):1201 build_r8lib = True1202 if build_r8lib:1203 gradle.RunGradle(['r8lib', '-Pno_internal'])1204 if options.hash:1205 # Download r8-<hash>.jar from1206 # https://storage.googleapis.com/r8-releases/raw/.1207 target = 'r8-{}.jar'.format(options.hash)1208 update_prebuilds_in_android.download_hash(1209 temp_dir, 'com/android/tools/r8/' + options.hash, target)1210 as_utils.MoveFile(1211 os.path.join(temp_dir, target), os.path.join(temp_dir, 'r8lib.jar'),1212 quiet=options.quiet)1213 elif options.version:1214 # Download r8-<version>.jar from1215 # https://storage.googleapis.com/r8-releases/raw/.1216 target = 'r8-{}.jar'.format(options.version)1217 update_prebuilds_in_android.download_version(1218 temp_dir, 'com/android/tools/r8/' + options.version, target)1219 as_utils.MoveFile(1220 os.path.join(temp_dir, target), os.path.join(temp_dir, 'r8lib.jar'),1221 quiet=options.quiet)1222 else:1223 # Make a copy of r8.jar and r8lib.jar such that they stay the same for1224 # the entire execution of this script.1225 if 'r8-nolib' in options.shrinker or 'r8-nolib-full' in options.shrinker:1226 assert os.path.isfile(utils.R8_JAR), 'Cannot build without r8.jar'1227 shutil.copyfile(utils.R8_JAR, os.path.join(temp_dir, 'r8.jar'))1228 if 'r8' in options.shrinker or 'r8-full' in options.shrinker:1229 assert os.path.isfile(utils.R8LIB_JAR), 'Cannot build without r8lib.jar'1230 shutil.copyfile(utils.R8LIB_JAR, os.path.join(temp_dir, 'r8lib.jar'))1231 result_per_shrinker_per_app = []1232 # If we are running on golem we kill all java processes after the run1233 # to ensure no hanging gradle daemons.1234 with EnsureNoGradleAlive(options.golem):1235 for (app, repo) in options.apps:1236 if app.skip:1237 continue1238 result_per_shrinker_per_app.append(1239 (app, GetResultsForApp(app, repo, options, temp_dir)))1240 return LogResultsForApps(result_per_shrinker_per_app, options)1241def success(message):1242 CGREEN = '\033[32m'1243 CEND = '\033[0m'1244 print(CGREEN + message + CEND)1245def warn(message):1246 CRED = '\033[91m'1247 CEND = '\033[0m'1248 print(CRED + message + CEND)1249if __name__ == '__main__':...

Full Screen

Full Screen

run_on_app_dump.py

Source:run_on_app_dump.py Github

copy

Full Screen

...491def build_app_with_shrinkers(app, options, temp_dir, app_dir):492 result_per_shrinker = {}493 for shrinker in options.shrinker:494 results = []495 build_app_and_run_with_shrinker(496 app, options, temp_dir, app_dir, shrinker, results)497 result_per_shrinker[shrinker] = results498 if len(options.apps) > 1:499 print('')500 log_results_for_app(app, result_per_shrinker, options)501 print('')502 return result_per_shrinker503def is_last_build(index, compilation_steps):504 return index == compilation_steps - 1505def build_app_and_run_with_shrinker(app, options, temp_dir, app_dir, shrinker,506 results):507 print('[{}] Building {} with {}'.format(508 datetime.now().strftime("%H:%M:%S"),509 app.name,510 shrinker))511 print('To compile locally: '512 'tools/run_on_app_dump.py --shrinker {} --r8-compilation-steps {} '513 '--app {}'.format(514 shrinker,515 options.r8_compilation_steps,516 app.name))517 print('HINT: use --shrinker r8-nolib --no-build if you have a local R8.jar')518 recomp_jar = None519 status = 'success'520 if options.r8_compilation_steps < 1:521 return522 compilation_steps = 1 if app.skip_recompilation else options.r8_compilation_steps523 for compilation_step in range(0, compilation_steps):524 if status != 'success':525 break526 print('Compiling {} of {}'.format(compilation_step + 1, compilation_steps))527 result = {}528 try:529 start = time.time()530 (app_jar, mapping, new_recomp_jar) = \531 build_app_with_shrinker(532 app, options, temp_dir, app_dir, shrinker, compilation_step,533 compilation_steps, recomp_jar)534 end = time.time()535 dex_size = compute_size_of_dex_files_in_package(app_jar)536 result['build_status'] = 'success'537 result['recompilation_status'] = 'success'538 result['output_jar'] = app_jar539 result['output_mapping'] = mapping540 result['dex_size'] = dex_size541 result['duration'] = int((end - start) * 1000) # Wall time542 if (new_recomp_jar is None543 and not is_last_build(compilation_step, compilation_steps)):544 result['recompilation_status'] = 'failed'545 warn('Failed to build {} with {}'.format(app.name, shrinker))546 recomp_jar = new_recomp_jar547 except Exception as e:548 warn('Failed to build {} with {}'.format(app.name, shrinker))549 if e:550 print('Error: ' + str(e))551 result['build_status'] = 'failed'552 status = 'failed'553 original_app_apk = os.path.join(app_dir, app.apk_app)554 app_apk_destination = os.path.join(555 temp_dir,"{}_{}.apk".format(app.id, compilation_step))556 if result.get('build_status') == 'success' and options.monkey:557 # Make a copy of the given APK, move the newly generated dex files into the558 # copied APK, and then sign the APK.559 apk_masseur.masseur(560 original_app_apk, dex=app_jar, resources='META-INF/services/*',561 out=app_apk_destination,562 quiet=options.quiet, logging=is_logging_enabled_for(app, options),563 keystore=options.keystore)564 result['monkey_status'] = 'success' if adb.run_monkey(565 app.id, options.emulator_id, app_apk_destination, options.monkey_events,566 options.quiet, is_logging_enabled_for(app, options)) else 'failed'567 if (result.get('build_status') == 'success'568 and options.run_tests and app.dump_test):569 if not os.path.isfile(app_apk_destination):570 apk_masseur.masseur(571 original_app_apk, dex=app_jar, resources='META-INF/services/*',572 out=app_apk_destination,573 quiet=options.quiet, logging=is_logging_enabled_for(app, options),574 keystore=options.keystore)575 # Compile the tests with the mapping file.576 test_jar = build_test_with_shrinker(577 app, options, temp_dir, app_dir,shrinker, compilation_step,578 result['output_mapping'])579 if not test_jar:580 result['instrumentation_test_status'] = 'compilation_failed'581 else:582 original_test_apk = os.path.join(app_dir, app.apk_test)583 test_apk_destination = os.path.join(584 temp_dir,"{}_{}.test.apk".format(app.id_test, compilation_step))585 apk_masseur.masseur(586 original_test_apk, dex=test_jar, resources='META-INF/services/*',587 out=test_apk_destination,588 quiet=options.quiet, logging=is_logging_enabled_for(app, options),589 keystore=options.keystore)590 result['instrumentation_test_status'] = 'success' if adb.run_instrumented(591 app.id, app.id_test, options.emulator_id, app_apk_destination,592 test_apk_destination, options.quiet,593 is_logging_enabled_for(app, options)) else 'failed'594 results.append(result)595 if result.get('recompilation_status') != 'success':596 break597def get_jdk_home(options, app):598 if options.golem:599 return os.path.join('benchmarks', app.name, 'linux')600 return None601def build_app_with_shrinker(app, options, temp_dir, app_dir, shrinker,602 compilation_step_index, compilation_steps,603 prev_recomp_jar):604 args = AttrDict({605 'dump': dump_for_app(app_dir, app),606 'r8_jar': get_r8_jar(options, temp_dir, shrinker),607 'ea': False if options.disable_assertions else True,608 'version': options.version,609 'compiler': 'r8full' if is_full_r8(shrinker) else 'r8',610 'debug_agent': options.debug_agent,611 'program_jar': prev_recomp_jar,612 'nolib': not is_minified_r8(shrinker),613 'config_file_consumer': remove_print_lines,614 'properties': app.compiler_properties,615 'disable_desugared_lib': False,616 'print_times': options.print_times,617 })618 app_jar = os.path.join(619 temp_dir, '{}_{}_{}_dex_out.jar'.format(620 app.name, shrinker, compilation_step_index))621 app_mapping = os.path.join(622 temp_dir, '{}_{}_{}_dex_out.jar.map'.format(623 app.name, shrinker, compilation_step_index))624 recomp_jar = None625 jdkhome = get_jdk_home(options, app)626 with utils.TempDir() as compile_temp_dir:627 compile_result = compiledump.run1(compile_temp_dir, args, [], jdkhome)628 out_jar = os.path.join(compile_temp_dir, "out.jar")629 out_mapping = os.path.join(compile_temp_dir, "out.jar.map")630 if compile_result != 0 or not os.path.isfile(out_jar):631 assert False, 'Compilation of {} failed'.format(dump_for_app(app_dir, app))632 shutil.move(out_jar, app_jar)633 shutil.move(out_mapping, app_mapping)634 if compilation_step_index < compilation_steps - 1:635 args['classfile'] = True636 args['min_api'] = "10000"637 args['disable_desugared_lib'] = True638 compile_result = compiledump.run1(compile_temp_dir, args, [], jdkhome)639 if compile_result == 0:640 recomp_jar = os.path.join(641 temp_dir, '{}_{}_{}_cf_out.jar'.format(642 app.name, shrinker, compilation_step_index))643 shutil.move(out_jar, recomp_jar)644 return (app_jar, app_mapping, recomp_jar)645def build_test_with_shrinker(app, options, temp_dir, app_dir, shrinker,646 compilation_step_index, mapping):647 def rewrite_file(file):648 remove_print_lines(file)649 with open(file) as f:650 lines = f.readlines()651 with open(file, 'w') as f:652 for line in lines:653 if '-applymapping' not in line:654 f.write(line + '\n')655 f.write("-applymapping " + mapping + '\n')656 args = AttrDict({657 'dump': dump_test_for_app(app_dir, app),658 'r8_jar': get_r8_jar(options, temp_dir, shrinker),659 'ea': False if options.disable_assertions else True,...

Full Screen

Full Screen

test_shrinker.py

Source:test_shrinker.py Github

copy

Full Screen

...28from tests.conjecture.common import SOME_LABEL, run_to_buffer, shrinking_from29@pytest.mark.parametrize("n", [1, 5, 8, 15])30def test_can_shrink_variable_draws_with_just_deletion(n, monkeypatch):31 @shrinking_from([n] + [0] * (n - 1) + [1])32 def shrinker(data):33 n = data.draw_bits(4)34 b = [data.draw_bits(8) for _ in range(n)]35 if any(b):36 data.mark_interesting()37 shrinker.fixate_shrink_passes(["minimize_individual_blocks"])38 assert list(shrinker.shrink_target.buffer) == [1, 1]39def test_deletion_and_lowering_fails_to_shrink(monkeypatch):40 monkeypatch.setattr(41 Shrinker,42 "shrink",43 lambda self: self.fixate_shrink_passes(["minimize_individual_blocks"]),44 )45 def gen(self):46 self.cached_test_function(10)47 monkeypatch.setattr(ConjectureRunner, "generate_new_examples", gen)48 @run_to_buffer49 def x(data):50 for _ in range(10):51 data.draw_bytes(1)52 data.mark_interesting()53 assert x == bytes(10)54def test_duplicate_blocks_that_go_away():55 @shrinking_from([1, 1, 1, 2] * 2 + [5] * 2)56 def shrinker(data):57 x = data.draw_bits(32)58 y = data.draw_bits(32)59 if x != y:60 data.mark_invalid()61 b = [data.draw_bytes(1) for _ in range(x & 255)]62 if len(set(b)) <= 1:63 data.mark_interesting()64 shrinker.fixate_shrink_passes(["minimize_duplicated_blocks"])65 assert shrinker.shrink_target.buffer == bytes(8)66def test_accidental_duplication(monkeypatch):67 @shrinking_from([18] * 20)68 def shrinker(data):69 x = data.draw_bits(8)70 y = data.draw_bits(8)71 if x != y:72 data.mark_invalid()73 if x < 5:74 data.mark_invalid()75 b = [data.draw_bytes(1) for _ in range(x)]76 if len(set(b)) == 1:77 data.mark_interesting()78 shrinker.fixate_shrink_passes(["minimize_duplicated_blocks"])79 assert list(shrinker.buffer) == [5] * 780def test_can_zero_subintervals(monkeypatch):81 @shrinking_from(bytes([3, 0, 0, 0, 1]) * 10)82 def shrinker(data):83 for _ in range(10):84 data.start_example(SOME_LABEL)85 n = data.draw_bits(8)86 data.draw_bytes(n)87 data.stop_example()88 if data.draw_bits(8) != 1:89 return90 data.mark_interesting()91 shrinker.shrink()92 assert list(shrinker.buffer) == [0, 1] * 1093def test_can_pass_to_an_indirect_descendant(monkeypatch):94 def tree(data):95 data.start_example(1)96 n = data.draw_bits(1)97 label = data.draw_bits(8)98 if n:99 tree(data)100 tree(data)101 data.stop_example(1)102 return label103 initial = bytes([1, 10, 0, 0, 1, 0, 0, 10, 0, 0])104 target = bytes([0, 10])105 good = {initial, target}106 @shrinking_from(initial)107 def shrinker(data):108 tree(data)109 if bytes(data.buffer) in good:110 data.mark_interesting()111 shrinker.fixate_shrink_passes(["pass_to_descendant"])112 assert shrinker.shrink_target.buffer == target113def shrink(buffer, *passes):114 def accept(f):115 shrinker = shrinking_from(buffer)(f)116 shrinker.fixate_shrink_passes(passes)117 return list(shrinker.buffer)118 return accept119def test_shrinking_blocks_from_common_offset():120 @shrinking_from([11, 10])121 def shrinker(data):122 m = data.draw_bits(8)123 n = data.draw_bits(8)124 if abs(m - n) <= 1 and max(m, n) > 0:125 data.mark_interesting()126 shrinker.mark_changed(0)127 shrinker.mark_changed(1)128 shrinker.lower_common_block_offset()129 x = shrinker.shrink_target.buffer130 assert sorted(x) == [0, 1]131def test_handle_empty_draws():132 @run_to_buffer133 def x(data):134 while True:135 data.start_example(SOME_LABEL)136 n = data.draw_bits(1)137 data.start_example(SOME_LABEL)138 data.stop_example()139 data.stop_example(discard=n > 0)140 if not n:141 break142 data.mark_interesting()143 assert x == bytes([0])144def test_can_reorder_examples():145 @shrinking_from([1, 0, 1, 1, 0, 1, 0, 0, 0])146 def shrinker(data):147 total = 0148 for _ in range(5):149 data.start_example(0)150 if data.draw_bits(8):151 total += data.draw_bits(9)152 data.stop_example(0)153 if total == 2:154 data.mark_interesting()155 shrinker.fixate_shrink_passes(["reorder_examples"])156 assert list(shrinker.buffer) == [0, 0, 0, 1, 0, 1, 1, 0, 1]157def test_permits_but_ignores_raising_order(monkeypatch):158 monkeypatch.setattr(159 ConjectureRunner,160 "generate_new_examples",161 lambda runner: runner.cached_test_function([1]),162 )163 monkeypatch.setattr(164 Shrinker, "shrink", lambda self: self.incorporate_new_buffer(bytes([2]))165 )166 @run_to_buffer167 def x(data):168 data.draw_bits(2)169 data.mark_interesting()170 assert list(x) == [1]171def test_block_deletion_can_delete_short_ranges(monkeypatch):172 @shrinking_from([v for i in range(5) for _ in range(i + 1) for v in [0, i]])173 def shrinker(data):174 while True:175 n = data.draw_bits(16)176 for _ in range(n):177 if data.draw_bits(16) != n:178 data.mark_invalid()179 if n == 4:180 data.mark_interesting()181 shrinker.fixate_shrink_passes([block_program("X" * i) for i in range(1, 5)])182 assert list(shrinker.shrink_target.buffer) == [0, 4] * 5183def test_try_shrinking_blocks_ignores_overrun_blocks(monkeypatch):184 monkeypatch.setattr(185 ConjectureRunner,186 "generate_new_examples",187 lambda runner: runner.cached_test_function([3, 3, 0, 1]),188 )189 monkeypatch.setattr(190 Shrinker,191 "shrink",192 lambda self: self.try_shrinking_blocks((0, 1, 5), bytes([2])),193 )194 @run_to_buffer195 def x(data):196 n1 = data.draw_bits(8)197 data.draw_bits(8)198 if n1 == 3:199 data.draw_bits(8)200 k = data.draw_bits(8)201 if k == 1:202 data.mark_interesting()203 assert list(x) == [2, 2, 1]204def test_dependent_block_pairs_is_up_to_shrinking_integers():205 # Unit test extracted from a failure in tests/nocover/test_integers.py206 distribution = Sampler([4.0, 8.0, 1.0, 1.0, 0.5])207 sizes = [8, 16, 32, 64, 128]208 @shrinking_from(b"\x03\x01\x00\x00\x00\x00\x00\x01\x00\x02\x01")209 def shrinker(data):210 size = sizes[distribution.sample(data)]211 result = data.draw_bits(size)212 sign = (-1) ** (result & 1)213 result = (result >> 1) * sign214 cap = data.draw_bits(8)215 if result >= 32768 and cap == 1:216 data.mark_interesting()217 shrinker.fixate_shrink_passes(["minimize_individual_blocks"])218 assert list(shrinker.shrink_target.buffer) == [1, 1, 0, 1, 0, 0, 1]219def test_finding_a_minimal_balanced_binary_tree():220 # Tests iteration while the shape of the thing being iterated over can221 # change. In particular the current example can go from trivial to non222 # trivial.223 def tree(data):224 # Returns height of a binary tree and whether it is height balanced.225 data.start_example("tree")226 n = data.draw_bits(1)227 if n == 0:228 result = (1, True)229 else:230 h1, b1 = tree(data)231 h2, b2 = tree(data)232 result = (1 + max(h1, h2), b1 and b2 and abs(h1 - h2) <= 1)233 data.stop_example("tree")234 return result235 # Starting from an unbalanced tree of depth six236 @shrinking_from([1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0])237 def shrinker(data):238 _, b = tree(data)239 if not b:240 data.mark_interesting()241 shrinker.shrink()242 assert list(shrinker.shrink_target.buffer) == [1, 0, 1, 0, 1, 0, 0]243def test_float_shrink_can_run_when_canonicalisation_does_not_work(monkeypatch):244 # This should be an error when called245 monkeypatch.setattr(Float, "shrink", None)246 base_buf = int_to_bytes(flt.base_float_to_lex(1000.0), 8) + bytes(1)247 @shrinking_from(base_buf)248 def shrinker(data):249 flt.draw_float(data)250 if bytes(data.buffer) == base_buf:251 data.mark_interesting()252 shrinker.fixate_shrink_passes(["minimize_floats"])253 assert shrinker.shrink_target.buffer == base_buf254def test_try_shrinking_blocks_out_of_bounds():255 @shrinking_from(bytes([1]))256 def shrinker(data):257 data.draw_bits(1)258 data.mark_interesting()259 assert not shrinker.try_shrinking_blocks((1,), bytes([1]))260def test_block_programs_are_adaptive():261 @shrinking_from(bytes(1000) + bytes([1]))262 def shrinker(data):263 while not data.draw_bits(1):264 pass265 data.mark_interesting()266 p = shrinker.add_new_pass(block_program("X"))267 shrinker.fixate_shrink_passes([p.name])268 assert len(shrinker.shrink_target.buffer) == 1269 assert shrinker.calls <= 60270def test_zero_examples_with_variable_min_size():271 @shrinking_from(bytes([255]) * 100)272 def shrinker(data):273 any_nonzero = False274 for i in range(1, 10):275 any_nonzero |= data.draw_bits(i * 8) > 0276 if not any_nonzero:277 data.mark_invalid()278 data.mark_interesting()279 shrinker.shrink()280 assert len([d for d in shrinker.shrink_target.blocks if not d.all_zero]) == 1281def test_zero_contained_examples():282 @shrinking_from(bytes([1]) * 8)283 def shrinker(data):284 for _ in range(4):285 data.start_example(1)286 if data.draw_bits(8) == 0:287 data.mark_invalid()288 data.start_example(1)289 data.draw_bits(8)290 data.stop_example()291 data.stop_example()292 data.mark_interesting()293 shrinker.shrink()294 assert list(shrinker.shrink_target.buffer) == [1, 0] * 4295def test_zig_zags_quickly():296 @shrinking_from(bytes([255]) * 4)297 def shrinker(data):298 m = data.draw_bits(16)299 n = data.draw_bits(16)300 if m == 0 or n == 0:301 data.mark_invalid()302 if abs(m - n) <= 1:303 data.mark_interesting(0)304 # Two different interesting origins for avoiding slipping in the305 # shrinker.306 if abs(m - n) <= 10:307 data.mark_interesting(1)308 shrinker.fixate_shrink_passes(["minimize_individual_blocks"])309 assert shrinker.engine.valid_examples <= 100310 assert list(shrinker.shrink_target.buffer) == [0, 1, 0, 1]311def test_zero_irregular_examples():312 @shrinking_from([255] * 6)313 def shrinker(data):314 data.start_example(1)315 data.draw_bits(8)316 data.draw_bits(16)317 data.stop_example()318 data.start_example(1)319 interesting = data.draw_bits(8) > 0 and data.draw_bits(16) > 0320 data.stop_example()321 if interesting:322 data.mark_interesting()323 shrinker.shrink()324 assert list(shrinker.shrink_target.buffer) == [0] * 3 + [1, 0, 1]325def test_retain_end_of_buffer():326 @shrinking_from([1, 2, 3, 4, 5, 6, 0])327 def shrinker(data):328 interesting = False329 while True:330 n = data.draw_bits(8)331 if n == 6:332 interesting = True333 if n == 0:334 break335 if interesting:336 data.mark_interesting()337 shrinker.shrink()338 assert list(shrinker.buffer) == [6, 0]339def test_can_expand_zeroed_region():340 @shrinking_from([255] * 5)341 def shrinker(data):342 seen_non_zero = False343 for _ in range(5):344 if data.draw_bits(8) == 0:345 if seen_non_zero:346 data.mark_invalid()347 else:348 seen_non_zero = True349 data.mark_interesting()350 shrinker.shrink()351 assert list(shrinker.shrink_target.buffer) == [0] * 5352def test_can_expand_deleted_region():353 @shrinking_from([1, 2, 3, 4, 0, 0])354 def shrinker(data):355 def t():356 data.start_example(1)357 data.start_example(1)358 m = data.draw_bits(8)359 data.stop_example()360 data.start_example(1)361 n = data.draw_bits(8)362 data.stop_example()363 data.stop_example()364 return (m, n)365 v1 = t()366 if v1 == (1, 2):367 if t() != (3, 4):368 data.mark_invalid()369 if v1 == (0, 0) or t() == (0, 0):370 data.mark_interesting()371 shrinker.shrink()372 assert list(shrinker.buffer) == [0, 0]373def test_shrink_pass_method_is_idempotent():374 @shrinking_from([255])375 def shrinker(data):376 data.draw_bits(8)377 data.mark_interesting()378 sp = shrinker.shrink_pass(block_program("X"))379 assert isinstance(sp, ShrinkPass)380 assert shrinker.shrink_pass(sp) is sp381def test_will_terminate_stalled_shrinks():382 # Suppress the time based slow shrinking check - we only want383 # the one that checks if we're in a stall where we've shrunk384 # as far as we're going to get.385 time.freeze()386 @shrinking_from([255] * 100)387 def shrinker(data):388 count = 0389 for _ in range(100):390 if data.draw_bits(8) != 255:391 count += 1392 if count >= 10:393 return394 data.mark_interesting()395 shrinker.shrink()396 assert shrinker.calls <= 1 + 2 * shrinker.max_stall397def test_will_let_fixate_shrink_passes_do_a_full_run_through():398 @shrinking_from(range(50))399 def shrinker(data):400 for i in range(50):401 if data.draw_bits(8) != i:402 data.mark_invalid()403 data.mark_interesting()404 shrinker.max_stall = 5405 passes = [block_program("X" * i) for i in range(1, 11)]406 with pytest.raises(StopShrinking):407 shrinker.fixate_shrink_passes(passes)408 assert shrinker.shrink_pass(passes[-1]).calls > 0409@pytest.mark.parametrize("n_gap", [0, 1, 2, 3])410def test_can_simultaneously_lower_non_duplicated_nearby_blocks(n_gap):411 @shrinking_from([1, 1] + [0] * n_gap + [0, 2])412 def shrinker(data):413 # Block off lowering the whole buffer414 if data.draw_bits(1) == 0:415 data.mark_invalid()416 m = data.draw_bits(8)417 for _ in range(n_gap):418 data.draw_bits(8)419 n = data.draw_bits(16)420 if n == m + 1:421 data.mark_interesting()422 shrinker.fixate_shrink_passes(["lower_blocks_together"])...

Full Screen

Full Screen

statemachine.js

Source:statemachine.js Github

copy

Full Screen

1"use strict";2/*3Copyright [2014] [Diagramo]4Licensed under the Apache License, Version 2.0 (the "License");5you may not use this file except in compliance with the License.6You may obtain a copy of the License at7 http://www.apache.org/licenses/LICENSE-2.08Unless required by applicable law or agreed to in writing, software9distributed under the License is distributed on an "AS IS" BASIS,10WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.11See the License for the specific language governing permissions and12limitations under the License.13*/14figureSets["statemachine"] = {15 name : 'UML: State machine',16 description : 'A set of figures needed to draw state diagrams',17 figures: [18 {figureFunction: "Start", image: "start.png"},19 {figureFunction: "End", image: "end.png"},20 {figureFunction: "State", image: "state.png"},21 {figureFunction: "Note", image: "note.png"}22 ]23}24function figure_Start(x,y)25{26 var circleRadius = 7;27 28 var f = new Figure("Start");29 f.style.fillStyle = "#000000";30 f.style.strokeStyle = FigureDefaults.strokeStyle;31 //CIRCLE32 var c = new Arc(x, y, circleRadius, 0, 360, false, 0);33 f.addPrimitive(c);34 //CONNECTION POINTS35 CONNECTOR_MANAGER.connectionPointCreate(f.id, new Point(x, y), ConnectionPoint.TYPE_FIGURE);36 f.finalise();37 38 return f;39}40function figure_End(x,y)41{42 var innerCircleRadius = 7;43 var outerCircleRadius = 12;44 45 var f = new Figure("Start");46 f.style.fillStyle = "#000000";47 f.style.strokeStyle = FigureDefaults.strokeStyle;48 //outer circle49 var oc = new Arc(x, y, outerCircleRadius, 0, 360, false, 0);50 oc.style.fillStyle = "#FFFFFF";51 oc.style.strokeStyle = '#000000';52 f.addPrimitive(oc);53 54 //inner circle55 var ic = new Arc(x, y, innerCircleRadius, 0, 360, false, 0);56 ic.style.fillStyle = "#000000";57 oc.style.strokeStyle = '#000000';58 f.addPrimitive(ic);59 //CONNECTION POINTS60 CONNECTOR_MANAGER.connectionPointCreate(f.id, new Point(x, y), ConnectionPoint.TYPE_FIGURE);61 CONNECTOR_MANAGER.connectionPointCreate(f.id, new Point(x - outerCircleRadius, y), ConnectionPoint.TYPE_FIGURE);62 CONNECTOR_MANAGER.connectionPointCreate(f.id, new Point(x + outerCircleRadius, y), ConnectionPoint.TYPE_FIGURE);63 CONNECTOR_MANAGER.connectionPointCreate(f.id, new Point(x , y + outerCircleRadius), ConnectionPoint.TYPE_FIGURE);64 CONNECTOR_MANAGER.connectionPointCreate(f.id, new Point(x , y - outerCircleRadius), ConnectionPoint.TYPE_FIGURE);65 f.finalise();66 67 return f;68}69function figure_State(x,y)70{71 var f = new Figure("State");72 f.style.fillStyle = FigureDefaults.fillStyle;73 f.style.strokeStyle = FigureDefaults.strokeStyle;74 f.style.lineWidth = 2;75 f.properties.push(new BuilderProperty('Text', 'primitives.1.str', BuilderProperty.TYPE_TEXT));76// f.properties.push(new BuilderProperty(BuilderProperty.SEPARATOR));77 f.properties.push(new BuilderProperty('URL', 'url', BuilderProperty.TYPE_URL));78 79 var p = new Path();80 var hShrinker = 10;81 var vShrinker = 6;82 var l1 = new Line(new Point(x + hShrinker, y + vShrinker),83 new Point(x + FigureDefaults.segmentSize - hShrinker, y + vShrinker));84 var c1 = new QuadCurve(new Point(x + FigureDefaults.segmentSize - hShrinker, y + vShrinker),85 new Point(x + FigureDefaults.segmentSize - hShrinker + FigureDefaults.corner*(FigureDefaults.cornerRoundness/10), y + FigureDefaults.corner/FigureDefaults.cornerRoundness + vShrinker),86 new Point(x + FigureDefaults.segmentSize - hShrinker + FigureDefaults.corner, y + FigureDefaults.corner + vShrinker))87 var l2 = new Line(new Point(x + FigureDefaults.segmentSize - hShrinker + FigureDefaults.corner, y + FigureDefaults.corner + vShrinker),88 new Point(x + FigureDefaults.segmentSize - hShrinker + FigureDefaults.corner, y + FigureDefaults.corner + FigureDefaults.segmentShortSize - vShrinker));89 var c2 = new QuadCurve(new Point(x + FigureDefaults.segmentSize - hShrinker + FigureDefaults.corner, y + FigureDefaults.corner + FigureDefaults.segmentShortSize - vShrinker),90 new Point(x + FigureDefaults.segmentSize - hShrinker + FigureDefaults.corner*(FigureDefaults.cornerRoundness/10), y + FigureDefaults.corner + FigureDefaults.segmentShortSize - vShrinker + FigureDefaults.corner*(FigureDefaults.cornerRoundness/10)),91 new Point(x + FigureDefaults.segmentSize - hShrinker, y + FigureDefaults.corner + FigureDefaults.segmentShortSize - vShrinker + FigureDefaults.corner))92 var l3 = new Line(new Point(x + FigureDefaults.segmentSize - hShrinker, y + FigureDefaults.corner + FigureDefaults.segmentShortSize - vShrinker + FigureDefaults.corner),93 new Point(x + hShrinker, y + FigureDefaults.corner + FigureDefaults.segmentShortSize - vShrinker + FigureDefaults.corner));94 var c3 = new QuadCurve(95 new Point(x + hShrinker, y + FigureDefaults.corner + FigureDefaults.segmentShortSize - vShrinker + FigureDefaults.corner),96 new Point(x + hShrinker - FigureDefaults.corner*(FigureDefaults.cornerRoundness/10), y + FigureDefaults.corner + FigureDefaults.segmentShortSize - vShrinker + FigureDefaults.corner*(FigureDefaults.cornerRoundness/10)),97 new Point(x + hShrinker - FigureDefaults.corner, y + FigureDefaults.corner + FigureDefaults.segmentShortSize - vShrinker))98 var l4 = new Line(new Point(x + hShrinker - FigureDefaults.corner, y + FigureDefaults.corner + FigureDefaults.segmentShortSize - vShrinker),99 new Point(x + hShrinker - FigureDefaults.corner, y + FigureDefaults.corner + vShrinker));100 var c4 = new QuadCurve(101 new Point(x + hShrinker - FigureDefaults.corner, y + FigureDefaults.corner + vShrinker),102 new Point(x + hShrinker - FigureDefaults.corner*(FigureDefaults.cornerRoundness/10), y + vShrinker),103 new Point(x + hShrinker, y + vShrinker))104 p.addPrimitive(l1);105 p.addPrimitive(c1);106 p.addPrimitive(l2);107 p.addPrimitive(c2);108 p.addPrimitive(l3);109 p.addPrimitive(c3);110 p.addPrimitive(l4);111 p.addPrimitive(c4);112 f.addPrimitive(p);113 var t2 = new Text(FigureDefaults.textStr, x + FigureDefaults.segmentSize/2, y + FigureDefaults.segmentShortSize/2 + FigureDefaults.corner, FigureDefaults.textFont, FigureDefaults.textSize);114 t2.style.fillStyle = FigureDefaults.textColor;115 f.addPrimitive(t2);116 var wid = FigureDefaults.segmentSize - hShrinker + FigureDefaults.corner;117 var height = FigureDefaults.corner + FigureDefaults.segmentShortSize - vShrinker + FigureDefaults.corner;118 //top119 CONNECTOR_MANAGER.connectionPointCreate(f.id, new Point(x + wid / 2 - 10, y + vShrinker), ConnectionPoint.TYPE_FIGURE);120 CONNECTOR_MANAGER.connectionPointCreate(f.id, new Point(x + wid / 2, y + vShrinker), ConnectionPoint.TYPE_FIGURE);121 CONNECTOR_MANAGER.connectionPointCreate(f.id, new Point(x + wid / 2 + 10, y + vShrinker), ConnectionPoint.TYPE_FIGURE);122 //right123 CONNECTOR_MANAGER.connectionPointCreate(f.id, new Point(x + wid, y + height / 2 - 10), ConnectionPoint.TYPE_FIGURE);124 CONNECTOR_MANAGER.connectionPointCreate(f.id, new Point(x + wid, y + height / 2), ConnectionPoint.TYPE_FIGURE);125 CONNECTOR_MANAGER.connectionPointCreate(f.id, new Point(x + wid, y + height / 2 + 10), ConnectionPoint.TYPE_FIGURE);126 //bottom127 CONNECTOR_MANAGER.connectionPointCreate(f.id, new Point(x + wid / 2 - 10, y + height), ConnectionPoint.TYPE_FIGURE);128 CONNECTOR_MANAGER.connectionPointCreate(f.id, new Point(x + wid / 2, y + height), ConnectionPoint.TYPE_FIGURE);129 CONNECTOR_MANAGER.connectionPointCreate(f.id, new Point(x + wid / 2 + 10, y + height), ConnectionPoint.TYPE_FIGURE);130 //left131 CONNECTOR_MANAGER.connectionPointCreate(f.id, new Point(x, y + height / 2 - 10), ConnectionPoint.TYPE_FIGURE);132 CONNECTOR_MANAGER.connectionPointCreate(f.id, new Point(x, y + height / 2), ConnectionPoint.TYPE_FIGURE);133 CONNECTOR_MANAGER.connectionPointCreate(f.id, new Point(x, y + height / 2 + 10), ConnectionPoint.TYPE_FIGURE);134 f.finalise();135 return f;136}137function figure_Note(x,y)138{139 var figureWidth = 60;140 var foldWidth = 10;141 142 143 //figure144 var f = new Figure("Note");145 146 f.style.fillStyle = FigureDefaults.fillStyle;147 f.style.strokeStyle = FigureDefaults.strokeStyle;148 f.style.lineCap = f.style.STYLE_LINE_CAP_ROUND;149 f.style.lineJoin = f.style.STYLE_LINE_CAP_ROUND;150 151 //base note152 var r = new Polygon(); 153 r.addPoint(new Point(x - figureWidth/2, y - figureWidth/2));154 r.addPoint(new Point(x + figureWidth/2 - foldWidth, y - figureWidth/2));155 r.addPoint(new Point(x + figureWidth/2, y - figureWidth/2 + foldWidth));156 r.addPoint(new Point(x + figureWidth/2, y + figureWidth/2));157 r.addPoint(new Point(x - figureWidth/2, y + figureWidth/2));158 f.addPrimitive(r);159 160 //fold161 var fold = new Polygon(); 162 fold.style.lineCap = f.style.STYLE_LINE_CAP_ROUND;163 fold.style.lineJoin = f.style.STYLE_LINE_CAP_ROUND;164 fold.addPoint(new Point(x + figureWidth/2 - foldWidth, y - figureWidth/2));165 fold.addPoint(new Point(x + figureWidth/2 - foldWidth, y - figureWidth/2 + foldWidth));166 fold.addPoint(new Point(x + figureWidth/2, y - figureWidth/2 + foldWidth)); 167 f.addPrimitive(fold);168 //Text169 var t2 = new Text(FigureDefaults.textStr, x , y , FigureDefaults.textFont, FigureDefaults.textSize);170 t2.style.fillStyle = FigureDefaults.textColor;171 f.addPrimitive(t2);172 173 174 f.properties.push(new BuilderProperty('Text', 'primitives.2.str', BuilderProperty.TYPE_TEXT));175 CONNECTOR_MANAGER.connectionPointCreate(f.id, new Point(x + figureWidth/2 , y), ConnectionPoint.TYPE_FIGURE);176 CONNECTOR_MANAGER.connectionPointCreate(f.id, new Point(x - figureWidth/2 , y), ConnectionPoint.TYPE_FIGURE);177 CONNECTOR_MANAGER.connectionPointCreate(f.id, new Point(x, y - figureWidth/2 ), ConnectionPoint.TYPE_FIGURE);178 CONNECTOR_MANAGER.connectionPointCreate(f.id, new Point(x, y + figureWidth/2 ), ConnectionPoint.TYPE_FIGURE);179 f.finalise();180 return f;...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1const fc = require('fast-check');2const shrinker = require('fast-check-monorepo').shrinker;3const { Shrinkable } = require('fast-check/lib/types/Shrinkable');4const { shrinkArray } = require('fast-check/lib/arbitrary/_internals/helpers/ShrinkableArray');5const { shrinkString } = require('fast-check/lib/arbitrary/_internals/helpers/ShrinkableString');6const { shrinkMap } = require('fast-check/lib/arbitrary/_internals/helpers/ShrinkableMap');7const { shrinkSet } = require('fast-check/lib/arbitrary/_internals/helpers/ShrinkableSet');8const { shrinkObject } = require('fast-check/lib/arbitrary/_internals/helpers/ShrinkableObject');9const { shrinkBigInt } = require('fast-check/lib/arbitrary/_internals/helpers/ShrinkableBigInt');10const { shrinkDate } = require('fast-check/lib/arbitrary/_internals/helpers/ShrinkableDate');11const { shrinkNumber } = require('fast-check/lib/arbitrary/_internals/helpers/ShrinkableNumber');12const { shrinkBoolean } = require('fast-check/lib/arbitrary/_internals/helpers/ShrinkableBoolean');13const { shrinkConstant } = require('fast-check/lib/arbitrary/_internals/helpers/ShrinkableConstant');14const { shrinkFunction } = require('fast-check/lib/arbitrary/_internals/helpers/ShrinkableFunction');15const { shrinkConstantFrom } = require('fast-check/lib/arbitrary/_internals/helpers/ShrinkableConstantFrom');16const { shrinkOneof } = require('fast-check/lib/arbitrary/_internals/helpers/ShrinkableOneOf');17const { shrinkSubarray } = require('fast-check/lib/arbitrary/_internals/helpers/ShrinkableSubarray');18const { shrinkSubarrayBy } = require('fast-check/lib/arbitrary/_internals/helpers/ShrinkableSubarrayBy');19const { shrinkTuple } = require('fast-check/lib/arbitrary/_internals/helpers/ShrinkableTuple');20const { shrinkObjectMap } = require('fast-check/lib/arbitrary/_internals/helpers/ShrinkableObjectMap');21const { shrinkObjectSet } = require('fast-check/lib/arbitrary/_internals/helpers/ShrinkableObjectSet');22const { shrinkObjectMapBy } = require('fast-check/lib/arbitrary/_internals/helpers/ShrinkableObjectMapBy');23const { shrinkObjectSetBy } = require('fast-check/lib/arbitrary/_internals/helpers/ShrinkableObjectSetBy');

Full Screen

Using AI Code Generation

copy

Full Screen

1import {shrinker} from 'fast-check-monorepo';2const shrunk = shrinker.shrink(10, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);3console.log(shrunk);4{5 "scripts": {6 },7 "dependencies": {8 }9}

Full Screen

Using AI Code Generation

copy

Full Screen

1const { shrinker } = require('fast-check-monorepo');2const shrinker = (values) => {3 return value;4};5module.exports = shrinker;6const { shrinker } = require('fast-check-monorepo');7describe('shrinker', () => {8});

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run fast-check-monorepo automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful