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 re, errno, logging, utils 6from autotest_lib.client.bin import test 7from autotest_lib.client.common_lib import error 8 9class platform_Mosys(test.test): 10 version = 1 11 12 def __TestAllLeafCommands(self): 13 """Tests all "leaf" sub-commands return non-error. 14 15 Commands that return ENOSYS or EINVAL are not counted as error. 16 Return value are not check for correctness. 17 18 Raises: 19 error.TestFail Raised for commands that return non-zero exit code. 20 """ 21 22 # Find all leaf commands by 'mosys -tv'. 23 # Old mosys keeps track root:branch:node numbers; the output for one 24 # command may look like, for example, 25 # [leaf 5:5] mosys platform variant 26 # Latest mosys removes these numbers: 27 # [leaf] mosys platform variant 28 cmd_re = re.compile('\[leaf[^\]]*\] (.+)') 29 bad_cmd_list = [] 30 cmd_list = utils.system_output('mosys -tv') 31 for line in cmd_list.splitlines(): 32 m = cmd_re.search(line) 33 if m and not self.__TestOneCommand(m.group(1)): 34 bad_cmd_list.append(m.group(1)) 35 36 if len(bad_cmd_list) == 1: 37 raise error.TestFail('Command not properly implemented: ' + 38 bad_cmd_list[0]) 39 elif len(bad_cmd_list) > 1: 40 raise error.TestFail('Commands not properly implemented: ' + 41 ','.join(bad_cmd_list)) 42 43 def __TestOneCommand(self, cmd): 44 """ Tests one "leaf" sub-command. 45 46 Returns 47 True if the command returns 0, ENOSYS or EINVAL; False otherwise. 48 """ 49 50 # Note that 'mosys eeprom map' takes about 30 sec to complete on Snow. 51 # We set timeout=40 to accommodate that. 52 result = utils.run(cmd, timeout=40, ignore_status=True) 53 rc = result.exit_status 54 if rc and rc not in [errno.ENOSYS, errno.EINVAL]: 55 # older mosys does not return useful exit code but instead, prints 56 # 'Command not supported on this platform' on stderr or prints 57 # usage info on stdout when the command needs arguments. These are 58 # not considered as error. 59 stderr = result.stderr 60 stdout = result.stdout 61 not_supported = (stderr and 62 stderr.startswith('Command not supported on this platform')) 63 need_argument = stdout and stdout.startswith('usage:') 64 unable_to_determine = (stderr and 65 stderr.startswith('Unable to determine')) 66 if not_supported: 67 logging.info('cmd not supported: "%s"', cmd); 68 elif need_argument: 69 logging.info('cmd needs argument: "%s"', cmd); 70 elif unable_to_determine: 71 logging.info('Unable to determine: "%s"', cmd); 72 else: 73 logging.error('failed to execute "%s"; exit code=%d', cmd, rc); 74 return False 75 76 return True 77 78 def run_once(self): 79 self.__TestAllLeafCommands() 80