# Copyright 2017 - The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Provides command 'check_compat'.""" from __future__ import print_function import argparse import logging from gsi_util.checkers import checker from gsi_util.commands.common import image_sources class CheckReporter(object): """Outputs the checker result with formatting.""" # The output will look like: # # check result 1 : pass # check result 2 : pass # # ------------------------------------ # Pass/Total : 2/2 _OUTPUT_FORMAT = '{:30}: {}' _ERR_MSE_FORMAT = ' {}' _OUTPUT_MAX_LEN = 36 _SUMMARY_NAME = 'Pass/Total' def __init__(self): """Whether to only output a summary result of all checks.""" self._only_summary = False def set_only_summary(self): """Only outputs summary result. When _only_summary is set, only shows the number of pass items over the number of total check items. """ self._only_summary = True @staticmethod def _get_result_str(result_ok): """Gets the result string 'pass' or 'fail' based on the check result.""" return 'pass' if result_ok else 'fail' def _output_result_item(self, result_item): """Outputs the result of a CheckResultItem(). Args: result_item: a namedtuple of check_result.CheckResultItem(). Returns: True if the test result passed. False otherwise. """ title, result_ok, stderr = result_item if not self._only_summary: result_str = self._get_result_str(result_ok) print(self._OUTPUT_FORMAT.format(title, result_str)) if stderr: print(self._ERR_MSE_FORMAT.format(stderr)) return result_ok def _output_summary(self, num_pass_items, num_all_items): """Outputs a summary of all checker tests. Args: num_pass_items: The number of passing tests. num_all_items: Total number of finished tests. """ print('-' * self._OUTPUT_MAX_LEN) summary_result_str = '{}/{}'.format(num_pass_items, num_all_items) print(self._OUTPUT_FORMAT.format(self._SUMMARY_NAME, summary_result_str)) def output(self, check_result_items): """The main public method to output a sequence of CheckResultItem()s.""" num_pass_items = 0 num_all_items = 0 for result_item in check_result_items: result_ok = self._output_result_item(result_item) if result_ok: num_pass_items += 1 num_all_items += 1 self._output_summary(num_pass_items, num_all_items) def _format_check_list(check_list): """Returns a string of check list item names.""" # The string is like: "'check_item1', 'check_item2', 'check_item3'". return ', '.join('{!r}'.format(x.check_item) for x in check_list) def do_list_checks(_): """Prints the all supported check items.""" print(_format_check_list(checker.Checker.get_all_check_list())) def do_check_compat(args): """The actual function to do 'gsi_util check_compat' command.""" logging.info('==== CHECK_COMPAT ====') logging.info(' system=%s vendor=%s', args.system, args.vendor) check_list = (checker.Checker.make_check_list(args.CHECK_ITEM) if args.CHECK_ITEM else checker.Checker.get_all_check_list()) logging.debug('Starting check list: %s', _format_check_list(check_list)) mounter = image_sources.create_composite_mounter_by_args(args) with mounter as file_accessor: the_checker = checker.Checker(file_accessor) check_result = the_checker.check(check_list) reporter = CheckReporter() if args.only_summary: reporter.set_only_summary() reporter.output(check_result) logging.info('==== DONE ====') _CHECK_COMPAT_DESC = """ 'check_compat' command checks compatibility between images. You must assign both image sources by SYSTEM and VENDOR. You could use command 'list_checks' to query all check items: $ ./gsi_util.py list_checks Here is an examples to check a system.img and a device are compatible: $ ./gsi_util.py check_compat --system system.img --vendor adb""" def setup_command_args(parser): """Sets up command 'list_checks' and 'check_compat'.""" # Command 'list_checks'. list_check_parser = parser.add_parser( 'list_checks', help='lists all possible check items. Run') list_check_parser.set_defaults(func=do_list_checks) # command 'check_compat' check_compat_parser = parser.add_parser( 'check_compat', help='checks compatibility between a system and a vendor', description=_CHECK_COMPAT_DESC, formatter_class=argparse.RawTextHelpFormatter) check_compat_parser.add_argument( '-s', '--only-summary', action='store_true', help='only output the summary result') image_sources.add_argument_group( check_compat_parser, required_images=['system', 'vendor']) check_compat_parser.add_argument( 'CHECK_ITEM', type=str, nargs='*', help=('the check item to be performed\n' 'select one from: {}\n'.format(_format_check_list( checker.Checker.get_all_check_list())) + 'if not given, it will check all')) check_compat_parser.set_defaults(func=do_check_compat)