• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (c) 2013 The Chromium OS 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
5import logging
6import subprocess
7
8from autotest_lib.client.common_lib import error
9from autotest_lib.client.common_lib import utils
10from autotest_lib.server import test
11from autotest_lib.server import frontend
12
13class hardware_StorageQualCheckSetup(test.test):
14    """
15    Verifies the moblab and DUT setup for storage qual
16    A correct setup consists of
17        At least one pool (the default "no pool" counts as a pool)
18        Each of the labels [retention, trim, suspend] is applied to exactly
19            one DUT in the pool.
20        No duplication of the labels, all labels are applied exactly once
21            per pool
22
23    The test will verify this set up. If any pool isn't configured correctly,
24    the test will fail. To pass the test, every DUT must be a part of a
25    correctly configured pool. This gives us confidence that the partners
26    will have a correct setup for storage qual no matter which pool they select
27    on RunSuite page.
28    """
29
30    version = 1
31
32    REQUIRED_LABELS = ['retention', 'trim', 'suspend']
33
34    def _group_hosts_into_pools(self, hosts):
35        pools = {}
36        for host in hosts:
37            labels = [label.name for label in host.get_labels()]
38
39            pool_name = 'none'
40            for label in labels:
41                if 'pool:' in label:
42                    pool_name = label.replace('pool:', '')
43
44            if pool_name not in pools:
45                pools[pool_name] = []
46
47            pools[pool_name].append({
48                'host': host.hostname,
49                'labels': labels
50            })
51
52        return pools
53
54
55    def run_once(self):
56        """ Tests the moblab's connected DUTs to see if the current
57        configuration is valid for storage qual
58        """
59
60        afe = frontend.AFE(server='localhost', user='moblab')
61
62        # get autotest statuses that indicate a live host
63        live_statuses = afe.host_statuses(live=True)
64
65        # get the hosts connected to autotest, find the live ones
66        hosts = []
67        for host in afe.get_hosts():
68            if host.status in live_statuses:
69                logging.info('Host %s is live, status %s' %
70                        (host.hostname, host.status))
71                hosts.append(host)
72            else:
73                logging.info('Host %s is not live, status %s' %
74                        (host.hostname, host.status))
75
76        pools = self._group_hosts_into_pools(hosts)
77
78        # verify that each pool is set up to run storage qual
79        # err on the side of caution by requiring all pools to have the correct
80        # setup, so it is clear to partners that they could run storage qual
81        # with any configuration on RunSuite page
82        required_set = set(self.REQUIRED_LABELS)
83        for pool_name, pool_hosts in pools.iteritems():
84            provided_set = set()
85            logging.info('Pool %s' % pool_name)
86            for host in pool_hosts:
87                host_provided_labels = set(host['labels']) & required_set
88                # check that each DUT has at most 1 storage qual label
89                if len(host_provided_labels) > 1:
90                    raise error.TestFail(
91                        ('Host %s is assigned more than '
92                            'one storage qual label %s') %
93                            (host['host'], str(host_provided_labels)))
94                if len(host_provided_labels) == 0:
95                    continue
96
97                # check that each label is only on one DUT in the pool
98                provided_label = host_provided_labels.pop()
99                if provided_label in provided_set:
100                    raise error.TestFail(
101                        ('Host %s is assigned label %s, which is already '
102                         'assigned to another DUT in pool %s') %
103                            (host['host'], provided_label, pool_name)
104                    )
105
106                provided_set.add(provided_label)
107                logging.info(' - %s %s' % (host['host'], provided_label))
108
109            # check that all storage qual labels are accounted for in the pool
110            missing_labels = required_set - provided_set
111            if len(missing_labels) > 0:
112                raise error.TestFail(
113                    'Pool %s is missing required labels %s' %
114                        (pool_name, str(missing_labels))
115                )
116
117        return
118