1# 2# SPDX-License-Identifier: MIT 3# 4 5import os 6import sys 7import errno 8import datetime 9import itertools 10from .commands import runCmd 11 12class BaseDumper(object): 13 """ Base class to dump commands from host/target """ 14 15 def __init__(self, cmds, parent_dir): 16 self.cmds = [] 17 # Some testing doesn't inherit testimage, so it is needed 18 # to set some defaults. 19 self.parent_dir = parent_dir 20 dft_cmds = """ top -bn1 21 iostat -x -z -N -d -p ALL 20 2 22 ps -ef 23 free 24 df 25 memstat 26 dmesg 27 ip -s link 28 netstat -an""" 29 if not cmds: 30 cmds = dft_cmds 31 for cmd in cmds.split('\n'): 32 cmd = cmd.lstrip() 33 if not cmd or cmd[0] == '#': 34 continue 35 self.cmds.append(cmd) 36 37 def create_dir(self, dir_suffix): 38 dump_subdir = ("%s_%s" % ( 39 datetime.datetime.now().strftime('%Y%m%d%H%M'), 40 dir_suffix)) 41 dump_dir = os.path.join(self.parent_dir, dump_subdir) 42 try: 43 os.makedirs(dump_dir) 44 except OSError as err: 45 if err.errno != errno.EEXIST: 46 raise err 47 self.dump_dir = dump_dir 48 49 def _write_dump(self, command, output): 50 if isinstance(self, HostDumper): 51 prefix = "host" 52 elif isinstance(self, TargetDumper): 53 prefix = "target" 54 else: 55 prefix = "unknown" 56 for i in itertools.count(): 57 filename = "%s_%02d_%s" % (prefix, i, command) 58 fullname = os.path.join(self.dump_dir, filename) 59 if not os.path.exists(fullname): 60 break 61 with open(fullname, 'w') as dump_file: 62 dump_file.write(output) 63 64 65class HostDumper(BaseDumper): 66 """ Class to get dumps from the host running the tests """ 67 68 def __init__(self, cmds, parent_dir): 69 super(HostDumper, self).__init__(cmds, parent_dir) 70 71 def dump_host(self, dump_dir=""): 72 if dump_dir: 73 self.dump_dir = dump_dir 74 for cmd in self.cmds: 75 result = runCmd(cmd, ignore_status=True) 76 self._write_dump(cmd.split()[0], result.output) 77 78class TargetDumper(BaseDumper): 79 """ Class to get dumps from target, it only works with QemuRunner """ 80 81 def __init__(self, cmds, parent_dir, runner): 82 super(TargetDumper, self).__init__(cmds, parent_dir) 83 self.runner = runner 84 85 def dump_target(self, dump_dir=""): 86 if dump_dir: 87 self.dump_dir = dump_dir 88 for cmd in self.cmds: 89 # We can continue with the testing if serial commands fail 90 try: 91 (status, output) = self.runner.run_serial(cmd) 92 self._write_dump(cmd.split()[0], output) 93 except: 94 print("Tried to dump info from target but " 95 "serial console failed") 96