• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2017 - The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14"""Provides command 'check_compat'."""
15
16from __future__ import print_function
17
18import argparse
19import logging
20
21from gsi_util.checkers import checker
22from gsi_util.commands.common import image_sources
23
24
25class CheckReporter(object):
26  """Outputs the checker result with formatting."""
27
28  # The output will look like:
29  #
30  # check result 1                : pass
31  # check result 2                : pass
32  #
33  # ------------------------------------
34  # Pass/Total                    : 2/2
35  _OUTPUT_FORMAT = '{:30}: {}'
36  _ERR_MSE_FORMAT = '    {}'
37  _OUTPUT_MAX_LEN = 36
38  _SUMMARY_NAME = 'Pass/Total'
39
40  def __init__(self):
41    """Whether to only output a summary result of all checks."""
42    self._only_summary = False
43
44  def set_only_summary(self):
45    """Only outputs summary result.
46
47    When _only_summary is set, only shows the number of pass items over
48    the number of total check items.
49    """
50    self._only_summary = True
51
52  @staticmethod
53  def _get_result_str(result_ok):
54    """Gets the result string 'pass' or 'fail' based on the check result."""
55    return 'pass' if result_ok else 'fail'
56
57  def _output_result_item(self, result_item):
58    """Outputs the result of a CheckResultItem().
59
60    Args:
61      result_item: a namedtuple of check_result.CheckResultItem().
62
63    Returns:
64      True if the test result passed. False otherwise.
65    """
66    title, result_ok, stderr = result_item
67
68    if not self._only_summary:
69      result_str = self._get_result_str(result_ok)
70      print(self._OUTPUT_FORMAT.format(title, result_str))
71      if stderr:
72        print(self._ERR_MSE_FORMAT.format(stderr))
73
74    return result_ok
75
76  def _output_summary(self, num_pass_items, num_all_items):
77    """Outputs a summary of all checker tests.
78
79    Args:
80      num_pass_items: The number of passing tests.
81      num_all_items: Total number of finished tests.
82    """
83    print('-' * self._OUTPUT_MAX_LEN)
84    summary_result_str = '{}/{}'.format(num_pass_items, num_all_items)
85    print(self._OUTPUT_FORMAT.format(self._SUMMARY_NAME, summary_result_str))
86
87  def output(self, check_result_items):
88    """The main public method to output a sequence of CheckResultItem()s."""
89    num_pass_items = 0
90    num_all_items = 0
91    for result_item in check_result_items:
92      result_ok = self._output_result_item(result_item)
93      if result_ok:
94        num_pass_items += 1
95      num_all_items += 1
96    self._output_summary(num_pass_items, num_all_items)
97
98
99def _format_check_list(check_list):
100  """Returns a string of check list item names."""
101  # The string is like: "'check_item1', 'check_item2', 'check_item3'".
102  return ', '.join('{!r}'.format(x.check_item) for x in check_list)
103
104
105def do_list_checks(_):
106  """Prints the all supported check items."""
107  print(_format_check_list(checker.Checker.get_all_check_list()))
108
109
110def do_check_compat(args):
111  """The actual function to do 'gsi_util check_compat' command."""
112  logging.info('==== CHECK_COMPAT ====')
113  logging.info('  system=%s vendor=%s', args.system, args.vendor)
114
115  check_list = (checker.Checker.make_check_list(args.CHECK_ITEM)
116                if args.CHECK_ITEM else checker.Checker.get_all_check_list())
117  logging.debug('Starting check list: %s', _format_check_list(check_list))
118  mounter = image_sources.create_composite_mounter_by_args(args)
119  with mounter as file_accessor:
120    the_checker = checker.Checker(file_accessor)
121    check_result = the_checker.check(check_list)
122
123  reporter = CheckReporter()
124  if args.only_summary:
125    reporter.set_only_summary()
126  reporter.output(check_result)
127
128  logging.info('==== DONE ====')
129
130
131_CHECK_COMPAT_DESC = """
132'check_compat' command checks compatibility between images.
133
134You must assign both image sources by SYSTEM and VENDOR.
135
136You could use command 'list_checks' to query all check items:
137
138    $ ./gsi_util.py list_checks
139
140Here is an examples to check a system.img and a device are compatible:
141
142    $ ./gsi_util.py check_compat --system system.img --vendor adb"""
143
144
145def setup_command_args(parser):
146  """Sets up command 'list_checks' and 'check_compat'."""
147
148  # Command 'list_checks'.
149  list_check_parser = parser.add_parser(
150      'list_checks', help='lists all possible check items. Run')
151  list_check_parser.set_defaults(func=do_list_checks)
152
153  # command 'check_compat'
154  check_compat_parser = parser.add_parser(
155      'check_compat',
156      help='checks compatibility between a system and a vendor',
157      description=_CHECK_COMPAT_DESC,
158      formatter_class=argparse.RawTextHelpFormatter)
159  check_compat_parser.add_argument(
160      '-s',
161      '--only-summary',
162      action='store_true',
163      help='only output the summary result')
164  image_sources.add_argument_group(
165      check_compat_parser,
166      required_images=['system', 'vendor'])
167  check_compat_parser.add_argument(
168      'CHECK_ITEM',
169      type=str,
170      nargs='*',
171      help=('the check item to be performed\n'
172            'select one from: {}\n'.format(_format_check_list(
173                checker.Checker.get_all_check_list())) +
174            'if not given, it will check all'))
175  check_compat_parser.set_defaults(func=do_check_compat)
176