common_args.py 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. # Copyright 2018 The Chromium Authors. All rights reserved.
  2. # Use of this source code is governed by a BSD-style license that can be
  3. # found in the LICENSE file.
  4. import argparse
  5. import importlib
  6. import logging
  7. import multiprocessing
  8. import os
  9. import sys
  10. from common import GetHostArchFromPlatform
  11. BUILTIN_TARGET_NAMES = ['qemu', 'device', 'fvdl']
  12. def _AddTargetSpecificationArgs(arg_parser):
  13. """Returns a parser that handles the target type used for the test run."""
  14. device_args = arg_parser.add_argument_group(
  15. 'target',
  16. 'Arguments specifying the Fuchsia target type. To see a list of '
  17. 'arguments available for a specific target type, specify the desired '
  18. 'target to use and add the --help flag.')
  19. device_args.add_argument('--target-cpu',
  20. default=GetHostArchFromPlatform(),
  21. help='GN target_cpu setting for the build. Defaults '
  22. 'to the same architecture as host cpu.')
  23. device_args.add_argument('--device',
  24. default=None,
  25. choices=BUILTIN_TARGET_NAMES + ['custom'],
  26. help='Choose to run on fvdl|qemu|device. '
  27. 'By default, Fuchsia will run on Fvdl on x64 '
  28. 'hosts and QEMU on arm64 hosts. Alternatively, '
  29. 'setting to custom will require specifying the '
  30. 'subclass of Target class used via the '
  31. '--custom-device-target flag.')
  32. device_args.add_argument('-d',
  33. action='store_const',
  34. dest='device',
  35. const='device',
  36. help='Run on device instead of emulator.')
  37. device_args.add_argument('--custom-device-target',
  38. default=None,
  39. help='Specify path to file that contains the '
  40. 'subclass of Target that will be used. Only '
  41. 'needed if device specific operations is '
  42. 'required.')
  43. def _GetPathToBuiltinTarget(target_name):
  44. return '%s_target' % target_name
  45. def _LoadTargetClass(target_path):
  46. try:
  47. loaded_target = importlib.import_module(target_path)
  48. except ImportError:
  49. logging.error(
  50. 'Cannot import from %s. Make sure that --custom-device-target '
  51. 'is pointing to a file containing a target '
  52. 'module.' % target_path)
  53. raise
  54. return loaded_target.GetTargetType()
  55. def _GetDefaultEmulatedCpuCoreCount():
  56. # Revise the processor count on arm64, the trybots on arm64 are in
  57. # dockers and cannot use all processors.
  58. # For x64, fvdl always assumes hyperthreading is supported by intel
  59. # processors, but the cpu_count returns the number regarding if the core
  60. # is a physical one or a hyperthreading one, so the number should be
  61. # divided by 2 to avoid creating more threads than the processor
  62. # supports.
  63. if GetHostArchFromPlatform() == 'x64':
  64. return max(int(multiprocessing.cpu_count() / 2) - 1, 4)
  65. return 4
  66. def AddCommonArgs(arg_parser):
  67. """Adds command line arguments to |arg_parser| for options which are shared
  68. across test and executable target types.
  69. Args:
  70. arg_parser: an ArgumentParser object."""
  71. common_args = arg_parser.add_argument_group('common', 'Common arguments')
  72. common_args.add_argument('--logs-dir', help='Directory to write logs to.')
  73. common_args.add_argument('--verbose',
  74. '-v',
  75. default=False,
  76. action='store_true',
  77. help='Enable debug-level logging.')
  78. common_args.add_argument(
  79. '--out-dir',
  80. type=os.path.realpath,
  81. help=('Path to the directory in which build files are located. '
  82. 'Defaults to current directory.'))
  83. common_args.add_argument('--fuchsia-out-dir',
  84. default=None,
  85. help='Path to a Fuchsia build output directory. '
  86. 'Setting the GN arg '
  87. '"default_fuchsia_build_dir_for_installation" '
  88. 'will cause it to be passed here.')
  89. package_args = arg_parser.add_argument_group('package', 'Fuchsia Packages')
  90. package_args.add_argument(
  91. '--package',
  92. action='append',
  93. help='Paths of the packages to install, including '
  94. 'all dependencies.')
  95. package_args.add_argument(
  96. '--package-name',
  97. help='Name of the package to execute, defined in ' + 'package metadata.')
  98. package_args.add_argument('--component-version',
  99. help='Component version of the package to execute',
  100. default='1')
  101. emu_args = arg_parser.add_argument_group('emu', 'General emulator arguments')
  102. emu_args.add_argument('--cpu-cores',
  103. type=int,
  104. default=_GetDefaultEmulatedCpuCoreCount(),
  105. help='Sets the number of CPU cores to provide.')
  106. emu_args.add_argument('--ram-size-mb',
  107. type=int,
  108. default=8192,
  109. help='Sets the emulated RAM size (MB).'),
  110. emu_args.add_argument('--allow-no-kvm',
  111. action='store_false',
  112. dest='require_kvm',
  113. default=True,
  114. help='Do not require KVM acceleration for '
  115. 'emulators.')
  116. # Register the arguments for all known target types and the optional custom
  117. # target type (specified on the commandline).
  118. def AddTargetSpecificArgs(arg_parser):
  119. # Parse the minimal set of arguments to determine if custom targets need to
  120. # be loaded so that their arguments can be registered.
  121. target_spec_parser = argparse.ArgumentParser(add_help=False)
  122. _AddTargetSpecificationArgs(target_spec_parser)
  123. target_spec_args, _ = target_spec_parser.parse_known_args()
  124. _AddTargetSpecificationArgs(arg_parser)
  125. for target in BUILTIN_TARGET_NAMES:
  126. _LoadTargetClass(_GetPathToBuiltinTarget(target)).RegisterArgs(arg_parser)
  127. if target_spec_args.custom_device_target:
  128. _LoadTargetClass(
  129. target_spec_args.custom_device_target).RegisterArgs(arg_parser)
  130. def ConfigureLogging(args):
  131. """Configures the logging level based on command line |args|."""
  132. logging.basicConfig(level=(logging.DEBUG if args.verbose else logging.INFO),
  133. format='%(asctime)s:%(levelname)s:%(name)s:%(message)s')
  134. # The test server spawner is too noisy with INFO level logging, so tweak
  135. # its verbosity a bit by adjusting its logging level.
  136. logging.getLogger('chrome_test_server_spawner').setLevel(
  137. logging.DEBUG if args.verbose else logging.WARN)
  138. # Verbose SCP output can be useful at times but oftentimes is just too noisy.
  139. # Only enable it if -vv is passed.
  140. logging.getLogger('ssh').setLevel(
  141. logging.DEBUG if args.verbose else logging.WARN)
  142. def InitializeTargetArgs():
  143. """Set args for all targets to default values. This is used by test scripts
  144. that have their own parser but still uses the target classes."""
  145. parser = argparse.ArgumentParser()
  146. AddCommonArgs(parser)
  147. AddTargetSpecificArgs(parser)
  148. return parser.parse_args([])
  149. def GetDeploymentTargetForArgs(args):
  150. """Constructs a deployment target object using command line arguments.
  151. If needed, an additional_args dict can be used to supplement the
  152. command line arguments."""
  153. if args.device == 'custom':
  154. return _LoadTargetClass(args.custom_device_target).CreateFromArgs(args)
  155. if args.device:
  156. device = args.device
  157. else:
  158. device = 'fvdl' if args.target_cpu == 'x64' else 'qemu'
  159. return _LoadTargetClass(_GetPathToBuiltinTarget(device)).CreateFromArgs(args)