xref: /aosp_15_r20/external/autotest/cli/label.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
1*9c5db199SXin Li#
2*9c5db199SXin Li# Copyright 2008 Google Inc. All Rights Reserved.
3*9c5db199SXin Li
4*9c5db199SXin Li"""
5*9c5db199SXin LiThe label module contains the objects and methods used to
6*9c5db199SXin Limanage labels in Autotest.
7*9c5db199SXin Li
8*9c5db199SXin LiThe valid actions are:
9*9c5db199SXin Liadd:     adds label(s), or hosts to an LABEL
10*9c5db199SXin Liremove:      deletes label(s), or hosts from an LABEL
11*9c5db199SXin Lilist:    lists label(s)
12*9c5db199SXin Li
13*9c5db199SXin LiThe common options are:
14*9c5db199SXin Li--blist / -B: file containing a list of LABELs
15*9c5db199SXin Li
16*9c5db199SXin LiSee topic_common.py for a High Level Design and Algorithm.
17*9c5db199SXin Li"""
18*9c5db199SXin Li
19*9c5db199SXin Liimport sys
20*9c5db199SXin Lifrom autotest_lib.cli import topic_common, action_common
21*9c5db199SXin Li
22*9c5db199SXin Li
23*9c5db199SXin Liclass label(topic_common.atest):
24*9c5db199SXin Li    """Label class
25*9c5db199SXin Li    atest label [create|delete|list|add|remove] <options>"""
26*9c5db199SXin Li    usage_action = '[create|delete|list|add|remove]'
27*9c5db199SXin Li    topic = msg_topic = 'label'
28*9c5db199SXin Li    msg_items = '<labels>'
29*9c5db199SXin Li
30*9c5db199SXin Li    def __init__(self):
31*9c5db199SXin Li        """Add to the parser the options common to all the
32*9c5db199SXin Li        label actions"""
33*9c5db199SXin Li        super(label, self).__init__()
34*9c5db199SXin Li
35*9c5db199SXin Li        self.parser.add_option('-B', '--blist',
36*9c5db199SXin Li                               help='File listing the labels',
37*9c5db199SXin Li                               type='string',
38*9c5db199SXin Li                               default=None,
39*9c5db199SXin Li                               metavar='LABEL_FLIST')
40*9c5db199SXin Li
41*9c5db199SXin Li        self.topic_parse_info = topic_common.item_parse_info(
42*9c5db199SXin Li            attribute_name='labels',
43*9c5db199SXin Li            filename_option='blist',
44*9c5db199SXin Li            use_leftover=True)
45*9c5db199SXin Li
46*9c5db199SXin Li
47*9c5db199SXin Li    def get_items(self):
48*9c5db199SXin Li        return self.labels
49*9c5db199SXin Li
50*9c5db199SXin Li
51*9c5db199SXin Liclass label_help(label):
52*9c5db199SXin Li    """Just here to get the atest logic working.
53*9c5db199SXin Li    Usage is set by its parent"""
54*9c5db199SXin Li    pass
55*9c5db199SXin Li
56*9c5db199SXin Li
57*9c5db199SXin Liclass label_list(action_common.atest_list, label):
58*9c5db199SXin Li    """atest label list [--platform] [--all]
59*9c5db199SXin Li    [--valid-only] [--machine <machine>]
60*9c5db199SXin Li    [--blist <file>] [<labels>]"""
61*9c5db199SXin Li    def __init__(self):
62*9c5db199SXin Li        super(label_list, self).__init__()
63*9c5db199SXin Li
64*9c5db199SXin Li        self.parser.add_option('-t', '--platform-only',
65*9c5db199SXin Li                               help='Display only platform labels',
66*9c5db199SXin Li                               action='store_true')
67*9c5db199SXin Li
68*9c5db199SXin Li        self.parser.add_option('-d', '--valid-only',
69*9c5db199SXin Li                               help='Display only valid labels',
70*9c5db199SXin Li                               action='store_true')
71*9c5db199SXin Li
72*9c5db199SXin Li        self.parser.add_option('-a', '--all',
73*9c5db199SXin Li                               help=('Display both normal & '
74*9c5db199SXin Li                                     'platform labels'),
75*9c5db199SXin Li                               action='store_true')
76*9c5db199SXin Li
77*9c5db199SXin Li        self.parser.add_option('-m', '--machine',
78*9c5db199SXin Li                               help='List LABELs of MACHINE',
79*9c5db199SXin Li                               type='string',
80*9c5db199SXin Li                               metavar='MACHINE')
81*9c5db199SXin Li
82*9c5db199SXin Li
83*9c5db199SXin Li    def parse(self):
84*9c5db199SXin Li        host_info = topic_common.item_parse_info(attribute_name='hosts',
85*9c5db199SXin Li                                                 inline_option='machine')
86*9c5db199SXin Li        (options, leftover) = super(label_list, self).parse([host_info])
87*9c5db199SXin Li
88*9c5db199SXin Li        exclusives = [options.all, options.platform_only]
89*9c5db199SXin Li        if exclusives.count(True) > 1:
90*9c5db199SXin Li            self.invalid_syntax('Only specify one of --all,'
91*9c5db199SXin Li                                '--platform')
92*9c5db199SXin Li
93*9c5db199SXin Li        if len(self.hosts) > 1:
94*9c5db199SXin Li            self.invalid_syntax(('Only one machine name allowed. '
95*9c5db199SXin Li                                '''Use '%s host list %s' '''
96*9c5db199SXin Li                                 'instead.') %
97*9c5db199SXin Li                                (sys.argv[0], ','.join(self.hosts)))
98*9c5db199SXin Li        self.all = options.all
99*9c5db199SXin Li        self.platform_only = options.platform_only
100*9c5db199SXin Li        self.valid_only = options.valid_only
101*9c5db199SXin Li        return (options, leftover)
102*9c5db199SXin Li
103*9c5db199SXin Li
104*9c5db199SXin Li    def execute(self):
105*9c5db199SXin Li        filters = {}
106*9c5db199SXin Li        check_results = {}
107*9c5db199SXin Li        if self.hosts:
108*9c5db199SXin Li            filters['host__hostname__in'] = self.hosts
109*9c5db199SXin Li            check_results['host__hostname__in'] = None
110*9c5db199SXin Li
111*9c5db199SXin Li        if self.labels:
112*9c5db199SXin Li            filters['name__in'] = self.labels
113*9c5db199SXin Li            check_results['name__in'] = 'name'
114*9c5db199SXin Li
115*9c5db199SXin Li        return super(label_list, self).execute(op='get_labels',
116*9c5db199SXin Li                                               filters=filters,
117*9c5db199SXin Li                                               check_results=check_results)
118*9c5db199SXin Li
119*9c5db199SXin Li
120*9c5db199SXin Li    def output(self, results):
121*9c5db199SXin Li        if self.valid_only:
122*9c5db199SXin Li            results = [label for label in results
123*9c5db199SXin Li                       if not label['invalid']]
124*9c5db199SXin Li
125*9c5db199SXin Li        if self.platform_only:
126*9c5db199SXin Li            results = [label for label in results
127*9c5db199SXin Li                       if label['platform']]
128*9c5db199SXin Li            keys = ['name', 'invalid']
129*9c5db199SXin Li        elif not self.all:
130*9c5db199SXin Li            results = [label for label in results
131*9c5db199SXin Li                       if not label['platform']]
132*9c5db199SXin Li            keys = ['name', 'only_if_needed', 'invalid']
133*9c5db199SXin Li        else:
134*9c5db199SXin Li            keys = ['name', 'platform', 'only_if_needed', 'invalid']
135*9c5db199SXin Li
136*9c5db199SXin Li        super(label_list, self).output(results, keys)
137*9c5db199SXin Li
138*9c5db199SXin Li
139*9c5db199SXin Liclass label_create(action_common.atest_create, label):
140*9c5db199SXin Li    """atest label create <labels>|--blist <file> --platform"""
141*9c5db199SXin Li    def __init__(self):
142*9c5db199SXin Li        super(label_create, self).__init__()
143*9c5db199SXin Li        self.parser.add_option('-t', '--platform',
144*9c5db199SXin Li                               help='To create this label as a platform',
145*9c5db199SXin Li                               default=False,
146*9c5db199SXin Li                               action='store_true')
147*9c5db199SXin Li        self.parser.add_option('-o', '--only_if_needed',
148*9c5db199SXin Li                               help='To mark the label as "only use if needed',
149*9c5db199SXin Li                               default=False,
150*9c5db199SXin Li                               action='store_true')
151*9c5db199SXin Li
152*9c5db199SXin Li
153*9c5db199SXin Li    def parse(self):
154*9c5db199SXin Li        (options, leftover) = super(label_create,
155*9c5db199SXin Li                                    self).parse(req_items='labels')
156*9c5db199SXin Li        self.data_item_key = 'name'
157*9c5db199SXin Li        self.data['platform'] = options.platform
158*9c5db199SXin Li        self.data['only_if_needed'] = options.only_if_needed
159*9c5db199SXin Li        return (options, leftover)
160*9c5db199SXin Li
161*9c5db199SXin Li
162*9c5db199SXin Liclass label_delete(action_common.atest_delete, label):
163*9c5db199SXin Li    """atest label delete <labels>|--blist <file>"""
164*9c5db199SXin Li    pass
165*9c5db199SXin Li
166*9c5db199SXin Li
167*9c5db199SXin Li
168*9c5db199SXin Liclass label_add_or_remove(label):
169*9c5db199SXin Li    """Parent for `atest label` add and `label remove`"""
170*9c5db199SXin Li    def __init__(self):
171*9c5db199SXin Li        super(label_add_or_remove, self).__init__()
172*9c5db199SXin Li        lower_words = tuple(word.lower() for word in self.usage_words)
173*9c5db199SXin Li        self.parser.add_option('-m', '--machine',
174*9c5db199SXin Li                               help=('%s MACHINE(s) %s the LABEL' %
175*9c5db199SXin Li                                     self.usage_words),
176*9c5db199SXin Li                               type='string',
177*9c5db199SXin Li                               metavar='MACHINE')
178*9c5db199SXin Li        self.parser.add_option('-M', '--mlist',
179*9c5db199SXin Li                               help='File containing machines to %s %s '
180*9c5db199SXin Li                               'the LABEL' % lower_words,
181*9c5db199SXin Li                               type='string',
182*9c5db199SXin Li                               metavar='MACHINE_FLIST')
183*9c5db199SXin Li
184*9c5db199SXin Li
185*9c5db199SXin Li    def parse(self):
186*9c5db199SXin Li        host_info = topic_common.item_parse_info(attribute_name='hosts',
187*9c5db199SXin Li                                                 inline_option='machine',
188*9c5db199SXin Li                                                 filename_option='mlist')
189*9c5db199SXin Li        (options, leftover) = super(label_add_or_remove,
190*9c5db199SXin Li                                    self).parse([host_info],
191*9c5db199SXin Li                                                req_items='labels')
192*9c5db199SXin Li
193*9c5db199SXin Li        if not getattr(self, 'hosts', None):
194*9c5db199SXin Li            self.invalid_syntax('%s %s requires at least one host' %
195*9c5db199SXin Li                                (self.msg_topic,
196*9c5db199SXin Li                                 self.usage_action))
197*9c5db199SXin Li        return (options, leftover)
198*9c5db199SXin Li
199*9c5db199SXin Li
200*9c5db199SXin Liclass label_add(action_common.atest_add, label_add_or_remove):
201*9c5db199SXin Li    """atest label add <labels>|--blist <file>
202*9c5db199SXin Li    --platform [--machine <machine>] [--mlist <file>]"""
203*9c5db199SXin Li    pass
204*9c5db199SXin Li
205*9c5db199SXin Li
206*9c5db199SXin Liclass label_remove(action_common.atest_remove, label_add_or_remove):
207*9c5db199SXin Li    """atest label remove <labels>|--blist <file>
208*9c5db199SXin Li     [--machine <machine>] [--mlist <file>]"""
209*9c5db199SXin Li    pass
210