[fuchsia] Refactor the femu recipe This reduces the nesting level of each step and makes it simpler to edit the recipe. Change-Id: I04c672b5a88447e4ef44247ec26f35f3ed6e12a2 Reviewed-on: https://flutter-review.googlesource.com/c/recipes/+/40480 Reviewed-by: Zach Anderson <zra@google.com> Reviewed-by: Anthony Fandrianto <atyfto@google.com> Commit-Queue: Sébastien Marchand <sebmarchand@google.com>
diff --git a/recipes/engine/femu_test.py b/recipes/engine/femu_test.py index 0bef8e6..1963256 100644 --- a/recipes/engine/femu_test.py +++ b/recipes/engine/femu_test.py
@@ -116,7 +116,6 @@ return manifest_data['id'] -# TODO(yuanzhi) Move this logic to vdl recipe_module def CasRoot(api): """Create a CAS containing flutter test components and fuchsia runfiles for FEMU.""" sdk_version = GetFuchsiaBuildId(api) @@ -179,6 +178,108 @@ return test_suites, root_dir, cas_hash +def RunTestSuiteOnFfxEmuImpl(api, suite, ffx, arch): + # Launch the emulator + if arch == 'arm64': + launch_step = api.step( + 'launch arm64 emulator with QEMU engine', [ + ffx, '-v', 'emu', 'start', 'terminal.qemu-arm64', '--engine', + 'qemu', '--headless', '--startup-timeout', '360' + ] + ) + else: + launch_step = api.step( + 'launch x64 emulator', + [ffx, '-v', 'emu', 'start', 'terminal.qemu-x64', '--headless'] + ) + + # Output information for current emulator + # Contains version, product information, etc. + api.step('list all targets in the collection', [ffx, 'target', 'list']) + api.step('retrieve femu information', [ffx, 'target', 'show']) + ffx_repo_list_json = api.step( + 'get repository information', + [ffx, '--machine', 'json', 'repository', 'list'], + stdout=api.json.output() + ).stdout + ffx_repo_path = ffx_repo_list_json[0]['spec']['path'] + + for package in suite['package_basenames']: + api.step( + 'ffx repository publish {}'.format(package), [ + ffx, 'repository', 'publish', ffx_repo_path, '--package-archive', + package + ] + ) + + api.step('start FFX repository', [ffx, 'repository', 'server', 'start']) + api.step( + 'Register repository', + [ffx, 'target', 'repository', 'register', '--alias', 'fuchsia.com'] + ) + + # Run the actual test + # Test command is guaranteed to be well-formed + # TODO(http://fxb/121613): Emulator instances are not cleaned up + # when tests fail. Added a clean up step before tests start to + # stop all running emulators. + with api.step.defer_results(): + api.retry.step('run ffx test', [ffx] + suite['test_command'].split(' ')) + + +def ReadLogFiles(api): + """ + Read the log files generated by ffx and by the Fuchsia emulator and present + them in the test result page. + """ + with api.step.nest('logs') as dump_step: + dump_step.presentation.logs['ffx_daemon_log'] = api.file.read_text( + 'read ffx daemon log', + api.path.join( + api.context.env.get('FFX_ISOLATE_DIR'), 'cache', 'logs', + 'ffx.daemon.log' + ) + ) + dump_step.presentation.logs['ffx_log'] = api.file.read_text( + 'read ffx log', + api.path.join( + api.context.env.get('FFX_ISOLATE_DIR'), 'cache', 'logs', 'ffx.log' + ) + ) + dump_step.presentation.logs['emulator_log'] = api.file.read_text( + 'read ffx daemon log', + api.path.join( + api.context.env.get('FFX_ISOLATE_DIR'), 'data', 'emu', 'instances', + 'fuchsia-emulator', 'emulator.log' + ) + ) + dump_step.presentation.logs['emulator_serial_log'] = api.file.read_text( + 'read ffx daemon log', + api.path.join( + api.context.env.get('FFX_ISOLATE_DIR'), 'data', 'emu', 'instances', + 'fuchsia-emulator', 'emulator.log.serial' + ) + ) + + +def CleanupAfterTestRun(api, ffx, arch): + ReadLogFiles(api) + # Cleans up running processes to prevent clashing with future test runs + api.step('stop FFX repository', [ffx, 'repository', 'server', 'stop']) + api.step('stop {} emulator'.format(arch), [ffx, '-v', 'emu', 'stop', '--all']) + + +def RunTestSuiteOnFfxEmu(api, suite, ffx, arch): + """ + Run the Fuchsia test suite |suite| on the Fuchsia emulator, using ffx. + """ + with api.step.nest('run %s' % suite['name']): + try: + RunTestSuiteOnFfxEmuImpl(api, suite, ffx, arch) + finally: + CleanupAfterTestRun(api, ffx, arch) + + def TestFuchsiaFEMU(api): """Run flutter tests on FEMU.""" test_suites, root_dir, cas_hash = CasRoot(api) @@ -243,101 +344,7 @@ with api.context(cwd=root_dir), api.step.nest('run FEMU test on %s' % arch): for suite in test_suites: - with api.step.nest('run %s' % suite['name']): - try: - # Launch the emulator - if arch == 'arm64': - launch_step = api.step( - 'launch arm64 emulator with QEMU engine', [ - ffx, '-v', 'emu', 'start', 'terminal.qemu-arm64', - '--engine', 'qemu', '--headless', '--startup-timeout', '360' - ] - ) - else: - launch_step = api.step( - 'launch x64 emulator', - [ffx, '-v', 'emu', 'start', 'terminal.qemu-x64', '--headless'] - ) - - # Output information for current emulator - # Contains version, product information, etc. - api.step( - 'list all targets in the collection', [ffx, 'target', 'list'] - ) - api.step('retrieve femu information', [ffx, 'target', 'show']) - ffx_repo_list_json = api.step( - 'get repository information', - [ffx, '--machine', 'json', 'repository', 'list'], - stdout=api.json.output() - ).stdout - ffx_repo_path = ffx_repo_list_json[0]['spec']['path'] - - for package in suite['package_basenames']: - api.step( - 'ffx repository publish {}'.format(package), [ - ffx, 'repository', 'publish', ffx_repo_path, - '--package-archive', package - ] - ) - - api.step( - 'start FFX repository', [ffx, 'repository', 'server', 'start'] - ) - api.step( - 'Register repository', [ - ffx, 'target', 'repository', 'register', '--alias', - 'fuchsia.com' - ] - ) - - # Run the actual test - # Test command is guaranteed to be well-formed - # TODO(http://fxb/121613): Emulator instances are not cleaned up - # when tests fail. Added a clean up step before tests start to - # stop all running emulators. - with api.step.defer_results(): - api.retry.step( - 'run ffx test', [ffx] + suite['test_command'].split(' ') - ) - - finally: - with api.step.nest('logs') as dump_step: - dump_step.presentation.logs['ffx_daemon_log'] = api.file.read_text( - 'read ffx daemon log', - api.path.join( - api.context.env.get('FFX_ISOLATE_DIR'), 'cache', 'logs', - 'ffx.daemon.log' - ) - ) - dump_step.presentation.logs['ffx_log'] = api.file.read_text( - 'read ffx log', - api.path.join( - api.context.env.get('FFX_ISOLATE_DIR'), 'cache', 'logs', - 'ffx.log' - ) - ) - dump_step.presentation.logs['emulator_log'] = api.file.read_text( - 'read ffx daemon log', - api.path.join( - api.context.env.get('FFX_ISOLATE_DIR'), 'data', 'emu', - 'instances', 'fuchsia-emulator', 'emulator.log' - ) - ) - dump_step.presentation.logs['emulator_serial_log'] = api.file.read_text( - 'read ffx daemon log', - api.path.join( - api.context.env.get('FFX_ISOLATE_DIR'), 'data', 'emu', - 'instances', 'fuchsia-emulator', 'emulator.log.serial' - ) - ) - - # Cleans up running processes to prevent clashing with future test runs - api.step( - 'stop FFX repository', [ffx, 'repository', 'server', 'stop'] - ) - api.step( - 'stop %s emulator' % arch, [ffx, '-v', 'emu', 'stop', '--all'] - ) + RunTestSuiteOnFfxEmu(api, suite, ffx, arch) def BuildFuchsia(api):